From dovecot at dovecot.org Sun Mar 1 20:14:36 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 01 Mar 2015 20:14:36 +0000 Subject: dovecot-2.2: lib-storage: Allow up to 255 chars in a single mail... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6e3cb68b274d changeset: 18279:6e3cb68b274d user: Timo Sirainen date: Sun Mar 01 22:14:01 2015 +0200 description: lib-storage: Allow up to 255 chars in a single mailbox hierarchy name. This also reduces the max number of hierarchy levels, but 16 should still be enough for normal uses. diffstat: src/lib-storage/mailbox-list.c | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) diffs (22 lines): diff -r 7f67e5c86af9 -r 6e3cb68b274d src/lib-storage/mailbox-list.c --- a/src/lib-storage/mailbox-list.c Fri Feb 27 14:29:10 2015 +0200 +++ b/src/lib-storage/mailbox-list.c Sun Mar 01 22:14:01 2015 +0200 @@ -27,13 +27,14 @@ #include #include -/* 20 * (200+1) < 4096 which is the standard PATH_MAX. Having these settings +/* 16 * (255+1) = 4096 which is the standard PATH_MAX. Having these settings prevents malicious user from creating eg. "a/a/a/.../a" mailbox name and then start renaming them to larger names from end to beginning, which eventually would start causing the failures when trying to use too - long mailbox names. */ -#define MAILBOX_MAX_HIERARCHY_LEVELS 20 -#define MAILBOX_MAX_HIERARCHY_NAME_LENGTH 200 + long mailbox names. 255 is the standard single directory name length, so + allow up to that high. */ +#define MAILBOX_MAX_HIERARCHY_LEVELS 16 +#define MAILBOX_MAX_HIERARCHY_NAME_LENGTH 255 struct mailbox_list_module_register mailbox_list_module_register = { 0 }; From dovecot at dovecot.org Mon Mar 2 12:36:52 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Mar 2015 12:36:52 +0000 Subject: dovecot-2.2: lib: Give a name for istream-seekable's temporary f... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7b2275ae8c19 changeset: 18280:7b2275ae8c19 user: Timo Sirainen date: Mon Mar 02 14:36:15 2015 +0200 description: lib: Give a name for istream-seekable's temporary fd istream. diffstat: src/lib/istream-seekable.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 6e3cb68b274d -r 7b2275ae8c19 src/lib/istream-seekable.c --- a/src/lib/istream-seekable.c Sun Mar 01 22:14:01 2015 +0200 +++ b/src/lib/istream-seekable.c Mon Mar 02 14:36:15 2015 +0200 @@ -105,6 +105,8 @@ sstream->fd = fd; sstream->fd_input = i_stream_create_fd_autoclose(&fd, sstream->istream.max_buffer_size); + i_stream_set_name(sstream->fd_input, t_strdup_printf( + "(seekable temp-istream for: %s)", i_stream_get_name(&stream->istream))); /* read back the data we just had in our buffer */ i_stream_seek(sstream->fd_input, stream->istream.v_offset); From dovecot at dovecot.org Mon Mar 2 12:41:49 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Mar 2015 12:41:49 +0000 Subject: dovecot-2.2: lib: Added assert to i_stream_create_seekable*() to... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/98302e52074e changeset: 18281:98302e52074e user: Timo Sirainen date: Mon Mar 02 14:41:11 2015 +0200 description: lib: Added assert to i_stream_create_seekable*() to have non-zero max_buffer_size. This size is used for the created fd istream and it can't be zero. diffstat: src/lib/istream-seekable.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diffs (30 lines): diff -r 7b2275ae8c19 -r 98302e52074e src/lib/istream-seekable.c --- a/src/lib/istream-seekable.c Mon Mar 02 14:36:15 2015 +0200 +++ b/src/lib/istream-seekable.c Mon Mar 02 14:41:11 2015 +0200 @@ -377,6 +377,8 @@ size_t size; bool blocking = TRUE; + i_assert(max_buffer_size > 0); + /* if any of the streams isn't blocking, set ourself also nonblocking */ for (count = 0; input[count] != NULL; count++) { if (!input[count]->blocking) @@ -434,6 +436,8 @@ int (*fd_callback)(const char **path_r, void *context), void *context) { + i_assert(max_buffer_size > 0); + /* If all input streams are seekable, use concat istream instead */ if (inputs_are_seekable(input)) return i_stream_create_concat(input); @@ -475,6 +479,8 @@ struct seekable_istream *sstream; struct istream *stream; + i_assert(max_buffer_size > 0); + if (inputs_are_seekable(input)) return i_stream_create_concat(input); From dovecot at dovecot.org Mon Mar 2 13:08:26 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Mar 2015 13:08:26 +0000 Subject: dovecot-2.2: dict-redis: Added support for changing the Redis da... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/62e4062302de changeset: 18282:62e4062302de user: Timo Sirainen date: Mon Mar 02 15:07:20 2015 +0200 description: dict-redis: Added support for changing the Redis database. Adding :db=N to the dict string specifies the database. diffstat: src/lib-dict/dict-redis.c | 34 +++++++++++++++++++++++++++++++++- 1 files changed, 33 insertions(+), 1 deletions(-) diffs (100 lines): diff -r 98302e52074e -r 62e4062302de src/lib-dict/dict-redis.c --- a/src/lib-dict/dict-redis.c Mon Mar 02 14:41:11 2015 +0200 +++ b/src/lib-dict/dict-redis.c Mon Mar 02 15:07:20 2015 +0200 @@ -13,6 +13,8 @@ #define DICT_USERNAME_SEPARATOR '/' enum redis_input_state { + /* expecting +OK reply for SELECT */ + REDIS_INPUT_STATE_SELECT, /* expecting $-1 / $ followed by GET reply */ REDIS_INPUT_STATE_GET, /* expecting +QUEUED */ @@ -44,7 +46,7 @@ struct redis_dict { struct dict dict; char *username, *key_prefix, *expire_value; - unsigned int timeout_msecs; + unsigned int timeout_msecs, db_id; struct ioloop *ioloop, *prev_ioloop; struct redis_connection conn; @@ -54,6 +56,7 @@ bool connected; bool transaction_open; + bool db_id_set; }; struct redis_dict_transaction_context { @@ -96,6 +99,7 @@ struct redis_connection *conn = (struct redis_connection *)_conn; const struct redis_dict_reply *reply; + conn->dict->db_id_set = FALSE; conn->dict->connected = FALSE; connection_disconnect(_conn); @@ -215,6 +219,7 @@ switch (state) { case REDIS_INPUT_STATE_GET: i_unreached(); + case REDIS_INPUT_STATE_SELECT: case REDIS_INPUT_STATE_MULTI: case REDIS_INPUT_STATE_DISCARD: if (line[0] != '+') @@ -362,6 +367,12 @@ } else if (strncmp(*args, "prefix=", 7) == 0) { i_free(dict->key_prefix); dict->key_prefix = i_strdup(*args + 7); + } else if (strncmp(*args, "db=", 3) == 0) { + if (str_to_uint(*args+3, &dict->db_id) < 0) { + *error_r = t_strdup_printf( + "Invalid db number: %s", *args+3); + ret = -1; + } } else if (strncmp(*args, "expire_secs=", 12) == 0) { const char *value = *args + 12; @@ -458,6 +469,24 @@ return key; } +static void redis_dict_select_db(struct redis_dict *dict) +{ + const char *cmd, *db_str; + + if (dict->db_id_set) + return; + dict->db_id_set = TRUE; + if (dict->db_id == 0) { + /* 0 is the default */ + return; + } + db_str = dec2str(dict->db_id); + cmd = t_strdup_printf("*2\r\n$6\r\nSELECT\r\n$%d\r\n%s\r\n", + (int)strlen(db_str), db_str); + o_stream_nsend_str(dict->conn.conn.output, cmd); + redis_input_state_add(dict, REDIS_INPUT_STATE_SELECT); +} + static int redis_dict_lookup_real(struct redis_dict *dict, pool_t pool, const char *key, const char **value_r) @@ -488,6 +517,7 @@ } if (dict->connected) { + redis_dict_select_db(dict); cmd = t_strdup_printf("*2\r\n$3\r\nGET\r\n$%d\r\n%s\r\n", (int)strlen(key), key); o_stream_nsend_str(dict->conn.conn.output, cmd); @@ -556,6 +586,8 @@ /* wait for connection */ redis_wait(dict); } + if (dict->connected) + redis_dict_select_db(dict); return &ctx->ctx; } From dovecot at dovecot.org Mon Mar 2 19:15:32 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Mar 2015 19:15:32 +0000 Subject: dovecot-2.2: rawlog: Removed double '.' chars from log filenames Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/63338685c25e changeset: 18283:63338685c25e user: Timo Sirainen date: Mon Mar 02 21:14:55 2015 +0200 description: rawlog: Removed double '.' chars from log filenames diffstat: src/util/rawlog.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 62e4062302de -r 63338685c25e src/util/rawlog.c --- a/src/util/rawlog.c Mon Mar 02 15:07:20 2015 +0200 +++ b/src/util/rawlog.c Mon Mar 02 21:14:55 2015 +0200 @@ -226,7 +226,7 @@ if (ip_addr != NULL && (proxy->flags & RAWLOG_FLAG_LOG_IP_IN_FILENAME) != 0) str_printfa(path_prefix, "%s-", ip_addr); - str_printfa(path_prefix, "%s-%s.", timestamp, dec2str(getpid())); + str_printfa(path_prefix, "%s-%s", timestamp, dec2str(getpid())); if ((proxy->flags & RAWLOG_FLAG_LOG_INPUT) != 0) { fname = t_strdup_printf("%s.in", str_c(path_prefix)); From dovecot at dovecot.org Mon Mar 2 23:06:25 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Mar 2015 23:06:25 +0000 Subject: dovecot-2.2: lib-fs: Added FS_ITER_FLAG_NOCACHE Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e270bf24491c changeset: 18284:e270bf24491c user: Timo Sirainen date: Tue Mar 03 01:05:49 2015 +0200 description: lib-fs: Added FS_ITER_FLAG_NOCACHE diffstat: src/lib-fs/fs-api.h | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diffs (17 lines): diff -r 63338685c25e -r e270bf24491c src/lib-fs/fs-api.h --- a/src/lib-fs/fs-api.h Mon Mar 02 21:14:55 2015 +0200 +++ b/src/lib-fs/fs-api.h Tue Mar 03 01:05:49 2015 +0200 @@ -85,7 +85,12 @@ If this isn't supported, the is returned empty. The object IDs are always hex-encoded data. This flag can be used only if FS_PROPERTY_OBJECTIDS is enabled. */ - FS_ITER_FLAG_OBJECTIDS = 0x04 + FS_ITER_FLAG_OBJECTIDS = 0x04, + /* Explicitly disable all caching for this iteration (if anything + happens to be enabled). This should be used only in situations where + the iteration is used to fix something that is broken, e.g. doveadm + force-resync. */ + FS_ITER_FLAG_NOCACHE = 0x08 }; struct fs_settings { From dovecot at dovecot.org Tue Mar 3 15:26:10 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 03 Mar 2015 15:26:10 +0000 Subject: dovecot-2.2: lib-imap-client: Get capabilities again after recon... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/31c0b82250b6 changeset: 18285:31c0b82250b6 user: Timo Sirainen date: Tue Mar 03 17:25:33 2015 +0200 description: lib-imap-client: Get capabilities again after reconnection to server. This is needed most importantly if we're not using plaintext authentication to log in. diffstat: src/lib-imap-client/imapc-connection.c | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-) diffs (19 lines): diff -r e270bf24491c -r 31c0b82250b6 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Tue Mar 03 01:05:49 2015 +0200 +++ b/src/lib-imap-client/imapc-connection.c Tue Mar 03 17:25:33 2015 +0200 @@ -400,6 +400,15 @@ conn->fd = -1; } + /* get capabilities again after reconnection. this is especially + important because post-login capabilities often do not contain AUTH= + capabilities. */ + conn->capabilities = 0; + if (conn->capabilities_list != NULL) { + p_strsplit_free(default_pool, conn->capabilities_list); + conn->capabilities_list = NULL; + } + imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED); imapc_connection_abort_commands(conn, NULL, reconnecting); } From dovecot at dovecot.org Tue Mar 3 17:35:44 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 03 Mar 2015 17:35:44 +0000 Subject: dovecot-2.2: doveadm backup -R: Open the mailbox as readonly, so... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ef0bfe110ed9 changeset: 18286:ef0bfe110ed9 user: Timo Sirainen date: Tue Mar 03 19:32:28 2015 +0200 description: doveadm backup -R: Open the mailbox as readonly, so with imapc EXAMINE is used. diffstat: src/doveadm/dsync/dsync-brain-mailbox.c | 15 +++++++++++---- 1 files changed, 11 insertions(+), 4 deletions(-) diffs (38 lines): diff -r 31c0b82250b6 -r ef0bfe110ed9 src/doveadm/dsync/dsync-brain-mailbox.c --- a/src/doveadm/dsync/dsync-brain-mailbox.c Tue Mar 03 17:25:33 2015 +0200 +++ b/src/doveadm/dsync/dsync-brain-mailbox.c Tue Mar 03 19:32:28 2015 +0200 @@ -14,15 +14,22 @@ #include "dsync-brain-private.h" static int -ns_mailbox_try_alloc(struct mail_namespace *ns, const guid_128_t guid, - struct mailbox **box_r, const char **error_r) +ns_mailbox_try_alloc(struct dsync_brain *brain, struct mail_namespace *ns, + const guid_128_t guid, struct mailbox **box_r, + const char **error_r) { + enum mailbox_flags flags = 0; struct mailbox *box; enum mailbox_existence existence; enum mail_error err; int ret; - box = mailbox_alloc_guid(ns->list, guid, 0); + if (brain->backup_send) { + /* make sure mailbox isn't modified */ + flags |= MAILBOX_FLAG_READONLY; + } + + box = mailbox_alloc_guid(ns->list, guid, flags); ret = mailbox_exists(box, FALSE, &existence); if (ret < 0) { *error_r = mailbox_get_last_error(box, &err); @@ -51,7 +58,7 @@ for (ns = brain->user->namespaces; ns != NULL; ns = ns->next) { if (!dsync_brain_want_namespace(brain, ns)) continue; - if ((ret = ns_mailbox_try_alloc(ns, guid, box_r, error_r)) != 0) { + if ((ret = ns_mailbox_try_alloc(brain, ns, guid, box_r, error_r)) != 0) { if (ret < 0) brain->failed = TRUE; return ret; From dovecot at dovecot.org Tue Mar 3 17:35:45 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 03 Mar 2015 17:35:45 +0000 Subject: dovecot-2.2: dsync: Open mailboxes with readonly-flag whenever p... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/06c4c42549a7 changeset: 18287:06c4c42549a7 user: Timo Sirainen date: Tue Mar 03 19:34:59 2015 +0200 description: dsync: Open mailboxes with readonly-flag whenever possible. There shouldn't be any actual functional difference though. diffstat: src/doveadm/dsync/dsync-brain-mailbox-tree.c | 2 +- src/doveadm/dsync/dsync-brain.c | 3 ++- src/doveadm/dsync/dsync-mailbox-tree-fill.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diffs (37 lines): diff -r ef0bfe110ed9 -r 06c4c42549a7 src/doveadm/dsync/dsync-brain-mailbox-tree.c --- a/src/doveadm/dsync/dsync-brain-mailbox-tree.c Tue Mar 03 19:32:28 2015 +0200 +++ b/src/doveadm/dsync/dsync-brain-mailbox-tree.c Tue Mar 03 19:34:59 2015 +0200 @@ -173,7 +173,7 @@ struct mailbox *box; bool ret; - box = mailbox_alloc(ns->list, vname, 0); + box = mailbox_alloc(ns->list, vname, MAILBOX_FLAG_READONLY); ret = mailbox_verify_create_name(box) == 0; mailbox_free(&box); return ret; diff -r ef0bfe110ed9 -r 06c4c42549a7 src/doveadm/dsync/dsync-brain.c --- a/src/doveadm/dsync/dsync-brain.c Tue Mar 03 19:32:28 2015 +0200 +++ b/src/doveadm/dsync/dsync-brain.c Tue Mar 03 19:34:59 2015 +0200 @@ -148,7 +148,8 @@ struct mail_namespace *ns; ns = mail_namespace_find(brain->user->namespaces, vname); - brain->virtual_all_box = mailbox_alloc(ns->list, vname, 0); + brain->virtual_all_box = + mailbox_alloc(ns->list, vname, MAILBOX_FLAG_READONLY); } struct dsync_brain * diff -r ef0bfe110ed9 -r 06c4c42549a7 src/doveadm/dsync/dsync-mailbox-tree-fill.c --- a/src/doveadm/dsync/dsync-mailbox-tree-fill.c Tue Mar 03 19:32:28 2015 +0200 +++ b/src/doveadm/dsync/dsync-mailbox-tree-fill.c Tue Mar 03 19:34:59 2015 +0200 @@ -89,7 +89,7 @@ } /* get GUID and UIDVALIDITY for selectable mailbox */ - box = mailbox_alloc(info->ns->list, info->vname, 0); + box = mailbox_alloc(info->ns->list, info->vname, MAILBOX_FLAG_READONLY); if (dsync_mailbox_tree_get_selectable(box, &metadata, &status) < 0) { errstr = mailbox_get_last_error(box, &error); switch (error) { From dovecot at dovecot.org Tue Mar 3 17:48:58 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 03 Mar 2015 17:48:58 +0000 Subject: dovecot-2.2: doveadm backup: Try to avoid crashing on unexpected... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fdc7a0a2b18d changeset: 18288:fdc7a0a2b18d user: Timo Sirainen date: Tue Mar 03 19:48:23 2015 +0200 description: doveadm backup: Try to avoid crashing on unexpected destination changes. It's a bit difficult to reproduce this bug.. But at least this change should change the assert, if nothing else. diffstat: src/doveadm/dsync/dsync-mailbox-tree-sync.c | 12 ++++++++---- 1 files changed, 8 insertions(+), 4 deletions(-) diffs (39 lines): diff -r 06c4c42549a7 -r fdc7a0a2b18d src/doveadm/dsync/dsync-mailbox-tree-sync.c --- a/src/doveadm/dsync/dsync-mailbox-tree-sync.c Tue Mar 03 19:34:59 2015 +0200 +++ b/src/doveadm/dsync/dsync-mailbox-tree-sync.c Tue Mar 03 19:48:23 2015 +0200 @@ -663,14 +663,16 @@ remote_node1, local_node1, reason_r); *reason_r = t_strconcat(*reason_r, "(local: remote_node1=NULL)", NULL); return TRUE; - } else if (node_has_parent(local_node1, local_node2)) { + } else if (node_has_parent(local_node1, local_node2) && + ctx->sync_type != DSYNC_MAILBOX_TREES_SYNC_TYPE_PRESERVE_LOCAL) { /* node2 is a parent of node1, but it should be vice versa */ sync_rename_node_to_temp(ctx, ctx->local_tree, local_node1, local_node2->parent, reason_r); *reason_r = t_strconcat(*reason_r, "(local: node2 parent of node1)", NULL); return TRUE; - } else if (node_has_parent(local_node2, local_node1)) { + } else if (node_has_parent(local_node2, local_node1) && + ctx->sync_type != DSYNC_MAILBOX_TREES_SYNC_TYPE_PRESERVE_LOCAL) { /* node1 is a parent of node2, but it should be vice versa */ sync_rename_node_to_temp(ctx, ctx->local_tree, @@ -702,12 +704,14 @@ local_node2, remote_node2, reason_r); *reason_r = t_strconcat(*reason_r, "(remote: local_node2=NULL)", NULL); return TRUE; - } else if (node_has_parent(remote_node1, remote_node2)) { + } else if (node_has_parent(remote_node1, remote_node2) && + ctx->sync_type != DSYNC_MAILBOX_TREES_SYNC_TYPE_PRESERVE_REMOTE) { sync_rename_node_to_temp(ctx, ctx->remote_tree, remote_node1, remote_node2->parent, reason_r); *reason_r = t_strconcat(*reason_r, "(remote: node2 parent of node1)", NULL); return TRUE; - } else if (node_has_parent(remote_node2, remote_node1)) { + } else if (node_has_parent(remote_node2, remote_node1) && + ctx->sync_type != DSYNC_MAILBOX_TREES_SYNC_TYPE_PRESERVE_REMOTE) { sync_rename_node_to_temp(ctx, ctx->remote_tree, remote_node2, remote_node1->parent, reason_r); *reason_r = t_strconcat(*reason_r, "(remote: node1 parent of node2)", NULL); From dovecot at dovecot.org Thu Mar 5 21:05:29 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 05 Mar 2015 21:05:29 +0000 Subject: dovecot-2.2: lib-fs: Added fs_get_parent() and fs_get_driver() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/422b5a01d18e changeset: 18289:422b5a01d18e user: Timo Sirainen date: Thu Mar 05 22:17:09 2015 +0200 description: lib-fs: Added fs_get_parent() and fs_get_driver() These can be used to iterate through fs wrappers and see what they are. diffstat: src/lib-fs/fs-api.c | 10 ++++++++++ src/lib-fs/fs-api.h | 5 +++++ 2 files changed, 15 insertions(+), 0 deletions(-) diffs (35 lines): diff -r fdc7a0a2b18d -r 422b5a01d18e src/lib-fs/fs-api.c --- a/src/lib-fs/fs-api.c Tue Mar 03 19:48:23 2015 +0200 +++ b/src/lib-fs/fs-api.c Thu Mar 05 22:17:09 2015 +0200 @@ -155,6 +155,16 @@ str_free(&last_error); } +struct fs *fs_get_parent(struct fs *fs) +{ + return fs->parent; +} + +const char *fs_get_driver(struct fs *fs) +{ + return fs->name; +} + const char *fs_get_root_driver(struct fs *fs) { while (fs->parent != NULL) diff -r fdc7a0a2b18d -r 422b5a01d18e src/lib-fs/fs-api.h --- a/src/lib-fs/fs-api.h Tue Mar 03 19:48:23 2015 +0200 +++ b/src/lib-fs/fs-api.h Thu Mar 05 22:17:09 2015 +0200 @@ -135,6 +135,11 @@ struct fs **fs_r, const char **error_r); void fs_deinit(struct fs **fs); +/* Returns the parent filesystem (if this is a wrapper fs) or NULL if + there's no parent. */ +struct fs *fs_get_parent(struct fs *fs); +/* Returns the filesystem's driver name. */ +const char *fs_get_driver(struct fs *fs); /* Returns the root fs's driver name (bypassing all wrapper fses) */ const char *fs_get_root_driver(struct fs *fs); From dovecot at dovecot.org Thu Mar 5 21:05:30 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 05 Mar 2015 21:05:30 +0000 Subject: dovecot-2.2: lib-fs: Track how many different operations have be... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/18721584583b changeset: 18290:18721584583b user: Timo Sirainen date: Thu Mar 05 22:18:04 2015 +0200 description: lib-fs: Track how many different operations have been done on the fs. diffstat: src/lib-fs/fs-api-private.h | 7 +++++++ src/lib-fs/fs-api.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/lib-fs/fs-api.h | 26 ++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 0 deletions(-) diffs (206 lines): diff -r 422b5a01d18e -r 18721584583b src/lib-fs/fs-api-private.h --- a/src/lib-fs/fs-api-private.h Thu Mar 05 22:17:09 2015 +0200 +++ b/src/lib-fs/fs-api-private.h Thu Mar 05 22:18:04 2015 +0200 @@ -70,6 +70,8 @@ unsigned int files_open_count; struct fs_file *files; struct fs_iter *iters; + + struct fs_stats stats; }; struct fs_file { @@ -96,6 +98,11 @@ unsigned int write_pending:1; unsigned int metadata_changed:1; + + unsigned int read_counted:1; + unsigned int prefetch_counted:1; + unsigned int lookup_metadata_counted:1; + unsigned int stat_counted:1; }; struct fs_lock { diff -r 422b5a01d18e -r 18721584583b src/lib-fs/fs-api.c --- a/src/lib-fs/fs-api.c Thu Mar 05 22:17:09 2015 +0200 +++ b/src/lib-fs/fs-api.c Thu Mar 05 22:18:04 2015 +0200 @@ -269,6 +269,11 @@ fs_set_error(file->fs, "Metadata not supported by backend"); return -1; } + if (!file->read_counted && !file->prefetch_counted && + !file->lookup_metadata_counted) { + file->lookup_metadata_counted = TRUE; + file->fs->stats.lookup_metadata_count++; + } T_BEGIN { ret = file->fs->v.get_metadata(file, metadata_r); } T_END; @@ -336,6 +341,10 @@ { bool ret; + if (!file->read_counted && !file->prefetch_counted) { + file->prefetch_counted = TRUE; + file->fs->stats.prefetch_count++; + } T_BEGIN { ret = file->fs->v.prefetch(file, length); } T_END; @@ -374,6 +383,11 @@ { int ret; + if (!file->read_counted && !file->prefetch_counted) { + file->read_counted = TRUE; + file->fs->stats.read_count++; + } + if (file->fs->v.read != NULL) { T_BEGIN { ret = file->fs->v.read(file, buf, size); @@ -394,6 +408,11 @@ ssize_t ret; bool want_seekable = FALSE; + if (!file->read_counted && !file->prefetch_counted) { + file->read_counted = TRUE; + file->fs->stats.read_count++; + } + if (file->seekable_input != NULL) { i_stream_seek(file->seekable_input, 0); i_stream_ref(file->seekable_input); @@ -476,6 +495,7 @@ { int ret; + file->fs->stats.write_count++; if (file->fs->v.write != NULL) { T_BEGIN { ret = file->fs->v.write(file, data, size); @@ -490,6 +510,7 @@ struct ostream *fs_write_stream(struct fs_file *file) { + file->fs->stats.write_count++; T_BEGIN { file->fs->v.write_stream(file); } T_END; @@ -607,6 +628,7 @@ else return errno == ENOENT ? 0 : -1; } + file->fs->stats.exists_count++; T_BEGIN { ret = file->fs->v.exists(file); } T_END; @@ -617,6 +639,11 @@ { int ret; + if (!file->read_counted && !file->prefetch_counted && + !file->lookup_metadata_counted && !file->stat_counted) { + file->stat_counted = TRUE; + file->fs->stats.stat_count++; + } T_BEGIN { ret = file->fs->v.stat(file, st_r); } T_END; @@ -625,6 +652,10 @@ int fs_default_copy(struct fs_file *src, struct fs_file *dest) { + /* we're going to be counting this as read+write, so remove the + copy_count we just added */ + dest->fs->stats.copy_count--; + if (dest->copy_src != NULL) { i_assert(src == NULL || src == dest->copy_src); if (dest->copy_output == NULL) { @@ -675,6 +706,7 @@ i_assert(src->fs == dest->fs); + dest->fs->stats.copy_count++; T_BEGIN { ret = src->fs->v.copy(src, dest); } T_END; @@ -701,6 +733,7 @@ i_assert(src->fs == dest->fs); + dest->fs->stats.rename_count++; T_BEGIN { ret = src->fs->v.rename(src, dest); } T_END; @@ -711,6 +744,7 @@ { int ret; + file->fs->stats.delete_count++; T_BEGIN { ret = file->fs->v.delete_file(file); } T_END; @@ -725,6 +759,7 @@ i_assert((flags & FS_ITER_FLAG_OBJECTIDS) == 0 || (fs_get_properties(fs) & FS_PROPERTY_OBJECTIDS) != 0); + fs->stats.iter_count++; T_BEGIN { iter = fs->v.iter_init(fs, path, flags); } T_END; @@ -768,6 +803,11 @@ return iter->async_have_more; } +const struct fs_stats *fs_get_stats(struct fs *fs) +{ + return &fs->stats; +} + void fs_set_error(struct fs *fs, const char *fmt, ...) { va_list args; diff -r 422b5a01d18e -r 18721584583b src/lib-fs/fs-api.h --- a/src/lib-fs/fs-api.h Thu Mar 05 22:17:09 2015 +0200 +++ b/src/lib-fs/fs-api.h Thu Mar 05 22:18:04 2015 +0200 @@ -122,6 +122,27 @@ bool debug; }; +struct fs_stats { + /* Number of fs_prefetch() calls. */ + unsigned int prefetch_count; + /* Number of fs_read*() calls. Counted only if fs_prefetch() hasn't + been called for the file. */ + unsigned int read_count; + /* Number of fs_lookup_metadata() calls. Counted only if neither + fs_read*() nor fs_prefetch() has been called for the file. */ + unsigned int lookup_metadata_count; + /* Number of fs_stat() calls. Counted only if none of the above + has been called (because the stat result should be cached). */ + unsigned int stat_count; + + unsigned int write_count; + unsigned int exists_count; + unsigned int delete_count; + unsigned int copy_count; + unsigned int rename_count; + unsigned int iter_count; +}; + struct fs_metadata { const char *key; const char *value; @@ -264,4 +285,9 @@ function to determine if you should wait for more data or finish up. */ bool fs_iter_have_more(struct fs_iter *iter); +/* Return the filesystem's fs_stats. Note that each wrapper filesystem keeps + track of its own fs_stats calls. You can use fs_get_parent() to get to the + filesystem whose stats you want to see. */ +const struct fs_stats *fs_get_stats(struct fs *fs); + #endif From dovecot at dovecot.org Thu Mar 5 21:05:30 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 05 Mar 2015 21:05:30 +0000 Subject: dovecot-2.2: lib: Don't call ioloop context deactivate() if acti... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c98991820dde changeset: 18291:c98991820dde user: Timo Sirainen date: Thu Mar 05 22:19:02 2015 +0200 description: lib: Don't call ioloop context deactivate() if activate() hasn't been called yet. This could have happened immediately after the callback was registered. diffstat: src/lib/ioloop-private.h | 1 + src/lib/ioloop.c | 22 ++++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diffs (56 lines): diff -r 18721584583b -r c98991820dde src/lib/ioloop-private.h --- a/src/lib/ioloop-private.h Thu Mar 05 22:18:04 2015 +0200 +++ b/src/lib/ioloop-private.h Thu Mar 05 22:19:02 2015 +0200 @@ -77,6 +77,7 @@ io_callback_t *activate; io_callback_t *deactivate; void *context; + bool activated; }; struct ioloop_context { diff -r 18721584583b -r c98991820dde src/lib/ioloop.c --- a/src/lib/ioloop.c Thu Mar 05 22:18:04 2015 +0200 +++ b/src/lib/ioloop.c Thu Mar 05 22:19:02 2015 +0200 @@ -781,25 +781,35 @@ void io_loop_context_activate(struct ioloop_context *ctx) { - const struct ioloop_context_callback *cb; + struct ioloop_context_callback *cb; i_assert(ctx->ioloop->cur_ctx == NULL); ctx->ioloop->cur_ctx = ctx; io_loop_context_ref(ctx); - array_foreach(&ctx->callbacks, cb) { + array_foreach_modifiable(&ctx->callbacks, cb) { + i_assert(!cb->activated); if (cb->activate != NULL) cb->activate(cb->context); + cb->activated = TRUE; } } void io_loop_context_deactivate(struct ioloop_context *ctx) { - const struct ioloop_context_callback *cb; + struct ioloop_context_callback *cb; - array_foreach(&ctx->callbacks, cb) { - if (cb->deactivate != NULL) - cb->deactivate(cb->context); + i_assert(ctx->ioloop->cur_ctx != NULL); + + array_foreach_modifiable(&ctx->callbacks, cb) { + if (!cb->activated) { + /* we just added this callback. don't deactivate it + before it gets first activated. */ + } else { + if (cb->deactivate != NULL) + cb->deactivate(cb->context); + cb->activated = FALSE; + } } ctx->ioloop->cur_ctx = NULL; io_loop_context_remove_deleted_callbacks(ctx); From dovecot at dovecot.org Thu Mar 5 21:05:30 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 05 Mar 2015 21:05:30 +0000 Subject: dovecot-2.2: stats process/plugin redesign to be more modular. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a9952ceeac61 changeset: 18292:a9952ceeac61 user: Timo Sirainen date: Thu Mar 05 23:02:48 2015 +0200 description: stats process/plugin redesign to be more modular. The visible functionality doesn't actually change with this patch yet, but it allows other plugins/services to add their own fields to stats process. For example auth process could send auth success/failures or auth cache hits/misses. diffstat: configure.ac | 3 +- src/Makefile.am | 1 + src/lib-dovecot/Makefile.am | 1 + src/lib-stats/Makefile.am | 15 + src/lib-stats/stats-parser.c | 180 +++++++++++++++ src/lib-stats/stats-parser.h | 29 ++ src/lib-stats/stats.c | 220 +++++++++++++++++++ src/lib-stats/stats.h | 69 ++++++ src/lib-storage/mail-user.c | 11 + src/lib-storage/mail-user.h | 8 +- src/plugins/imap-stats/Makefile.am | 1 + src/plugins/imap-stats/imap-stats-plugin.c | 36 +- src/plugins/stats/Makefile.am | 12 + src/plugins/stats/mail-stats-fill.c | 130 +++++++++++ src/plugins/stats/mail-stats.c | 168 ++++++++++++++ src/plugins/stats/mail-stats.h | 38 +++ src/plugins/stats/stats-connection.c | 14 +- src/plugins/stats/stats-connection.h | 2 +- src/plugins/stats/stats-plugin.c | 327 ++++------------------------ src/plugins/stats/stats-plugin.h | 43 +-- src/stats/Makefile.am | 5 +- src/stats/client-export.c | 123 +++++----- src/stats/mail-command.c | 34 ++- src/stats/mail-domain.c | 7 +- src/stats/mail-domain.h | 4 +- src/stats/mail-ip.c | 7 +- src/stats/mail-ip.h | 2 +- src/stats/mail-server-connection.c | 24 +- src/stats/mail-session.c | 36 ++- src/stats/mail-session.h | 4 +- src/stats/mail-stats.c | 277 +----------------------- src/stats/mail-stats.h | 40 +-- src/stats/mail-user.c | 7 +- src/stats/mail-user.h | 4 +- src/stats/main.c | 22 +- 35 files changed, 1164 insertions(+), 740 deletions(-) diffs (truncated from 2751 to 300 lines): diff -r c98991820dde -r a9952ceeac61 configure.ac --- a/configure.ac Thu Mar 05 22:19:02 2015 +0200 +++ b/configure.ac Thu Mar 05 23:02:48 2015 +0200 @@ -2549,7 +2549,7 @@ LIBDOVECOT_COMPRESS='$(top_builddir)/src/lib-compression/libcompression.la' LIBDOVECOT_LDA='$(top_builddir)/src/lib-lda/libdovecot-lda.la' else - LIBDOVECOT_DEPS='$(top_builddir)/src/lib-master/libmaster.la $(top_builddir)/src/lib-settings/libsettings.la $(top_builddir)/src/lib-http/libhttp.la $(top_builddir)/src/lib-dict/libdict.la $(top_builddir)/src/lib-dns/libdns.la $(top_builddir)/src/lib-fs/libfs.la $(top_builddir)/src/lib-imap/libimap.la $(top_builddir)/src/lib-mail/libmail.la $(top_builddir)/src/lib-sasl/libsasl.la $(top_builddir)/src/lib-auth/libauth.la $(top_builddir)/src/lib-charset/libcharset.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la $(top_builddir)/src/lib-test/libtest.la $(top_builddir)/src/lib/liblib.la' + LIBDOVECOT_DEPS='$(top_builddir)/src/lib-master/libmaster.la $(top_builddir)/src/lib-settings/libsettings.la $(top_builddir)/src/lib-stats/libstats.la $(top_builddir)/src/lib-http/libhttp.la $(top_builddir)/src/lib-dict/libdict.la $(top_builddir)/src/lib-dns/libdns.la $(top_builddir)/src/lib-fs/libfs.la $(top_builddir)/src/lib-imap/libimap.la $(top_builddir)/src/lib-mail/libmail.la $(top_builddir)/src/lib-sasl/libsasl.la $(top_builddir)/src/lib-auth/libauth.la $(top_builddir)/src/lib-charset/libcharset.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la $(top_builddir)/src/lib-test/libtest.la $(top_builddir)/src/lib/liblib.la' LIBDOVECOT="$LIBDOVECOT_DEPS \$(LIBICONV) \$(MODULE_LIBS)" LIBDOVECOT_STORAGE_DEPS='$(top_builddir)/src/lib-storage/libstorage.la' LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/liblogin.la' @@ -2849,6 +2849,7 @@ src/lib-sasl/Makefile src/lib-settings/Makefile src/lib-ssl-iostream/Makefile +src/lib-stats/Makefile src/lib-test/Makefile src/lib-storage/Makefile src/lib-storage/list/Makefile diff -r c98991820dde -r a9952ceeac61 src/Makefile.am --- a/src/Makefile.am Thu Mar 05 22:19:02 2015 +0200 +++ b/src/Makefile.am Thu Mar 05 23:02:48 2015 +0200 @@ -9,6 +9,7 @@ lib-dict \ lib-sasl \ lib-ssl-iostream \ + lib-stats \ lib-http \ lib-fs \ lib-mail \ diff -r c98991820dde -r a9952ceeac61 src/lib-dovecot/Makefile.am --- a/src/lib-dovecot/Makefile.am Thu Mar 05 22:19:02 2015 +0200 +++ b/src/lib-dovecot/Makefile.am Thu Mar 05 23:02:48 2015 +0200 @@ -3,6 +3,7 @@ ../lib-master/libmaster.la \ ../lib-fs/libfs.la \ ../lib-settings/libsettings.la \ + ../lib-stats/libstats.la \ ../lib-http/libhttp.la \ ../lib-dict/libdict.la \ ../lib-imap/libimap.la \ diff -r c98991820dde -r a9952ceeac61 src/lib-stats/Makefile.am --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-stats/Makefile.am Thu Mar 05 23:02:48 2015 +0200 @@ -0,0 +1,15 @@ +noinst_LTLIBRARIES = libstats.la + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/lib + +libstats_la_SOURCES = \ + stats.c \ + stats-parser.c + +headers = \ + stats.h \ + stats-parser.h + +pkginc_libdir = $(pkgincludedir) +pkginc_lib_HEADERS = $(headers) diff -r c98991820dde -r a9952ceeac61 src/lib-stats/stats-parser.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-stats/stats-parser.c Thu Mar 05 23:02:48 2015 +0200 @@ -0,0 +1,180 @@ +/* Copyright (c) 2011-2015 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "str.h" +#include "time-util.h" +#include "stats-parser.h" + +#define USECS_PER_SEC 1000000 + +static bool stats_diff_timeval(struct timeval *dest, + const struct timeval *src1, + const struct timeval *src2) +{ + long long diff_usecs; + + diff_usecs = timeval_diff_usecs(src2, src1); + if (diff_usecs < 0) + return FALSE; + dest->tv_sec = diff_usecs / USECS_PER_SEC; + dest->tv_usec = diff_usecs % USECS_PER_SEC; + return TRUE; +} + +static bool +stats_diff_uint32(uint32_t *dest, const uint32_t *src1, const uint32_t *src2) +{ + if (*src1 > *src2) + return FALSE; + *dest = *src2 - *src1; + return TRUE; +} + +static bool +stats_diff_uint64(uint64_t *dest, const uint64_t *src1, const uint64_t *src2) +{ + if (*src1 > *src2) + return FALSE; + *dest = *src2 - *src1; + return TRUE; +} + +bool stats_parser_diff(const struct stats_parser_field *fields, + unsigned int fields_count, + const struct stats *stats1, const struct stats *stats2, + struct stats *diff_stats_r, const char **error_r) +{ + unsigned int i; + + for (i = 0; i < fields_count; i++) { + unsigned int offset = fields[i].offset; + void *dest = PTR_OFFSET(diff_stats_r, offset); + const void *src1 = CONST_PTR_OFFSET(stats1, offset); + const void *src2 = CONST_PTR_OFFSET(stats2, offset); + + switch (fields[i].type) { + case STATS_PARSER_TYPE_UINT: + switch (fields[i].size) { + case sizeof(uint32_t): + if (!stats_diff_uint32(dest, src1, src2)) { + *error_r = t_strdup_printf("%s %u < %u", + fields[i].name, + *(const uint32_t *)src2, + *(const uint32_t *)src1); + return FALSE; + } + break; + case sizeof(uint64_t): + if (!stats_diff_uint64(dest, src1, src2)) { + const uint64_t *n1 = src1, *n2 = src2; + + *error_r = t_strdup_printf("%s %llu < %llu", + fields[i].name, + (unsigned long long)*n2, + (unsigned long long)*n1); + return FALSE; + } + break; + default: + i_unreached(); + } + break; + case STATS_PARSER_TYPE_TIMEVAL: + if (!stats_diff_timeval(dest, src1, src2)) { + const struct timeval *tv1 = src1, *tv2 = src2; + + *error_r = t_strdup_printf("%s %ld.%d < %ld.%d", + fields[i].name, + (long)tv2->tv_sec, (int)tv2->tv_usec, + (long)tv1->tv_sec, (int)tv1->tv_usec); + return FALSE; + } + break; + } + } + return TRUE; +} + +static void stats_timeval_add(struct timeval *dest, const struct timeval *src) +{ + dest->tv_sec += src->tv_sec; + dest->tv_usec += src->tv_usec; + if (dest->tv_usec > USECS_PER_SEC) { + dest->tv_usec -= USECS_PER_SEC; + dest->tv_sec++; + } +} + +void stats_parser_add(const struct stats_parser_field *fields, + unsigned int fields_count, + struct stats *dest, const struct stats *src) +{ + unsigned int i; + + for (i = 0; i < fields_count; i++) { + unsigned int offset = fields[i].offset; + void *f_dest = PTR_OFFSET(dest, offset); + const void *f_src = CONST_PTR_OFFSET(src, offset); + + switch (fields[i].type) { + case STATS_PARSER_TYPE_UINT: + switch (fields[i].size) { + case sizeof(uint32_t): { + uint32_t *n_dest = f_dest; + const uint32_t *n_src = f_src; + + *n_dest += *n_src; + break; + } + case sizeof(uint64_t): { + uint64_t *n_dest = f_dest; + const uint64_t *n_src = f_src; + + *n_dest += *n_src; + break; + } + default: + i_unreached(); + } + break; + case STATS_PARSER_TYPE_TIMEVAL: + stats_timeval_add(f_dest, f_src); + break; + } + } +} + +void stats_parser_value(string_t *str, + const struct stats_parser_field *field, + const void *data) +{ + const void *ptr = CONST_PTR_OFFSET(data, field->offset); + + switch (field->type) { + case STATS_PARSER_TYPE_UINT: + switch (field->size) { + case sizeof(uint32_t): { + const uint32_t *n = ptr; + + str_printfa(str, "%u", *n); + break; + } + case sizeof(uint64_t): { + const uint64_t *n = ptr; + + str_printfa(str, "%llu", (unsigned long long)*n); + break; + } + default: + i_unreached(); + } + break; + case STATS_PARSER_TYPE_TIMEVAL: { + const struct timeval *tv = ptr; + + str_printfa(str, "%lu.%u", (unsigned long)tv->tv_sec, + (unsigned int)tv->tv_usec); + break; + } + } +} diff -r c98991820dde -r a9952ceeac61 src/lib-stats/stats-parser.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-stats/stats-parser.h Thu Mar 05 23:02:48 2015 +0200 @@ -0,0 +1,29 @@ +#ifndef STATS_PARSER_H +#define STATS_PARSER_H + +struct stats; + +enum stats_parser_type { + STATS_PARSER_TYPE_UINT, + STATS_PARSER_TYPE_TIMEVAL +}; + +struct stats_parser_field { + const char *name; + unsigned int offset; + unsigned int size; + enum stats_parser_type type; +}; + +bool stats_parser_diff(const struct stats_parser_field *fields, + unsigned int fields_count, + const struct stats *stats1, const struct stats *stats2, + struct stats *diff_stats_r, const char **error_r); +void stats_parser_add(const struct stats_parser_field *fields, + unsigned int fields_count, + struct stats *dest, const struct stats *src); +void stats_parser_value(string_t *str, + const struct stats_parser_field *field, + const void *data); + +#endif diff -r c98991820dde -r a9952ceeac61 src/lib-stats/stats.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-stats/stats.c Thu Mar 05 23:02:48 2015 +0200 @@ -0,0 +1,220 @@ +/* Copyright (c) 2015 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "array.h" +#include "stats.h" + +struct stats_item { + struct stats_vfuncs v; + size_t pos; +}; + +static ARRAY(struct stats_item *) stats_items = ARRAY_INIT; +static unsigned int stats_total_size = 0; +static bool stats_allocated = FALSE; + +struct stats_item *stats_register(const struct stats_vfuncs *vfuncs) +{ + struct stats_item *item; From dovecot at dovecot.org Thu Mar 5 22:41:53 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 05 Mar 2015 22:41:53 +0000 Subject: dovecot-2.2: quota: If overquota-flag in userdb is wrong, execut... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a54408ed4767 changeset: 18293:a54408ed4767 user: Timo Sirainen date: Fri Mar 06 00:40:46 2015 +0200 description: quota: If overquota-flag in userdb is wrong, execute a configured script. The idea here is that a quota_warning script could set user's overquota-flag to e.g. LDAP where MTA could reject mails already at RCPT TO stage. The quota_warning scripts however have race conditions that are difficult (or impossible) to fix, so sometimes the overquota-flag could become wrong and might require manual intervention to fix it. This feature is supposed to solve the issue by comparing the overquota-flag's status to the actual current quota usage and execute a script to fix up the situation if needed. This script is of course racy as well, but there's always the next login that can fix the situation. Also it's pretty rare that user's quota is jumping just around the limit. The overquota-flag name in userdb must be "quota_over_flag". There are two settings to configure what to do: plugin { # If quota_over_flag=TRUE, the overquota-flag is enabled. Otherwise not. quota_over_flag_value = TRUE # Any non-empty value for quota_over_flag means user is over quota. # Wildcards can be used in a generic way, e.g. "*yes" or "*TRUE*" #quota_over_flag_value = * # Service script to execute if overquota-flag is wrong. Configured the # same as quota_warning scripts. The current quota_over_flag's value is # appended as the last parameter. quota_over_script = quota-warning mismatch %u } diffstat: src/plugins/quota/quota-private.h | 2 + src/plugins/quota/quota-storage.c | 2 + src/plugins/quota/quota.c | 68 +++++++++++++++++++++++++++++++++++++- src/plugins/quota/quota.h | 3 + 4 files changed, 73 insertions(+), 2 deletions(-) diffs (146 lines): diff -r a9952ceeac61 -r a54408ed4767 src/plugins/quota/quota-private.h --- a/src/plugins/quota/quota-private.h Thu Mar 05 23:02:48 2015 +0200 +++ b/src/plugins/quota/quota-private.h Fri Mar 06 00:40:46 2015 +0200 @@ -81,6 +81,8 @@ struct quota_root_settings { /* Unique quota root name. */ const char *name; + /* Name in settings, e.g. "quota", "quota2", .. */ + const char *set_name; struct quota_settings *set; const char *args; diff -r a9952ceeac61 -r a54408ed4767 src/plugins/quota/quota-storage.c --- a/src/plugins/quota/quota-storage.c Thu Mar 05 23:02:48 2015 +0200 +++ b/src/plugins/quota/quota-storage.c Fri Mar 06 00:40:46 2015 +0200 @@ -631,4 +631,6 @@ roots = array_get("a->roots, &count); for (i = 0; i < count; i++) quota_root_set_namespace(roots[i], namespaces); + + quota_over_flag_check(namespaces->user, quota); } diff -r a9952ceeac61 -r a54408ed4767 src/plugins/quota/quota.c --- a/src/plugins/quota/quota.c Thu Mar 05 23:02:48 2015 +0200 +++ b/src/plugins/quota/quota.c Fri Mar 06 00:40:46 2015 +0200 @@ -7,6 +7,7 @@ #include "net.h" #include "write-full.h" #include "eacces-error.h" +#include "wildcard-match.h" #include "dict.h" #include "mailbox-list-private.h" #include "quota-private.h" @@ -191,6 +192,7 @@ if (quota_root_settings_init(quota_set, env, &root_set, error_r) < 0) return -1; + root_set->set_name = p_strdup(quota_set->pool, root_name); if (quota_root_add_rules(user, root_name, root_set, error_r) < 0) return -1; if (quota_root_add_warning_rules(user, root_name, root_set, error_r) < 0) @@ -823,7 +825,8 @@ return 0; } -static void quota_warning_execute(struct quota_root *root, const char *cmd) +static void quota_warning_execute(struct quota_root *root, const char *cmd, + const char *last_arg) { const char *socket_path, *const *args; string_t *str; @@ -833,6 +836,14 @@ i_debug("quota: Executing warning: %s", cmd); args = t_strsplit_spaces(cmd, " "); + if (last_arg != NULL) { + unsigned int count = str_array_length(args); + const char **new_args = t_new(const char *, count + 2); + + memcpy(new_args, args, sizeof(const char *) * count); + new_args[count] = last_arg; + args = new_args; + } socket_path = args[0]; args++; @@ -892,7 +903,7 @@ if (quota_warning_match(&warnings[i], bytes_before, bytes_current, count_before, count_current)) { - quota_warning_execute(root, warnings[i].command); + quota_warning_execute(root, warnings[i].command, NULL); break; } } @@ -951,6 +962,59 @@ return ret; } +static void +quota_over_flag_check_root(struct mail_user *user, struct quota_root *root) +{ + const char *name, *flag_mask, *overquota_value, *overquota_script; + const char *const *resources; + unsigned int i; + uint64_t value, limit; + bool overquota_flag, cur_overquota = FALSE; + int ret; + + name = t_strconcat(root->set->set_name, "_over_script", NULL); + overquota_script = mail_user_plugin_getenv(user, name); + if (overquota_script == NULL) + return; + + /* e.g.: quota_over_flag_value=TRUE or quota_over_flag_value=* */ + name = t_strconcat(root->set->set_name, "_over_flag_value", NULL); + flag_mask = mail_user_plugin_getenv(user, name); + if (flag_mask == NULL) + return; + + /* compare quota_over_flag's value to quota_over_flag_value and + save the result. */ + name = t_strconcat(root->set->set_name, "_over_flag", NULL); + overquota_value = mail_user_plugin_getenv(user, name); + overquota_flag = overquota_value != NULL && + overquota_value[0] != '\0' && + wildcard_match_icase(overquota_value, flag_mask); + + resources = quota_root_get_resources(root); + for (i = 0; resources[i] != NULL; i++) { + ret = quota_get_resource(root, "", resources[i], &value, &limit); + if (ret < 0) { + /* can't reliably verify this */ + return; + } + if (ret > 0 && value > limit) + cur_overquota = TRUE; + } + if (cur_overquota != overquota_flag) + quota_warning_execute(root, overquota_script, overquota_value); +} + +void quota_over_flag_check(struct mail_user *user, struct quota *quota) +{ + struct quota_root *const *roots; + unsigned int i, count; + + roots = array_get("a->roots, &count); + for (i = 0; i < count; i++) + quota_over_flag_check_root(user, roots[i]); +} + void quota_transaction_rollback(struct quota_transaction_context **_ctx) { struct quota_transaction_context *ctx = *_ctx; diff -r a9952ceeac61 -r a54408ed4767 src/plugins/quota/quota.h --- a/src/plugins/quota/quota.h Thu Mar 05 23:02:48 2015 +0200 +++ b/src/plugins/quota/quota.h Fri Mar 06 00:40:46 2015 +0200 @@ -83,4 +83,7 @@ /* Mark the quota to be recalculated */ void quota_recalculate(struct quota_transaction_context *ctx); +/* Execute quota_over_scripts if needed. */ +void quota_over_flag_check(struct mail_user *user, struct quota *quota); + #endif From dovecot at dovecot.org Thu Mar 5 22:41:53 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 05 Mar 2015 22:41:53 +0000 Subject: dovecot-2.2: lib: Minor improvement to test-wildcard-match unit ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/91852459f388 changeset: 18294:91852459f388 user: Timo Sirainen date: Fri Mar 06 00:41:14 2015 +0200 description: lib: Minor improvement to test-wildcard-match unit test. diffstat: src/lib/test-wildcard-match.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (14 lines): diff -r a54408ed4767 -r 91852459f388 src/lib/test-wildcard-match.c --- a/src/lib/test-wildcard-match.c Fri Mar 06 00:40:46 2015 +0200 +++ b/src/lib/test-wildcard-match.c Fri Mar 06 00:41:14 2015 +0200 @@ -27,6 +27,10 @@ { "foo", "f*o*o*o", FALSE }, { "foo", "f???*", FALSE }, + { "*foo", "foo", FALSE }, + { "foo*", "foo", FALSE }, + { "*foo*", "foo", FALSE }, + { "", "*", TRUE }, { "", "", TRUE }, { "", "?", FALSE } From dovecot at dovecot.org Thu Mar 5 23:02:07 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 05 Mar 2015 23:02:07 +0000 Subject: dovecot-2.2: pop3-login: Disconnect client on 3rd invalid comman... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2589f9c5cc04 changeset: 18295:2589f9c5cc04 user: Timo Sirainen date: Fri Mar 06 01:01:28 2015 +0200 description: pop3-login: Disconnect client on 3rd invalid command (not 11th). diffstat: src/pop3-login/client.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 91852459f388 -r 2589f9c5cc04 src/pop3-login/client.c --- a/src/pop3-login/client.c Fri Mar 06 00:41:14 2015 +0200 +++ b/src/pop3-login/client.c Fri Mar 06 01:01:28 2015 +0200 @@ -20,7 +20,7 @@ #include "pop3-login-settings.h" /* Disconnect client when it sends too many bad commands */ -#define CLIENT_MAX_BAD_COMMANDS 10 +#define CLIENT_MAX_BAD_COMMANDS 3 static bool cmd_stls(struct pop3_client *client) { @@ -130,7 +130,7 @@ if (client_command_execute(pop3_client, line, args != NULL ? args : "")) client->bad_counter = 0; - else if (++client->bad_counter > CLIENT_MAX_BAD_COMMANDS) { + else if (++client->bad_counter >= CLIENT_MAX_BAD_COMMANDS) { client_send_reply(client, POP3_CMD_REPLY_ERROR, "Too many invalid bad commands."); client_destroy(client, From dovecot at dovecot.org Fri Mar 6 00:06:53 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 06 Mar 2015 00:06:53 +0000 Subject: dovecot-2.2: lmtp: Changed rcpt_to array to contain pointers to ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c1403c1eb3e9 changeset: 18296:c1403c1eb3e9 user: Timo Sirainen date: Fri Mar 06 02:06:10 2015 +0200 description: lmtp: Changed rcpt_to array to contain pointers to struct mail_recipient This allow storing the pointers so they don't change. diffstat: src/lmtp/client.c | 6 +++--- src/lmtp/client.h | 2 +- src/lmtp/commands.c | 32 ++++++++++++++++---------------- 3 files changed, 20 insertions(+), 20 deletions(-) diffs (139 lines): diff -r 2589f9c5cc04 -r c1403c1eb3e9 src/lmtp/client.c --- a/src/lmtp/client.c Fri Mar 06 01:01:28 2015 +0200 +++ b/src/lmtp/client.c Fri Mar 06 02:06:10 2015 +0200 @@ -349,14 +349,14 @@ void client_state_reset(struct client *client, const char *state_name) { - struct mail_recipient *rcpt; + struct mail_recipient *const *rcptp; if (client->proxy != NULL) lmtp_proxy_deinit(&client->proxy); if (array_is_created(&client->state.rcpt_to)) { - array_foreach_modifiable(&client->state.rcpt_to, rcpt) - mail_storage_service_user_free(&rcpt->service_user); + array_foreach_modifiable(&client->state.rcpt_to, rcptp) + mail_storage_service_user_free(&(*rcptp)->service_user); } if (client->state.raw_mail != NULL) { diff -r 2589f9c5cc04 -r c1403c1eb3e9 src/lmtp/client.h --- a/src/lmtp/client.h Fri Mar 06 01:01:28 2015 +0200 +++ b/src/lmtp/client.h Fri Mar 06 02:06:10 2015 +0200 @@ -18,7 +18,7 @@ const char *name; const char *session_id; const char *mail_from; - ARRAY(struct mail_recipient) rcpt_to; + ARRAY(struct mail_recipient *) rcpt_to; unsigned int rcpt_idx; unsigned int data_end_idx; diff -r 2589f9c5cc04 -r c1403c1eb3e9 src/lmtp/commands.c --- a/src/lmtp/commands.c Fri Mar 06 01:01:28 2015 +0200 +++ b/src/lmtp/commands.c Fri Mar 06 02:06:10 2015 +0200 @@ -565,7 +565,7 @@ int cmd_rcpt(struct client *client, const char *args) { - struct mail_recipient rcpt; + struct mail_recipient *rcpt; struct mail_storage_service_input input; const char *params, *address, *username, *detail, *prefix; const char *const *argv; @@ -583,13 +583,13 @@ return 0; } - memset(&rcpt, 0, sizeof(rcpt)); + rcpt = p_new(client->state_pool, struct mail_recipient, 1); address = lmtp_unescape_address(address); argv = t_strsplit(params, " "); for (; *argv != NULL; argv++) { if (strncasecmp(*argv, "ORCPT=", 6) == 0) { - rcpt.params.dsn_orcpt = parse_xtext(client, *argv + 6); + rcpt->params.dsn_orcpt = parse_xtext(client, *argv + 6); } else { client_send_line(client, "501 5.5.4 Unsupported options"); return 0; @@ -601,7 +601,7 @@ if (client->lmtp_set->lmtp_proxy) { if (client_proxy_rcpt(client, address, username, detail, - &rcpt.params)) + &rcpt->params)) return 0; } @@ -615,7 +615,7 @@ input.session_id = client->state.session_id; ret = mail_storage_service_lookup(storage_service, &input, - &rcpt.service_user, &error); + &rcpt->service_user, &error); if (ret < 0) { prefix = t_strdup_printf(ERRSTR_TEMP_USERDB_FAIL_PREFIX, @@ -641,11 +641,11 @@ lmtp_address_translate(client, &address); - rcpt.address = p_strdup(client->state_pool, address); - rcpt.detail = p_strdup(client->state_pool, detail); - if ((ret = lmtp_rcpt_to_is_over_quota(client, &rcpt)) < 0) { + rcpt->address = p_strdup(client->state_pool, address); + rcpt->detail = p_strdup(client->state_pool, detail); + if ((ret = lmtp_rcpt_to_is_over_quota(client, rcpt)) < 0) { client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL, - rcpt.address); + rcpt->address); return 0; } if (ret == 0) { @@ -813,13 +813,13 @@ static bool client_deliver_next(struct client *client, struct mail *src_mail, struct mail_deliver_session *session) { - const struct mail_recipient *rcpts; + struct mail_recipient *const *rcpts; unsigned int count; int ret; rcpts = array_get(&client->state.rcpt_to, &count); while (client->state.rcpt_idx < count) { - ret = client_deliver(client, &rcpts[client->state.rcpt_idx], + ret = client_deliver(client, rcpts[client->state.rcpt_idx], src_mail, session); client_state_set(client, "DATA", ""); i_set_failure_prefix("lmtp(%s): ", my_pid); @@ -836,11 +836,11 @@ static void client_rcpt_fail_all(struct client *client) { - const struct mail_recipient *rcpt; + struct mail_recipient *const *rcptp; - array_foreach(&client->state.rcpt_to, rcpt) { + array_foreach(&client->state.rcpt_to, rcptp) { client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL, - rcpt->address); + (*rcptp)->address); } } @@ -986,10 +986,10 @@ const char *host, *rcpt_to = NULL; if (array_count(&client->state.rcpt_to) == 1) { - const struct mail_recipient *rcpt = + struct mail_recipient *const *rcptp = array_idx(&client->state.rcpt_to, 0); - rcpt_to = rcpt->address; + rcpt_to = (*rcptp)->address; } /* don't set Return-Path when proxying so it won't get added twice */ From dovecot at dovecot.org Fri Mar 6 00:10:42 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 06 Mar 2015 00:10:42 +0000 Subject: dovecot-2.2: lmtp: Added lmtp_user_concurrency_limit setting. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0e657cfb3f98 changeset: 18297:0e657cfb3f98 user: Timo Sirainen date: Fri Mar 06 02:10:02 2015 +0200 description: lmtp: Added lmtp_user_concurrency_limit setting. This allows limiting the number of concurrent deliveries to a single user. Useful in case one user is receiving a lot of mails and causing other deliveries to be delayed. If the limit is reached, Dovecot returns temporary failure error at DATA stage. diffstat: src/lmtp/client.c | 6 +++- src/lmtp/client.h | 7 ++++ src/lmtp/commands.c | 75 ++++++++++++++++++++++++++++++++++++++++++++--- src/lmtp/lmtp-settings.c | 2 + src/lmtp/lmtp-settings.h | 1 + src/lmtp/main.c | 4 ++ src/lmtp/main.h | 1 + 7 files changed, 89 insertions(+), 7 deletions(-) diffs (284 lines): diff -r c1403c1eb3e9 -r 0e657cfb3f98 src/lmtp/client.c --- a/src/lmtp/client.c Fri Mar 06 02:06:10 2015 +0200 +++ b/src/lmtp/client.c Fri Mar 06 02:10:02 2015 +0200 @@ -11,6 +11,7 @@ #include "process-title.h" #include "var-expand.h" #include "settings-parser.h" +#include "anvil-client.h" #include "master-service.h" #include "master-service-ssl.h" #include "master-service-settings.h" @@ -355,8 +356,11 @@ lmtp_proxy_deinit(&client->proxy); if (array_is_created(&client->state.rcpt_to)) { - array_foreach_modifiable(&client->state.rcpt_to, rcptp) + array_foreach_modifiable(&client->state.rcpt_to, rcptp) { + if ((*rcptp)->anvil_query != NULL) + anvil_client_query_abort(anvil, &(*rcptp)->anvil_query); mail_storage_service_user_free(&(*rcptp)->service_user); + } } if (client->state.raw_mail != NULL) { diff -r c1403c1eb3e9 -r 0e657cfb3f98 src/lmtp/client.h --- a/src/lmtp/client.h Fri Mar 06 02:06:10 2015 +0200 +++ b/src/lmtp/client.h Fri Mar 06 02:10:02 2015 +0200 @@ -7,11 +7,15 @@ #define CLIENT_MAIL_DATA_MAX_INMEMORY_SIZE (1024*128) struct mail_recipient { + struct client *client; + const char *address; const char *detail; /* +detail part is also in address */ struct lmtp_recipient_params params; + struct anvil_query *anvil_query; struct mail_storage_service_user *service_user; + unsigned int parallel_count; }; struct client_state { @@ -21,6 +25,9 @@ ARRAY(struct mail_recipient *) rcpt_to; unsigned int rcpt_idx; + unsigned int anvil_queries; + bool anvil_pending_data_write; + unsigned int data_end_idx; /* Initially we start writing to mail_data. If it grows too large, diff -r c1403c1eb3e9 -r 0e657cfb3f98 src/lmtp/commands.c --- a/src/lmtp/commands.c Fri Mar 06 02:06:10 2015 +0200 +++ b/src/lmtp/commands.c Fri Mar 06 02:10:02 2015 +0200 @@ -15,6 +15,7 @@ #include "var-expand.h" #include "restrict-access.h" #include "settings-parser.h" +#include "anvil-client.h" #include "master-service.h" #include "master-service-ssl.h" #include "iostream-ssl.h" @@ -41,6 +42,8 @@ #define LMTP_PROXY_DEFAULT_TIMEOUT_MSECS (1000*30) +static void client_input_data_write(struct client *client); + int cmd_lhlo(struct client *client, const char *args) { struct rfc822_parser_context parser; @@ -563,6 +566,34 @@ return ret; } +static void rcpt_anvil_lookup_callback(const char *reply, void *context) +{ + struct mail_recipient *rcpt = context; + + i_assert(rcpt->client->state.anvil_queries > 0); + + rcpt->anvil_query = NULL; + if (reply == NULL) { + /* lookup failed */ + } else if (str_to_uint(reply, &rcpt->parallel_count) < 0) { + i_error("Invalid reply from anvil: %s", reply); + } + if (--rcpt->client->state.anvil_queries == 0 && + rcpt->client->state.anvil_pending_data_write) { + /* DATA command was finished, but we were still waiting on + anvil before handling any users */ + client_input_data_write(rcpt->client); + } +} + +static void lmtp_anvil_init(void) +{ + if (anvil == NULL) { + const char *path = t_strdup_printf("%s/anvil", base_dir); + anvil = anvil_client_init(path, NULL, 0); + } +} + int cmd_rcpt(struct client *client, const char *args) { struct mail_recipient *rcpt; @@ -584,6 +615,7 @@ } rcpt = p_new(client->state_pool, struct mail_recipient, 1); + rcpt->client = client; address = lmtp_unescape_address(address); argv = t_strsplit(params, " "); @@ -652,6 +684,17 @@ array_append(&client->state.rcpt_to, &rcpt, 1); client_send_line(client, "250 2.1.5 OK"); } + + if (client->lmtp_set->lmtp_user_concurrency_limit > 0) { + const char *query = t_strconcat("LOOKUP\t", + master_service_get_name(master_service), + "/", str_tabescape(username), NULL); + lmtp_anvil_init(); + rcpt->anvil_query = anvil_client_query(anvil, query, + rcpt_anvil_lookup_callback, rcpt); + if (rcpt->anvil_query != NULL) + client->state.anvil_queries++; + } return 0; } @@ -710,9 +753,18 @@ enum mail_error mail_error; int ret; + i_assert(client->state.anvil_queries == 0); + input = mail_storage_service_user_get_input(rcpt->service_user); username = t_strdup(input->username); + if (rcpt->parallel_count >= client->lmtp_set->lmtp_user_concurrency_limit) { + client_send_line(client, ERRSTR_TEMP_USERDB_FAIL_PREFIX + "Too many concurrent deliveries for user", + rcpt->address); + return -1; + } + mail_set = mail_storage_service_user_get_mail_set(rcpt->service_user); set_parser = mail_storage_service_user_get_settings_parser(rcpt->service_user); if (client->proxy_timeout_secs > 0 && @@ -776,6 +828,11 @@ dctx.save_dest_mail = array_count(&client->state.rcpt_to) > 1 && client->state.first_saved_mail == NULL; + if (client->lmtp_set->lmtp_user_concurrency_limit > 0) { + master_service_anvil_send(master_service, t_strconcat( + "CONNECT\t", my_pid, "\t", master_service_get_name(master_service), + "/", username, "\n", NULL)); + } if (mail_deliver(&dctx, &storage) == 0) { if (dctx.dest_mail != NULL) { i_assert(client->state.first_saved_mail == NULL); @@ -807,6 +864,11 @@ rcpt->address); ret = -1; } + if (client->lmtp_set->lmtp_user_concurrency_limit > 0) { + master_service_anvil_send(master_service, t_strconcat( + "DISCONNECT\t", my_pid, "\t", master_service_get_name(master_service), + "/", username, "\n", NULL)); + } return ret; } @@ -1019,10 +1081,9 @@ return str_c(str); } -static bool client_input_data_write(struct client *client) +static void client_input_data_write(struct client *client) { struct istream *input; - bool ret = TRUE; /* stop handling client input until saving/proxying is finished */ if (client->to_idle != NULL) @@ -1037,10 +1098,10 @@ client_state_set(client, "DATA", "proxying"); lmtp_proxy_start(client->proxy, input, client_proxy_finish, client); - ret = FALSE; + } else { + client_input_data_finish(client); } i_stream_unref(&input); - return ret; } static int client_input_add_file(struct client *client, @@ -1127,8 +1188,10 @@ return; } - if (client_input_data_write(client)) - client_input_data_finish(client); + if (client->state.anvil_queries == 0) + client_input_data_write(client); + else + client->state.anvil_pending_data_write = TRUE; } static void client_input_data(struct client *client) diff -r c1403c1eb3e9 -r 0e657cfb3f98 src/lmtp/lmtp-settings.c --- a/src/lmtp/lmtp-settings.c Fri Mar 06 02:06:10 2015 +0200 +++ b/src/lmtp/lmtp-settings.c Fri Mar 06 02:10:02 2015 +0200 @@ -60,6 +60,7 @@ DEF(SET_BOOL, lmtp_proxy), DEF(SET_BOOL, lmtp_save_to_detail_mailbox), DEF(SET_BOOL, lmtp_rcpt_check_quota), + DEF(SET_UINT, lmtp_user_concurrency_limit), DEF(SET_STR, lmtp_address_translate), DEF(SET_STR_VARS, login_greeting), DEF(SET_STR, login_trusted_networks), @@ -71,6 +72,7 @@ .lmtp_proxy = FALSE, .lmtp_save_to_detail_mailbox = FALSE, .lmtp_rcpt_check_quota = FALSE, + .lmtp_user_concurrency_limit = 0, .lmtp_address_translate = "", .login_greeting = PACKAGE_NAME" ready.", .login_trusted_networks = "" diff -r c1403c1eb3e9 -r 0e657cfb3f98 src/lmtp/lmtp-settings.h --- a/src/lmtp/lmtp-settings.h Fri Mar 06 02:06:10 2015 +0200 +++ b/src/lmtp/lmtp-settings.h Fri Mar 06 02:10:02 2015 +0200 @@ -8,6 +8,7 @@ bool lmtp_proxy; bool lmtp_save_to_detail_mailbox; bool lmtp_rcpt_check_quota; + unsigned int lmtp_user_concurrency_limit; const char *lmtp_address_translate; const char *login_greeting; const char *login_trusted_networks; diff -r c1403c1eb3e9 -r 0e657cfb3f98 src/lmtp/main.c --- a/src/lmtp/main.c Fri Mar 06 02:06:10 2015 +0200 +++ b/src/lmtp/main.c Fri Mar 06 02:10:02 2015 +0200 @@ -7,6 +7,7 @@ #include "abspath.h" #include "restrict-access.h" #include "fd-close-on-exec.h" +#include "anvil-client.h" #include "master-service.h" #include "master-service-settings.h" #include "master-interface.h" @@ -27,6 +28,7 @@ const char *dns_client_socket_path, *base_dir; struct mail_storage_service_ctx *storage_service; +struct anvil_client *anvil; static void client_connected(struct master_service_connection *conn) { @@ -69,6 +71,8 @@ static void main_deinit(void) { clients_destroy(); + if (anvil != NULL) + anvil_client_deinit(&anvil); } int main(int argc, char *argv[]) diff -r c1403c1eb3e9 -r 0e657cfb3f98 src/lmtp/main.h --- a/src/lmtp/main.h Fri Mar 06 02:06:10 2015 +0200 +++ b/src/lmtp/main.h Fri Mar 06 02:10:02 2015 +0200 @@ -3,6 +3,7 @@ extern const char *dns_client_socket_path, *base_dir; extern struct mail_storage_service_ctx *storage_service; +extern struct anvil_client *anvil; void listener_client_destroyed(void); From dovecot at dovecot.org Fri Mar 6 00:24:34 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 06 Mar 2015 00:24:34 +0000 Subject: dovecot-2.2: lib-master: Added anvil_client_query_abort() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/03931c3b43b5 changeset: 18298:03931c3b43b5 user: Timo Sirainen date: Fri Mar 06 02:23:56 2015 +0200 description: lib-master: Added anvil_client_query_abort() diffstat: src/lib-master/anvil-client.c | 53 ++++++++++++++++++++++++++++++++---------- src/lib-master/anvil-client.h | 12 +++++++-- 2 files changed, 49 insertions(+), 16 deletions(-) diffs (126 lines): diff -r 0e657cfb3f98 -r 03931c3b43b5 src/lib-master/anvil-client.c --- a/src/lib-master/anvil-client.c Fri Mar 06 02:10:02 2015 +0200 +++ b/src/lib-master/anvil-client.c Fri Mar 06 02:23:56 2015 +0200 @@ -24,7 +24,7 @@ struct timeout *to_reconnect; time_t last_reconnect; - ARRAY(struct anvil_query) queries_arr; + ARRAY(struct anvil_query *) queries_arr; struct aqueue *queries; bool (*reconnect_callback)(void); @@ -91,7 +91,8 @@ static void anvil_input(struct anvil_client *client) { - const struct anvil_query *queries, *query; + struct anvil_query *const *queries; + struct anvil_query *query; const char *line; unsigned int count; @@ -102,10 +103,11 @@ continue; } - query = &queries[aqueue_idx(client->queries, 0)]; - T_BEGIN { + query = queries[aqueue_idx(client->queries, 0)]; + if (query->callback != NULL) T_BEGIN { query->callback(line, query->context); } T_END; + i_free(query); aqueue_delete_tail(client->queries); } if (client->input->stream_errno != 0) { @@ -148,13 +150,15 @@ static void anvil_client_cancel_queries(struct anvil_client *client) { - const struct anvil_query *queries, *query; + struct anvil_query *const *queries, *query; unsigned int count; queries = array_get(&client->queries_arr, &count); while (aqueue_count(client->queries) > 0) { - query = &queries[aqueue_idx(client->queries, 0)]; - query->callback(NULL, query->context); + query = queries[aqueue_idx(client->queries, 0)]; + if (query->callback != NULL) + query->callback(NULL, query->context); + i_free(query); aqueue_delete_tail(client->queries); } } @@ -190,19 +194,42 @@ return 0; } -void anvil_client_query(struct anvil_client *client, const char *query, - anvil_callback_t *callback, void *context) +struct anvil_query * +anvil_client_query(struct anvil_client *client, const char *query, + anvil_callback_t *callback, void *context) { - struct anvil_query anvil_query; + struct anvil_query *anvil_query; if (anvil_client_send(client, query) < 0) { callback(NULL, context); - return; + return NULL; } - anvil_query.callback = callback; - anvil_query.context = context; + anvil_query = i_new(struct anvil_query, 1); + anvil_query->callback = callback; + anvil_query->context = context; aqueue_append(client->queries, &anvil_query); + return anvil_query; +} + +void anvil_client_query_abort(struct anvil_client *client, + struct anvil_query **_query) +{ + struct anvil_query *query = *_query; + struct anvil_query *const *queries; + unsigned int i, count; + + *_query = NULL; + + count = aqueue_count(client->queries); + queries = array_idx(&client->queries_arr, 0); + for (i = 0; i < count; i++) { + if (queries[aqueue_idx(client->queries, i)] == query) { + query->callback = NULL; + return; + } + } + i_panic("anvil query to be aborted doesn't exist"); } void anvil_client_cmd(struct anvil_client *client, const char *cmd) diff -r 0e657cfb3f98 -r 03931c3b43b5 src/lib-master/anvil-client.h --- a/src/lib-master/anvil-client.h Fri Mar 06 02:10:02 2015 +0200 +++ b/src/lib-master/anvil-client.h Fri Mar 06 02:23:56 2015 +0200 @@ -19,9 +19,15 @@ /* Connect to anvil. If retry=TRUE, try connecting for a while */ int anvil_client_connect(struct anvil_client *client, bool retry); -/* Send a query to anvil, expect a one line reply. */ -void anvil_client_query(struct anvil_client *client, const char *query, - anvil_callback_t *callback, void *context); +/* Send a query to anvil, expect a one line reply. The returned pointer can be + used to abort the query later. It becomes invalid when callback is + called (= the callback must not call it). Returns NULL if the query couldn't + be sent. */ +struct anvil_query * +anvil_client_query(struct anvil_client *client, const char *query, + anvil_callback_t *callback, void *context); +void anvil_client_query_abort(struct anvil_client *client, + struct anvil_query **query); /* Send a command to anvil, don't expect any replies. */ void anvil_client_cmd(struct anvil_client *client, const char *cmd); From dovecot at dovecot.org Fri Mar 6 09:52:36 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 06 Mar 2015 09:52:36 +0000 Subject: dovecot-2.2: lib-fs: Minor code cleanup: Merge read_counted & pr... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/03d9e1e6caaa changeset: 18299:03d9e1e6caaa user: Timo Sirainen date: Fri Mar 06 11:51:55 2015 +0200 description: lib-fs: Minor code cleanup: Merge read_counted & prefetch_counted into read_or_prefetch_counted diffstat: src/lib-fs/fs-api-private.h | 3 +-- src/lib-fs/fs-api.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) diffs (67 lines): diff -r 03931c3b43b5 -r 03d9e1e6caaa src/lib-fs/fs-api-private.h --- a/src/lib-fs/fs-api-private.h Fri Mar 06 02:23:56 2015 +0200 +++ b/src/lib-fs/fs-api-private.h Fri Mar 06 11:51:55 2015 +0200 @@ -99,8 +99,7 @@ unsigned int write_pending:1; unsigned int metadata_changed:1; - unsigned int read_counted:1; - unsigned int prefetch_counted:1; + unsigned int read_or_prefetch_counted:1; unsigned int lookup_metadata_counted:1; unsigned int stat_counted:1; }; diff -r 03931c3b43b5 -r 03d9e1e6caaa src/lib-fs/fs-api.c --- a/src/lib-fs/fs-api.c Fri Mar 06 02:23:56 2015 +0200 +++ b/src/lib-fs/fs-api.c Fri Mar 06 11:51:55 2015 +0200 @@ -269,7 +269,7 @@ fs_set_error(file->fs, "Metadata not supported by backend"); return -1; } - if (!file->read_counted && !file->prefetch_counted && + if (!file->read_or_prefetch_counted && !file->lookup_metadata_counted) { file->lookup_metadata_counted = TRUE; file->fs->stats.lookup_metadata_count++; @@ -341,8 +341,8 @@ { bool ret; - if (!file->read_counted && !file->prefetch_counted) { - file->prefetch_counted = TRUE; + if (!file->read_or_prefetch_counted) { + file->read_or_prefetch_counted = TRUE; file->fs->stats.prefetch_count++; } T_BEGIN { @@ -383,8 +383,8 @@ { int ret; - if (!file->read_counted && !file->prefetch_counted) { - file->read_counted = TRUE; + if (!file->read_or_prefetch_counted) { + file->read_or_prefetch_counted = TRUE; file->fs->stats.read_count++; } @@ -408,8 +408,8 @@ ssize_t ret; bool want_seekable = FALSE; - if (!file->read_counted && !file->prefetch_counted) { - file->read_counted = TRUE; + if (!file->read_or_prefetch_counted) { + file->read_or_prefetch_counted = TRUE; file->fs->stats.read_count++; } @@ -639,7 +639,7 @@ { int ret; - if (!file->read_counted && !file->prefetch_counted && + if (!file->read_or_prefetch_counted && !file->lookup_metadata_counted && !file->stat_counted) { file->stat_counted = TRUE; file->fs->stats.stat_count++; From dovecot at dovecot.org Fri Mar 6 09:56:24 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 06 Mar 2015 09:56:24 +0000 Subject: dovecot-2.2: lib-fs: struct fs_stats comment updates Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0effbc9afeee changeset: 18300:0effbc9afeee user: Timo Sirainen date: Fri Mar 06 11:55:45 2015 +0200 description: lib-fs: struct fs_stats comment updates diffstat: src/lib-fs/fs-api.h | 16 ++++++++++++++-- 1 files changed, 14 insertions(+), 2 deletions(-) diffs (40 lines): diff -r 03d9e1e6caaa -r 0effbc9afeee src/lib-fs/fs-api.h --- a/src/lib-fs/fs-api.h Fri Mar 06 11:51:55 2015 +0200 +++ b/src/lib-fs/fs-api.h Fri Mar 06 11:55:45 2015 +0200 @@ -123,10 +123,12 @@ }; struct fs_stats { - /* Number of fs_prefetch() calls. */ + /* Number of fs_prefetch() calls. Counted only if fs_read*() hasn't + already been called for the file (which would be pretty pointless + to do). */ unsigned int prefetch_count; /* Number of fs_read*() calls. Counted only if fs_prefetch() hasn't - been called for the file. */ + already been called for the file. */ unsigned int read_count; /* Number of fs_lookup_metadata() calls. Counted only if neither fs_read*() nor fs_prefetch() has been called for the file. */ @@ -135,11 +137,21 @@ has been called (because the stat result should be cached). */ unsigned int stat_count; + /* Number of fs_write*() calls. */ unsigned int write_count; + /* Number of fs_exists() calls, which actually went to the backend + instead of being handled by fs_stat() call due to fs_exists() not + being implemented. */ unsigned int exists_count; + /* Number of fs_delete() calls. */ unsigned int delete_count; + /* Number of fs_copy() calls. If backend doesn't implement copying + operation but falls back to regular read+write instead, this count + isn't increased but the read+write counters are. */ unsigned int copy_count; + /* Number of fs_rename() calls. */ unsigned int rename_count; + /* Number of fs_iter_init() calls. */ unsigned int iter_count; }; From dovecot at dovecot.org Fri Mar 6 14:34:03 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 06 Mar 2015 14:34:03 +0000 Subject: dovecot-2.2: lib-lda: lmtp client now supports checking for time... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9a384f83b2a3 changeset: 18301:9a384f83b2a3 user: Timo Sirainen date: Fri Mar 06 16:30:55 2015 +0200 description: lib-lda: lmtp client now supports checking for timeouts internally. The default is still to have no timeout. diffstat: src/lib-lda/lmtp-client.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/lib-lda/lmtp-client.h | 3 +++ 2 files changed, 50 insertions(+), 0 deletions(-) diffs (135 lines): diff -r 0effbc9afeee -r 9a384f83b2a3 src/lib-lda/lmtp-client.c --- a/src/lib-lda/lmtp-client.c Fri Mar 06 11:55:45 2015 +0200 +++ b/src/lib-lda/lmtp-client.c Fri Mar 06 16:30:55 2015 +0200 @@ -55,6 +55,7 @@ struct istream *input; struct ostream *output; struct io *io; + struct timeout *to; int fd; void (*data_output_callback)(void *); @@ -103,6 +104,7 @@ client->set.source_port = set->source_port; client->set.proxy_ttl = set->proxy_ttl; client->set.proxy_timeout_secs = set->proxy_timeout_secs; + client->set.timeout_secs = set->timeout_secs; client->finish_callback = finish_callback; client->finish_context = context; client->fd = -1; @@ -115,6 +117,8 @@ { if (client->dns_lookup != NULL) dns_lookup_abort(&client->dns_lookup); + if (client->to != NULL) + timeout_remove(&client->to); if (client->io != NULL) io_remove(&client->io); if (client->input != NULL) @@ -604,6 +608,8 @@ " (disconnected in input)"); } o_stream_uncork(client->output); + if (client->to != NULL) + timeout_reset(client->to); lmtp_client_unref(&client); } @@ -619,11 +625,21 @@ " (connect)"); return; } + if (client->to != NULL) + timeout_remove(&client->to); io_remove(&client->io); client->io = io_add(client->fd, IO_READ, lmtp_client_input, client); lmtp_client_input(client); } +static void lmtp_client_connect_timeout(struct lmtp_client *client) +{ + i_error("lmtp client: connect(%s, %u) failed: Timed out in %u secs", + client->host, client->port, client->set.timeout_secs); + lmtp_client_fail(client, ERRSTR_TEMP_REMOTE_FAILURE + " (connect timeout)"); +} + static int lmtp_client_output(struct lmtp_client *client) { int ret; @@ -636,12 +652,16 @@ else if (client->input_state == LMTP_INPUT_STATE_DATA) (void)lmtp_client_send_data(client); o_stream_uncork(client->output); + if (client->to != NULL) + timeout_reset(client->to); lmtp_client_unref(&client); return ret; } static int lmtp_client_connect(struct lmtp_client *client) { + i_assert(client->fd == -1); + client->fd = net_connect_ip(&client->ip, client->port, NULL); if (client->fd == -1) { i_error("lmtp client: connect(%s, %u) failed: %m", @@ -656,6 +676,10 @@ /* we're already sending data in ostream, so can't use IO_WRITE here */ client->io = io_add(client->fd, IO_READ, lmtp_client_wait_connect, client); + if (client->set.timeout_secs > 0) { + client->to = timeout_add(client->set.timeout_secs*1000, + lmtp_client_connect_timeout, client); + } return 0; } @@ -808,11 +832,34 @@ lmtp_client_send_rcpts(client); } +static void lmtp_client_timeout(struct lmtp_client *client) +{ + const char *line; + + line = t_strdup_printf(ERRSTR_TEMP_REMOTE_FAILURE + " (Timed out after %u secs while waiting for reply to %s)", + client->set.timeout_secs, lmtp_client_state_to_string(client)); + lmtp_client_fail(client, line); +} + void lmtp_client_send(struct lmtp_client *client, struct istream *data_input) { + i_assert(client->data_input == NULL); + i_stream_ref(data_input); client->data_input = data_input; + /* now we actually want to start doing I/O. start the timeout + handling. */ + if (client->set.timeout_secs > 0) { + if (client->to != NULL) { + /* still waiting for connect to finish */ + timeout_remove(&client->to); + } + client->to = timeout_add(client->set.timeout_secs*1000, + lmtp_client_timeout, client); + } + (void)lmtp_client_send_data_cmd(client); } diff -r 0effbc9afeee -r 9a384f83b2a3 src/lib-lda/lmtp-client.h --- a/src/lib-lda/lmtp-client.h Fri Mar 06 11:55:45 2015 +0200 +++ b/src/lib-lda/lmtp-client.h Fri Mar 06 16:30:55 2015 +0200 @@ -42,6 +42,9 @@ this many seconds, so it should try to keep lock waits and such lower than this. */ unsigned int proxy_timeout_secs; + /* Don't wait an answer from destination server longer than this many + seconds (0 = unlimited) */ + unsigned int timeout_secs; }; /* reply contains the reply coming from remote server, or NULL From dovecot at dovecot.org Fri Mar 6 14:34:04 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 06 Mar 2015 14:34:04 +0000 Subject: dovecot-2.2: lib-lda: Added smtp_client_deinit_timeout() to give... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/bf2dbc8ec74b changeset: 18302:bf2dbc8ec74b user: Timo Sirainen date: Fri Mar 06 16:32:05 2015 +0200 description: lib-lda: Added smtp_client_deinit_timeout() to give a session timeout. diffstat: src/lib-lda/smtp-client.c | 12 ++++++++++-- src/lib-lda/smtp-client.h | 3 +++ 2 files changed, 13 insertions(+), 2 deletions(-) diffs (56 lines): diff -r 9a384f83b2a3 -r bf2dbc8ec74b src/lib-lda/smtp-client.c --- a/src/lib-lda/smtp-client.c Fri Mar 06 16:30:55 2015 +0200 +++ b/src/lib-lda/smtp-client.c Fri Mar 06 16:32:05 2015 +0200 @@ -248,7 +248,8 @@ } static int -smtp_client_send_flush(struct smtp_client *smtp_client, const char **error_r) +smtp_client_send_flush(struct smtp_client *smtp_client, + unsigned int timeout_secs, const char **error_r) { struct lmtp_client_settings client_set; struct lmtp_client *client; @@ -285,6 +286,7 @@ client_set.mail_from = smtp_client->return_path == NULL ? "<>" : t_strconcat("<", smtp_client->return_path, ">", NULL); client_set.my_hostname = smtp_client->set->hostname; + client_set.timeout_secs = timeout_secs; ioloop = io_loop_create(); client = lmtp_client_init(&client_set, smtp_client_send_finished, @@ -344,6 +346,12 @@ int smtp_client_deinit(struct smtp_client *client, const char **error_r) { + return smtp_client_deinit_timeout(client, 0, error_r); +} + +int smtp_client_deinit_timeout(struct smtp_client *client, + unsigned int timeout_secs, const char **error_r) +{ int ret; if (!client->use_smtp) { @@ -355,7 +363,7 @@ } /* the mail has been written to a file. now actually send it. */ - ret = smtp_client_send_flush(client, error_r); + ret = smtp_client_send_flush(client, timeout_secs, error_r); smtp_client_abort(&client); return ret; diff -r 9a384f83b2a3 -r bf2dbc8ec74b src/lib-lda/smtp-client.h --- a/src/lib-lda/smtp-client.h Fri Mar 06 16:30:55 2015 +0200 +++ b/src/lib-lda/smtp-client.h Fri Mar 06 16:32:05 2015 +0200 @@ -12,6 +12,9 @@ /* Returns 1 on success, 0 on permanent failure (e.g. invalid destination), -1 on temporary failure. */ int smtp_client_deinit(struct smtp_client *client, const char **error_r); +/* Same as smtp_client_deinit(), but timeout after given number of seconds. */ +int smtp_client_deinit_timeout(struct smtp_client *client, + unsigned int timeout_secs, const char **error_r); /* FIXME: obsolete API, remove in v2.3: */ struct smtp_client * ATTR_NULL(3) From dovecot at dovecot.org Fri Mar 6 14:34:09 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 06 Mar 2015 14:34:09 +0000 Subject: dovecot-2.2: lda/lmtp: Added a hardcoded LDA_SUBMISSION_TIMEOUT_... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/73e013bc64a4 changeset: 18303:73e013bc64a4 user: Timo Sirainen date: Fri Mar 06 16:33:23 2015 +0200 description: lda/lmtp: Added a hardcoded LDA_SUBMISSION_TIMEOUT_SECS=30 timeout for SMTP client. Maybe we could have a new setting if needed later on, but we've been working pretty successfully without any timeout for a long time.. diffstat: src/lda/main.c | 1 + src/lib-lda/mail-deliver.h | 5 +++++ src/lib-lda/mail-send.c | 2 +- src/lmtp/commands.c | 1 + 4 files changed, 8 insertions(+), 1 deletions(-) diffs (56 lines): diff -r bf2dbc8ec74b -r 73e013bc64a4 src/lda/main.c --- a/src/lda/main.c Fri Mar 06 16:32:05 2015 +0200 +++ b/src/lda/main.c Fri Mar 06 16:33:23 2015 +0200 @@ -315,6 +315,7 @@ ctx.session = mail_deliver_session_init(); ctx.pool = ctx.session->pool; ctx.dest_mailbox_name = "INBOX"; + ctx.timeout_secs = LDA_SUBMISSION_TIMEOUT_SECS; path = NULL; user = getenv("USER"); diff -r bf2dbc8ec74b -r 73e013bc64a4 src/lib-lda/mail-deliver.h --- a/src/lib-lda/mail-deliver.h Fri Mar 06 16:32:05 2015 +0200 +++ b/src/lib-lda/mail-deliver.h Fri Mar 06 16:33:23 2015 +0200 @@ -5,6 +5,10 @@ #include "mail-types.h" #include "mail-error.h" +/* How many seconds to wait for replies from SMTP before failing. Used for + sending rejects, forward, etc. */ +#define LDA_SUBMISSION_TIMEOUT_SECS 30 + struct mail_storage; struct mail_save_context; struct mailbox; @@ -20,6 +24,7 @@ pool_t pool; const struct lda_settings *set; struct mail_deliver_session *session; + unsigned int timeout_secs; struct duplicate_context *dup_ctx; diff -r bf2dbc8ec74b -r 73e013bc64a4 src/lib-lda/mail-send.c --- a/src/lib-lda/mail-send.c Fri Mar 06 16:32:05 2015 +0200 +++ b/src/lib-lda/mail-send.c Fri Mar 06 16:33:23 2015 +0200 @@ -180,7 +180,7 @@ str_truncate(str, 0); str_printfa(str, "\r\n\r\n--%s--\r\n", boundary); o_stream_nsend(output, str_data(str), str_len(str)); - if ((ret = smtp_client_deinit(smtp_client, &error)) < 0) { + if ((ret = smtp_client_deinit_timeout(smtp_client, ctx->timeout_secs, &error)) < 0) { i_error("msgid=%s: Temporarily failed to send rejection: %s", orig_msgid == NULL ? "" : str_sanitize(orig_msgid, 80), str_sanitize(error, 512)); diff -r bf2dbc8ec74b -r 73e013bc64a4 src/lmtp/commands.c --- a/src/lmtp/commands.c Fri Mar 06 16:32:05 2015 +0200 +++ b/src/lmtp/commands.c Fri Mar 06 16:33:23 2015 +0200 @@ -803,6 +803,7 @@ dctx.session = session; dctx.pool = session->pool; dctx.set = lda_set; + dctx.timeout_secs = LDA_SUBMISSION_TIMEOUT_SECS; dctx.session_id = client->state.session_id; dctx.src_mail = src_mail; dctx.src_envelope_sender = client->state.mail_from; From dovecot at dovecot.org Fri Mar 6 14:37:46 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 06 Mar 2015 14:37:46 +0000 Subject: dovecot-2.2: lmtp: Fixed lmtp_user_concurrency_limit=0 to actual... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9c69c197b527 changeset: 18304:9c69c197b527 user: Timo Sirainen date: Fri Mar 06 16:37:07 2015 +0200 description: lmtp: Fixed lmtp_user_concurrency_limit=0 to actually mean unlimited diffstat: src/lmtp/commands.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 73e013bc64a4 -r 9c69c197b527 src/lmtp/commands.c --- a/src/lmtp/commands.c Fri Mar 06 16:33:23 2015 +0200 +++ b/src/lmtp/commands.c Fri Mar 06 16:37:07 2015 +0200 @@ -758,7 +758,8 @@ input = mail_storage_service_user_get_input(rcpt->service_user); username = t_strdup(input->username); - if (rcpt->parallel_count >= client->lmtp_set->lmtp_user_concurrency_limit) { + if (client->lmtp_set->lmtp_user_concurrency_limit > 0 && + rcpt->parallel_count >= client->lmtp_set->lmtp_user_concurrency_limit) { client_send_line(client, ERRSTR_TEMP_USERDB_FAIL_PREFIX "Too many concurrent deliveries for user", rcpt->address); From dovecot at dovecot.org Fri Mar 6 15:47:07 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 06 Mar 2015 15:47:07 +0000 Subject: dovecot-2.2: lib-mail: Unit test fix to make static analyzer hap... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e4c9a9be1627 changeset: 18305:e4c9a9be1627 user: Timo Sirainen date: Fri Mar 06 17:46:26 2015 +0200 description: lib-mail: Unit test fix to make static analyzer happier diffstat: src/lib-mail/test-message-part.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 9c69c197b527 -r e4c9a9be1627 src/lib-mail/test-message-part.c --- a/src/lib-mail/test-message-part.c Fri Mar 06 16:37:07 2015 +0200 +++ b/src/lib-mail/test-message-part.c Fri Mar 06 17:46:26 2015 +0200 @@ -74,7 +74,7 @@ part = message_part_by_idx(parts, i); test_assert(part != NULL); test_assert(part != NULL && message_part_to_idx(part) == i); - test_assert(part != NULL && + test_assert(part != NULL && prev_part != NULL && prev_part->physical_pos < part->physical_pos); } test_assert(message_part_by_idx(parts, i) == NULL); From dovecot at dovecot.org Fri Mar 6 15:50:17 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 06 Mar 2015 15:50:17 +0000 Subject: dovecot-2.2: Released v2.2.16.rc1. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a3c27cec4112 changeset: 18306:a3c27cec4112 user: Timo Sirainen date: Fri Mar 06 17:47:34 2015 +0200 description: Released v2.2.16.rc1. diffstat: NEWS | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 4 +- 2 files changed, 74 insertions(+), 2 deletions(-) diffs (93 lines): diff -r e4c9a9be1627 -r a3c27cec4112 NEWS --- a/NEWS Fri Mar 06 17:46:26 2015 +0200 +++ b/NEWS Fri Mar 06 17:47:34 2015 +0200 @@ -1,3 +1,75 @@ +v2.2.16 2015-03-xx Timo Sirainen + + * dbox: Resyncing (e.g. doveadm force-resync) no longer deletes + dovecot.index.cache file. The cache file was rarely the problem + so this just caused unnecessary slowness. + * Mailbox name limits changed during mailbox creation: Each part of + a hierarchical name (e.g. "x" or "y" in "x/y") can now be up to 255 + chars long (instead of 200). This also reduces the max number of + hierarchical levels to 16 (instead of 20) to keep the maximum name + length 4096 (a common PATH_MAX limit). The 255 char limit is + hopefully large enough for migrations from all existing systems. + It's also the limit on many filesystems. + + + director: Added director_consistent_hashing setting to enable + consistent hashing (instead of the mostly-random MD5 hashing). + This causes fewer user moves between backends when backend counts + are changed, which may improve performance (mainly due to caching). + + director: Added support for "tags", which allows one director ring + to serve multiple backend clusters with different sets of users. + + LMTP server: Added lmtp_user_concurrency_limit setting to limit how + many LMTP deliveries can be done concurrently for a single user. + + LMTP server: Added support for STARTTLS command. + + If logging data is generated faster than it can be written, log a + warning about it and show information about it in log process's + process title in ps output. Also don't allow a single service to + flood too long at the cost of delaying other services' logging. + + stats: Added support for getting global statistics. + + stats: Use the same session IDs as the rest of Dovecot. + + stats: Plugins can now create their own statistics fields + + doveadm server: Non-mail related commands can now also be used + via doveadm server (TCP socket). + + doveadm proxying: passdb lookup can now override doveadm_port and + change the username. + + doveadm: Search query supports now "oldestonly" parameter to stop + immediately on the first non-match. This can be used to optimize: + doveadm expunge mailbox Trash savedbefore 30d oldestonly + + doveadm: Added "save" command to directly save mails to specified + mailbox (bypassing Sieve). + + doveadm fetch: Added body.snippet field, which returns the first + 100 chars of a message without whitespace or HTML tags. The result + is stored into dovecot.index.cache, so it can be fetched efficiently. + + dsync: Added -t parameter to sync only mails newer than + the given received-timestamp. + + dsync: Added -F [-] parameter to sync only mails with[out] the + given flag/keyword. + + dsync: Added -a parameter to specify the virtual mailbox + containing user's all mails. If this mailbox is already found to + contain the wanted mail (by its GUID), the message is copied from + there instead of being re-saved. (This isn't efficient enough yet + for incremental replication.) + + dsync: -m parameter can now specify \Special-use names for mailboxes. + + imapc: Added imapc_features=gmail-migration to help migrations from + GMail. See http://wiki2.dovecot.org/Migration/Gmail + + imapc: Added imapc_features=search to support IMAP SEARCH command. + (Currently requires ESEARCH support from remote server.) + + expire plugin: Added expire_cache=yes setting to cache most of the + database lookups in dovecot index files. + + quota: If overquota-flag in userdb doesn't match the current quota + usage, execute a configured script. + + redis dict: Added support for expiring keys (:expire_secs=n) and + specifying the database number (:db=n) + - auth: Don't crash if master user login is attempted without + any configured master=yes passdbs + - Parsing UTF-8 text for mails could have caused broken results + sometimes if buffering was split in the middle of a UTF-8 character. + This affected at least searching messages. + - String sanitization for some logged output wasn't done properly: + UTF-8 text could have been truncated wrongly or the truncation may + not have happened at all. + - fts-lucene: Lookups from virtual mailbox consisting of over 32 + physical mailboxes could have caused crashes. + v2.2.15 2014-10-24 Timo Sirainen * Plugins can now print a banner comment in doveconf output diff -r e4c9a9be1627 -r a3c27cec4112 configure.ac --- a/configure.ac Fri Mar 06 17:46:26 2015 +0200 +++ b/configure.ac Fri Mar 06 17:47:34 2015 +0200 @@ -2,8 +2,8 @@ # Be sure to update ABI version also if anything changes that might require # recompiling plugins. Most importantly that means if any structs are changed. -AC_INIT([Dovecot],[2.2.15],[dovecot at dovecot.org]) -AC_DEFINE_UNQUOTED([DOVECOT_ABI_VERSION], "2.2.ABIv15($PACKAGE_VERSION)", [Dovecot ABI version]) +AC_INIT([Dovecot],[2.2.16.rc1],[dovecot at dovecot.org]) +AC_DEFINE_UNQUOTED([DOVECOT_ABI_VERSION], "2.2.ABIv16($PACKAGE_VERSION)", [Dovecot ABI version]) AC_CONFIG_SRCDIR([src]) From dovecot at dovecot.org Fri Mar 6 15:50:17 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 06 Mar 2015 15:50:17 +0000 Subject: dovecot-2.2: Added tag 2.2.16.rc1 for changeset a3c27cec4112 Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/222d7d7c5491 changeset: 18307:222d7d7c5491 user: Timo Sirainen date: Fri Mar 06 17:47:34 2015 +0200 description: Added tag 2.2.16.rc1 for changeset a3c27cec4112 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r a3c27cec4112 -r 222d7d7c5491 .hgtags --- a/.hgtags Fri Mar 06 17:47:34 2015 +0200 +++ b/.hgtags Fri Mar 06 17:47:34 2015 +0200 @@ -121,3 +121,4 @@ 34e52cbeb83725178c0c0a282ffa5ef1c161e3cb 2.2.14.rc1 6dad1f6e8930940f3c763cf3f27aaa7a9c979520 2.2.14 e8b793f2c4091f76075e66d5166b38cf82e598bd 2.2.15 +a3c27cec411261b3ff2947795b3b8ff96a5320a1 2.2.16.rc1 From dovecot at dovecot.org Fri Mar 6 15:50:17 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 06 Mar 2015 15:50:17 +0000 Subject: dovecot-2.2: Added signature for changeset a3c27cec4112 Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1f0428d0fece changeset: 18308:1f0428d0fece user: Timo Sirainen date: Fri Mar 06 17:47:38 2015 +0200 description: Added signature for changeset a3c27cec4112 diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 222d7d7c5491 -r 1f0428d0fece .hgsigs --- a/.hgsigs Fri Mar 06 17:47:34 2015 +0200 +++ b/.hgsigs Fri Mar 06 17:47:38 2015 +0200 @@ -84,3 +84,4 @@ 34e52cbeb83725178c0c0a282ffa5ef1c161e3cb 0 iEYEABECAAYFAlQuvlIACgkQyUhSUUBVislFdwCfTD1ctLwAmkwWzuIugFdnLBo7wYoAoJbAtUIRsFyyxdgvslqT9aJ6Mg0A 6dad1f6e8930940f3c763cf3f27aaa7a9c979520 0 iEYEABECAAYFAlQ9VDQACgkQyUhSUUBVisk1fgCfdmFGZA/0DGz9vQFDeBTFK/JLhAEAnA966b+cMBaRegwj/v0Zta7c62lS e8b793f2c4091f76075e66d5166b38cf82e598bd 0 iEYEABECAAYFAlRLH5gACgkQyUhSUUBVisn+6gCfcGV1kM2OS9udaFxY7MVtqaaGwYAAnRxUc/RGeUhvJGdg9LvSSzBFPCfz +a3c27cec411261b3ff2947795b3b8ff96a5320a1 0 iEYEABECAAYFAlT5zBYACgkQyUhSUUBVisnQ4gCdFb/4T+WZYCAxRKjfup+xIiP26bkAn2CbIlsJBU1f3WnAJX9KsAmhphlY From pigeonhole at rename-it.nl Fri Mar 6 16:12:42 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 06 Mar 2015 17:12:42 +0100 Subject: dovecot-2.2-pigeonhole: doveadm sieve plugin: Forgot to add new ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/72ff74f6cb11 changeset: 1992:72ff74f6cb11 user: Stephan Bosch date: Fri Mar 06 17:12:35 2015 +0100 description: doveadm sieve plugin: Forgot to add new headers to distribution. diffstat: src/plugins/doveadm-sieve/Makefile.am | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diffs (23 lines): diff -r c8edece267cd -r 72ff74f6cb11 src/plugins/doveadm-sieve/Makefile.am --- a/src/plugins/doveadm-sieve/Makefile.am Mon Feb 23 09:21:10 2015 +0100 +++ b/src/plugins/doveadm-sieve/Makefile.am Fri Mar 06 17:12:35 2015 +0100 @@ -9,6 +9,9 @@ doveadm_module_LTLIBRARIES = lib10_doveadm_sieve_plugin.la +lib10_doveadm_sieve_plugin_la_LIBADD = \ + $(top_builddir)/src/lib-sieve/libdovecot-sieve.la + commands = \ doveadm-sieve-cmd-list.c \ doveadm-sieve-cmd-get.c \ @@ -22,5 +25,7 @@ doveadm-sieve-cmd.c \ doveadm-sieve-sync.c \ doveadm-sieve-plugin.c -lib10_doveadm_sieve_plugin_la_LIBADD = \ - $(top_builddir)/src/lib-sieve/libdovecot-sieve.la + +noinst_HEADERS = \ + doveadm-sieve-cmd.h \ + doveadm-sieve-plugin.h From pigeonhole at rename-it.nl Fri Mar 6 18:03:00 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 06 Mar 2015 19:03:00 +0100 Subject: dovecot-2.2-pigeonhole: lda sieve plugin: Started using smtp_cli... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/572300c87a17 changeset: 1993:572300c87a17 user: Stephan Bosch date: Fri Mar 06 18:59:46 2015 +0100 description: lda sieve plugin: Started using smtp_client_deinit_timeout() to give a session timeout. diffstat: src/lib-sieve/sieve-smtp.c | 6 +++--- src/lib-sieve/sieve-types.h | 11 ++++++++--- src/plugins/lda-sieve/lda-sieve-plugin.c | 15 +++++++++++---- src/sieve-tools/sieve-test.c | 10 +++++++--- src/testsuite/testsuite-smtp.c | 16 +++++++--------- src/testsuite/testsuite-smtp.h | 11 ++++++++--- 6 files changed, 44 insertions(+), 25 deletions(-) diffs (194 lines): diff -r 72ff74f6cb11 -r 572300c87a17 src/lib-sieve/sieve-smtp.c --- a/src/lib-sieve/sieve-smtp.c Fri Mar 06 17:12:35 2015 +0100 +++ b/src/lib-sieve/sieve-smtp.c Fri Mar 06 18:59:46 2015 +0100 @@ -42,7 +42,7 @@ (struct sieve_smtp_context *sctx, const char *address) { i_assert(!sctx->sent); - sctx->senv->smtp_add_rcpt(sctx->handle, address); + sctx->senv->smtp_add_rcpt(sctx->senv, sctx->handle, address); } struct ostream *sieve_smtp_send @@ -51,7 +51,7 @@ i_assert(!sctx->sent); sctx->sent = TRUE; - return sctx->senv->smtp_send(sctx->handle); + return sctx->senv->smtp_send(sctx->senv, sctx->handle); } struct sieve_smtp_context *sieve_smtp_start_single @@ -74,6 +74,6 @@ void *handle = sctx->handle; i_free(sctx); - return senv->smtp_finish(handle, error_r); + return senv->smtp_finish(senv, handle, error_r); } diff -r 72ff74f6cb11 -r 572300c87a17 src/lib-sieve/sieve-types.h --- a/src/lib-sieve/sieve-types.h Fri Mar 06 17:12:35 2015 +0100 +++ b/src/lib-sieve/sieve-types.h Fri Mar 06 18:59:46 2015 +0100 @@ -193,12 +193,17 @@ void *(*smtp_start) (const struct sieve_script_env *senv, const char *return_path); /* Add a new recipient */ - void (*smtp_add_rcpt) (void *handle, const char *address); + void (*smtp_add_rcpt) + (const struct sieve_script_env *senv, void *handle, + const char *address); /* Get an output stream where the message can be written to. The recipients must already be added before calling this. */ - struct ostream *(*smtp_send)(void *handle); + struct ostream *(*smtp_send) + (const struct sieve_script_env *senv, void *handle); /* Returns 1 on success, 0 on permanent failure, -1 on temporary failure. */ - int (*smtp_finish)(void *handle, const char **error_r); + int (*smtp_finish) + (const struct sieve_script_env *senv, void *handle, + const char **error_r); /* Interface for marking and checking duplicates */ int (*duplicate_check) diff -r 72ff74f6cb11 -r 572300c87a17 src/plugins/lda-sieve/lda-sieve-plugin.c --- a/src/plugins/lda-sieve/lda-sieve-plugin.c Fri Mar 06 17:12:35 2015 +0100 +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c Fri Mar 06 18:59:46 2015 +0100 @@ -77,14 +77,17 @@ return (void *)smtp_client_init(dctx->set, return_path); } -static void lda_sieve_smtp_add_rcpt(void *handle, const char *address) +static void lda_sieve_smtp_add_rcpt +(const struct sieve_script_env *senv ATTR_UNUSED, void *handle, + const char *address) { struct smtp_client *smtp_client = (struct smtp_client *) handle; smtp_client_add_rcpt(smtp_client, address); } -static struct ostream *lda_sieve_smtp_send(void *handle) +static struct ostream *lda_sieve_smtp_send +(const struct sieve_script_env *senv ATTR_UNUSED, void *handle) { struct smtp_client *smtp_client = (struct smtp_client *) handle; @@ -92,11 +95,15 @@ } static int lda_sieve_smtp_finish -(void *handle, const char **error_r) +(const struct sieve_script_env *senv, void *handle, + const char **error_r) { + struct mail_deliver_context *dctx = + (struct mail_deliver_context *) senv->script_context; struct smtp_client *smtp_client = (struct smtp_client *) handle; - return smtp_client_deinit(smtp_client, error_r); + return smtp_client_deinit_timeout + (smtp_client, dctx->timeout_secs, error_r); } static int lda_sieve_reject_mail diff -r 72ff74f6cb11 -r 572300c87a17 src/sieve-tools/sieve-test.c --- a/src/sieve-tools/sieve-test.c Fri Mar 06 17:12:35 2015 +0100 +++ b/src/sieve-tools/sieve-test.c Fri Mar 06 18:59:46 2015 +0100 @@ -70,12 +70,15 @@ } static void sieve_smtp_add_rcpt -(void *handle ATTR_UNUSED, const char *address) +(const struct sieve_script_env *senv ATTR_UNUSED, + void *handle ATTR_UNUSED, const char *address) { printf("\nRECIPIENT: %s\n", address); } -static struct ostream *sieve_smtp_send(void *handle) +static struct ostream *sieve_smtp_send +(const struct sieve_script_env *senv ATTR_UNUSED, + void *handle) { printf("START MESSAGE:\n"); @@ -83,7 +86,8 @@ } static int sieve_smtp_finish -(void *handle, const char **error_r ATTR_UNUSED) +(const struct sieve_script_env *senv ATTR_UNUSED, + void *handle, const char **error_r ATTR_UNUSED) { struct ostream *output = (struct ostream *)handle; diff -r 72ff74f6cb11 -r 572300c87a17 src/testsuite/testsuite-smtp.c --- a/src/testsuite/testsuite-smtp.c Fri Mar 06 17:12:35 2015 +0100 +++ b/src/testsuite/testsuite-smtp.c Fri Mar 06 18:59:46 2015 +0100 @@ -74,12 +74,6 @@ struct ostream *output; }; -void testsuite_smtp_add_rcpt(void *handle, const char *address); -struct ostream *testsuite_smtp_send(void *handle); -int testsuite_smtp_finish - (void *handle, const char **error_r); - - void *testsuite_smtp_start (const struct sieve_script_env *senv ATTR_UNUSED, const char *return_path) { @@ -102,7 +96,9 @@ return (void *) smtp; } -void testsuite_smtp_add_rcpt(void *handle, const char *address) +void testsuite_smtp_add_rcpt +(const struct sieve_script_env *senv ATTR_UNUSED, + void *handle, const char *address) { struct testsuite_smtp *smtp = (struct testsuite_smtp *) handle; struct testsuite_smtp_message *msg; @@ -114,7 +110,8 @@ msg->envelope_to = p_strdup(testsuite_smtp_pool, address); } -struct ostream *testsuite_smtp_send(void *handle) +struct ostream *testsuite_smtp_send +(const struct sieve_script_env *senv ATTR_UNUSED, void *handle) { struct testsuite_smtp *smtp = (struct testsuite_smtp *) handle; @@ -122,7 +119,8 @@ } int testsuite_smtp_finish -(void *handle, const char **error_r ATTR_UNUSED) +(const struct sieve_script_env *senv ATTR_UNUSED, + void *handle, const char **error_r ATTR_UNUSED) { struct testsuite_smtp *smtp = (struct testsuite_smtp *) handle; diff -r 72ff74f6cb11 -r 572300c87a17 src/testsuite/testsuite-smtp.h --- a/src/testsuite/testsuite-smtp.h Fri Mar 06 17:12:35 2015 +0100 +++ b/src/testsuite/testsuite-smtp.h Fri Mar 06 18:59:46 2015 +0100 @@ -15,10 +15,15 @@ void *testsuite_smtp_start (const struct sieve_script_env *senv ATTR_UNUSED, const char *return_path); -void testsuite_smtp_add_rcpt(void *handle, const char *address); -struct ostream *testsuite_smtp_send(void *handle); +void testsuite_smtp_add_rcpt + (const struct sieve_script_env *senv ATTR_UNUSED, + void *handle, const char *address); +struct ostream *testsuite_smtp_send + (const struct sieve_script_env *senv ATTR_UNUSED, + void *handle); int testsuite_smtp_finish - (void *handle, const char **error_r); + (const struct sieve_script_env *senv ATTR_UNUSED, + void *handle, const char **error_r); /* * Access From pigeonhole at rename-it.nl Fri Mar 6 18:03:00 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 06 Mar 2015 19:03:00 +0100 Subject: dovecot-2.2-pigeonhole: metadata: Fixed testsuite after changes ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/3f1d2b649e19 changeset: 1994:3f1d2b649e19 user: Stephan Bosch date: Fri Mar 06 19:02:53 2015 +0100 description: metadata: Fixed testsuite after changes in Dovecot. Currently cannot freely assing server metadata items for testing. Disabled tests for now. diffstat: tests/extensions/metadata/execute.svtest | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (18 lines): diff -r 572300c87a17 -r 3f1d2b649e19 tests/extensions/metadata/execute.svtest --- a/tests/extensions/metadata/execute.svtest Fri Mar 06 18:59:46 2015 +0100 +++ b/tests/extensions/metadata/execute.svtest Fri Mar 06 19:02:53 2015 +0100 @@ -77,6 +77,9 @@ } } +# currently not possible to test servermetadata +if false { + test_imap_metadata_set "/private/frop" "FROP!"; test_imap_metadata_set "/private/friep" "FRIEP!"; @@ -139,3 +142,4 @@ } } +} #disabled From pigeonhole at rename-it.nl Fri Mar 6 19:02:57 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 06 Mar 2015 20:02:57 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: editheader extension: Made pr... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/c13471f102be changeset: 1995:c13471f102be user: Stephan Bosch date: Fri Mar 06 20:02:15 2015 +0100 description: lib-sieve: editheader extension: Made protection against addition and deletion of headers configurable separately. Also, the received and auto-submitted headers are now only protected against deletion as required in the RFC. Updated the documentation accordingly. diffstat: doc/extensions/editheader.txt | 25 ++- src/lib-sieve/plugins/editheader/cmd-addheader.c | 18 +- src/lib-sieve/plugins/editheader/cmd-deleteheader.c | 17 +- src/lib-sieve/plugins/editheader/ext-editheader-common.c | 112 +++++++++----- src/lib-sieve/plugins/editheader/ext-editheader-common.h | 6 +- tests/extensions/editheader/protected.svtest | 76 ++++++++++ 6 files changed, 194 insertions(+), 60 deletions(-) diffs (truncated from 390 to 300 lines): diff -r 3f1d2b649e19 -r c13471f102be doc/extensions/editheader.txt --- a/doc/extensions/editheader.txt Fri Mar 06 19:02:53 2015 +0100 +++ b/doc/extensions/editheader.txt Fri Mar 06 20:02:15 2015 +0100 @@ -26,11 +26,23 @@ command. The minimum value for this setting is 1024 bytes. The value is in bytes, unless followed by a k(ilo). +sieve_editheader_forbid_add = + A space-separated list of headers that cannot be added to the message header. + Addition of the `Subject:' header cannot be prohibited, as required by the RFC + specification. Therefore, adding this header to this setting has no effect. + +sieve_editheader_forbid_delete = + A space-separated list of headers that cannot be deleted from the message + header. Deleting the `Received:' and `Auto-Submitted:' fields is always + forbidden, while removing the `Subject:' header cannot be prohibited, + as required by the RFC specification. Therefore, adding one of these headers + to this setting has no effect. + sieve_editheader_protected = - A space-separated list of headers that cannot be added to nor removed from the - message header. The `Received:' and `Auto-Submitted:' fields are always - protected and the `Subject:' header cannot be protected, as required by the - RFC specification; adding one of these headers to this setting has no effect. + A space-separated list of headers that cannot be added to or deleted from + the message header. This setting is provided for backwards compatibility. It + is a combination of the sieve_editheader_forbid_add and + sieve_editheader_forbid_delete settings. The same limitations apply. Invalid values for the settings above will make the Sieve interpreter log a warning and revert to the default values. @@ -45,7 +57,8 @@ # Header fiels must not exceed one 1k sieve_editheader_max_header_size = 1k - # Protect special header - sieve_editheader_protected = X-Verified + # Protected special headers + sieve_editheader_forbid_add = X-Verified + sieve_editheader_forbid_delete = X-Verified X-Seen } diff -r 3f1d2b649e19 -r c13471f102be src/lib-sieve/plugins/editheader/cmd-addheader.c --- a/src/lib-sieve/plugins/editheader/cmd-addheader.c Fri Mar 06 19:02:53 2015 +0100 +++ b/src/lib-sieve/plugins/editheader/cmd-addheader.c Fri Mar 06 20:02:15 2015 +0100 @@ -130,10 +130,13 @@ return FALSE; } - if ( ext_editheader_header_is_protected(cmd->ext, str_c(fname)) ) { - sieve_argument_validate_warning(valdtr, arg, "addheader command: " - "specified header field `%s' is protected; " - "modification will be denied", str_sanitize(str_c(fname), 80)); + if ( !ext_editheader_header_allow_add + (cmd->ext, str_c(fname)) ) { + sieve_argument_validate_warning + (valdtr, arg, "addheader command: " + "adding specified header field `%s' is forbidden; " + "modification will be denied", + str_sanitize(str_c(fname), 80)); } } @@ -298,10 +301,11 @@ return SIEVE_EXEC_FAILURE; } - if ( ext_editheader_header_is_protected(this_ext, str_c(field_name)) ) { + if ( !ext_editheader_header_allow_add + (this_ext, str_c(field_name)) ) { sieve_runtime_warning(renv, NULL, "addheader action: " - "specified header field `%s' is protected; modification denied", - str_sanitize(str_c(field_name), 80)); + "adding specified header field `%s' is forbidden; " + "modification denied", str_sanitize(str_c(field_name), 80)); return SIEVE_EXEC_OK; } diff -r 3f1d2b649e19 -r c13471f102be src/lib-sieve/plugins/editheader/cmd-deleteheader.c --- a/src/lib-sieve/plugins/editheader/cmd-deleteheader.c Fri Mar 06 19:02:53 2015 +0100 +++ b/src/lib-sieve/plugins/editheader/cmd-deleteheader.c Fri Mar 06 20:02:15 2015 +0100 @@ -259,10 +259,13 @@ return FALSE; } - if ( ext_editheader_header_is_protected(cmd->ext, str_c(fname)) ) { - sieve_argument_validate_warning(valdtr, arg, "deleteheader command: " - "specified header field `%s' is protected; " - "modification will be denied", str_sanitize(str_c(fname), 80)); + if ( !ext_editheader_header_allow_delete + (cmd->ext, str_c(fname)) ) { + sieve_argument_validate_warning + (valdtr, arg, "deleteheader command: " + "deleting specified header field `%s' is forbidden; " + "modification will be denied", + str_sanitize(str_c(fname), 80)); } } @@ -426,9 +429,11 @@ return SIEVE_EXEC_FAILURE; } - if ( ext_editheader_header_is_protected(this_ext, str_c(field_name)) ) { + if ( !ext_editheader_header_allow_delete + (this_ext, str_c(field_name)) ) { sieve_runtime_warning(renv, NULL, "deleteheader action: " - "specified header field `%s' is protected; modification denied", + "deleting specified header field `%s' is forbidden; " + "modification denied", str_sanitize(str_c(field_name), 80)); return SIEVE_EXEC_OK; } diff -r 3f1d2b649e19 -r c13471f102be src/lib-sieve/plugins/editheader/ext-editheader-common.c --- a/src/lib-sieve/plugins/editheader/ext-editheader-common.c Fri Mar 06 19:02:53 2015 +0100 +++ b/src/lib-sieve/plugins/editheader/ext-editheader-common.c Fri Mar 06 20:02:15 2015 +0100 @@ -22,8 +22,8 @@ struct ext_editheader_header { const char *name; - /* may extend this later */ - unsigned int protected:1; + unsigned int forbid_add:1; + unsigned int forbid_delete:1; }; struct ext_editheader_config { @@ -49,12 +49,49 @@ return NULL; } +static void ext_editheader_config_headers +(struct sieve_instance *svinst, + struct ext_editheader_config *ext_config, + const char *setting, bool forbid_add, bool forbid_delete) +{ + const char *setval; + + setval = sieve_setting_get(svinst, setting); + if ( setval != NULL ) { + const char **headers = t_strsplit_spaces(setval, " \t"); + + while ( *headers != NULL ) { + struct ext_editheader_header *header; + + if ( !rfc2822_header_field_name_verify + (*headers, strlen(*headers)) ) { + sieve_sys_warning(svinst, "editheader: " + "setting %s contains invalid header field name " + "`%s' (ignored)", setting, *headers); + continue; + } + + header=ext_editheader_config_header_find(ext_config, *headers); + if ( header == NULL ) { + header = array_append_space(&ext_config->headers); + header->name = p_strdup(ext_config->pool, *headers); + } + + if (forbid_add) + header->forbid_add = TRUE; + if (forbid_delete) + header->forbid_delete = TRUE; + + headers++; + } + } +} + bool ext_editheader_load (const struct sieve_extension *ext, void **context) { struct ext_editheader_config *ext_config; struct sieve_instance *svinst = ext->svinst; - const char *protected; size_t max_header_size; pool_t pool; @@ -71,31 +108,12 @@ p_array_init(&ext_config->headers, pool, 16); - protected = sieve_setting_get(svinst, "sieve_editheader_protected"); - if ( protected != NULL ) { - const char **headers = t_strsplit_spaces(protected, " \t"); - - while ( *headers != NULL ) { - struct ext_editheader_header *header; - - if ( !rfc2822_header_field_name_verify(*headers, strlen(*headers)) ) { - sieve_sys_warning(svinst, - "editheader: setting sieve_editheader_protected contains " - "invalid header field name `%s' (ignored)", *headers); - continue; - } - - header=ext_editheader_config_header_find(ext_config, *headers); - if ( header == NULL ) { - header = array_append_space(&ext_config->headers); - header->name = p_strdup(pool, *headers); - } - - header->protected = TRUE; - - headers++; - } - } + ext_editheader_config_headers(svinst, ext_config, + "sieve_editheader_protected", TRUE, TRUE); + ext_editheader_config_headers(svinst, ext_config, + "sieve_editheader_forbid_add", TRUE, FALSE); + ext_editheader_config_headers(svinst, ext_config, + "sieve_editheader_forbid_delete", FALSE, TRUE); if ( sieve_setting_get_size_value (svinst, "sieve_editheader_max_header_size", &max_header_size) ) { @@ -129,7 +147,24 @@ * Protected headers */ -bool ext_editheader_header_is_protected +bool ext_editheader_header_allow_add +(const struct sieve_extension *ext, const char *hname) +{ + struct ext_editheader_config *ext_config = + (struct ext_editheader_config *) ext->context; + const struct ext_editheader_header *header; + + if ( strcasecmp(hname, "subject") == 0 ) + return TRUE; + + if ( (header=ext_editheader_config_header_find + (ext_config, hname)) == NULL ) + return TRUE; + + return !header->forbid_add; +} + +bool ext_editheader_header_allow_delete (const struct sieve_extension *ext, const char *hname) { struct ext_editheader_config *ext_config = @@ -137,18 +172,17 @@ const struct ext_editheader_header *header; if ( strcasecmp(hname, "received") == 0 - || strcasecmp(hname, "auto-submitted") == 0 ) { - return TRUE; - } - - if ( strcasecmp(hname, "subject") == 0 ) { - return FALSE; - } - - if ( (header=ext_editheader_config_header_find(ext_config, hname)) == NULL ) + || strcasecmp(hname, "auto-submitted") == 0 ) return FALSE; - return header->protected; + if ( strcasecmp(hname, "subject") == 0 ) + return TRUE; + + if ( (header=ext_editheader_config_header_find + (ext_config, hname)) == NULL ) + return TRUE; + + return !header->forbid_delete; } /* diff -r 3f1d2b649e19 -r c13471f102be src/lib-sieve/plugins/editheader/ext-editheader-common.h --- a/src/lib-sieve/plugins/editheader/ext-editheader-common.h Fri Mar 06 19:02:53 2015 +0100 +++ b/src/lib-sieve/plugins/editheader/ext-editheader-common.h Fri Mar 06 20:02:15 2015 +0100 @@ -37,8 +37,10 @@ * Protected headers */ -bool ext_editheader_header_is_protected - (const struct sieve_extension *ext, const char *header); +bool ext_editheader_header_allow_add + (const struct sieve_extension *ext, const char *hname); +bool ext_editheader_header_allow_delete + (const struct sieve_extension *ext, const char *hname); /* * Limits diff -r 3f1d2b649e19 -r c13471f102be tests/extensions/editheader/protected.svtest --- a/tests/extensions/editheader/protected.svtest Fri Mar 06 19:02:53 2015 +0100 +++ b/tests/extensions/editheader/protected.svtest Fri Mar 06 20:02:15 2015 +0100 @@ -9,6 +9,7 @@ id 32A131WFW23QWE4; Mon, 21 Nov 2011 05:25:26 +0200 (EET) Delivery-date: Mon, 21 Nov 2011 04:26:04 +0100 Auto-Submitted: yes +X-Friep: frop 3 Subject: Frop! From: stephan at example.com To: tss at example.com @@ -29,6 +30,7 @@ deleteheader "received"; From pigeonhole at rename-it.nl Fri Mar 6 20:14:43 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 06 Mar 2015 21:14:43 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: Cleaned up error handling for... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/465ec119b394 changeset: 1996:465ec119b394 user: Stephan Bosch date: Fri Mar 06 21:14:01 2015 +0100 description: lib-sieve: Cleaned up error handling for the lexical scanner. diffstat: src/lib-sieve/sieve-lexer.c | 23 +++++++++++------------ src/lib-sieve/sieve-lexer.h | 2 +- 2 files changed, 12 insertions(+), 13 deletions(-) diffs (70 lines): diff -r c13471f102be -r 465ec119b394 src/lib-sieve/sieve-lexer.c --- a/src/lib-sieve/sieve-lexer.c Fri Mar 06 20:02:15 2015 +0100 +++ b/src/lib-sieve/sieve-lexer.c Fri Mar 06 21:14:01 2015 +0100 @@ -285,13 +285,13 @@ while ( sieve_lexer_curchar(scanner) != '\n' ) { switch( sieve_lexer_curchar(scanner) ) { case -1: - if ( scanner->input->eof ) { - sieve_lexer_warning(lexer, - "no newline (CRLF) at end of hash comment at end of file"); - lexer->token_type = STT_WHITESPACE; - } else { + if ( !scanner->input->eof ) { lexer->token_type = STT_ERROR; + return FALSE; } + sieve_lexer_warning(lexer, + "no newline (CRLF) at end of hash comment at end of file"); + lexer->token_type = STT_WHITESPACE; return TRUE; case '\0': sieve_lexer_error @@ -532,10 +532,11 @@ /* EOF */ case -1: - if ( scanner->input->eof ) - lexer->token_type = STT_EOF; - else + if ( !scanner->input->eof ) { lexer->token_type = STT_ERROR; + return FALSE; + } + lexer->token_type = STT_EOF; return TRUE; default: @@ -816,7 +817,7 @@ } } -bool sieve_lexer_skip_token(const struct sieve_lexer *lexer) +void sieve_lexer_skip_token(const struct sieve_lexer *lexer) { /* Scan token while skipping whitespace */ do { @@ -830,10 +831,8 @@ "error reading script during lexical analysis: %s", i_stream_get_error(scanner->input)); } - return FALSE; + return; } } while ( lexer->token_type == STT_WHITESPACE ); - - return TRUE; } diff -r c13471f102be -r 465ec119b394 src/lib-sieve/sieve-lexer.h --- a/src/lib-sieve/sieve-lexer.h Fri Mar 06 20:02:15 2015 +0100 +++ b/src/lib-sieve/sieve-lexer.h Fri Mar 06 21:14:01 2015 +0100 @@ -67,7 +67,7 @@ * Scanning */ -bool sieve_lexer_skip_token(const struct sieve_lexer *lexer); +void sieve_lexer_skip_token(const struct sieve_lexer *lexer); /* * Token access From pigeonhole at rename-it.nl Fri Mar 6 20:39:12 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 06 Mar 2015 21:39:12 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: Moved lexical scanner to syst... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/c74220e16e0f changeset: 1997:c74220e16e0f user: Stephan Bosch date: Fri Mar 06 21:36:40 2015 +0100 description: lib-sieve: Moved lexical scanner to system pool. diffstat: src/lib-sieve/sieve-lexer.c | 24 ++++++++++-------------- 1 files changed, 10 insertions(+), 14 deletions(-) diffs (59 lines): diff -r 465ec119b394 -r c74220e16e0f src/lib-sieve/sieve-lexer.c --- a/src/lib-sieve/sieve-lexer.c Fri Mar 06 21:14:01 2015 +0100 +++ b/src/lib-sieve/sieve-lexer.c Fri Mar 06 21:36:40 2015 +0100 @@ -64,7 +64,6 @@ (struct sieve_script *script, struct sieve_error_handler *ehandler, enum sieve_error *error_r) { - pool_t pool; struct sieve_lexical_scanner *scanner; struct sieve_instance *svinst = sieve_script_svinst(script); struct istream *stream; @@ -86,9 +85,7 @@ return NULL; } - pool = pool_alloconly_create("sieve_lexer_scanner", 1024); - scanner = p_new(pool, struct sieve_lexical_scanner, 1); - scanner->pool = pool; + scanner = i_new(struct sieve_lexical_scanner, 1); scanner->lexer.scanner = scanner; scanner->ehandler = ehandler; @@ -105,7 +102,7 @@ scanner->buffer_pos = 0; scanner->lexer.token_type = STT_NONE; - scanner->lexer.token_str_value = str_new(pool, 256); + scanner->lexer.token_str_value = str_new(default_pool, 256); scanner->lexer.token_int_value = 0; scanner->lexer.token_line = 1; @@ -114,19 +111,18 @@ return &scanner->lexer; } -void sieve_lexer_free(const struct sieve_lexer **lexer) +void sieve_lexer_free(const struct sieve_lexer **_lexer) { - struct sieve_lexical_scanner *scanner = (*lexer)->scanner; + const struct sieve_lexer *lexer = *_lexer; + struct sieve_lexical_scanner *scanner = lexer->scanner; i_stream_unref(&scanner->input); + sieve_script_unref(&scanner->script); + sieve_error_handler_unref(&scanner->ehandler); + str_free(&scanner->lexer.token_str_value); - sieve_script_unref(&scanner->script); - - sieve_error_handler_unref(&scanner->ehandler); - - pool_unref(&scanner->pool); - - *lexer = NULL; + i_free(scanner); + *_lexer = NULL; } /* From dovecot at dovecot.org Mon Mar 9 13:42:56 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Mar 2015 13:42:56 +0000 Subject: dovecot-2.2: fs-posix: Make sure the file isn't attempted to be ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/966680fbe2a9 changeset: 18309:966680fbe2a9 user: Timo Sirainen date: Mon Mar 09 15:26:01 2015 +0200 description: fs-posix: Make sure the file isn't attempted to be opened for reading while it's being written. Also if the write failed, the read should fail. diffstat: src/lib-fs/fs-posix.c | 26 +++++++++++++++++--------- 1 files changed, 17 insertions(+), 9 deletions(-) diffs (54 lines): diff -r 1f0428d0fece -r 966680fbe2a9 src/lib-fs/fs-posix.c --- a/src/lib-fs/fs-posix.c Fri Mar 06 17:47:38 2015 +0200 +++ b/src/lib-fs/fs-posix.c Mon Mar 09 15:26:01 2015 +0200 @@ -312,14 +312,24 @@ i_free(file); } +static int fs_posix_open_for_read(struct posix_fs_file *file) +{ + i_assert(file->file.output == NULL); + i_assert(file->temp_path == NULL); + + if (file->fd == -1) { + if (fs_posix_open(file) < 0) + return -1; + } + return 0; +} + static bool fs_posix_prefetch(struct fs_file *_file, uoff_t length ATTR_UNUSED) { struct posix_fs_file *file = (struct posix_fs_file *)_file; - if (file->fd == -1) { - if (fs_posix_open(file) < 0) - return TRUE; - } + if (fs_posix_open_for_read(file) < 0) + return TRUE; /* HAVE_POSIX_FADVISE alone isn't enough for CentOS 4.9 */ #if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED) @@ -336,10 +346,8 @@ struct posix_fs_file *file = (struct posix_fs_file *)_file; ssize_t ret; - if (file->fd == -1) { - if (fs_posix_open(file) < 0) - return -1; - } + if (fs_posix_open_for_read(file) < 0) + return -1; if (file->seek_to_beginning) { file->seek_to_beginning = FALSE; @@ -363,7 +371,7 @@ struct posix_fs_file *file = (struct posix_fs_file *)_file; struct istream *input; - if (file->fd == -1 && fs_posix_open(file) < 0) + if (fs_posix_open_for_read(file) < 0) input = i_stream_create_error_str(errno, "%s", fs_last_error(_file->fs)); else { /* the stream could live even after the fs_file */ From dovecot at dovecot.org Mon Mar 9 13:42:58 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Mar 2015 13:42:58 +0000 Subject: dovecot-2.2: fs-posix: Don't close file fd after its writing is ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/08aa1949227b changeset: 18310:08aa1949227b user: Timo Sirainen date: Mon Mar 09 15:26:45 2015 +0200 description: fs-posix: Don't close file fd after its writing is finished. This allows reading the file after writing without having to re-open the file (which in turn might fail in some situations). diffstat: src/lib-fs/fs-posix.c | 8 -------- 1 files changed, 0 insertions(+), 8 deletions(-) diffs (18 lines): diff -r 966680fbe2a9 -r 08aa1949227b src/lib-fs/fs-posix.c --- a/src/lib-fs/fs-posix.c Mon Mar 09 15:26:01 2015 +0200 +++ b/src/lib-fs/fs-posix.c Mon Mar 09 15:26:45 2015 +0200 @@ -393,14 +393,6 @@ } } - if (close(file->fd) < 0) { - file->fd = -1; - fs_set_error(file->file.fs, "close(%s) failed: %m", - file->full_path); - return -1; - } - file->fd = -1; - switch (file->open_mode) { case FS_OPEN_MODE_CREATE_UNIQUE_128: case FS_OPEN_MODE_CREATE: From dovecot at dovecot.org Mon Mar 9 13:43:01 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Mar 2015 13:43:01 +0000 Subject: dovecot-2.2: lib-imap-client: Fixed GMail [THROTTLED] detection. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c28d8e2ae6a9 changeset: 18311:c28d8e2ae6a9 user: Timo Sirainen date: Mon Mar 09 15:32:23 2015 +0200 description: lib-imap-client: Fixed GMail [THROTTLED] detection. It's not a resp-text-code, but appended at the end of line. diffstat: src/lib-imap-client/imapc-connection.c | 22 +++++++++++++--------- 1 files changed, 13 insertions(+), 9 deletions(-) diffs (39 lines): diff -r 08aa1949227b -r c28d8e2ae6a9 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Mon Mar 09 15:26:45 2015 +0200 +++ b/src/lib-imap-client/imapc-connection.c Mon Mar 09 15:32:23 2015 +0200 @@ -634,15 +634,6 @@ conn->selecting_box = NULL; } } - if (strcasecmp(key, "THROTTLED") == 0 && !conn->throttle_pending) { - /* GMail throttling - start slowing down commands. */ - conn->throttle_end_timeval = ioloop_timeval; - timeval_add_msecs(&conn->throttle_end_timeval, - (1U << conn->throttle_counter) * 1000); - conn->throttle_pending = TRUE; - if (conn->throttle_counter < IMAPC_THROTTLE_COUNTER_MAX_EXP) - conn->throttle_counter++; - } return 0; } @@ -1190,6 +1181,19 @@ reply.text_without_resp = reply.text_full; } if (!conn->throttle_pending && + strstr(reply.text_full, "[THROTTLED]") != NULL) { + /* GMail throttling - start slowing down commands. + unfortunately this isn't a nice resp-text-code, but just + appended at the end of the line (although we kind of support + it as resp-text-code also in here if it's uppercased). */ + conn->throttle_end_timeval = ioloop_timeval; + timeval_add_msecs(&conn->throttle_end_timeval, + (1U << conn->throttle_counter) * 1000); + conn->throttle_pending = TRUE; + if (conn->throttle_counter < IMAPC_THROTTLE_COUNTER_MAX_EXP) + conn->throttle_counter++; + } + if (!conn->throttle_pending && timeval_cmp(&ioloop_timeval, &conn->throttle_end_timeval) >= 0) { /* tagged reply without [THROTTLED] and it was received after the throttling ended. we can completely reset the throttling From dovecot at dovecot.org Mon Mar 9 14:17:51 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Mar 2015 14:17:51 +0000 Subject: dovecot-2.2: indexer-worker: Added missing error logging. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/00d40bf9c289 changeset: 18312:00d40bf9c289 user: Timo Sirainen date: Mon Mar 09 16:17:08 2015 +0200 description: indexer-worker: Added missing error logging. diffstat: src/indexer/master-connection.c | 23 ++++++++++++++++++----- 1 files changed, 18 insertions(+), 5 deletions(-) diffs (43 lines): diff -r c28d8e2ae6a9 -r 00d40bf9c289 src/indexer/master-connection.c --- a/src/indexer/master-connection.c Mon Mar 09 15:32:23 2015 +0200 +++ b/src/indexer/master-connection.c Mon Mar 09 16:17:08 2015 +0200 @@ -68,10 +68,17 @@ int ret = 0; if (mailbox_get_metadata(box, MAILBOX_METADATA_PRECACHE_FIELDS, - &metadata) < 0 || - mailbox_get_status(box, STATUS_MESSAGES | STATUS_LAST_CACHED_SEQ, - &status) < 0) + &metadata) < 0) { + i_error("Mailbox %s: Precache-fields lookup failed: %s", + mailbox_get_vname(box), mailbox_get_last_error(box, NULL)); return -1; + } + if (mailbox_get_status(box, STATUS_MESSAGES | STATUS_LAST_CACHED_SEQ, + &status) < 0) { + i_error("Mailbox %s: Status lookup failed: %s", + mailbox_get_vname(box), mailbox_get_last_error(box, NULL)); + return -1; + } seq = status.last_cached_seq + 1; trans = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_NO_CACHE_DEC); @@ -99,10 +106,16 @@ counter, max); } } - if (mailbox_search_deinit(&ctx) < 0) + if (mailbox_search_deinit(&ctx) < 0) { + i_error("Mailbox %s: Mail search failed: %s", + mailbox_get_vname(box), mailbox_get_last_error(box, NULL)); ret = -1; - if (mailbox_transaction_commit(&trans) < 0) + } + if (mailbox_transaction_commit(&trans) < 0) { + i_error("Mailbox %s: Transaction commit failed: %s", + mailbox_get_vname(box), mailbox_get_last_error(box, NULL)); ret = -1; + } if (ret == 0) { i_info("Indexed %u messages in %s", counter, mailbox_get_vname(box)); From dovecot at dovecot.org Mon Mar 9 15:15:48 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Mar 2015 15:15:48 +0000 Subject: dovecot-2.2: lib: Recent module_dir_load() changes broke error l... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8cb9f50f5b40 changeset: 18313:8cb9f50f5b40 user: Timo Sirainen date: Mon Mar 09 17:14:35 2015 +0200 description: lib: Recent module_dir_load() changes broke error logging. If there was a required list of modules, the error was properly returned. But when loading all plugins, the errors weren't logged. diffstat: src/lib/module-dir.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diffs (20 lines): diff -r 00d40bf9c289 -r 8cb9f50f5b40 src/lib/module-dir.c --- a/src/lib/module-dir.c Mon Mar 09 16:17:08 2015 +0200 +++ b/src/lib/module-dir.c Mon Mar 09 17:14:35 2015 +0200 @@ -461,9 +461,14 @@ else { path = t_strconcat(dir, "/", name, NULL); ret = module_load(path, stripped_name, set, modules, &module, &error); - if (ret < 0 && module_names != NULL) { - *error_r = i_strdup_printf("Couldn't load required plugins: %s", error); + if (ret == 0) + ; + else if (module_names != NULL) { + *error_r = i_strdup_printf("Couldn't load required plugin %s: %s", + path, error); i = count; + } else { + i_error("Couldn't load plugin %s: %s", path, error); } } From dovecot at dovecot.org Mon Mar 9 15:15:48 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Mar 2015 15:15:48 +0000 Subject: dovecot-2.2: lib: Small error logging improvements for module_di... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d978da323d44 changeset: 18314:d978da323d44 user: Timo Sirainen date: Mon Mar 09 17:15:03 2015 +0200 description: lib: Small error logging improvements for module_dir_load() diffstat: src/lib/module-dir.c | 17 ++++++++--------- 1 files changed, 8 insertions(+), 9 deletions(-) diffs (48 lines): diff -r 8cb9f50f5b40 -r d978da323d44 src/lib/module-dir.c --- a/src/lib/module-dir.c Mon Mar 09 17:14:35 2015 +0200 +++ b/src/lib/module-dir.c Mon Mar 09 17:15:03 2015 +0200 @@ -129,9 +129,8 @@ } if (m == NULL) { errmsg = t_str_new(128); - str_printfa(errmsg, "Can't load plugin %s: " - "Plugin %s must be loaded also", - module->name, *deps); + str_printfa(errmsg, "Plugin %s must be loaded also", + *deps); if (set->setting_name != NULL) { str_printfa(errmsg, " (you must set: %s=$%s %s)", @@ -213,8 +212,8 @@ } else { handle = dlopen(path, RTLD_GLOBAL | RTLD_NOW); if (handle == NULL) { - *error_r = t_strdup_printf("dlopen(%s) failed: %s", - path, dlerror()); + *error_r = t_strdup_printf("dlopen() failed: %s", + dlerror()); #ifdef RTLD_LAZY /* try to give a better error message by lazily loading the plugin and checking its dependencies */ @@ -237,8 +236,8 @@ if (module_version != NULL && !versions_equal(*module_version, set->abi_version)) { *error_r = t_strdup_printf( - "Module is for different ABI version %s (we have %s): %s", - *module_version, set->abi_version, path); + "Module is for different ABI version %s (we have %s)", + *module_version, set->abi_version); module_free(module); return -1; } @@ -254,8 +253,8 @@ if ((module->init == NULL || module->deinit == NULL) && set->require_init_funcs) { *error_r = t_strdup_printf( - "Module doesn't have %s function: %s", - module->init == NULL ? "init" : "deinit", path); + "Module doesn't have %s function", + module->init == NULL ? "init" : "deinit"); } else if (!module_check_wrong_binary_dependency(set, module, error_r)) { /* failed */ } else if (!module_check_missing_plugin_dependencies(set, module, From dovecot at dovecot.org Mon Mar 9 15:36:56 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Mar 2015 15:36:56 +0000 Subject: dovecot-2.2: lib: And another module_dir_load() bugfix.. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4d19d56e09fb changeset: 18315:4d19d56e09fb user: Timo Sirainen date: Mon Mar 09 17:36:11 2015 +0200 description: lib: And another module_dir_load() bugfix.. diffstat: src/lib/module-dir.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r d978da323d44 -r 4d19d56e09fb src/lib/module-dir.c --- a/src/lib/module-dir.c Mon Mar 09 17:15:03 2015 +0200 +++ b/src/lib/module-dir.c Mon Mar 09 17:36:11 2015 +0200 @@ -460,7 +460,7 @@ else { path = t_strconcat(dir, "/", name, NULL); ret = module_load(path, stripped_name, set, modules, &module, &error); - if (ret == 0) + if (ret >= 0) ; else if (module_names != NULL) { *error_r = i_strdup_printf("Couldn't load required plugin %s: %s", From dovecot at dovecot.org Mon Mar 9 17:29:50 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Mar 2015 17:29:50 +0000 Subject: dovecot-2.2: fs-posix: Don't try to unlink() the temp file twice... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5bd6e2eee650 changeset: 18316:5bd6e2eee650 user: Timo Sirainen date: Mon Mar 09 19:29:04 2015 +0200 description: fs-posix: Don't try to unlink() the temp file twice after failure. diffstat: src/lib-fs/fs-posix.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 4d19d56e09fb -r 5bd6e2eee650 src/lib-fs/fs-posix.c --- a/src/lib-fs/fs-posix.c Mon Mar 09 17:36:11 2015 +0200 +++ b/src/lib-fs/fs-posix.c Mon Mar 09 19:29:04 2015 +0200 @@ -404,6 +404,8 @@ fs_set_error(file->file.fs, "unlink(%s) failed: %m", file->temp_path); } + fs_posix_file_close(&file->file); + i_free_and_null(file->temp_path); if (ret < 0) return -1; break; From dovecot at dovecot.org Mon Mar 9 18:27:37 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Mar 2015 18:27:37 +0000 Subject: dovecot-2.2: fs-posix: Implement fs_stat() with fstat() if fd is... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2def20c622a6 changeset: 18317:2def20c622a6 user: Timo Sirainen date: Mon Mar 09 20:26:50 2015 +0200 description: fs-posix: Implement fs_stat() with fstat() if fd is already open. diffstat: src/lib-fs/fs-posix.c | 14 +++++++++++--- 1 files changed, 11 insertions(+), 3 deletions(-) diffs (24 lines): diff -r 5bd6e2eee650 -r 2def20c622a6 src/lib-fs/fs-posix.c --- a/src/lib-fs/fs-posix.c Mon Mar 09 19:29:04 2015 +0200 +++ b/src/lib-fs/fs-posix.c Mon Mar 09 20:26:50 2015 +0200 @@ -606,9 +606,17 @@ static int fs_posix_stat(struct fs_file *_file, struct stat *st_r) { struct posix_fs_file *file = (struct posix_fs_file *)_file; - if (stat(file->full_path, st_r) < 0) { - fs_set_error(_file->fs, "stat(%s) failed: %m", file->full_path); - return -1; + + if (file->fd != -1) { + if (fstat(file->fd, st_r) < 0) { + fs_set_error(_file->fs, "fstat(%s) failed: %m", file->full_path); + return -1; + } + } else { + if (stat(file->full_path, st_r) < 0) { + fs_set_error(_file->fs, "stat(%s) failed: %m", file->full_path); + return -1; + } } return 0; } From dovecot at dovecot.org Mon Mar 9 18:37:56 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Mar 2015 18:37:56 +0000 Subject: dovecot-2.2: fs-posix: Don't close fd after successful write. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4a80d3bbf14d changeset: 18318:4a80d3bbf14d user: Timo Sirainen date: Mon Mar 09 20:33:13 2015 +0200 description: fs-posix: Don't close fd after successful write. 5bd6e2eee650 should have been done only on failures. diffstat: src/lib-fs/fs-posix.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diffs (18 lines): diff -r 2def20c622a6 -r 4a80d3bbf14d src/lib-fs/fs-posix.c --- a/src/lib-fs/fs-posix.c Mon Mar 09 20:26:50 2015 +0200 +++ b/src/lib-fs/fs-posix.c Mon Mar 09 20:33:13 2015 +0200 @@ -404,10 +404,11 @@ fs_set_error(file->file.fs, "unlink(%s) failed: %m", file->temp_path); } - fs_posix_file_close(&file->file); - i_free_and_null(file->temp_path); - if (ret < 0) + if (ret < 0) { + fs_posix_file_close(&file->file); + i_free_and_null(file->temp_path); return -1; + } break; case FS_OPEN_MODE_REPLACE: if (rename(file->temp_path, file->full_path) < 0) { From dovecot at dovecot.org Mon Mar 9 19:28:35 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Mar 2015 19:28:35 +0000 Subject: dovecot-2.2: lib-fs: Optimized fs_stat() for fs-metawrap after w... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fa42da3cc614 changeset: 18319:fa42da3cc614 user: Timo Sirainen date: Mon Mar 09 21:27:51 2015 +0200 description: lib-fs: Optimized fs_stat() for fs-metawrap after writing a file. diffstat: src/lib-fs/fs-metawrap.c | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diffs (29 lines): diff -r 4a80d3bbf14d -r fa42da3cc614 src/lib-fs/fs-metawrap.c --- a/src/lib-fs/fs-metawrap.c Mon Mar 09 20:33:13 2015 +0200 +++ b/src/lib-fs/fs-metawrap.c Mon Mar 09 21:27:51 2015 +0200 @@ -354,6 +354,8 @@ input2 = i_stream_create_concat(inputs); i_stream_unref(&inputs[0]); i_stream_unref(&inputs[1]); + + file->metadata_write_size = str_len(file->metadata_header); return input2; } @@ -450,6 +452,16 @@ if (!file->fs->wrap_metadata) return fs_stat(file->super, st_r); + + if (file->metadata_write_size != 0) { + /* fs_stat() after a write. we can do this quickly. */ + if (fs_stat(file->super, st_r) < 0) + return -1; + i_assert((uoff_t)st_r->st_size > file->metadata_write_size); + st_r->st_size -= file->metadata_write_size; + return 0; + } + input = fs_read_stream(_file, IO_BLOCK_SIZE); if ((ret = i_stream_get_size(input, TRUE, &input_size)) < 0) { fs_set_error(_file->fs, "i_stream_get_size(%s) failed: %m", From pigeonhole at rename-it.nl Tue Mar 10 02:18:22 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 10 Mar 2015 03:18:22 +0100 Subject: dovecot-2.2-pigeonhole: Added tag 0.4.7.rc1 for changeset 27ad95... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/e1e9d50b2c15 changeset: 2000:e1e9d50b2c15 user: Stephan Bosch date: Tue Mar 10 03:17:53 2015 +0100 description: Added tag 0.4.7.rc1 for changeset 27ad95fd05a0 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 27ad95fd05a0 -r e1e9d50b2c15 .hgtags --- a/.hgtags Tue Mar 10 03:17:33 2015 +0100 +++ b/.hgtags Tue Mar 10 03:17:53 2015 +0100 @@ -23,3 +23,4 @@ b3303f675157c954d2de08599e2c83db5a772450 0.4.4 f5e3ef477a32498584ac924963ff2e11c75cd477 0.4.5 99d796a8cd26f5f64d56b02c1f0e720ffd6131e7 0.4.6 +27ad95fd05a039c39f7fec5d76bf28eac20362ce 0.4.7.rc1 From pigeonhole at rename-it.nl Tue Mar 10 02:18:22 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 10 Mar 2015 03:18:22 +0100 Subject: dovecot-2.2-pigeonhole: Updated README with addition of support ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/b04ce69445fc changeset: 1998:b04ce69445fc user: Stephan Bosch date: Tue Mar 10 02:42:53 2015 +0100 description: Updated README with addition of support for the metadata extensions. diffstat: README | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diffs (20 lines): diff -r c74220e16e0f -r b04ce69445fc README --- a/README Fri Mar 06 21:36:40 2015 +0100 +++ b/README Tue Mar 10 02:42:53 2015 +0100 @@ -120,6 +120,7 @@ ihave (RFC 5463): fully supported (v0.2.4+). mailbox (RFC 5490; Section 3): fully supported (v0.1.10+), but ACL permissions are not verified for mailboxexists. + mboxmetadata and servermetadata (RFC 5490): fully supported (v0.4.7+) include (RFC 6609): fully supported (v0.4.0+) duplicate (RFC 7352): fully supported (v0.4.3+). regex (draft v08; not latest version): almost fully supported, but @@ -148,8 +149,6 @@ The following extensions are under development: - mboxmetadata and servermetadata (RFC 5490): partially implemented; - Dovecot adjustments needed. ereject (RFC 5429; page 4): implemented, but currently equal to reject Many more extensions to the language exist. Not all of these extensions are From pigeonhole at rename-it.nl Tue Mar 10 02:18:22 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 10 Mar 2015 03:18:22 +0100 Subject: dovecot-2.2-pigeonhole: Released v0.4.7.rc1 for Dovecot v2.2.16.... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/27ad95fd05a0 changeset: 1999:27ad95fd05a0 user: Stephan Bosch date: Tue Mar 10 03:17:33 2015 +0100 description: Released v0.4.7.rc1 for Dovecot v2.2.16.rc1. diffstat: NEWS | 28 ++++++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 29 insertions(+), 1 deletions(-) diffs (44 lines): diff -r b04ce69445fc -r 27ad95fd05a0 NEWS --- a/NEWS Tue Mar 10 02:42:53 2015 +0100 +++ b/NEWS Tue Mar 10 03:17:33 2015 +0100 @@ -1,3 +1,31 @@ +v0.4.7 xx-03-2015 Stephan Bosch + + * editheader extension: Made protection against addition and deletion of + headers configurable separately. Also, the `Received' and `Auto-Submitted' + headers are no longer protected against addition by default. + * Turned message envelope address parse errors into warnings. + * The interpreter now accepts non-standard domain names, e.g. containing '_'. + + Implemented the Sieve index extension (RFC 5260). + + Implemented support for the mboxmetadata and servermetadata extensions + (RFC 5490). + + Implemented new sieve commands for the doveadm command line utility. These + commands are currently limited to ManageSieve operations, but the other + current sieve tools will be migrated to doveadm in the near future as well. + + Added more debug output to binary up-to-date checking. + - The Sieve interpreter now flushes duplicate database during start phase of + result execution rather than commit phase. This makes sure locks on the + duplicate database are released as soon as possible, preventing contention. + - Performed a few optimizations in the lexical scanner of the language. + - Fixed bug in `:matches' match-type that made a pattern without + wildcards match as if there were a '*' at the beginning. + - file storage: Restructured storage initialization to address backwards + compatibility issues. + - Fixed crash in validation of the string parameter of the comparator tag. + - extprograms extension: Made sure supplemental group privileges are also + dropped. This was a problem reported by Debian lintian. + - Fixed bug in handling of binary errors for action side-effects and message + overrides. + v0.4.6 02-11-2014 Stephan Bosch - After make distclean the distributed tarball would fail to recompile. diff -r b04ce69445fc -r 27ad95fd05a0 configure.ac --- a/configure.ac Tue Mar 10 02:42:53 2015 +0100 +++ b/configure.ac Tue Mar 10 03:17:33 2015 +0100 @@ -1,4 +1,4 @@ -AC_INIT([Pigeonhole], [0.4.6], [dovecot at dovecot.org], [dovecot-2.2-pigeonhole]) +AC_INIT([Pigeonhole], [0.4.7.rc1], [dovecot at dovecot.org], [dovecot-2.2-pigeonhole]) AC_CONFIG_AUX_DIR([.]) AC_CONFIG_SRCDIR([src]) AC_CONFIG_MACRO_DIR([m4]) From pigeonhole at rename-it.nl Tue Mar 10 02:19:36 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 10 Mar 2015 03:19:36 +0100 Subject: dovecot-2.2-pigeonhole: Added signature for changeset 27ad95fd05a0 Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/961c66e7f414 changeset: 2001:961c66e7f414 user: Stephan Bosch date: Tue Mar 10 03:19:39 2015 +0100 description: Added signature for changeset 27ad95fd05a0 diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r e1e9d50b2c15 -r 961c66e7f414 .hgsigs --- a/.hgsigs Tue Mar 10 03:17:53 2015 +0100 +++ b/.hgsigs Tue Mar 10 03:19:39 2015 +0100 @@ -17,3 +17,4 @@ b3303f675157c954d2de08599e2c83db5a772450 0 iQEcBAABAgAGBQJUTukTAAoJEATWKx49+7T0nWQH/3enKf5GbOe8eDBU83MvlYARFAbGEGb70coH3sVFhC50SjPSyIAU+Am048jVmLKvy2r/ABYXHwVn73rRbgR+X92iH4Q+ivYI7ZtUEr7iUoEUVetwks6YkUezthnzCVyWk+Hy9BnkoTEN08zPGkLnVt/e5SPAqQ1tZttpKOO+HZp3JxzGtMFBY/k+ZX8fU6PZKM6FZEPu8S8m2PnQUGaCgREZrt+ikMAzgwqgpEtYoiT6M6yQLyAVRpDvFsIU3q56vA3Zc3rl6vdJjBY9AMflyd1fEYv1IfUkVPjKZg/9JL42qRRQLccEGU2W+xpd7HYi1WfI+60buVmjPNTNr/GYPfo= f5e3ef477a32498584ac924963ff2e11c75cd477 0 iQEcBAABAgAGBQJUUrtaAAoJEATWKx49+7T0C+AH+QGUi15egTON1XwJ0aZEuI3qQScDif04EoteSwjRN+RYFLSkMPnkjG+4kx0tAG2RahlZ9gdyr4TW5a95aQhAxYS7j0bbEyJNIAektYtVniWhuxxxo5m1LjNbI6yYIYjqAqnyfzI55E15tNT2O2VkUBxgExdWACMcv0YiMGidQ+7JVox1QFwFMrJPK17NiCsboByZN9J0xj4tg0hibkt2MZ1TaYj10TMmyYDxVvZPedwa71YRNz/T3T+reroqhUYqAL2XszSX+PSMwdcxyo8+qoErBQyacD4zNAcXhwUmhTjw2g4QtwSk1WK0FDC/BunIlb6ccFoZ6FpQhO/8lu74Wjc= 99d796a8cd26f5f64d56b02c1f0e720ffd6131e7 0 iQEcBAABAgAGBQJUVmtZAAoJEATWKx49+7T0/wgH/0GyApuqHfn/PtKhZUhX78wvZ5t6IdU7Rs905qC/j4Y1u5JRg3EhvXs/JJUDlDsJBAVU9EwQRi37erF+LPIm+1W9ZuNr4H4kgea2QM+lnEFhmmt7tqgXUhPnpufkPP1pfnyjDOq5oeMeA8i/Ecic9pdBIIY+YEU80knf0PbqFxGzpA4gbX2dXOPQlqs+9h0hEUjg8t8hUXtqxSkO2qoJIbWQIFqGaqXCUCnLQ4LZYxLOGMki3I8Nrjaa/objgDlH+bsNe2zGyUdICQgcyKc4ZeeZcEpnJBZvVhlhfzDlCaJIXxGmZjRF1lt382dvObNhlDEOi0NzapCwF0xE4WtOPIw= +27ad95fd05a039c39f7fec5d76bf28eac20362ce 0 iQEcBAABAgAGBQJU/lS3AAoJEATWKx49+7T0yJ8IAKsrq2CuRLRiH9YMPWJJzIwVTOudE+H14vUCkeR5/RAAyrBDkf9H3FKda8fTOIqhPoRKwoiKp7cMfTJfU28MkUAic/709bTAMwX+QHEr2g44dSZvRlAzh6CrOZSB/Q39FU8s67U9WDPoz9e0kluIuh7QeLwWdJSklSGw7cpDjAQ2wtFyCK4kSA44JNoTK2KnXiy+Pqu2GEZC5YrnBNuOGXJaX2eIIou8Udf2qnYwX+7UAp0Kgn+uveiY1AMdax/DC7+RSVFyneFHt0Fgx+ZvTLVZMLfLu/a9GDb4LV5gON1ZRYSg/LjQKzs243T1FwTT0Y6ujDvkgw1BoCYWjmvql/o= From dovecot at dovecot.org Wed Mar 11 14:40:51 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 11 Mar 2015 14:40:51 +0000 Subject: dovecot-2.2: lib-master: Get log timestamp prefix from LOG_STDER... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/13021170e269 changeset: 18320:13021170e269 user: Timo Sirainen date: Wed Mar 11 13:27:49 2015 +0200 description: lib-master: Get log timestamp prefix from LOG_STDERR_TIMESTAMP environment. diffstat: src/lib-master/master-service.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (18 lines): diff -r fa42da3cc614 -r 13021170e269 src/lib-master/master-service.c --- a/src/lib-master/master-service.c Mon Mar 09 21:27:51 2015 +0200 +++ b/src/lib-master/master-service.c Wed Mar 11 13:27:49 2015 +0200 @@ -262,10 +262,13 @@ void master_service_init_log(struct master_service *service, const char *prefix) { - const char *path; + const char *path, *timestamp; if ((service->flags & MASTER_SERVICE_FLAG_STANDALONE) != 0 && (service->flags & MASTER_SERVICE_FLAG_DONT_LOG_TO_STDERR) == 0) { + timestamp = getenv("LOG_STDERR_TIMESTAMP"); + if (timestamp != NULL) + i_set_failure_timestamp_format(timestamp); i_set_failure_file("/dev/stderr", ""); return; } From dovecot at dovecot.org Wed Mar 11 14:40:51 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 11 Mar 2015 14:40:51 +0000 Subject: dovecot-2.2: doveadm: Initialize logging. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/878e9d914339 changeset: 18321:878e9d914339 user: Timo Sirainen date: Wed Mar 11 13:28:24 2015 +0200 description: doveadm: Initialize logging. Most importantly so that LOG_STDERR_TIMESTAMP can be used to prefix each line with a timestamp. diffstat: src/doveadm/doveadm.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 13021170e269 -r 878e9d914339 src/doveadm/doveadm.c --- a/src/doveadm/doveadm.c Wed Mar 11 13:27:49 2015 +0200 +++ b/src/doveadm/doveadm.c Wed Mar 11 13:28:24 2015 +0200 @@ -297,6 +297,7 @@ } else { doveadm_read_settings(); } + master_service_init_log(master_service, "doveadm: "); doveadm_cmds_init(); for (i = 0; i < N_ELEMENTS(doveadm_cmdline_commands); i++) From dovecot at dovecot.org Wed Mar 11 14:40:51 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 11 Mar 2015 14:40:51 +0000 Subject: dovecot-2.2: imapc: Make sure we don't flush prefetch FETCH comm... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d21f71ab9f28 changeset: 18322:d21f71ab9f28 user: Timo Sirainen date: Wed Mar 11 14:39:26 2015 +0200 description: imapc: Make sure we don't flush prefetch FETCH command unneededly. diffstat: src/lib-storage/index/imapc/imapc-mail-fetch.c | 10 ++++++++-- src/lib-storage/index/imapc/imapc-mail.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diffs (58 lines): diff -r 878e9d914339 -r d21f71ab9f28 src/lib-storage/index/imapc/imapc-mail-fetch.c --- a/src/lib-storage/index/imapc/imapc-mail-fetch.c Wed Mar 11 13:28:24 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-mail-fetch.c Wed Mar 11 14:39:26 2015 +0200 @@ -171,7 +171,7 @@ if (headers_have_subset(mail->fetching_headers, headers)) headers = NULL; if (fields == 0 && headers == NULL) - return 0; + return mail->fetch_sent ? 0 : 1; if (!_mail->saving) { /* if we already know that the mail is expunged, @@ -229,6 +229,7 @@ pool_ref(mail->imail.mail.pool); mail->fetching_fields |= fields; mail->fetch_count++; + mail->fetch_sent = FALSE; imapc_mail_delayed_send_or_merge(mail, str); return 1; @@ -365,7 +366,8 @@ /* we'll continue waiting until we've got all the fields we wanted, or until all FETCH replies have been received (i.e. some FETCHes failed) */ - imapc_mail_fetch_flush(mbox); + if (ret > 0) + imapc_mail_fetch_flush(mbox); while (imail->fetch_count > 0 && (!imapc_mail_have_fields(imail, fields) || !imail->header_list_fetched)) @@ -376,12 +378,16 @@ void imapc_mail_fetch_flush(struct imapc_mailbox *mbox) { struct imapc_command *cmd; + struct imapc_mail *const *mailp; if (mbox->pending_fetch_request == NULL) { i_assert(mbox->to_pending_fetch_send == NULL); return; } + array_foreach(&mbox->pending_fetch_request->mails, mailp) + (*mailp)->fetch_sent = TRUE; + cmd = imapc_client_mailbox_cmd(mbox->client_box, imapc_mail_fetch_callback, mbox->pending_fetch_request); diff -r 878e9d914339 -r d21f71ab9f28 src/lib-storage/index/imapc/imapc-mail.h --- a/src/lib-storage/index/imapc/imapc-mail.h Wed Mar 11 13:28:24 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-mail.h Wed Mar 11 14:39:26 2015 +0200 @@ -13,6 +13,7 @@ enum mail_fetch_field fetching_fields; const char *const *fetching_headers; unsigned int fetch_count; + bool fetch_sent; int fd; buffer_t *body; From dovecot at dovecot.org Wed Mar 11 14:40:57 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 11 Mar 2015 14:40:57 +0000 Subject: dovecot-2.2: imapc: Don't flush prefetch FETCH command before it... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f8f57dde247d changeset: 18323:f8f57dde247d user: Timo Sirainen date: Wed Mar 11 14:39:52 2015 +0200 description: imapc: Don't flush prefetch FETCH command before it has mail_prefetch_count number of mails. diffstat: src/lib-storage/index/imapc/imapc-mail-fetch.c | 17 +++++++++++++++-- 1 files changed, 15 insertions(+), 2 deletions(-) diffs (34 lines): diff -r d21f71ab9f28 -r f8f57dde247d src/lib-storage/index/imapc/imapc-mail-fetch.c --- a/src/lib-storage/index/imapc/imapc-mail-fetch.c Wed Mar 11 14:39:26 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-mail-fetch.c Wed Mar 11 14:39:52 2015 +0200 @@ -146,7 +146,19 @@ } array_append(&mbox->pending_fetch_request->mails, &mail, 1); - if (mbox->to_pending_fetch_send == NULL) { + if (mbox->to_pending_fetch_send == NULL && + array_count(&mbox->pending_fetch_request->mails) > + mbox->box.storage->set->mail_prefetch_count) { + /* we're now prefetching the maximum number of mails. this + most likely means that we need to flush out the command now + before sending anything else. delay it a little bit though + in case the sending code doesn't actually use + mail_prefetch_count and wants to fetch more. + + note that we don't want to add this timeout too early, + because we want to optimize the maximum number of messages + placed into a single FETCH. even without timeout the command + gets flushed by imapc_mail_fetch() call. */ mbox->to_pending_fetch_send = timeout_add_short(0, imapc_mail_fetch_flush, mbox); } @@ -397,7 +409,8 @@ imapc_command_send(cmd, str_c(mbox->pending_fetch_cmd)); mbox->pending_fetch_request = NULL; - timeout_remove(&mbox->to_pending_fetch_send); + if (mbox->to_pending_fetch_send != NULL) + timeout_remove(&mbox->to_pending_fetch_send); str_truncate(mbox->pending_fetch_cmd, 0); } From dovecot at dovecot.org Wed Mar 11 14:41:02 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 11 Mar 2015 14:41:02 +0000 Subject: dovecot-2.2: lib-master: If write() to anvil fails, reconnect to... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f7b3c923cf4d changeset: 18324:f7b3c923cf4d user: Timo Sirainen date: Wed Mar 11 16:39:24 2015 +0200 description: lib-master: If write() to anvil fails, reconnect to it. diffstat: src/lib-master/anvil-client.c | 15 ++++++++++++--- 1 files changed, 12 insertions(+), 3 deletions(-) diffs (33 lines): diff -r f8f57dde247d -r f7b3c923cf4d src/lib-master/anvil-client.c --- a/src/lib-master/anvil-client.c Wed Mar 11 14:39:52 2015 +0200 +++ b/src/lib-master/anvil-client.c Wed Mar 11 16:39:24 2015 +0200 @@ -142,9 +142,13 @@ client->fd = fd; client->input = i_stream_create_fd(fd, ANVIL_INBUF_SIZE, FALSE); client->output = o_stream_create_fd(fd, (size_t)-1, FALSE); - o_stream_set_no_error_handling(client->output, TRUE); client->io = io_add(fd, IO_READ, anvil_input, client); - o_stream_nsend_str(client->output, ANVIL_HANDSHAKE); + if (o_stream_send_str(client->output, ANVIL_HANDSHAKE) < 0) { + i_error("write(%s) failed: %s", client->path, + o_stream_get_error(client->output)); + anvil_reconnect(client); + return -1; + } return 0; } @@ -190,7 +194,12 @@ iov[0].iov_len = strlen(cmd); iov[1].iov_base = "\n"; iov[1].iov_len = 1; - o_stream_nsendv(client->output, iov, 2); + if (o_stream_sendv(client->output, iov, 2) < 0) { + i_error("write(%s) failed: %s", client->path, + o_stream_get_error(client->output)); + anvil_reconnect(client); + return -1; + } return 0; } From dovecot at dovecot.org Wed Mar 11 14:41:02 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 11 Mar 2015 14:41:02 +0000 Subject: dovecot-2.2: lib-master: Timeout anvil queries after 5 seconds. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ae12cfc7e064 changeset: 18325:ae12cfc7e064 user: Timo Sirainen date: Wed Mar 11 16:40:05 2015 +0200 description: lib-master: Timeout anvil queries after 5 seconds. diffstat: src/lib-master/anvil-client.c | 25 ++++++++++++++++++++++++- 1 files changed, 24 insertions(+), 1 deletions(-) diffs (75 lines): diff -r f7b3c923cf4d -r ae12cfc7e064 src/lib-master/anvil-client.c --- a/src/lib-master/anvil-client.c Wed Mar 11 16:39:24 2015 +0200 +++ b/src/lib-master/anvil-client.c Wed Mar 11 16:40:05 2015 +0200 @@ -20,6 +20,7 @@ struct istream *input; struct ostream *output; struct io *io; + struct timeout *to_query; struct timeout *to_reconnect; time_t last_reconnect; @@ -34,6 +35,7 @@ #define ANVIL_HANDSHAKE "VERSION\tanvil\t1\t0\n" #define ANVIL_INBUF_SIZE 1024 #define ANVIL_RECONNECT_MIN_SECS 5 +#define ANVIL_QUERY_TIMEOUT_MSECS (1000*5) static void anvil_client_disconnect(struct anvil_client *client); @@ -116,6 +118,11 @@ } else if (client->input->eof) { i_error("read(%s) failed: EOF", client->path); anvil_reconnect(client); + } else if (client->to_query != NULL) { + if (aqueue_count(client->queries) == 0) + timeout_remove(&client->to_query); + else + timeout_reset(client->to_query); } } @@ -165,12 +172,14 @@ i_free(query); aqueue_delete_tail(client->queries); } + if (client->to_query != NULL) + timeout_remove(&client->to_query); } static void anvil_client_disconnect(struct anvil_client *client) { + anvil_client_cancel_queries(client); if (client->fd != -1) { - anvil_client_cancel_queries(client); io_remove(&client->io); i_stream_destroy(&client->input); o_stream_destroy(&client->output); @@ -181,6 +190,16 @@ timeout_remove(&client->to_reconnect); } +static void anvil_client_timeout(struct anvil_client *client) +{ + i_assert(aqueue_count(client->queries) > 0); + + i_error("%s: Anvil queries timed out after %u secs - aborting queries", + client->path, ANVIL_QUERY_TIMEOUT_MSECS/1000); + /* perhaps reconnect helps */ + anvil_reconnect(client); +} + static int anvil_client_send(struct anvil_client *client, const char *cmd) { struct const_iovec iov[2]; @@ -190,6 +209,10 @@ return -1; } + if (client->to_query == NULL) { + client->to_query = timeout_add(ANVIL_QUERY_TIMEOUT_MSECS, + anvil_client_timeout, client); + } iov[0].iov_base = cmd; iov[0].iov_len = strlen(cmd); iov[1].iov_base = "\n"; From dovecot at dovecot.org Wed Mar 11 15:29:58 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 11 Mar 2015 15:29:58 +0000 Subject: dovecot-2.2: imapc: Removed Exchange-workaround for ignoring mis... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/06362f6d26ca changeset: 18326:06362f6d26ca user: Timo Sirainen date: Wed Mar 11 17:29:12 2015 +0200 description: imapc: Removed Exchange-workaround for ignoring missing BODY[] replies. This causes data loss if server was actually returning a NO temporary error that would have succeeded later on. diffstat: src/lib-storage/index/imapc/imapc-mail.c | 44 +++++++++++-------------------- 1 files changed, 16 insertions(+), 28 deletions(-) diffs (94 lines): diff -r ae12cfc7e064 -r 06362f6d26ca src/lib-storage/index/imapc/imapc-mail.c --- a/src/lib-storage/index/imapc/imapc-mail.c Wed Mar 11 16:40:05 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-mail.c Wed Mar 11 17:29:12 2015 +0200 @@ -52,22 +52,27 @@ return !imapc_msgmap_uid_to_rseq(msgmap, _mail->uid, &rseq); } -static int imapc_mail_failed(struct mail *mail, const char *field) +static void 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)) { mail_set_expunged(mail); - 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 { + /* NOTE: earlier we didn't treat this as a failure, because + old Exchange versions fail to return any data for messages + in Calendars mailbox. But it's a bad idea to always assume + that a missing field is intentional, because there's + potential for data loss. Ideally we could detect whether + this is an Exchange issue or not, but I don't have access + to such an old Exchange anymore. So at least for now until + someone complains, the Exchange workaround is disabled. */ 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; } } @@ -83,11 +88,8 @@ if (imapc_mail_fetch(_mail, MAIL_FETCH_RECEIVED_DATE, NULL) < 0) return -1; if (data->received_date == (time_t)-1) { - 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; + imapc_mail_failed(_mail, "INTERNALDATE"); + return -1; } } *date_r = data->received_date; @@ -130,11 +132,8 @@ if (imapc_mail_fetch(_mail, MAIL_FETCH_PHYSICAL_SIZE, NULL) < 0) return -1; if (data->physical_size == (uoff_t)-1) { - if (imapc_mail_failed(_mail, "RFC822.SIZE") < 0) - return -1; - /* assume that the server never returns RFC822.SIZE - for this mail (see BODY[] failure handling) */ - data->physical_size = 0; + imapc_mail_failed(_mail, "RFC822.SIZE"); + return -1; } *size_r = data->physical_size; return 0; @@ -255,19 +254,8 @@ return -1; if (data->stream == NULL) { - 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 - 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(&uchar_nul, 0); - imapc_mail_init_stream(mail, TRUE); + imapc_mail_failed(_mail, "BODY[]"); + return -1; } } @@ -443,7 +431,7 @@ if (imapc_mail_fetch(_mail, MAIL_FETCH_GUID, NULL) < 0) return -1; if (imail->data.guid == NULL) { - (void)imapc_mail_failed(_mail, mbox->guid_fetch_field_name); + imapc_mail_failed(_mail, mbox->guid_fetch_field_name); return -1; } } else { From dovecot at dovecot.org Wed Mar 11 15:55:16 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 11 Mar 2015 15:55:16 +0000 Subject: dovecot-2.2: imapc: Add prefetched GUIDs to cache. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/946be805b3cc changeset: 18327:946be805b3cc user: Timo Sirainen date: Wed Mar 11 17:54:21 2015 +0200 description: imapc: Add prefetched GUIDs to cache. diffstat: src/lib-storage/index/imapc/imapc-mail.c | 36 ++++++++++++++++++++++++-------- 1 files changed, 27 insertions(+), 9 deletions(-) diffs (57 lines): diff -r 06362f6d26ca -r 946be805b3cc src/lib-storage/index/imapc/imapc-mail.c --- a/src/lib-storage/index/imapc/imapc-mail.c Wed Mar 11 17:29:12 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-mail.c Wed Mar 11 17:54:21 2015 +0200 @@ -406,26 +406,44 @@ return 0; } +static bool imapc_mail_get_cached_guid(struct mail *_mail) +{ + struct index_mail *imail = (struct index_mail *)_mail; + const enum index_cache_field cache_idx = + imail->ibox->cache_fields[MAIL_CACHE_GUID].idx; + string_t *str; + + if (imail->data.guid != NULL) { + if (mail_cache_field_can_add(_mail->transaction->cache_trans, + _mail->seq, cache_idx)) { + /* GUID was prefetched - add to cache */ + index_mail_cache_add_idx(imail, cache_idx, + imail->data.guid, strlen(imail->data.guid)+1); + } + return TRUE; + } + + str = str_new(imail->mail.data_pool, 64); + if (mail_cache_lookup_field(_mail->transaction->cache_view, + str, imail->mail.mail.seq, cache_idx) > 0) { + imail->data.guid = str_c(str); + return TRUE; + } + return FALSE; +} + 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) { + if (imapc_mail_get_cached_guid(_mail)) { *value_r = imail->data.guid; return 0; } - str = str_new(imail->mail.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 (mbox->guid_fetch_field_name != NULL) { if (imapc_mail_fetch(_mail, MAIL_FETCH_GUID, NULL) < 0) From dovecot at dovecot.org Wed Mar 11 15:55:16 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 11 Mar 2015 15:55:16 +0000 Subject: dovecot-2.2: imapc: Use GUIDs from cache. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f32ddc04fce7 changeset: 18328:f32ddc04fce7 user: Timo Sirainen date: Wed Mar 11 17:54:27 2015 +0200 description: imapc: Use GUIDs from cache. diffstat: src/lib-storage/index/imapc/imapc-mail.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (21 lines): diff -r 946be805b3cc -r f32ddc04fce7 src/lib-storage/index/imapc/imapc-mail.c --- a/src/lib-storage/index/imapc/imapc-mail.c Wed Mar 11 17:54:21 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-mail.c Wed Mar 11 17:54:27 2015 +0200 @@ -11,6 +11,8 @@ #include "imapc-client.h" #include "imapc-storage.h" +static bool imapc_mail_get_cached_guid(struct mail *_mail); + struct mail * imapc_mail_alloc(struct mailbox_transaction_context *t, enum mail_fetch_field wanted_fields, @@ -300,6 +302,8 @@ !IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_RFC822_SIZE)) data->access_part |= READ_HDR | READ_BODY; } + if ((data->wanted_fields & MAIL_FETCH_GUID) != 0) + (void)imapc_mail_get_cached_guid(_mail); if (data->access_part == 0 && data->wanted_headers != NULL && !IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_FETCH_HEADERS)) { From dovecot at dovecot.org Wed Mar 11 16:33:54 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 11 Mar 2015 16:33:54 +0000 Subject: dovecot-2.2: imapc: If imapc_features has gmail-migration, fetch... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3effe57f223d changeset: 18329:3effe57f223d user: Timo Sirainen date: Wed Mar 11 18:30:19 2015 +0200 description: imapc: If imapc_features has gmail-migration, fetch X-GM-MSGID at startup and cache it. This works only if index files haven't been disabled. diffstat: src/lib-storage/index/imapc/imapc-mailbox.c | 29 ++++++++++++++++++++++++++++- src/lib-storage/index/imapc/imapc-storage.h | 2 ++ src/lib-storage/index/imapc/imapc-sync.c | 18 +++++++++++++++++- 3 files changed, 47 insertions(+), 2 deletions(-) diffs (139 lines): diff -r f32ddc04fce7 -r 3effe57f223d src/lib-storage/index/imapc/imapc-mailbox.c --- a/src/lib-storage/index/imapc/imapc-mailbox.c Wed Mar 11 17:54:27 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-mailbox.c Wed Mar 11 18:30:19 2015 +0200 @@ -48,11 +48,20 @@ if (mbox->delayed_sync_trans != NULL) return; + i_assert(mbox->delayed_sync_cache_view == NULL); + i_assert(mbox->delayed_sync_cache_trans == NULL); + mbox->delayed_sync_trans = mail_index_transaction_begin(imapc_mailbox_get_sync_view(mbox), MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL); mbox->delayed_sync_view = mail_index_transaction_open_updated_view(mbox->delayed_sync_trans); + + mbox->delayed_sync_cache_view = + mail_cache_view_open(mbox->box.cache, mbox->delayed_sync_view); + mbox->delayed_sync_cache_trans = + mail_cache_get_transaction(mbox->delayed_sync_cache_view, + mbox->delayed_sync_trans); } static int imapc_mailbox_commit_delayed_expunges(struct imapc_mailbox *mbox) @@ -92,6 +101,9 @@ } *changes_r = TRUE; } + mbox->delayed_sync_cache_trans = NULL; + if (mbox->delayed_sync_cache_view != NULL) + mail_cache_view_close(&mbox->delayed_sync_cache_view); if (mbox->sync_view != NULL) mail_index_view_close(&mbox->sync_view); @@ -259,7 +271,7 @@ struct imapc_fetch_request *const *fetch_requestp; struct imapc_mail *const *mailp; const struct imap_arg *list, *flags_list; - const char *atom; + const char *atom, *guid = NULL; const struct mail_index_record *rec = NULL; enum mail_flags flags; uint32_t fetch_uid, uid; @@ -295,6 +307,10 @@ array_append(&keywords, &atom, 1); } } + } else if (strcasecmp(atom, "X-GM-MSGID") == 0 && + !mbox->initial_sync_done) { + if (imap_arg_get_atom(&list[i+1], &atom)) + guid = atom; } else if (strcasecmp(atom, "X-GM-LABELS") == 0 && IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_GMAIL_MIGRATION)) { if (!imap_arg_get_list(&list[i+1], &flags_list)) @@ -382,6 +398,17 @@ } mail_index_keywords_unref(&kw); } + if (guid != NULL) { + struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(&mbox->box); + const enum index_cache_field guid_cache_idx = + ibox->cache_fields[MAIL_CACHE_GUID].idx; + + if (mail_cache_field_can_add(mbox->delayed_sync_cache_trans, + lseq, guid_cache_idx)) { + mail_cache_add(mbox->delayed_sync_cache_trans, lseq, + guid_cache_idx, guid, strlen(guid)+1); + } + } imapc_mailbox_idle_notify(mbox); } diff -r f32ddc04fce7 -r 3effe57f223d src/lib-storage/index/imapc/imapc-storage.h --- a/src/lib-storage/index/imapc/imapc-storage.h Wed Mar 11 17:54:27 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-storage.h Wed Mar 11 18:30:19 2015 +0200 @@ -87,6 +87,8 @@ struct mail_index_transaction *delayed_sync_trans; struct mail_index_view *sync_view, *delayed_sync_view; + struct mail_cache_view *delayed_sync_cache_view; + struct mail_cache_transaction_ctx *delayed_sync_cache_trans; struct timeout *to_idle_check, *to_idle_delay; ARRAY(struct imapc_fetch_request *) fetch_requests; diff -r f32ddc04fce7 -r 3effe57f223d src/lib-storage/index/imapc/imapc-sync.c --- a/src/lib-storage/index/imapc/imapc-sync.c Wed Mar 11 17:54:27 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-sync.c Wed Mar 11 18:30:19 2015 +0200 @@ -4,6 +4,7 @@ #include "ioloop.h" #include "str.h" #include "imap-util.h" +#include "mail-cache.h" #include "index-sync-private.h" #include "imapc-client.h" #include "imapc-msgmap.h" @@ -282,13 +283,20 @@ str_printfa(cmd, "UID FETCH %u:* (FLAGS", first_uid); if (IMAPC_BOX_HAS_FEATURE(ctx->mbox, IMAPC_FEATURE_GMAIL_MIGRATION)) { - /* do this only for the \All mailbox */ enum mailbox_info_flags flags; + if (first_uid == 1 && + !mail_index_is_in_memory(ctx->mbox->box.index)) { + /* these can be efficiently fetched among flags and + stored into cache */ + str_append(cmd, " X-GM-MSGID"); + } + /* do this only for the \All mailbox */ if (imapc_list_get_mailbox_flags(ctx->mbox->box.list, ctx->mbox->box.name, &flags) == 0 && (flags & MAILBOX_SPECIALUSE_ALL) != 0) str_append(cmd, " X-GM-LABELS"); + } str_append_c(cmd, ')'); imapc_sync_cmd(ctx, str_c(cmd)); @@ -419,6 +427,11 @@ mbox->delayed_sync_view = mail_index_transaction_open_updated_view(ctx->trans); mbox->delayed_sync_trans = ctx->trans; + mbox->delayed_sync_cache_view = + mail_cache_view_open(mbox->box.cache, mbox->delayed_sync_view); + mbox->delayed_sync_cache_trans = + mail_cache_get_transaction(mbox->delayed_sync_cache_view, + mbox->delayed_sync_trans); mbox->min_append_uid = mail_index_get_header(ctx->sync_view)->next_uid; mbox->syncing = TRUE; @@ -455,6 +468,9 @@ i_free_and_null(ctx->mbox->sync_gmail_pop3_search_tag); ret = -1; } + mail_cache_view_close(&ctx->mbox->delayed_sync_cache_view); + ctx->mbox->delayed_sync_cache_trans = NULL; + ctx->mbox->syncing = FALSE; ctx->mbox->sync_ctx = NULL; From dovecot at dovecot.org Wed Mar 11 17:45:34 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 11 Mar 2015 17:45:34 +0000 Subject: dovecot-2.2: lib-imap-client: Implemented a bit more complicated... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/bac6a6a444d3 changeset: 18330:bac6a6a444d3 user: Timo Sirainen date: Wed Mar 11 19:44:48 2015 +0200 description: lib-imap-client: Implemented a bit more complicated [THROTTLING] behavior. The throttling is now more continuous and decreases more slowly. diffstat: src/lib-imap-client/imapc-connection.c | 111 ++++++++++++++++++++++++-------- 1 files changed, 84 insertions(+), 27 deletions(-) diffs (172 lines): diff -r 3effe57f223d -r bac6a6a444d3 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Wed Mar 11 18:30:19 2015 +0200 +++ b/src/lib-imap-client/imapc-connection.c Wed Mar 11 19:44:48 2015 +0200 @@ -25,9 +25,10 @@ #define IMAPC_COMMAND_STATE_AUTHENTICATE_CONTINUE 10000 #define IMAPC_MAX_INLINE_LITERAL_SIZE (1024*32) -/* max seconds to wait after receiving [THROTTLED] as - 2^IMAPC_THROTTLE_COUNTER_MAX_EXP */ -#define IMAPC_THROTTLE_COUNTER_MAX_EXP 4 +/* [THROTTLED] handling behavior */ +#define IMAPC_THROTTLE_INIT_MSECS 50 +#define IMAPC_THROTTLE_MAX_MSECS (16*1000) +#define IMAPC_THROTTLE_SHRINK_MIN_MSECS 500 enum imapc_input_state { IMAPC_INPUT_STATE_NONE = 0, @@ -121,10 +122,12 @@ struct imapc_connection_literal literal; ARRAY(struct imapc_arg_file) literal_files; - unsigned int throttle_counter; + unsigned int throttle_msecs; + unsigned int throttle_shrink_msecs; + unsigned int last_successful_throttle_msecs; bool throttle_pending; struct timeval throttle_end_timeval; - struct timeout *to_throttle; + struct timeout *to_throttle, *to_throttle_shrink; unsigned int idling:1; unsigned int idle_stopping:1; @@ -202,6 +205,8 @@ conn->to = io_loop_move_timeout(&conn->to); if (conn->to_throttle != NULL) conn->to_throttle = io_loop_move_timeout(&conn->to_throttle); + if (conn->to_throttle_shrink != NULL) + conn->to_throttle_shrink = io_loop_move_timeout(&conn->to_throttle_shrink); if (conn->output != NULL) o_stream_switch_ioloop(conn->output); if (conn->dns_lookup != NULL) @@ -387,6 +392,8 @@ timeout_remove(&conn->to_output); if (conn->to_throttle != NULL) timeout_remove(&conn->to_throttle); + if (conn->to_throttle_shrink != NULL) + timeout_remove(&conn->to_throttle_shrink); if (conn->parser != NULL) imap_parser_unref(&conn->parser); if (conn->io != NULL) @@ -1121,6 +1128,72 @@ } static void +imapc_connection_throttle_shrink_timeout(struct imapc_connection *conn) +{ + if (conn->throttle_msecs <= 1) + conn->throttle_msecs = 0; + else + conn->throttle_msecs = conn->throttle_msecs*3 / 4; + + if (conn->throttle_shrink_msecs <= IMAPC_THROTTLE_SHRINK_MIN_MSECS) + conn->throttle_shrink_msecs = 0; + else + conn->throttle_shrink_msecs = conn->throttle_shrink_msecs*3 / 4; + + timeout_remove(&conn->to_throttle_shrink); + if (conn->throttle_shrink_msecs > 0) { + conn->to_throttle_shrink = + timeout_add(conn->throttle_shrink_msecs, + imapc_connection_throttle_shrink_timeout, conn); + } +} + +static void +imapc_connection_throttle(struct imapc_connection *conn, + const struct imapc_command_reply *reply) +{ + if (conn->to_throttle != NULL) + timeout_remove(&conn->to_throttle); + + /* If GMail returns [THROTTLED], start slowing down commands. + Unfortunately this isn't a nice resp-text-code, but just + appended at the end of the line (although we kind of support + it as resp-text-code also in here if it's uppercased). */ + if (strstr(reply->text_full, "[THROTTLED]") != NULL) { + if (conn->throttle_msecs == 0) + conn->throttle_msecs = IMAPC_THROTTLE_INIT_MSECS; + else if (conn->throttle_msecs < conn->last_successful_throttle_msecs) + conn->throttle_msecs = conn->last_successful_throttle_msecs; + else { + conn->throttle_msecs *= 2; + if (conn->throttle_msecs > IMAPC_THROTTLE_MAX_MSECS) + conn->throttle_msecs = IMAPC_THROTTLE_MAX_MSECS; + } + if (conn->throttle_shrink_msecs == 0) + conn->throttle_shrink_msecs = IMAPC_THROTTLE_SHRINK_MIN_MSECS; + else + conn->throttle_shrink_msecs *= 2; + if (conn->to_throttle_shrink != NULL) + timeout_reset(conn->to_throttle_shrink); + } else { + if (conn->throttle_shrink_msecs > 0 && + conn->to_throttle_shrink == NULL) { + conn->to_throttle_shrink = + timeout_add(conn->throttle_shrink_msecs, + imapc_connection_throttle_shrink_timeout, conn); + } + conn->last_successful_throttle_msecs = conn->throttle_msecs; + } + + if (conn->throttle_msecs > 0) { + conn->throttle_end_timeval = ioloop_timeval; + timeval_add_msecs(&conn->throttle_end_timeval, + conn->throttle_msecs); + conn->throttle_pending = TRUE; + } +} + +static void imapc_command_reply_free(struct imapc_command *cmd, const struct imapc_command_reply *reply) { @@ -1180,26 +1253,10 @@ } else { reply.text_without_resp = reply.text_full; } - if (!conn->throttle_pending && - strstr(reply.text_full, "[THROTTLED]") != NULL) { - /* GMail throttling - start slowing down commands. - unfortunately this isn't a nice resp-text-code, but just - appended at the end of the line (although we kind of support - it as resp-text-code also in here if it's uppercased). */ - conn->throttle_end_timeval = ioloop_timeval; - timeval_add_msecs(&conn->throttle_end_timeval, - (1U << conn->throttle_counter) * 1000); - conn->throttle_pending = TRUE; - if (conn->throttle_counter < IMAPC_THROTTLE_COUNTER_MAX_EXP) - conn->throttle_counter++; - } - if (!conn->throttle_pending && - timeval_cmp(&ioloop_timeval, &conn->throttle_end_timeval) >= 0) { - /* tagged reply without [THROTTLED] and it was received after - the throttling ended. we can completely reset the throttling - state now */ - conn->throttle_counter = 0; - } + /* if we've pipelined multiple commands, handle [THROTTLED] reply + from only one of them */ + if (!conn->throttle_pending) + imapc_connection_throttle(conn, &reply); /* find the command. it's either the first command in send queue (literal failed) or somewhere in wait list. */ @@ -1790,7 +1847,7 @@ if (conn->to_throttle != NULL) timeout_remove(&conn->to_throttle); - if (conn->throttle_counter == 0) { + if (conn->throttle_msecs == 0) { /* we haven't received [THROTTLED] recently */ return FALSE; } @@ -1799,7 +1856,7 @@ replies to see if we're still throttled */ return TRUE; } - if (timeval_cmp(&ioloop_timeval, &conn->throttle_end_timeval) > 0) { + if (timeval_cmp(&ioloop_timeval, &conn->throttle_end_timeval) >= 0) { /* we reached the throttle timeout - send the next command */ conn->throttle_pending = FALSE; return FALSE; From dovecot at dovecot.org Wed Mar 11 18:03:06 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 11 Mar 2015 18:03:06 +0000 Subject: dovecot-2.2: imapc: Added throttling settings to imapc_features=... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1bccf90e54ca changeset: 18331:1bccf90e54ca user: Timo Sirainen date: Wed Mar 11 20:02:20 2015 +0200 description: imapc: Added throttling settings to imapc_features=throttle:a:b:c This change could be reverted once good settings are found. diffstat: src/lib-imap-client/imapc-client.c | 8 ++++++++ src/lib-imap-client/imapc-client.h | 8 ++++++++ src/lib-imap-client/imapc-connection.c | 15 +++++---------- src/lib-imap-client/imapc-connection.h | 5 +++++ src/lib-storage/index/imapc/imapc-settings.c | 22 ++++++++++++++++++++++ src/lib-storage/index/imapc/imapc-settings.h | 3 +++ src/lib-storage/index/imapc/imapc-storage.c | 4 ++++ 7 files changed, 55 insertions(+), 10 deletions(-) diffs (169 lines): diff -r bac6a6a444d3 -r 1bccf90e54ca src/lib-imap-client/imapc-client.c --- a/src/lib-imap-client/imapc-client.c Wed Mar 11 19:44:48 2015 +0200 +++ b/src/lib-imap-client/imapc-client.c Wed Mar 11 20:02:20 2015 +0200 @@ -67,6 +67,14 @@ IMAPC_DEFAULT_CONNECT_TIMEOUT_MSECS; client->set.cmd_timeout_msecs = set->cmd_timeout_msecs != 0 ? set->cmd_timeout_msecs : IMAPC_DEFAULT_COMMAND_TIMEOUT_MSECS; + client->set.throttle_set = set->throttle_set; + + if (client->set.throttle_set.init_msecs == 0) + client->set.throttle_set.init_msecs = IMAPC_THROTTLE_DEFAULT_INIT_MSECS; + if (client->set.throttle_set.max_msecs == 0) + client->set.throttle_set.max_msecs = IMAPC_THROTTLE_DEFAULT_MAX_MSECS; + if (client->set.throttle_set.shrink_min_msecs == 0) + client->set.throttle_set.shrink_min_msecs = IMAPC_THROTTLE_DEFAULT_SHRINK_MIN_MSECS; if (set->ssl_mode != IMAPC_CLIENT_SSL_MODE_NONE) { client->set.ssl_mode = set->ssl_mode; diff -r bac6a6a444d3 -r 1bccf90e54ca src/lib-imap-client/imapc-client.h --- a/src/lib-imap-client/imapc-client.h Wed Mar 11 19:44:48 2015 +0200 +++ b/src/lib-imap-client/imapc-client.h Wed Mar 11 20:02:20 2015 +0200 @@ -54,6 +54,12 @@ #define IMAPC_DEFAULT_CONNECT_TIMEOUT_MSECS (1000*30) #define IMAPC_DEFAULT_COMMAND_TIMEOUT_MSECS (1000*60*5) +struct imapc_throttling_settings { + unsigned int init_msecs; + unsigned int max_msecs; + unsigned int shrink_min_msecs; +}; + struct imapc_client_settings { const char *host; unsigned int port; @@ -82,6 +88,8 @@ /* Timeout for IMAP commands. Reset every time more data is being sent or received. 0 = default. */ unsigned int cmd_timeout_msecs; + + struct imapc_throttling_settings throttle_set; }; struct imapc_command_reply { diff -r bac6a6a444d3 -r 1bccf90e54ca src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Wed Mar 11 19:44:48 2015 +0200 +++ b/src/lib-imap-client/imapc-connection.c Wed Mar 11 20:02:20 2015 +0200 @@ -25,11 +25,6 @@ #define IMAPC_COMMAND_STATE_AUTHENTICATE_CONTINUE 10000 #define IMAPC_MAX_INLINE_LITERAL_SIZE (1024*32) -/* [THROTTLED] handling behavior */ -#define IMAPC_THROTTLE_INIT_MSECS 50 -#define IMAPC_THROTTLE_MAX_MSECS (16*1000) -#define IMAPC_THROTTLE_SHRINK_MIN_MSECS 500 - enum imapc_input_state { IMAPC_INPUT_STATE_NONE = 0, IMAPC_INPUT_STATE_PLUS, @@ -1135,7 +1130,7 @@ else conn->throttle_msecs = conn->throttle_msecs*3 / 4; - if (conn->throttle_shrink_msecs <= IMAPC_THROTTLE_SHRINK_MIN_MSECS) + if (conn->throttle_shrink_msecs <= conn->client->set.throttle_set.shrink_min_msecs) conn->throttle_shrink_msecs = 0; else conn->throttle_shrink_msecs = conn->throttle_shrink_msecs*3 / 4; @@ -1161,16 +1156,16 @@ it as resp-text-code also in here if it's uppercased). */ if (strstr(reply->text_full, "[THROTTLED]") != NULL) { if (conn->throttle_msecs == 0) - conn->throttle_msecs = IMAPC_THROTTLE_INIT_MSECS; + conn->throttle_msecs = conn->client->set.throttle_set.init_msecs; else if (conn->throttle_msecs < conn->last_successful_throttle_msecs) conn->throttle_msecs = conn->last_successful_throttle_msecs; else { conn->throttle_msecs *= 2; - if (conn->throttle_msecs > IMAPC_THROTTLE_MAX_MSECS) - conn->throttle_msecs = IMAPC_THROTTLE_MAX_MSECS; + if (conn->throttle_msecs > conn->client->set.throttle_set.max_msecs) + conn->throttle_msecs = conn->client->set.throttle_set.max_msecs; } if (conn->throttle_shrink_msecs == 0) - conn->throttle_shrink_msecs = IMAPC_THROTTLE_SHRINK_MIN_MSECS; + conn->throttle_shrink_msecs = conn->client->set.throttle_set.shrink_min_msecs; else conn->throttle_shrink_msecs *= 2; if (conn->to_throttle_shrink != NULL) diff -r bac6a6a444d3 -r 1bccf90e54ca src/lib-imap-client/imapc-connection.h --- a/src/lib-imap-client/imapc-connection.h Wed Mar 11 19:44:48 2015 +0200 +++ b/src/lib-imap-client/imapc-connection.h Wed Mar 11 20:02:20 2015 +0200 @@ -3,6 +3,11 @@ #include "imapc-client.h" +/* [THROTTLED] handling behavior */ +#define IMAPC_THROTTLE_DEFAULT_INIT_MSECS 50 +#define IMAPC_THROTTLE_DEFAULT_MAX_MSECS (16*1000) +#define IMAPC_THROTTLE_DEFAULT_SHRINK_MIN_MSECS 500 + struct imapc_client; struct imapc_connection; diff -r bac6a6a444d3 -r 1bccf90e54ca src/lib-storage/index/imapc/imapc-settings.c --- a/src/lib-storage/index/imapc/imapc-settings.c Wed Mar 11 19:44:48 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-settings.c Wed Mar 11 20:02:20 2015 +0200 @@ -90,6 +90,23 @@ }; static int +imapc_settings_parse_throttle(struct imapc_settings *set, + const char *throttle_str, const char **error_r) +{ + const char *const *tmp; + + tmp = t_strsplit(throttle_str, ":"); + if (str_array_length(tmp) != 3 || + str_to_uint(tmp[0], &set->throttle_init_msecs) < 0 || + str_to_uint(tmp[1], &set->throttle_max_msecs) < 0 || + str_to_uint(tmp[2], &set->throttle_shrink_min_msecs) < 0) { + *error_r = "imapc_features: Invalid throttle settings"; + return -1; + } + return 0; +} + +static int imapc_settings_parse_features(struct imapc_settings *set, const char **error_r) { @@ -106,6 +123,11 @@ break; } } + if (strncasecmp(*str, "throttle:", 9) == 0) { + if (imapc_settings_parse_throttle(set, *str + 9, error_r) < 0) + return -1; + continue; + } if (list->name == NULL) { *error_r = t_strdup_printf("imapc_features: " "Unknown feature: %s", *str); diff -r bac6a6a444d3 -r 1bccf90e54ca src/lib-storage/index/imapc/imapc-settings.h --- a/src/lib-storage/index/imapc/imapc-settings.h Wed Mar 11 19:44:48 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-settings.h Wed Mar 11 20:02:20 2015 +0200 @@ -31,6 +31,9 @@ const char *pop3_deleted_flag; enum imapc_features parsed_features; + unsigned int throttle_init_msecs; + unsigned int throttle_max_msecs; + unsigned int throttle_shrink_min_msecs; }; const struct setting_parser_info *imapc_get_setting_parser_info(void); diff -r bac6a6a444d3 -r 1bccf90e54ca src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Wed Mar 11 19:44:48 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-storage.c Wed Mar 11 20:02:20 2015 +0200 @@ -246,6 +246,10 @@ set.ssl_mode = IMAPC_CLIENT_SSL_MODE_NONE; set.ssl_crypto_device = mail_set->ssl_crypto_device; + set.throttle_set.init_msecs = imapc_set->throttle_init_msecs; + set.throttle_set.max_msecs = imapc_set->throttle_max_msecs; + set.throttle_set.shrink_min_msecs = imapc_set->throttle_shrink_min_msecs; + client = i_new(struct imapc_storage_client, 1); client->refcount = 1; i_array_init(&client->untagged_callbacks, 16); From dovecot at dovecot.org Wed Mar 11 18:39:38 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 11 Mar 2015 18:39:38 +0000 Subject: dovecot-2.2: lib-master: Crashfix to earlier anvil query timeout... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/83662ff4d93d changeset: 18332:83662ff4d93d user: Timo Sirainen date: Wed Mar 11 20:38:52 2015 +0200 description: lib-master: Crashfix to earlier anvil query timeout change. diffstat: src/lib-master/anvil-client.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diffs (25 lines): diff -r 1bccf90e54ca -r 83662ff4d93d src/lib-master/anvil-client.c --- a/src/lib-master/anvil-client.c Wed Mar 11 20:02:20 2015 +0200 +++ b/src/lib-master/anvil-client.c Wed Mar 11 20:38:52 2015 +0200 @@ -209,10 +209,6 @@ return -1; } - if (client->to_query == NULL) { - client->to_query = timeout_add(ANVIL_QUERY_TIMEOUT_MSECS, - anvil_client_timeout, client); - } iov[0].iov_base = cmd; iov[0].iov_len = strlen(cmd); iov[1].iov_base = "\n"; @@ -241,6 +237,10 @@ anvil_query->callback = callback; anvil_query->context = context; aqueue_append(client->queries, &anvil_query); + if (client->to_query == NULL) { + client->to_query = timeout_add(ANVIL_QUERY_TIMEOUT_MSECS, + anvil_client_timeout, client); + } return anvil_query; } From dovecot at dovecot.org Wed Mar 11 21:06:20 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 11 Mar 2015 21:06:20 +0000 Subject: dovecot-2.2: imapc: Prefetching wasn't done for headers if there... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/910727378a16 changeset: 18333:910727378a16 user: Timo Sirainen date: Wed Mar 11 23:05:34 2015 +0200 description: imapc: Prefetching wasn't done for headers if there weren't also other fields. diffstat: src/lib-storage/index/imapc/imapc-mail-fetch.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 83662ff4d93d -r 910727378a16 src/lib-storage/index/imapc/imapc-mail-fetch.c --- a/src/lib-storage/index/imapc/imapc-mail-fetch.c Wed Mar 11 20:38:52 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-mail-fetch.c Wed Mar 11 23:05:34 2015 +0200 @@ -315,7 +315,7 @@ imapc_mail_update_access_parts(&mail->imail); fields = imapc_mail_get_wanted_fetch_fields(mail); - if (fields != 0) T_BEGIN { + if (fields != 0 || data->wanted_headers != NULL) T_BEGIN { if (imapc_mail_send_fetch(_mail, fields, data->wanted_headers == NULL ? NULL : data->wanted_headers->name) > 0) From pigeonhole at rename-it.nl Wed Mar 11 22:59:59 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Wed, 11 Mar 2015 23:59:59 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: script: Added more debug outp... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/986ea6e9c270 changeset: 2002:986ea6e9c270 user: Stephan Bosch date: Wed Mar 11 23:59:51 2015 +0100 description: lib-sieve: script: Added more debug output about metadata up-to-date status. diffstat: src/lib-sieve/sieve-script.c | 18 ++++++++++++++---- 1 files changed, 14 insertions(+), 4 deletions(-) diffs (44 lines): diff -r 961c66e7f414 -r 986ea6e9c270 src/lib-sieve/sieve-script.c --- a/src/lib-sieve/sieve-script.c Tue Mar 10 03:19:39 2015 +0100 +++ b/src/lib-sieve/sieve-script.c Wed Mar 11 23:59:51 2015 +0100 @@ -338,6 +338,7 @@ { struct sieve_binary *sbin = sieve_binary_block_get_binary(sblock); string_t *storage_class, *location; + const char *script_location; unsigned int version; if ( sieve_binary_block_get_size(sblock) - *offset == 0 ) @@ -351,8 +352,13 @@ sieve_binary_path(sbin), sieve_script_location(script)); return -1; } - if ( strcmp(str_c(storage_class), script->driver_name) != 0 ) + if ( strcmp(str_c(storage_class), script->driver_name) != 0 ) { + sieve_script_sys_debug(script, + "Binary reports unexpected driver name " + "(`%s' rather than `%s')", + str_c(storage_class), script->driver_name); return 0; + } /* version */ if ( !sieve_binary_read_unsigned(sblock, offset, &version) ) { @@ -379,10 +385,14 @@ sieve_binary_path(sbin), sieve_script_location(script)); return -1; } - if ( script->location == NULL ) + script_location = ( script->location == NULL ? "" : script->location); + if ( strcmp(str_c(location), script_location) != 0 ) { + sieve_script_sys_debug(script, + "Binary reports different script location " + "(`%s' rather than `%s')", + str_c(location), script_location); return 0; - if ( strcmp(str_c(location), script->location) != 0 ) - return 0; + } if ( script->v.binary_read_metadata == NULL ) return 1; From dovecot at dovecot.org Thu Mar 12 10:33:55 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Mar 2015 10:33:55 +0000 Subject: dovecot-2.2: doveadm: Added several missing error logging calls. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/072170010eac changeset: 18334:072170010eac user: Timo Sirainen date: Thu Mar 12 12:32:30 2015 +0200 description: doveadm: Added several missing error logging calls. diffstat: src/doveadm/doveadm-mail-deduplicate.c | 9 +++++++++ src/doveadm/doveadm-mail-expunge.c | 9 +++++++++ src/doveadm/doveadm-mail-index.c | 22 +++++++++++++++++----- src/doveadm/doveadm-mail-iter.c | 8 +++++++- src/doveadm/doveadm-mail-mailbox-metadata.c | 8 +++++++- src/doveadm/doveadm-mail-mailbox-status.c | 2 ++ 6 files changed, 51 insertions(+), 7 deletions(-) diffs (152 lines): diff -r 910727378a16 -r 072170010eac src/doveadm/doveadm-mail-deduplicate.c --- a/src/doveadm/doveadm-mail-deduplicate.c Wed Mar 11 23:05:34 2015 +0200 +++ b/src/doveadm/doveadm-mail-deduplicate.c Thu Mar 12 12:32:30 2015 +0200 @@ -49,10 +49,16 @@ while (mailbox_search_next(search_ctx, &mail)) mail_expunge(mail); if (mailbox_search_deinit(&search_ctx) < 0) { + i_error("Searching mailbox '%s' failed: %s", + mailbox_get_vname(box), + mailbox_get_last_error(box, NULL)); doveadm_mail_failed_mailbox(_ctx, box); ret = -1; } if (mailbox_transaction_commit(&trans) < 0) { + i_error("Committing mailbox '%s' transaction failed: %s", + mailbox_get_vname(box), + mailbox_get_last_error(box, NULL)); doveadm_mail_failed_mailbox(_ctx, box); ret = -1; } @@ -140,6 +146,9 @@ pool_unref(&pool); if (mailbox_sync(box, 0) < 0) { + i_error("Syncing mailbox '%s' failed: %s", + mailbox_get_vname(box), + mailbox_get_last_error(box, NULL)); doveadm_mail_failed_mailbox(_ctx, box); ret = -1; } diff -r 910727378a16 -r 072170010eac src/doveadm/doveadm-mail-expunge.c --- a/src/doveadm/doveadm-mail-expunge.c Wed Mar 11 23:05:34 2015 +0200 +++ b/src/doveadm/doveadm-mail-expunge.c Thu Mar 12 12:32:30 2015 +0200 @@ -41,6 +41,9 @@ if (doveadm_mail_iter_deinit_keep_box(&iter, &box) < 0) ret = -1; else if (mailbox_sync(box, 0) < 0) { + i_error("Syncing mailbox '%s' failed: %s", + mailbox_get_vname(box), + mailbox_get_last_error(box, NULL)); doveadm_mail_failed_mailbox(_ctx, box); ret = -1; } @@ -49,11 +52,17 @@ if (mailbox_delete_empty(box) < 0) { error = mailbox_get_last_mail_error(box); if (error != MAIL_ERROR_EXISTS) { + i_error("Deleting mailbox '%s' failed: %s", + mailbox_get_vname(box), + mailbox_get_last_error(box, NULL)); doveadm_mail_failed_mailbox(_ctx, box); ret = -1; } } else { if (mailbox_set_subscribed(box, FALSE) < 0) { + i_error("Unsubscribing mailbox '%s' failed: %s", + mailbox_get_vname(box), + mailbox_get_last_error(box, NULL)); doveadm_mail_failed_mailbox(_ctx, box); ret = -1; } diff -r 910727378a16 -r 072170010eac src/doveadm/doveadm-mail-index.c --- a/src/doveadm/doveadm-mail-index.c Wed Mar 11 23:05:34 2015 +0200 +++ b/src/doveadm/doveadm-mail-index.c Thu Mar 12 12:32:30 2015 +0200 @@ -39,10 +39,16 @@ int ret = 0; if (mailbox_get_metadata(box, MAILBOX_METADATA_PRECACHE_FIELDS, - &metadata) < 0 || - mailbox_get_status(box, STATUS_MESSAGES | STATUS_LAST_CACHED_SEQ, - &status) < 0) + &metadata) < 0) { + i_error("Mailbox %s: Precache-fields lookup failed: %s", + mailbox_get_vname(box), mailbox_get_last_error(box, NULL)); + } + if (mailbox_get_status(box, STATUS_MESSAGES | STATUS_LAST_CACHED_SEQ, + &status) < 0) { + i_error("Mailbox %s: Status lookup failed: %s", + mailbox_get_vname(box), mailbox_get_last_error(box, NULL)); return -1; + } seq = status.last_cached_seq + 1; if (seq > status.messages) { @@ -74,10 +80,16 @@ } if (doveadm_verbose) printf("\r%u/%u\n", counter, max); - if (mailbox_search_deinit(&ctx) < 0) + if (mailbox_search_deinit(&ctx) < 0) { + i_error("Mailbox %s: Mail search failed: %s", + mailbox_get_vname(box), mailbox_get_last_error(box, NULL)); ret = -1; - if (mailbox_transaction_commit(&trans) < 0) + } + if (mailbox_transaction_commit(&trans) < 0) { + i_error("Mailbox %s: Transaction commit failed: %s", + mailbox_get_vname(box), mailbox_get_last_error(box, NULL)); ret = -1; + } return ret; } diff -r 910727378a16 -r 072170010eac src/doveadm/doveadm-mail-iter.c --- a/src/doveadm/doveadm-mail-iter.c Wed Mar 11 23:05:34 2015 +0200 +++ b/src/doveadm/doveadm-mail-iter.c Thu Mar 12 12:32:30 2015 +0200 @@ -99,8 +99,14 @@ *_iter = NULL; ret = doveadm_mail_iter_deinit_transaction(iter, commit); - if (ret == 0 && sync) + if (ret == 0 && sync) { ret = mailbox_sync(iter->box, 0); + if (ret < 0) { + i_error("Mailbox %s: Mailbox sync failed: %s", + mailbox_get_vname(iter->box), + mailbox_get_last_error(iter->box, NULL)); + } + } if (ret < 0) doveadm_mail_failed_mailbox(iter->ctx, iter->box); if (!keep_box) diff -r 910727378a16 -r 072170010eac src/doveadm/doveadm-mail-mailbox-metadata.c --- a/src/doveadm/doveadm-mail-mailbox-metadata.c Wed Mar 11 23:05:34 2015 +0200 +++ b/src/doveadm/doveadm-mail-mailbox-metadata.c Thu Mar 12 12:32:30 2015 +0200 @@ -212,7 +212,13 @@ iter = mailbox_attribute_iter_init(box, type, ctx->key); while ((key = mailbox_attribute_iter_next(iter)) != NULL) doveadm_print(key); - return mailbox_attribute_iter_deinit(&iter); + if (mailbox_attribute_iter_deinit(&iter) < 0) { + i_error("Mailbox %s: Failed to iterate mailbox attributes: %s", + mailbox_get_vname(box), + mailbox_get_last_error(box, NULL)); + return -1; + } + return 0; } static int diff -r 910727378a16 -r 072170010eac src/doveadm/doveadm-mail-mailbox-status.c --- a/src/doveadm/doveadm-mail-mailbox-status.c Wed Mar 11 23:05:34 2015 +0200 +++ b/src/doveadm/doveadm-mail-mailbox-status.c Thu Mar 12 12:32:30 2015 +0200 @@ -129,6 +129,8 @@ box = doveadm_mailbox_find(ctx->ctx.cur_mail_user, info->vname); if (mailbox_get_status(box, ctx->status_items, &status) < 0 || mailbox_get_metadata(box, ctx->metadata_items, &metadata) < 0) { + i_error("Mailbox %s: Failed to lookup mailbox status: %s", + mailbox_get_vname(box), mailbox_get_last_error(box, NULL)); doveadm_mail_failed_mailbox(&ctx->ctx, box); mailbox_free(&box); return -1; From dovecot at dovecot.org Thu Mar 12 10:33:55 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Mar 2015 10:33:55 +0000 Subject: dovecot-2.2: fts: Added missing error logging/setting. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/65e55166c794 changeset: 18335:65e55166c794 user: Timo Sirainen date: Thu Mar 12 12:32:54 2015 +0200 description: fts: Added missing error logging/setting. diffstat: src/plugins/fts/fts-build-mail.c | 10 ++++++++-- src/plugins/fts/fts-storage.c | 8 ++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diffs (43 lines): diff -r 072170010eac -r 65e55166c794 src/plugins/fts/fts-build-mail.c --- a/src/plugins/fts/fts-build-mail.c Thu Mar 12 12:32:30 2015 +0200 +++ b/src/plugins/fts/fts-build-mail.c Thu Mar 12 12:32:54 2015 +0200 @@ -278,8 +278,14 @@ bool binary_body; int ret; - if (mail_get_stream(mail, NULL, NULL, &input) < 0) - return mail->expunged ? 0 : -1; + if (mail_get_stream(mail, NULL, NULL, &input) < 0) { + if (mail->expunged) + return 0; + i_error("Failed to read mailbox %s mail UID=%u stream: %s", + mailbox_get_vname(mail->box), mail->uid, + mailbox_get_last_error(mail->box, NULL)); + return -1; + } memset(&ctx, 0, sizeof(ctx)); ctx.update_ctx = update_ctx; diff -r 072170010eac -r 65e55166c794 src/plugins/fts/fts-storage.c --- a/src/plugins/fts/fts-storage.c Thu Mar 12 12:32:30 2015 +0200 +++ b/src/plugins/fts/fts-storage.c Thu Mar 12 12:32:54 2015 +0200 @@ -598,13 +598,17 @@ struct fts_mailbox *fbox = FTS_CONTEXT(t->box); struct mailbox *box = t->box; bool autoindex; - int ret; + int ret = 0; autoindex = ft->mails_saved && mail_user_plugin_getenv(box->storage->user, "fts_autoindex") != NULL; - ret = fts_transaction_end(t); + if (fts_transaction_end(t) < 0) { + mail_storage_set_error(t->box->storage, MAIL_ERROR_TEMP, + "FTS transaction commit failed"); + ret = -1; + } if (fbox->module_ctx.super.transaction_commit(t, changes_r) < 0) ret = -1; if (ret < 0) From dovecot at dovecot.org Thu Mar 12 13:34:07 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Mar 2015 13:34:07 +0000 Subject: dovecot-2.2: doveadm: Fixed table formatter for UTF-8 output. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8780ca0fbf22 changeset: 18336:8780ca0fbf22 user: Timo Sirainen date: Thu Mar 12 15:33:13 2015 +0200 description: doveadm: Fixed table formatter for UTF-8 output. Based on patch by Hardy Flor diffstat: src/doveadm/doveadm-print-table.c | 20 +++++++++++++++++--- 1 files changed, 17 insertions(+), 3 deletions(-) diffs (52 lines): diff -r 65e55166c794 -r 8780ca0fbf22 src/doveadm/doveadm-print-table.c --- a/src/doveadm/doveadm-print-table.c Thu Mar 12 12:32:54 2015 +0200 +++ b/src/doveadm/doveadm-print-table.c Thu Mar 12 15:33:13 2015 +0200 @@ -3,6 +3,7 @@ #include "lib.h" #include "array.h" #include "str.h" +#include "unichar.h" #include "doveadm-print-private.h" #include @@ -64,7 +65,7 @@ for (line = 0; line < line_count; line++) { for (i = 0; i < hdr_count; i++) { value = values[line*hdr_count + i]; - len = value == NULL ? 0 : strlen(value); + len = value == NULL ? 0 : uni_utf8_strlen(value); if (headers[i].min_length > len) headers[i].min_length = len; if (headers[i].max_length < len) { @@ -116,16 +117,29 @@ } } +static size_t utf8_correction(const char *str) +{ + size_t i, len = 0; + + for (i = 0; str[i] != '\0'; i++) { + if ((str[i] & 0xc0) == 0x80) + len++; + } + return len; +} + static void doveadm_print_next(const char *value) { const struct doveadm_print_table_header *hdr; + int value_padded_len; hdr = array_idx(&ctx->headers, ctx->hdr_idx); + value_padded_len = hdr->length + utf8_correction(value); if ((hdr->flags & DOVEADM_PRINT_HEADER_FLAG_RIGHT_JUSTIFY) == 0) - printf("%-*s", (int)hdr->length, value); + printf("%-*s", value_padded_len, value); else - printf("%*s", (int)hdr->length, value); + printf("%*s", value_padded_len, value); if (++ctx->hdr_idx == array_count(&ctx->headers)) { ctx->hdr_idx = 0; From dovecot at dovecot.org Thu Mar 12 13:43:22 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Mar 2015 13:43:22 +0000 Subject: dovecot-2.2: dict: cdb support should be available only to dict ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/16ff063e3588 changeset: 18337:16ff063e3588 user: Timo Sirainen date: Thu Mar 12 15:42:31 2015 +0200 description: dict: cdb support should be available only to dict process. Because otherwise we need to link libcdb into pretty much all Dovecot binaries, which is part of what having the dict proxy tries to avoid. We could implement the direct linking optionally as well, but that would need to be done in a bit more generic way rather than just hardcoding it only to cdb support. diffstat: configure.ac | 1 + src/lib-dict/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 1 deletions(-) diffs (30 lines): diff -r 8780ca0fbf22 -r 16ff063e3588 configure.ac --- a/configure.ac Thu Mar 12 15:33:13 2015 +0200 +++ b/configure.ac Thu Mar 12 15:42:31 2015 +0200 @@ -2129,6 +2129,7 @@ AC_CHECK_LIB(cdb, cdb_init, [ AC_CHECK_HEADER(cdb.h, [ DICT_LIBS="$DICT_LIBS -lcdb" + dict_drivers="$dict_drivers cdb" AC_DEFINE(BUILD_CDB,, Build with CDB support) ], [ if test $want_cdb = yes; then diff -r 8780ca0fbf22 -r 16ff063e3588 src/lib-dict/Makefile.am --- a/src/lib-dict/Makefile.am Thu Mar 12 15:33:13 2015 +0200 +++ b/src/lib-dict/Makefile.am Thu Mar 12 15:42:31 2015 +0200 @@ -15,7 +15,6 @@ dict.c \ dict-client.c \ dict-file.c \ - dict-cdb.c \ dict-fs.c \ dict-memcached.c \ dict-memcached-ascii.c \ @@ -28,6 +27,7 @@ libdict_backend_a_SOURCES = \ dict-db.c \ + dict-cdb.c \ dict-sql.c \ dict-sql-settings.c From dovecot at dovecot.org Thu Mar 12 13:50:53 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Mar 2015 13:50:53 +0000 Subject: dovecot-2.2: rawlog: Changed -i to -I parameter Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cd5fc6ff8027 changeset: 18338:cd5fc6ff8027 user: Timo Sirainen date: Thu Mar 12 15:50:07 2015 +0200 description: rawlog: Changed -i to -I parameter We can't use -i, because it's handled by lib-master for instance selection. diffstat: src/util/rawlog.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 16ff063e3588 -r cd5fc6ff8027 src/util/rawlog.c --- a/src/util/rawlog.c Thu Mar 12 15:42:31 2015 +0200 +++ b/src/util/rawlog.c Thu Mar 12 15:50:07 2015 +0200 @@ -362,7 +362,7 @@ int c; master_service = master_service_init("rawlog", 0, - &argc, &argv, "+f:obit"); + &argc, &argv, "+f:obIt"); while ((c = master_getopt(master_service)) > 0) { switch (c) { case 'f': @@ -376,7 +376,7 @@ case 'b': flags |= RAWLOG_FLAG_LOG_BOUNDARIES; break; - case 'i': + case 'I': flags |= RAWLOG_FLAG_LOG_IP_IN_FILENAME; break; case 't': From dovecot at dovecot.org Thu Mar 12 13:51:45 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Mar 2015 13:51:45 +0000 Subject: dovecot-2.2: rawlog: Updated -i -> -I also in usage string. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/aed1e8340ea7 changeset: 18339:aed1e8340ea7 user: Timo Sirainen date: Thu Mar 12 15:50:59 2015 +0200 description: rawlog: Updated -i -> -I also in usage string. diffstat: src/util/rawlog.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r cd5fc6ff8027 -r aed1e8340ea7 src/util/rawlog.c --- a/src/util/rawlog.c Thu Mar 12 15:50:07 2015 +0200 +++ b/src/util/rawlog.c Thu Mar 12 15:50:59 2015 +0200 @@ -390,7 +390,7 @@ argv += optind; if (argc < 1) - i_fatal("Usage: rawlog [-f in|out] [-i] [-b] [-t] "); + i_fatal("Usage: rawlog [-f in|out] [-I] [-b] [-t] "); master_service_init_log(master_service, "rawlog: "); master_service_init_finish(master_service); From dovecot at dovecot.org Thu Mar 12 17:32:41 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Mar 2015 17:32:41 +0000 Subject: dovecot-2.2: Released v2.2.16. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0f8f0d8ee607 changeset: 18340:0f8f0d8ee607 user: Timo Sirainen date: Thu Mar 12 17:41:05 2015 +0200 description: Released v2.2.16. diffstat: NEWS | 2 +- configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r aed1e8340ea7 -r 0f8f0d8ee607 NEWS --- a/NEWS Thu Mar 12 15:50:59 2015 +0200 +++ b/NEWS Thu Mar 12 17:41:05 2015 +0200 @@ -1,4 +1,4 @@ -v2.2.16 2015-03-xx Timo Sirainen +v2.2.16 2015-03-12 Timo Sirainen * dbox: Resyncing (e.g. doveadm force-resync) no longer deletes dovecot.index.cache file. The cache file was rarely the problem diff -r aed1e8340ea7 -r 0f8f0d8ee607 configure.ac --- a/configure.ac Thu Mar 12 15:50:59 2015 +0200 +++ b/configure.ac Thu Mar 12 17:41:05 2015 +0200 @@ -2,7 +2,7 @@ # Be sure to update ABI version also if anything changes that might require # recompiling plugins. Most importantly that means if any structs are changed. -AC_INIT([Dovecot],[2.2.16.rc1],[dovecot at dovecot.org]) +AC_INIT([Dovecot],[2.2.16],[dovecot at dovecot.org]) AC_DEFINE_UNQUOTED([DOVECOT_ABI_VERSION], "2.2.ABIv16($PACKAGE_VERSION)", [Dovecot ABI version]) AC_CONFIG_SRCDIR([src]) From dovecot at dovecot.org Thu Mar 12 17:32:46 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Mar 2015 17:32:46 +0000 Subject: dovecot-2.2: Added tag 2.2.16 for changeset 0f8f0d8ee607 Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3589aab3ac25 changeset: 18341:3589aab3ac25 user: Timo Sirainen date: Thu Mar 12 17:41:05 2015 +0200 description: Added tag 2.2.16 for changeset 0f8f0d8ee607 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 0f8f0d8ee607 -r 3589aab3ac25 .hgtags --- a/.hgtags Thu Mar 12 17:41:05 2015 +0200 +++ b/.hgtags Thu Mar 12 17:41:05 2015 +0200 @@ -122,3 +122,4 @@ 6dad1f6e8930940f3c763cf3f27aaa7a9c979520 2.2.14 e8b793f2c4091f76075e66d5166b38cf82e598bd 2.2.15 a3c27cec411261b3ff2947795b3b8ff96a5320a1 2.2.16.rc1 +0f8f0d8ee60745f6ce7ff379da7f2660aec7c4d4 2.2.16 From dovecot at dovecot.org Thu Mar 12 17:32:46 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Mar 2015 17:32:46 +0000 Subject: dovecot-2.2: Added signature for changeset 0f8f0d8ee607 Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/34862aea421d changeset: 18342:34862aea421d user: Timo Sirainen date: Thu Mar 12 17:41:09 2015 +0200 description: Added signature for changeset 0f8f0d8ee607 diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 3589aab3ac25 -r 34862aea421d .hgsigs --- a/.hgsigs Thu Mar 12 17:41:05 2015 +0200 +++ b/.hgsigs Thu Mar 12 17:41:09 2015 +0200 @@ -85,3 +85,4 @@ 6dad1f6e8930940f3c763cf3f27aaa7a9c979520 0 iEYEABECAAYFAlQ9VDQACgkQyUhSUUBVisk1fgCfdmFGZA/0DGz9vQFDeBTFK/JLhAEAnA966b+cMBaRegwj/v0Zta7c62lS e8b793f2c4091f76075e66d5166b38cf82e598bd 0 iEYEABECAAYFAlRLH5gACgkQyUhSUUBVisn+6gCfcGV1kM2OS9udaFxY7MVtqaaGwYAAnRxUc/RGeUhvJGdg9LvSSzBFPCfz a3c27cec411261b3ff2947795b3b8ff96a5320a1 0 iEYEABECAAYFAlT5zBYACgkQyUhSUUBVisnQ4gCdFb/4T+WZYCAxRKjfup+xIiP26bkAn2CbIlsJBU1f3WnAJX9KsAmhphlY +0f8f0d8ee60745f6ce7ff379da7f2660aec7c4d4 0 iEYEABECAAYFAlUBs5IACgkQyUhSUUBVisn/yACcCUC3xDOCPFAgTKd72uyDrEUv7wcAn1tNcf+AyIUmM9ksDeB2fuZZZJFT From dovecot at dovecot.org Thu Mar 12 17:39:52 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Mar 2015 17:39:52 +0000 Subject: dovecot-2.2: lib-mail: Added HEADER_FILTER_CRLF_PRESERVE flag to... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/308a97126244 changeset: 18343:308a97126244 user: Timo Sirainen date: Thu Mar 12 19:39:03 2015 +0200 description: lib-mail: Added HEADER_FILTER_CRLF_PRESERVE flag to istream-header-filter. diffstat: src/lib-mail/istream-header-filter.c | 18 ++++++++++++------ src/lib-mail/istream-header-filter.h | 4 +++- 2 files changed, 15 insertions(+), 7 deletions(-) diffs (78 lines): diff -r 34862aea421d -r 308a97126244 src/lib-mail/istream-header-filter.c --- a/src/lib-mail/istream-header-filter.c Thu Mar 12 17:41:09 2015 +0200 +++ b/src/lib-mail/istream-header-filter.c Thu Mar 12 19:39:03 2015 +0200 @@ -33,6 +33,7 @@ unsigned int header_parsed:1; unsigned int exclude:1; unsigned int crlf:1; + unsigned int crlf_preserve:1; unsigned int hide_body:1; unsigned int add_missing_eoh:1; unsigned int end_body_with_lf:1; @@ -125,9 +126,9 @@ cmp_uint) != NULL; } -static void add_eol(struct header_filter_istream *mstream) +static void add_eol(struct header_filter_istream *mstream, bool orig_crlf) { - if (mstream->crlf) + if (mstream->crlf || (orig_crlf && mstream->crlf_preserve)) buffer_append(mstream->hdr_buf, "\r\n", 2); else buffer_append_c(mstream->hdr_buf, '\n'); @@ -197,7 +198,7 @@ continue; } - add_eol(mstream); + add_eol(mstream, hdr->crlf_newline); continue; } @@ -239,7 +240,7 @@ buffer_append(mstream->hdr_buf, hdr->value, hdr->value_len); if (!hdr->no_newline) - add_eol(mstream); + add_eol(mstream, hdr->crlf_newline); if (mstream->skip_count >= mstream->hdr_buf->used) { /* we need more */ @@ -266,7 +267,7 @@ } if (!mstream->seen_eoh && mstream->add_missing_eoh) { mstream->seen_eoh = TRUE; - add_eol(mstream); + add_eol(mstream, FALSE); } } @@ -554,7 +555,12 @@ mstream->callback = callback; mstream->context = context; mstream->exclude = (flags & HEADER_FILTER_EXCLUDE) != 0; - mstream->crlf = (flags & HEADER_FILTER_NO_CR) == 0; + if ((flags & HEADER_FILTER_CRLF_PRESERVE) != 0) + mstream->crlf_preserve = TRUE; + else if ((flags & HEADER_FILTER_NO_CR) != 0) + mstream->crlf = FALSE; + else + mstream->crlf = TRUE; mstream->hide_body = (flags & HEADER_FILTER_HIDE_BODY) != 0; mstream->add_missing_eoh = (flags & HEADER_FILTER_ADD_MISSING_EOH) != 0; mstream->end_body_with_lf = diff -r 34862aea421d -r 308a97126244 src/lib-mail/istream-header-filter.h --- a/src/lib-mail/istream-header-filter.h Thu Mar 12 17:41:09 2015 +0200 +++ b/src/lib-mail/istream-header-filter.h Thu Mar 12 19:39:03 2015 +0200 @@ -16,7 +16,9 @@ /* If the empty "end of headers" line doesn't exist, add it. */ HEADER_FILTER_ADD_MISSING_EOH = 0x10, /* If body doesn't end with [CR]LF, add it/them. */ - HEADER_FILTER_END_BODY_WITH_LF = 0x20 + HEADER_FILTER_END_BODY_WITH_LF = 0x20, + /* Preserve the original LF or CRLF. */ + HEADER_FILTER_CRLF_PRESERVE = 0x40 }; struct message_header_line; From dovecot at dovecot.org Fri Mar 13 13:07:08 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 13 Mar 2015 13:07:08 +0000 Subject: dovecot-2.2: Makefile: Avoid make race conditions when generatin... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d592417ec815 changeset: 18344:d592417ec815 user: Timo Sirainen date: Fri Mar 13 15:06:10 2015 +0200 description: Makefile: Avoid make race conditions when generating files that are used as dependencies. The file creation needs to be atomic, otherwise another process can start trying to use an unfinished file. So we first create .tmp file and then mv it into the final one. diffstat: src/config/Makefile.am | 2 +- src/lib-dict/Makefile.am | 33 ++++++++++++++++--------------- src/lib-sql/Makefile.am | 17 ++++++++------- src/lib-storage/register/Makefile.am | 38 ++++++++++++++++++----------------- src/lib/Makefile.am | 2 +- src/plugins/quota/Makefile.am | 5 ++- 6 files changed, 51 insertions(+), 46 deletions(-) diffs (193 lines): diff -r 308a97126244 -r d592417ec815 src/config/Makefile.am --- a/src/config/Makefile.am Thu Mar 12 19:39:03 2015 +0200 +++ b/src/config/Makefile.am Fri Mar 13 15:06:10 2015 +0200 @@ -55,7 +55,7 @@ config-request.h all-settings.c: $(SETTING_FILES) $(top_srcdir)/src/config/settings-get.pl - $(top_srcdir)/src/config/settings-get.pl $(SETTING_FILES) > all-settings.c || rm -f all-settings.c + $(top_srcdir)/src/config/settings-get.pl $(SETTING_FILES) > all-settings.c.tmp && mv all-settings.c.tmp all-settings.c EXTRA_DIST = \ config-settings.c \ diff -r 308a97126244 -r d592417ec815 src/lib-dict/Makefile.am --- a/src/lib-dict/Makefile.am Thu Mar 12 19:39:03 2015 +0200 +++ b/src/lib-dict/Makefile.am Fri Mar 13 15:06:10 2015 +0200 @@ -46,34 +46,35 @@ pkginc_lib_HEADERS = $(headers) dict-drivers-register.c: Makefile $(top_builddir)/config.h - rm -f $@ - echo '/* this file automatically generated by Makefile */' >$@ - echo '#include "lib.h"' >>$@ - echo '#include "dict.h"' >>$@ - echo '#include "dict-sql.h"' >>$@ + rm -f $@.tmp + echo '/* this file automatically generated by Makefile */' >$@.tmp + echo '#include "lib.h"' >>$@.tmp + echo '#include "dict.h"' >>$@.tmp + echo '#include "dict-sql.h"' >>$@.tmp for i in $(dict_drivers) null; do \ if [ "$${i}" != "null" ]; then \ - echo "extern struct dict dict_driver_$${i};" >>$@ ; \ + echo "extern struct dict dict_driver_$${i};" >>$@.tmp ; \ fi; \ done - echo 'void dict_drivers_register_all(void) {' >>$@ - echo 'dict_drivers_register_builtin();' >>$@ - echo 'dict_sql_register();' >>$@ + echo 'void dict_drivers_register_all(void) {' >>$@.tmp + echo 'dict_drivers_register_builtin();' >>$@.tmp + echo 'dict_sql_register();' >>$@.tmp for i in $(dict_drivers) null; do \ if [ "$${i}" != "null" ]; then \ - echo "dict_driver_register(&dict_driver_$${i});" >>$@ ; \ + echo "dict_driver_register(&dict_driver_$${i});" >>$@.tmp ; \ fi; \ done - echo '}' >>$@ - echo 'void dict_drivers_unregister_all(void) {' >>$@ - echo 'dict_drivers_unregister_builtin();' >>$@ - echo 'dict_sql_unregister();' >>$@ + echo '}' >>$@.tmp + echo 'void dict_drivers_unregister_all(void) {' >>$@.tmp + echo 'dict_drivers_unregister_builtin();' >>$@.tmp + echo 'dict_sql_unregister();' >>$@.tmp for i in $(dict_drivers) null; do \ if [ "$${i}" != "null" ]; then \ - echo "dict_driver_unregister(&dict_driver_$${i});" >>$@ ; \ + echo "dict_driver_unregister(&dict_driver_$${i});" >>$@.tmp ; \ fi; \ done - echo '}' >>$@ + echo '}' >>$@.tmp + mv $@.tmp $@ distclean-generic: rm -f Makefile dict-drivers-register.c diff -r 308a97126244 -r d592417ec815 src/lib-sql/Makefile.am --- a/src/lib-sql/Makefile.am Thu Mar 12 19:39:03 2015 +0200 +++ b/src/lib-sql/Makefile.am Fri Mar 13 15:06:10 2015 +0200 @@ -92,26 +92,27 @@ pkginc_lib_HEADERS = $(headers) sql-drivers-register.c: Makefile - rm -f $@ - echo '/* this file automatically generated by Makefile */' >$@ - echo '#include "lib.h"' >>$@ - echo '#include "sql-api.h"' >>$@ + rm -f $@.tmp + echo '/* this file automatically generated by Makefile */' >$@.tmp + echo '#include "lib.h"' >>$@.tmp + echo '#include "sql-api.h"' >>$@.tmp if ! SQL_PLUGINS for i in $(sql_drivers) null; do \ if [ "$${i}" != "null" ]; then \ - echo "extern struct sql_db driver_$${i}_db;" >>$@ ; \ + echo "extern struct sql_db driver_$${i}_db;" >>$@.tmp ; \ fi; \ done endif - echo 'void sql_drivers_register_all(void) {' >>$@ + echo 'void sql_drivers_register_all(void) {' >>$@.tmp if ! SQL_PLUGINS for i in $(sql_drivers) null; do \ if [ "$${i}" != "null" ]; then \ - echo "sql_driver_register(&driver_$${i}_db);" >>$@ ; \ + echo "sql_driver_register(&driver_$${i}_db);" >>$@.tmp ; \ fi; \ done endif - echo '}' >>$@ + echo '}' >>$@.tmp + mv $@.tmp $@ if SQL_PLUGINS install-exec-local: diff -r 308a97126244 -r d592417ec815 src/lib-storage/register/Makefile.am --- a/src/lib-storage/register/Makefile.am Thu Mar 12 19:39:03 2015 +0200 +++ b/src/lib-storage/register/Makefile.am Fri Mar 13 15:06:10 2015 +0200 @@ -5,34 +5,36 @@ mailbox_list_drivers = @mailbox_list_drivers@ mail-storage-register.c: Makefile - rm -f $@ - echo '/* this file automatically generated by Makefile */' >$@ - echo '#include "lib.h"' >>$@ - echo '#include "mail-storage.h"' >>$@ + rm -f $@.tmp + echo '/* this file automatically generated by Makefile */' >$@.tmp + echo '#include "lib.h"' >>$@.tmp + echo '#include "mail-storage.h"' >>$@.tmp for i in $(mail_storages) ; do \ - echo "extern struct mail_storage $${i}_storage;" >>$@ ; \ + echo "extern struct mail_storage $${i}_storage;" >>$@.tmp ; \ done - echo 'void mail_storage_register_all(void) {' >>$@ + echo 'void mail_storage_register_all(void) {' >>$@.tmp for i in $(mail_storages) ; do \ - echo "mail_storage_class_register(&$${i}_storage);" >>$@ ; \ + echo "mail_storage_class_register(&$${i}_storage);" >>$@.tmp ; \ done - echo '}' >>$@ + echo '}' >>$@.tmp + mv $@.tmp $@ mailbox-list-register.c: Makefile - rm -f $@ - echo '/* this file automatically generated by Makefile */' >$@ - echo '#include "lib.h"' >>$@ - echo '#include "mailbox-list.h"' >>$@ + rm -f $@.tmp + echo '/* this file automatically generated by Makefile */' >$@.tmp + echo '#include "lib.h"' >>$@.tmp + echo '#include "mailbox-list.h"' >>$@.tmp for i in $(mailbox_list_drivers) ; do \ - echo "extern struct mailbox_list $${i}_mailbox_list;" >>$@ ; \ + echo "extern struct mailbox_list $${i}_mailbox_list;" >>$@.tmp ; \ done - echo "void mailbox_list_index_init(void);" >>$@ - echo 'void mailbox_list_register_all(void) {' >>$@ + echo "void mailbox_list_index_init(void);" >>$@.tmp + echo 'void mailbox_list_register_all(void) {' >>$@.tmp for i in $(mailbox_list_drivers) ; do \ - echo "mailbox_list_register(&$${i}_mailbox_list);" >>$@ ; \ + echo "mailbox_list_register(&$${i}_mailbox_list);" >>$@.tmp ; \ done - echo "mailbox_list_index_init();" >>$@ - echo '}' >>$@ + echo "mailbox_list_index_init();" >>$@.tmp + echo '}' >>$@.tmp + mv $@.tmp $@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ diff -r 308a97126244 -r d592417ec815 src/lib/Makefile.am --- a/src/lib/Makefile.am Thu Mar 12 19:39:03 2015 +0200 +++ b/src/lib/Makefile.am Fri Mar 13 15:06:10 2015 +0200 @@ -8,7 +8,7 @@ test -f UnicodeData.txt || wget http://www.unicode.org/Public/UNIDATA/UnicodeData.txt $(srcdir)/unicodemap.c: unicodemap.pl UnicodeData.txt - perl $(srcdir)/unicodemap.pl < UnicodeData.txt > $@ + perl $(srcdir)/unicodemap.pl < UnicodeData.txt > $@.tmp && mv $@.tmp $@ liblib_la_SOURCES = \ abspath.c \ diff -r 308a97126244 -r d592417ec815 src/plugins/quota/Makefile.am --- a/src/plugins/quota/Makefile.am Thu Mar 12 19:39:03 2015 +0200 +++ b/src/plugins/quota/Makefile.am Fri Mar 13 15:06:10 2015 +0200 @@ -83,10 +83,11 @@ sed -e 's/IXDR_PUT/(void)IXDR_PUT/g' \ -e 's,/usr/include/rpcsvc/rquota.h,rquota.h,' \ -e 's/int32_t \*buf/int32_t *buf ATTR_UNUSED/' \ - -e 's/^static char rcsid.*//' ) > rquota_xdr.c + -e 's/^static char rcsid.*//' ) > rquota_xdr.c.tmp; \ + mv rquota_xdr.c.tmp rquota_xdr.c rquota.h: Makefile $(RQUOTA_X) - $(RPCGEN) -h $(RQUOTA_X) > rquota.h + $(RPCGEN) -h $(RQUOTA_X) > rquota.h.tmp && mv rquota.h.tmp rquota.h quota-fs.lo: rquota.h From dovecot at dovecot.org Fri Mar 13 14:04:57 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 13 Mar 2015 14:04:57 +0000 Subject: dovecot-2.2: fts: If fts-parser fails, stop indexing instead of ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f409deb63c40 changeset: 18345:f409deb63c40 user: Timo Sirainen date: Fri Mar 13 16:04:01 2015 +0200 description: fts: If fts-parser fails, stop indexing instead of ignoring the error and continuing. This is especially important in case there's just some temporary error. diffstat: src/plugins/fts/fts-build-mail.c | 5 +++-- src/plugins/fts/fts-parser-html.c | 3 ++- src/plugins/fts/fts-parser-script.c | 4 +++- src/plugins/fts/fts-parser-tika.c | 10 +++++++++- src/plugins/fts/fts-parser.c | 6 ++++-- src/plugins/fts/fts-parser.h | 4 ++-- 6 files changed, 23 insertions(+), 9 deletions(-) diffs (141 lines): diff -r d592417ec815 -r f409deb63c40 src/plugins/fts/fts-build-mail.c --- a/src/plugins/fts/fts-build-mail.c Fri Mar 13 15:06:10 2015 +0200 +++ b/src/plugins/fts/fts-build-mail.c Fri Mar 13 16:04:01 2015 +0200 @@ -260,7 +260,8 @@ } } while (block.size > 0); - fts_parser_deinit(&ctx->body_parser); + if (fts_parser_deinit(&ctx->body_parser) < 0) + ret = -1; return ret; } @@ -366,7 +367,7 @@ if (ret == 0) ret = fts_body_parser_finish(&ctx); else - fts_parser_deinit(&ctx.body_parser); + (void)fts_parser_deinit(&ctx.body_parser); } if (ret == 0 && body_part && !skip_body && !body_added) { /* make sure body is added even when it doesn't exist */ diff -r d592417ec815 -r f409deb63c40 src/plugins/fts/fts-parser-html.c --- a/src/plugins/fts/fts-parser-html.c Fri Mar 13 15:06:10 2015 +0200 +++ b/src/plugins/fts/fts-parser-html.c Fri Mar 13 16:04:01 2015 +0200 @@ -47,13 +47,14 @@ block->size = parser->output->used; } -static void fts_parser_html_deinit(struct fts_parser *_parser) +static int fts_parser_html_deinit(struct fts_parser *_parser) { struct html_fts_parser *parser = (struct html_fts_parser *)_parser; mail_html2text_deinit(&parser->html2text); buffer_free(&parser->output); i_free(parser); + return 0; } struct fts_parser_vfuncs fts_parser_html = { diff -r d592417ec815 -r f409deb63c40 src/plugins/fts/fts-parser-script.c --- a/src/plugins/fts/fts-parser-script.c Fri Mar 13 15:06:10 2015 +0200 +++ b/src/plugins/fts/fts-parser-script.c Fri Mar 13 16:04:01 2015 +0200 @@ -254,14 +254,16 @@ } } -static void fts_parser_script_deinit(struct fts_parser *_parser) +static int fts_parser_script_deinit(struct fts_parser *_parser) { struct script_fts_parser *parser = (struct script_fts_parser *)_parser; + int ret = parser->failed ? -1 : 0; if (close(parser->fd) < 0) i_error("close(%s) failed: %m", parser->path); i_free(parser->path); i_free(parser); + return ret; } struct fts_parser_vfuncs fts_parser_script = { diff -r d592417ec815 -r f409deb63c40 src/plugins/fts/fts-parser-tika.c --- a/src/plugins/fts/fts-parser-tika.c Fri Mar 13 15:06:10 2015 +0200 +++ b/src/plugins/fts/fts-parser-tika.c Fri Mar 13 16:04:01 2015 +0200 @@ -194,12 +194,19 @@ } else { /* finished */ i_assert(ret == -1); + if (parser->payload->stream_errno != 0) { + i_error("read(%s) failed: %s", + i_stream_get_name(parser->payload), + i_stream_get_error(parser->payload)); + parser->failed = TRUE; + } } } -static void fts_parser_tika_deinit(struct fts_parser *_parser) +static int fts_parser_tika_deinit(struct fts_parser *_parser) { struct tika_fts_parser *parser = (struct tika_fts_parser *)_parser; + int ret = parser->failed ? -1 : 0; if (parser->ioloop != NULL) { io_remove(&parser->io); @@ -212,6 +219,7 @@ if (parser->http_req != NULL) http_client_request_abort(&parser->http_req); i_free(parser); + return ret; } static void fts_parser_tika_unload(void) diff -r d592417ec815 -r f409deb63c40 src/plugins/fts/fts-parser.c --- a/src/plugins/fts/fts-parser.c Fri Mar 13 15:06:10 2015 +0200 +++ b/src/plugins/fts/fts-parser.c Fri Mar 13 16:04:01 2015 +0200 @@ -83,18 +83,20 @@ } } -void fts_parser_deinit(struct fts_parser **_parser) +int fts_parser_deinit(struct fts_parser **_parser) { struct fts_parser *parser = *_parser; + int ret = 0; *_parser = NULL; if (parser->utf8_output != NULL) buffer_free(&parser->utf8_output); if (parser->v.deinit != NULL) - parser->v.deinit(parser); + ret = parser->v.deinit(parser); else i_free(parser); + return ret; } void fts_parsers_unload(void) diff -r d592417ec815 -r f409deb63c40 src/plugins/fts/fts-parser.h --- a/src/plugins/fts/fts-parser.h Fri Mar 13 15:06:10 2015 +0200 +++ b/src/plugins/fts/fts-parser.h Fri Mar 13 16:04:01 2015 +0200 @@ -9,7 +9,7 @@ const char *content_type, const char *content_disposition); void (*more)(struct fts_parser *parser, struct message_block *block); - void (*deinit)(struct fts_parser *parser); + int (*deinit)(struct fts_parser *parser); void (*unload)(void); }; @@ -31,7 +31,7 @@ finished, it's still called with incoming size=0 while the parser increases it to non-zero. */ void fts_parser_more(struct fts_parser *parser, struct message_block *block); -void fts_parser_deinit(struct fts_parser **parser); +int fts_parser_deinit(struct fts_parser **parser); void fts_parsers_unload(void); From dovecot at dovecot.org Fri Mar 13 14:04:58 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 13 Mar 2015 14:04:58 +0000 Subject: dovecot-2.2: fts-tika, fts-solr: Added timeouts to requests so t... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4f8bfc6673a3 changeset: 18346:4f8bfc6673a3 user: Timo Sirainen date: Fri Mar 13 16:04:10 2015 +0200 description: fts-tika, fts-solr: Added timeouts to requests so they aren't attempted infinitely. diffstat: src/plugins/fts-solr/solr-connection.c | 2 ++ src/plugins/fts/fts-parser-tika.c | 2 ++ 2 files changed, 4 insertions(+), 0 deletions(-) diffs (24 lines): diff -r f409deb63c40 -r 4f8bfc6673a3 src/plugins/fts-solr/solr-connection.c --- a/src/plugins/fts-solr/solr-connection.c Fri Mar 13 16:04:01 2015 +0200 +++ b/src/plugins/fts-solr/solr-connection.c Fri Mar 13 16:04:10 2015 +0200 @@ -128,6 +128,8 @@ http_set.max_redirects = 1; http_set.max_attempts = 3; http_set.debug = debug; + http_set.connect_timeout_msecs = 5*1000; + http_set.request_timeout_msecs = 60*1000; solr_http_client = http_client_init(&http_set); } diff -r f409deb63c40 -r 4f8bfc6673a3 src/plugins/fts/fts-parser-tika.c --- a/src/plugins/fts/fts-parser-tika.c Fri Mar 13 16:04:01 2015 +0200 +++ b/src/plugins/fts/fts-parser-tika.c Fri Mar 13 16:04:10 2015 +0200 @@ -68,6 +68,8 @@ http_set.max_pipelined_requests = 1; http_set.max_redirects = 1; http_set.max_attempts = 3; + http_set.connect_timeout_msecs = 5*1000; + http_set.request_timeout_msecs = 60*1000; http_set.debug = user->mail_debug; tika_http_client = http_client_init(&http_set); } From dovecot at dovecot.org Fri Mar 13 14:18:07 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 13 Mar 2015 14:18:07 +0000 Subject: dovecot-2.2: fts: fts-parser doesn't need to be asked about all ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c82e9e5832a0 changeset: 18347:c82e9e5832a0 user: Timo Sirainen date: Fri Mar 13 16:12:37 2015 +0200 description: fts: fts-parser doesn't need to be asked about all the known-plaintext content-types. diffstat: src/plugins/fts/fts-parser.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) diffs (25 lines): diff -r 4f8bfc6673a3 -r c82e9e5832a0 src/plugins/fts/fts-parser.c --- a/src/plugins/fts/fts-parser.c Fri Mar 13 16:04:10 2015 +0200 +++ b/src/plugins/fts/fts-parser.c Fri Mar 13 16:12:37 2015 +0200 @@ -12,13 +12,20 @@ &fts_parser_tika }; +static const char *plaintext_content_types[] = { + "text/plain", + "message/delivery-status", + "message/disposition-notification", + "application/pgp-signature" +}; + bool fts_parser_init(struct mail_user *user, const char *content_type, const char *content_disposition, struct fts_parser **parser_r) { unsigned int i; - if (strcmp(content_type, "text/plain") == 0) { + if (str_array_find(plaintext_content_types, content_type)) { /* we probably don't want/need to allow parsers to handle plaintext? */ return FALSE; From dovecot at dovecot.org Fri Mar 13 14:29:18 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 13 Mar 2015 14:29:18 +0000 Subject: dovecot-2.2: lib-imap-client: If we get disconnected and reconne... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cf60180695ac changeset: 18348:cf60180695ac user: Timo Sirainen date: Fri Mar 13 16:28:31 2015 +0200 description: lib-imap-client: If we get disconnected and reconnect, log it as warning instead of as error. diffstat: src/lib-imap-client/imapc-client.c | 7 ++++++- src/lib-imap-client/imapc-client.h | 1 + src/lib-imap-client/imapc-connection.c | 26 ++++++++++++++++++++------ 3 files changed, 27 insertions(+), 7 deletions(-) diffs (91 lines): diff -r c82e9e5832a0 -r cf60180695ac src/lib-imap-client/imapc-client.c --- a/src/lib-imap-client/imapc-client.c Fri Mar 13 16:12:37 2015 +0200 +++ b/src/lib-imap-client/imapc-client.c Fri Mar 13 16:28:31 2015 +0200 @@ -303,9 +303,14 @@ } } +bool imapc_client_mailbox_can_reconnect(struct imapc_client_mailbox *box) +{ + return box->reopen_callback != NULL && box->reconnect_ok; +} + void imapc_client_mailbox_reconnect(struct imapc_client_mailbox *box) { - bool reconnect = box->reopen_callback != NULL && box->reconnect_ok; + bool reconnect = imapc_client_mailbox_can_reconnect(box); if (reconnect) { i_assert(!box->reconnecting); diff -r c82e9e5832a0 -r cf60180695ac src/lib-imap-client/imapc-client.h --- a/src/lib-imap-client/imapc-client.h Fri Mar 13 16:12:37 2015 +0200 +++ b/src/lib-imap-client/imapc-client.h Fri Mar 13 16:28:31 2015 +0200 @@ -182,6 +182,7 @@ void (*callback)(void *context), void *context); void imapc_client_mailbox_close(struct imapc_client_mailbox **box); +bool imapc_client_mailbox_can_reconnect(struct imapc_client_mailbox *box); void imapc_client_mailbox_reconnect(struct imapc_client_mailbox *box); struct imapc_command * imapc_client_mailbox_cmd(struct imapc_client_mailbox *box, diff -r c82e9e5832a0 -r cf60180695ac src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Fri Mar 13 16:12:37 2015 +0200 +++ b/src/lib-imap-client/imapc-connection.c Fri Mar 13 16:28:31 2015 +0200 @@ -421,6 +421,14 @@ imapc_connection_abort_commands(conn, NULL, FALSE); } +static bool imapc_connection_can_reconnect(struct imapc_connection *conn) +{ + if (conn->selected_box != NULL) + return imapc_client_mailbox_can_reconnect(conn->selected_box); + else + return FALSE; +} + static void imapc_connection_reconnect(struct imapc_connection *conn) { if (conn->selected_box != NULL) @@ -1351,6 +1359,7 @@ static void imapc_connection_input(struct imapc_connection *conn) { const char *errstr; + string_t *str; ssize_t ret = 0; /* we need to read as much as we can with SSL streams to avoid @@ -1361,23 +1370,28 @@ if (ret < 0) { /* disconnected */ + str = t_str_new(128); if (conn->disconnect_reason != NULL) { - i_error("imapc(%s): Server disconnected with message: %s", - conn->name, conn->disconnect_reason); + str_printfa(str, "Server disconnected with message: %s", + conn->disconnect_reason); } else if (conn->ssl_iostream == NULL) { errstr = conn->input->stream_errno == 0 ? "EOF" : i_stream_get_error(conn->input); - i_error("imapc(%s): Server disconnected unexpectedly: %s", - conn->name, errstr); + str_printfa(str, "Server disconnected unexpectedly: %s", + errstr); } else { errstr = ssl_iostream_get_last_error(conn->ssl_iostream); if (errstr == NULL) { errstr = conn->input->stream_errno == 0 ? "EOF" : i_stream_get_error(conn->input); } - i_error("imapc(%s): Server disconnected unexpectedly: %s", - conn->name, errstr); + str_printfa(str, "Server disconnected unexpectedly: %s", + errstr); } + if (!imapc_connection_can_reconnect(conn)) + i_error("imapc(%s): %s", conn->name, str_c(str)); + else + i_warning("imapc(%s): %s - reconnecting", conn->name, str_c(str)); imapc_connection_reconnect(conn); } imapc_connection_unref(&conn); From dovecot at dovecot.org Fri Mar 13 18:04:17 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 13 Mar 2015 18:04:17 +0000 Subject: dovecot-2.2: imapc: If reconnect fails during syncing, don't tre... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6efdf22c96f1 changeset: 18349:6efdf22c96f1 user: Timo Sirainen date: Fri Mar 13 20:03:27 2015 +0200 description: imapc: If reconnect fails during syncing, don't treat all mails as expunged in error handling code. diffstat: src/lib-storage/index/imapc/imapc-mail.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r cf60180695ac -r 6efdf22c96f1 src/lib-storage/index/imapc/imapc-mail.c --- a/src/lib-storage/index/imapc/imapc-mail.c Fri Mar 13 16:28:31 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-mail.c Fri Mar 13 20:03:27 2015 +0200 @@ -36,6 +36,11 @@ struct imapc_msgmap *msgmap; uint32_t lseq, rseq; + if (!mbox->initial_sync_done) { + /* unknown at this point */ + return FALSE; + } + if (mbox->sync_view != NULL) { /* check if another session has already expunged it */ if (!mail_index_lookup_seq(mbox->sync_view, _mail->uid, &lseq)) From dovecot at dovecot.org Fri Mar 13 18:09:39 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 13 Mar 2015 18:09:39 +0000 Subject: dovecot-2.2: dsync: Added an extra assert. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e86211e8d728 changeset: 18350:e86211e8d728 user: Timo Sirainen date: Fri Mar 13 20:05:03 2015 +0200 description: dsync: Added an extra assert. diffstat: src/doveadm/dsync/dsync-mailbox-export.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (20 lines): diff -r 6efdf22c96f1 -r e86211e8d728 src/doveadm/dsync/dsync-mailbox-export.c --- a/src/doveadm/dsync/dsync-mailbox-export.c Fri Mar 13 20:03:27 2015 +0200 +++ b/src/doveadm/dsync/dsync-mailbox-export.c Fri Mar 13 20:05:03 2015 +0200 @@ -353,7 +353,7 @@ struct mail *mail; enum mail_fetch_field wanted_fields = 0; struct mailbox_header_lookup_ctx *wanted_headers = NULL; - int ret; + int ret = 0; search_args = mail_search_build_init(); sarg = mail_search_build_add(search_args, SEARCH_UIDSET); @@ -395,6 +395,7 @@ if (ret < 0) break; } + i_assert(ret >= 0 || exporter->error != NULL); dsync_mailbox_export_drop_expunged_flag_changes(exporter); From dovecot at dovecot.org Fri Mar 13 18:09:39 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 13 Mar 2015 18:09:39 +0000 Subject: dovecot-2.2: dsync: Added an extra "finish" state to allow slave... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b4dbe64c0032 changeset: 18351:b4dbe64c0032 user: Timo Sirainen date: Fri Mar 13 20:08:34 2015 +0200 description: dsync: Added an extra "finish" state to allow slave-dsync to report error to master-dsync. I'm not sure if that's actually necessary, but just trying to follow the different possibilities on how dsync run can finish made me unsure about it. This should make it at least clear that if a slave-dsync has a failure flag set at deinit master-dsync will know about it before it returns success. diffstat: src/doveadm/dsync/dsync-brain-mailbox.c | 4 +- src/doveadm/dsync/dsync-brain-private.h | 1 + src/doveadm/dsync/dsync-brain.c | 24 +++++++++++++++ src/doveadm/dsync/dsync-ibc-pipe.c | 31 +++++++++++++++++++- src/doveadm/dsync/dsync-ibc-private.h | 4 ++ src/doveadm/dsync/dsync-ibc-stream.c | 50 +++++++++++++++++++++++++++++++- src/doveadm/dsync/dsync-ibc.c | 11 +++++++ src/doveadm/dsync/dsync-ibc.h | 4 ++ 8 files changed, 124 insertions(+), 5 deletions(-) diffs (289 lines): diff -r e86211e8d728 -r b4dbe64c0032 src/doveadm/dsync/dsync-brain-mailbox.c --- a/src/doveadm/dsync/dsync-brain-mailbox.c Fri Mar 13 20:05:03 2015 +0200 +++ b/src/doveadm/dsync/dsync-brain-mailbox.c Fri Mar 13 20:08:34 2015 +0200 @@ -534,7 +534,7 @@ i_assert(brain->box == NULL); if (!dsync_brain_next_mailbox(brain, &box, &dsync_box)) { - brain->state = DSYNC_STATE_DONE; + brain->state = DSYNC_STATE_FINISH; dsync_ibc_send_end_of_list(brain->ibc, DSYNC_IBC_EOL_MAILBOX); return; } @@ -722,7 +722,7 @@ if ((ret = dsync_ibc_recv_mailbox(brain->ibc, &dsync_box)) == 0) return FALSE; if (ret < 0) { - brain->state = DSYNC_STATE_DONE; + brain->state = DSYNC_STATE_FINISH; return TRUE; } diff -r e86211e8d728 -r b4dbe64c0032 src/doveadm/dsync/dsync-brain-private.h --- a/src/doveadm/dsync/dsync-brain-private.h Fri Mar 13 20:05:03 2015 +0200 +++ b/src/doveadm/dsync/dsync-brain-private.h Fri Mar 13 20:08:34 2015 +0200 @@ -32,6 +32,7 @@ after the mails are synced, another mailbox is synced. */ DSYNC_STATE_SYNC_MAILS, + DSYNC_STATE_FINISH, DSYNC_STATE_DONE }; diff -r e86211e8d728 -r b4dbe64c0032 src/doveadm/dsync/dsync-brain.c --- a/src/doveadm/dsync/dsync-brain.c Fri Mar 13 20:05:03 2015 +0200 +++ b/src/doveadm/dsync/dsync-brain.c Fri Mar 13 20:08:34 2015 +0200 @@ -30,6 +30,7 @@ "master_send_mailbox", "slave_recv_mailbox", "sync_mails", + "finish", "done" }; @@ -554,6 +555,26 @@ return changed; } +static bool dsync_brain_finish(struct dsync_brain *brain) +{ + const char *error; + + if (!brain->master_brain) { + dsync_ibc_send_finish(brain->ibc, + brain->failed ? "dsync failed" : NULL); + brain->state = DSYNC_STATE_DONE; + return TRUE; + } + if (dsync_ibc_recv_finish(brain->ibc, &error) == DSYNC_IBC_RECV_RET_TRYAGAIN) + return FALSE; + if (error != NULL) { + i_error("Remote dsync failed: %s", error); + brain->failed = TRUE; + } + brain->state = DSYNC_STATE_DONE; + return TRUE; +} + static bool dsync_brain_run_real(struct dsync_brain *brain, bool *changed_r) { enum dsync_state orig_state = brain->state; @@ -602,6 +623,9 @@ case DSYNC_STATE_SYNC_MAILS: changed = dsync_brain_sync_mails(brain); break; + case DSYNC_STATE_FINISH: + changed = dsync_brain_finish(brain); + break; case DSYNC_STATE_DONE: changed = TRUE; ret = FALSE; diff -r e86211e8d728 -r b4dbe64c0032 src/doveadm/dsync/dsync-ibc-pipe.c --- a/src/doveadm/dsync/dsync-ibc-pipe.c Fri Mar 13 20:05:03 2015 +0200 +++ b/src/doveadm/dsync/dsync-ibc-pipe.c Fri Mar 13 20:08:34 2015 +0200 @@ -19,7 +19,8 @@ ITEM_MAILBOX_ATTRIBUTE, ITEM_MAIL_CHANGE, ITEM_MAIL_REQUEST, - ITEM_MAIL + ITEM_MAIL, + ITEM_FINISH }; struct item { @@ -41,6 +42,7 @@ unsigned int count; char hierarchy_sep; } mailbox_delete; + const char *finish_error; } u; }; @@ -90,6 +92,7 @@ case ITEM_MAIL_CHANGE: case ITEM_MAIL_REQUEST: case ITEM_MAIL: + case ITEM_FINISH: item->pool = dsync_ibc_pipe_get_pool(pipe); break; } @@ -483,6 +486,30 @@ return DSYNC_IBC_RECV_RET_OK; } +static void +dsync_ibc_pipe_send_finish(struct dsync_ibc *ibc, const char *error) +{ + struct dsync_ibc_pipe *pipe = (struct dsync_ibc_pipe *)ibc; + struct item *item; + + item = dsync_ibc_pipe_push_item(pipe->remote, ITEM_FINISH); + item->u.finish_error = p_strdup(item->pool, error); +} + +static enum dsync_ibc_recv_ret +dsync_ibc_pipe_recv_finish(struct dsync_ibc *ibc, const char **error_r) +{ + struct dsync_ibc_pipe *pipe = (struct dsync_ibc_pipe *)ibc; + struct item *item; + + item = dsync_ibc_pipe_pop_item(pipe, ITEM_FINISH); + if (item == NULL) + return DSYNC_IBC_RECV_RET_TRYAGAIN; + + *error_r = item->u.finish_error; + return DSYNC_IBC_RECV_RET_OK; +} + static void pipe_close_mail_streams(struct dsync_ibc_pipe *pipe) { struct item *item; @@ -524,6 +551,8 @@ dsync_ibc_pipe_recv_mail_request, dsync_ibc_pipe_send_mail, dsync_ibc_pipe_recv_mail, + dsync_ibc_pipe_send_finish, + dsync_ibc_pipe_recv_finish, dsync_ibc_pipe_close_mail_streams, dsync_ibc_pipe_is_send_queue_full, dsync_ibc_pipe_has_pending_data diff -r e86211e8d728 -r b4dbe64c0032 src/doveadm/dsync/dsync-ibc-private.h --- a/src/doveadm/dsync/dsync-ibc-private.h Fri Mar 13 20:05:03 2015 +0200 +++ b/src/doveadm/dsync/dsync-ibc-private.h Fri Mar 13 20:08:34 2015 +0200 @@ -68,6 +68,10 @@ (*recv_mail)(struct dsync_ibc *ibc, struct dsync_mail **mail_r); + void (*send_finish)(struct dsync_ibc *ibc, const char *error); + enum dsync_ibc_recv_ret + (*recv_finish)(struct dsync_ibc *ibc, const char **error_r); + void (*close_mail_streams)(struct dsync_ibc *ibc); bool (*is_send_queue_full)(struct dsync_ibc *ibc); bool (*has_pending_data)(struct dsync_ibc *ibc); diff -r e86211e8d728 -r b4dbe64c0032 src/doveadm/dsync/dsync-ibc-stream.c --- a/src/doveadm/dsync/dsync-ibc-stream.c Fri Mar 13 20:05:03 2015 +0200 +++ b/src/doveadm/dsync/dsync-ibc-stream.c Fri Mar 13 20:08:34 2015 +0200 @@ -28,11 +28,12 @@ #define DSYNC_IBC_STREAM_OUTBUF_THROTTLE_SIZE (1024*128) #define DSYNC_PROTOCOL_VERSION_MAJOR 3 -#define DSYNC_PROTOCOL_VERSION_MINOR 2 -#define DSYNC_HANDSHAKE_VERSION "VERSION\tdsync\t3\t2\n" +#define DSYNC_PROTOCOL_VERSION_MINOR 3 +#define DSYNC_HANDSHAKE_VERSION "VERSION\tdsync\t3\t3\n" #define DSYNC_PROTOCOL_MINOR_HAVE_ATTRIBUTES 1 #define DSYNC_PROTOCOL_MINOR_HAVE_SAVE_GUID 2 +#define DSYNC_PROTOCOL_MINOR_HAVE_FINISH 3 enum item_type { ITEM_NONE, @@ -48,6 +49,7 @@ ITEM_MAIL_CHANGE, ITEM_MAIL_REQUEST, ITEM_MAIL, + ITEM_FINISH, ITEM_MAILBOX_CACHE_FIELD, @@ -122,6 +124,10 @@ .chr = 'M', .optional_keys = "guid uid pop3_uidl pop3_order received_date saved_date stream" }, + { .name = "finish", + .chr = 'F', + .optional_keys = "error" + }, { .name = "mailbox_cache_field", .chr = 'c', .required_keys = "name decision", @@ -1820,6 +1826,44 @@ return DSYNC_IBC_RECV_RET_OK; } +static void +dsync_ibc_stream_send_finish(struct dsync_ibc *_ibc, const char *error) +{ + struct dsync_ibc_stream *ibc = (struct dsync_ibc_stream *)_ibc; + struct dsync_serializer_encoder *encoder; + string_t *str = t_str_new(128); + + str_append_c(str, items[ITEM_FINISH].chr); + encoder = dsync_serializer_encode_begin(ibc->serializers[ITEM_FINISH]); + if (error != NULL) + dsync_serializer_encode_add(encoder, "error", error); + dsync_serializer_encode_finish(&encoder, str); + dsync_ibc_stream_send_string(ibc, str); +} + +static enum dsync_ibc_recv_ret +dsync_ibc_stream_recv_finish(struct dsync_ibc *_ibc, const char **error_r) +{ + struct dsync_ibc_stream *ibc = (struct dsync_ibc_stream *)_ibc; + struct dsync_deserializer_decoder *decoder; + const char *value; + enum dsync_ibc_recv_ret ret; + + *error_r = NULL; + p_clear(ibc->ret_pool); + + if (ibc->minor_version < DSYNC_PROTOCOL_MINOR_HAVE_FINISH) + return DSYNC_IBC_RECV_RET_OK; + + ret = dsync_ibc_stream_input_next(ibc, ITEM_FINISH, &decoder); + if (ret != DSYNC_IBC_RECV_RET_OK) + return ret; + + if (dsync_deserializer_decode_try(decoder, "error", &value)) + *error_r = p_strdup(ibc->ret_pool, value); + return DSYNC_IBC_RECV_RET_OK; +} + static void dsync_ibc_stream_close_mail_streams(struct dsync_ibc *_ibc) { struct dsync_ibc_stream *ibc = (struct dsync_ibc_stream *)_ibc; @@ -1874,6 +1918,8 @@ dsync_ibc_stream_recv_mail_request, dsync_ibc_stream_send_mail, dsync_ibc_stream_recv_mail, + dsync_ibc_stream_send_finish, + dsync_ibc_stream_recv_finish, dsync_ibc_stream_close_mail_streams, dsync_ibc_stream_is_send_queue_full, dsync_ibc_stream_has_pending_data diff -r e86211e8d728 -r b4dbe64c0032 src/doveadm/dsync/dsync-ibc.c --- a/src/doveadm/dsync/dsync-ibc.c Fri Mar 13 20:05:03 2015 +0200 +++ b/src/doveadm/dsync/dsync-ibc.c Fri Mar 13 20:08:34 2015 +0200 @@ -195,6 +195,17 @@ return ibc->v.recv_mail(ibc, mail_r); } +void dsync_ibc_send_finish(struct dsync_ibc *ibc, const char *error) +{ + ibc->v.send_finish(ibc, error); +} + +enum dsync_ibc_recv_ret +dsync_ibc_recv_finish(struct dsync_ibc *ibc, const char **error_r) +{ + return ibc->v.recv_finish(ibc, error_r); +} + void dsync_ibc_close_mail_streams(struct dsync_ibc *ibc) { ibc->v.close_mail_streams(ibc); diff -r e86211e8d728 -r b4dbe64c0032 src/doveadm/dsync/dsync-ibc.h --- a/src/doveadm/dsync/dsync-ibc.h Fri Mar 13 20:05:03 2015 +0200 +++ b/src/doveadm/dsync/dsync-ibc.h Fri Mar 13 20:08:34 2015 +0200 @@ -144,6 +144,10 @@ enum dsync_ibc_recv_ret dsync_ibc_recv_mail(struct dsync_ibc *ibc, struct dsync_mail **mail_r); +void dsync_ibc_send_finish(struct dsync_ibc *ibc, const char *error); +enum dsync_ibc_recv_ret +dsync_ibc_recv_finish(struct dsync_ibc *ibc, const char **error_r); + /* Close any mail input streams that are kept open. This needs to be called before the mail is attempted to be freed (usually on error conditions). */ void dsync_ibc_close_mail_streams(struct dsync_ibc *ibc); From pigeonhole at rename-it.nl Sat Mar 14 13:49:44 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 14 Mar 2015 14:49:44 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: Fixed handling of script stre... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/a58ba4e734b1 changeset: 2005:a58ba4e734b1 user: Stephan Bosch date: Sat Mar 14 14:42:30 2015 +0100 description: lib-sieve: Fixed handling of script stream errors. diffstat: src/lib-sieve/storage/file/sieve-file-script.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r e574d52c40bf -r a58ba4e734b1 src/lib-sieve/storage/file/sieve-file-script.c --- a/src/lib-sieve/storage/file/sieve-file-script.c Thu Mar 12 21:34:10 2015 +0100 +++ b/src/lib-sieve/storage/file/sieve-file-script.c Sat Mar 14 14:42:30 2015 +0100 @@ -460,6 +460,7 @@ "Failed to close sieve script: " "close(fd=%s) failed: %m", fscript->path); } + return -1; } *stream_r = result; From pigeonhole at rename-it.nl Sat Mar 14 13:49:44 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 14 Mar 2015 14:49:44 +0100 Subject: dovecot-2.2-pigeonhole: sievec: Don't pass the filename as scrip... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/16dfb44e0c1b changeset: 2008:16dfb44e0c1b user: Stephan Bosch date: Thu Mar 12 21:42:31 2015 +0100 description: sievec: Don't pass the filename as script name when compiling a whole directory. diffstat: src/sieve-tools/sievec.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 57f54356a8bf -r 16dfb44e0c1b src/sieve-tools/sievec.c --- a/src/sieve-tools/sievec.c Thu Mar 12 21:41:03 2015 +0100 +++ b/src/sieve-tools/sievec.c Thu Mar 12 21:42:31 2015 +0100 @@ -120,7 +120,7 @@ else file = t_strconcat(scriptfile, "/", dp->d_name, NULL); - sbin = sieve_tool_script_compile(svinst, file, dp->d_name); + sbin = sieve_tool_script_compile(svinst, file, NULL); if ( sbin != NULL ) { sieve_save(sbin, TRUE, NULL); @@ -142,7 +142,7 @@ if ( sbin != NULL ) { if ( dump ) sieve_tool_dump_binary_to(sbin, outfile, FALSE); - else { + else { sieve_save_as(sbin, outfile, TRUE, 0600, NULL); } From pigeonhole at rename-it.nl Sat Mar 14 13:49:44 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 14 Mar 2015 14:49:44 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: Restructured parsing of stora... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/adf9baf74a4d changeset: 2006:adf9baf74a4d user: Stephan Bosch date: Thu Mar 12 21:37:41 2015 +0100 description: lib-sieve: Restructured parsing of storage options. diffstat: src/lib-sieve/sieve-storage.c | 37 ++++++++++++++++++++----------------- 1 files changed, 20 insertions(+), 17 deletions(-) diffs (97 lines): diff -r a58ba4e734b1 -r adf9baf74a4d src/lib-sieve/sieve-storage.c --- a/src/lib-sieve/sieve-storage.c Sat Mar 14 14:42:30 2015 +0100 +++ b/src/lib-sieve/sieve-storage.c Thu Mar 12 21:37:41 2015 +0100 @@ -164,9 +164,9 @@ return ( storage_class == NULL ? -1 : 1 ); } -static bool sieve_storage_data_parse +static int sieve_storage_data_parse (struct sieve_storage *storage, const char *data, const char **location_r, - const char *const **options_r, const char **error_r) + const char *const **options_r) { ARRAY_TYPE(const_string) options; const char *const *tmp; @@ -174,7 +174,7 @@ if (*data == '\0') { *options_r = NULL; *location_r = data; - return TRUE; + return 0; } /* */ @@ -190,8 +190,10 @@ if ( strncasecmp(option, "name=", 5) == 0 ) { if ( option[5] == '\0' ) { - *error_r = "empty name not allowed"; - return FALSE; + sieve_storage_sys_error(storage, + "Failed to parse storage location: " + "Empty name not allowed"); + return -1; } if ( storage->script_name == NULL ) @@ -201,8 +203,10 @@ const char *bin_dir = option+7; if ( bin_dir[0] == '\0' ) { - *error_r = "empty bindir not allowed"; - return FALSE; + sieve_storage_sys_error(storage, + "Failed to parse storage location: " + "Empty bindir not allowed"); + return -1; } if ( bin_dir[0] == '~' ) { @@ -212,9 +216,11 @@ if ( home != NULL ) { bin_dir = home_expand_tilde(bin_dir, home); } else if ( bin_dir[1] == '/' || bin_dir[1] == '\0' ) { - *error_r = "bindir is relative to home directory (~/), " - "but home directory cannot be determined"; - return FALSE; + sieve_storage_sys_error(storage, + "Failed to parse storage location: " + "bindir is relative to home directory (~/), " + "but home directory cannot be determined"); + return -1; } } @@ -228,7 +234,7 @@ *options_r = array_idx(&options, 0); } - return TRUE; + return 0; } struct sieve_storage *sieve_storage_alloc @@ -258,7 +264,7 @@ { struct sieve_storage *storage; const char *const *options; - const char *location, *parse_error; + const char *location; enum sieve_error error; if ( error_r != NULL ) @@ -290,11 +296,8 @@ storage = sieve_storage_alloc (svinst, storage_class, data, flags, main); - if ( !sieve_storage_data_parse - (storage, data, &location, &options, &parse_error) ) { - sieve_sys_error(svinst, "%s storage: " - "Failed to parse storage location: %s", - storage_class->driver_name, parse_error); + if ( sieve_storage_data_parse + (storage, data, &location, &options) < 0 ) { *error_r = SIEVE_ERROR_TEMP_FAILURE; sieve_storage_unref(&storage); storage = NULL; From pigeonhole at rename-it.nl Sat Mar 14 13:49:44 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 14 Mar 2015 14:49:44 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: file storage: Improved checki... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/57f54356a8bf changeset: 2007:57f54356a8bf user: Stephan Bosch date: Thu Mar 12 21:41:03 2015 +0100 description: lib-sieve: file storage: Improved checking of active script link using t_normpath(). diffstat: src/lib-sieve/storage/file/sieve-file-storage-active.c | 77 +++++------------ 1 files changed, 22 insertions(+), 55 deletions(-) diffs (112 lines): diff -r adf9baf74a4d -r 57f54356a8bf src/lib-sieve/storage/file/sieve-file-storage-active.c --- a/src/lib-sieve/storage/file/sieve-file-storage-active.c Thu Mar 12 21:37:41 2015 +0100 +++ b/src/lib-sieve/storage/file/sieve-file-storage-active.c Thu Mar 12 21:41:03 2015 +0100 @@ -7,57 +7,12 @@ #include "hostpid.h" #include "file-copy.h" +#include "realpath.h" + #include "sieve-file-storage.h" #include -static int _file_path_cmp(const char *path1, const char *path2) -{ - const char *p1, *p2; - int ret; - - p1 = path1; p2 = path2; - if (*p2 == '\0' && *p1 != '\0') - return 1; - if (*p1 == '\0' && *p2 != '\0') - return -1; - if (*p1 == '/' && *p2 != '/') - return 1; - if (*p2 == '/' && *p1 != '/') - return -1; - for (;;) { - const char *s1, *s2; - size_t size1, size2; - - /* skip repeated slashes */ - for (; *p1 == '/'; p1++); - for (; *p2 == '/'; p2++); - /* check for end of comparison */ - if (*p1 == '\0' || *p2 == '\0') - break; - /* mark start of path element */ - s1 = p1; - s2 = p2; - /* scan to end of path elements */ - for (; *p1 != '\0' && *p1 != '/'; p1++); - for (; *p2 != '\0' && *p2 != '/'; p2++); - /* compare sizes */ - size1 = p1 - s1; - size2 = p2 - s2; - if (size1 != size2) - return size1 - size2; - /* compare */ - if (size1 > 0 && (ret=memcmp(s1, s2, size1)) != 0) - return ret; - } - if (*p1 == '\0') { - if (*p2 == '\0') - return 0; - return -1; - } - return 1; -} - /* * Symlink manipulation */ @@ -108,7 +63,14 @@ const char **scriptname_r) { struct sieve_storage *storage = &fstorage->storage; - const char *fname, *scriptname, *scriptpath; + const char *fname, *scriptname, *scriptpath, *link_dir; + + /* Split off directory from link path */ + fname = strrchr(fstorage->active_path, '/'); + if (fname == NULL) + link_dir = ""; + else + link_dir = t_strdup_until(fstorage->active_path, fname+1); /* Split link into path and filename */ fname = strrchr(link, '/'); @@ -126,20 +88,25 @@ /* Warn if link is deemed to be invalid */ if ( scriptname == NULL ) { sieve_storage_sys_warning(storage, - "Active sieve script symlink %s is broken: " - "invalid scriptname (points to %s).", + "Active Sieve script symlink %s is broken: " + "Invalid scriptname (points to %s).", fstorage->active_path, link); return NULL; } /* Check whether the path is any good */ - i_assert( fstorage->link_path != NULL ); - if ( _file_path_cmp(scriptpath, fstorage->link_path) != 0 && - _file_path_cmp(scriptpath, fstorage->path) != 0 ) { + if ( t_normpath_to(scriptpath, link_dir, &scriptpath) < 0 ) { + sieve_storage_sys_warning(storage, + "Failed to check active Sieve script symlink %s: " + "Failed to normalize path (points to %s).", + fstorage->active_path, scriptpath); + return NULL; + } + if ( strcmp(scriptpath, fstorage->path) != 0 ) { sieve_storage_sys_warning(storage, "Active sieve script symlink %s is broken: " - "invalid/unknown path to storage (points to %s).", - fstorage->active_path, link); + "Invalid/unknown path to storage (points to %s).", + fstorage->active_path, scriptpath); return NULL; } From pigeonhole at rename-it.nl Sat Mar 14 13:49:44 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 14 Mar 2015 14:49:44 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: Implemented utility functions... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/163a8fbfdc1a changeset: 2003:163a8fbfdc1a user: Stephan Bosch date: Thu Mar 12 21:03:28 2015 +0100 description: lib-sieve: Implemented utility functions to normalize filesystem paths. diffstat: src/lib-sieve/util/Makefile.am | 6 +- src/lib-sieve/util/realpath.c | 237 +++++++++++++++++++++++++++++++++++++++++ src/lib-sieve/util/realpath.h | 33 +++++ 3 files changed, 274 insertions(+), 2 deletions(-) diffs (299 lines): diff -r 986ea6e9c270 -r 163a8fbfdc1a src/lib-sieve/util/Makefile.am --- a/src/lib-sieve/util/Makefile.am Wed Mar 11 23:59:51 2015 +0100 +++ b/src/lib-sieve/util/Makefile.am Thu Mar 12 21:03:28 2015 +0100 @@ -12,13 +12,15 @@ rfc2822.c \ program-client-local.c \ program-client-remote.c \ - program-client.c + program-client.c \ + realpath.c headers = \ edit-mail.h \ rfc2822.h \ program-client-private.h \ - program-client.h + program-client.h \ + realpath.h pkginc_libdir=$(dovecot_pkgincludedir)/sieve pkginc_lib_HEADERS = $(headers) diff -r 986ea6e9c270 -r 163a8fbfdc1a src/lib-sieve/util/realpath.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-sieve/util/realpath.c Thu Mar 12 21:03:28 2015 +0100 @@ -0,0 +1,237 @@ +/* Copyright (c) 2009-2015 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "str.h" + +#include "realpath.h" + +#include +#include +#include +#include + +// FIXME: move/merge to Dovecot + +#define REALPATH_MAX_PATH 8*1024 +#define REALPATH_MAX_SYMLINKS 80 + +static int t_getcwd_alloc(char **dir_r, size_t *asize_r) +{ + /* @UNSAFE */ + char *dir; + size_t asize = 128; + + dir = t_buffer_get(asize); + while (getcwd(dir, asize) == NULL) { + if (errno != ERANGE) + return -1; + asize = nearest_power(asize+1); + dir = t_buffer_get(asize); + } + *asize_r = asize; + *dir_r = dir; + return 0; +} + +static int path_normalize(const char *path, bool resolve_links, + const char **npath_r) +{ + /* @UNSAFE */ + unsigned int link_count = 0; + char *npath, *npath_pos; + const char *p; + size_t asize; + + if (path[0] != '/') { + /* relative; initialize npath with current directory */ + if (t_getcwd_alloc(&npath, &asize) < 0) + return -1; + npath_pos = npath + strlen(npath); + i_assert(npath[0] == '/'); + } else { + /* absolute; initialize npath with root */ + asize = 128; + npath = t_buffer_get(asize); + npath[0] = '/'; + npath_pos = npath + 1; + } + + p = path; + while (*p != '\0') { + struct stat st; + ptrdiff_t seglen; + const char *segend; + + /* skip duplicate shashes */ + while (*p == '/') + p++; + + /* find end of path segment */ + for (segend = p; *segend != '\0' && *segend != '/'; segend++); + + if (segend == p) + break; /* '\0' */ + seglen = segend - p; + if (seglen == 1 && p[0] == '.') { + /* a reference to this segment; nothing to do */ + } else if (seglen == 2 && p[0] == '.' && p[1] == '.') { + /* a reference to parent segment; back up to previous slash */ + if (npath_pos > npath + 1) { + if (*npath_pos == '/') + npath_pos--; + for (; *npath_pos != '/'; npath_pos--); + } + } else { + /* make sure npath now ends in slash */ + if (*(npath_pos-1) != '/') + *(npath_pos++) = '/'; + + /* allocate space if necessary */ + if ((npath_pos + seglen + 1) >= (npath + asize)) { + ptrdiff_t npath_offset = npath_pos - npath; + asize = nearest_power(npath_offset + seglen + 2); + npath = t_buffer_reget(npath, asize); + npath_pos = npath + npath_offset; + } + + /* copy segment to normalized path */ + (void)memmove(npath_pos, p, segend - p); + npath_pos += seglen; + } + + if (resolve_links) { + /* stat path up to here (segend points to tail) */ + *npath_pos = '\0'; + if (lstat(npath, &st) < 0) + return -1; + + if (S_ISLNK (st.st_mode)) { + /* symlink */ + char *npath_link; + size_t lsize = 128, tlen = strlen(segend), espace; + size_t ltlen = (link_count == 0 ? 0 : tlen); + ssize_t ret; + + /* limit link dereferences */ + if (++link_count > REALPATH_MAX_SYMLINKS) { + errno = ELOOP; + return -1; + } + + /* allocate space for preserving tail of previous symlink and + first attempt at reading symlink with room for the tail + + buffer will look like this: + [npath][0][preserved tail][link buffer][room for tail][0] + */ + espace = ltlen + tlen + 2; + if ((npath_pos + espace + lsize) >= (npath + asize)) { + ptrdiff_t npath_offset = npath_pos - npath; + asize = nearest_power((npath_offset + espace + lsize) + 1); + lsize = asize - (npath_offset + espace); + npath = t_buffer_reget(npath, asize); + npath_pos = npath + npath_offset; + } + + if (ltlen > 0) { + /* preserve tail just after end of npath */ + (void)memmove(npath_pos + 1, segend, ltlen); + } + + /* read the symlink after the preserved tail */ + for (;;) { + npath_link = (npath_pos + 1) + ltlen; + + /* attempt to read the link */ + if ((ret=readlink(npath, npath_link, lsize)) < 0) + return -1; + if ((size_t)ret < lsize) + break; + + /* sum of new symlink content length and path tail length may not + exeed maximum */ + if ((size_t)(ret + tlen) >= REALPATH_MAX_PATH) { + errno = ENAMETOOLONG; + return -1; + } + + /* try again with bigger buffer */ + espace = ltlen + tlen + 2; + if ((npath_pos + espace + lsize) >= (npath + asize)) { + ptrdiff_t npath_offset = npath_pos - npath; + asize = nearest_power((npath_offset + espace + lsize) + 1); + lsize = asize - (npath_offset + espace); + npath = t_buffer_reget(npath, asize); + npath_pos = npath + npath_offset; + } + } + + /* add tail of previous path at end of symlink */ + if (ltlen > 0) + (void)memcpy(npath_link + ret, npath_pos + 1, tlen); + else + (void)memcpy(npath_link + ret, segend, tlen); + *(npath_link+ret+tlen) = '\0'; + + /* use as new source path */ + path = segend = npath_link; + + if (path[0] == '/') { + /* absolute symlink; start over at root */ + npath_pos = npath + 1; + } else { + /* relative symlink; back up to previous segment */ + if (npath_pos > npath + 1) { + if (*npath_pos == '/') + npath_pos--; + for (; *npath_pos != '/'; npath_pos--); + } + } + + } else if (*segend != '\0' && !S_ISDIR (st.st_mode)) { + /* not last segment, but not a directory either */ + errno = ENOTDIR; + return -1; + } + } + + p = segend; + } + + /* remove any trailing slash */ + if (npath_pos > npath + 1 && *(npath_pos-1) == '/') + npath_pos--; + *npath_pos = '\0'; + + t_buffer_alloc(npath_pos - npath + 1); + *npath_r = npath; + return 0; +} + +int t_normpath(const char *path, const char **npath_r) +{ + return path_normalize(path, FALSE, npath_r); +} + +int t_normpath_to(const char *path, const char *root, + const char **npath_r) +{ + if (*path == '/') + return t_normpath(path, npath_r); + + return t_normpath(t_strconcat(root, "/", path, NULL), npath_r); +} + +int t_realpath(const char *path, const char **npath_r) +{ + return path_normalize(path, TRUE, npath_r); +} + +int t_realpath_to(const char *path, const char *root, + const char **npath_r) +{ + if (*path == '/') + return t_realpath(path, npath_r); + + return t_realpath(t_strconcat(root, "/", path, NULL), npath_r); +} diff -r 986ea6e9c270 -r 163a8fbfdc1a src/lib-sieve/util/realpath.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-sieve/util/realpath.h Thu Mar 12 21:03:28 2015 +0100 @@ -0,0 +1,33 @@ +#ifndef REALPATH_H +#define REALPATH_H + +/* Returns path as the normalized absolute path, which means that './' + and '../' components are resolved, and that duplicate and trailing + slashes are removed. If it's not already the absolute path, it's + assumed to be relative to the current working directory. + + NOTE: Be careful with this function. The resolution of '../' components + with the parent component as if it were a normal directory is not valid + if the path contains symbolic links. + */ +int t_normpath(const char *path, const char **npath_r); +/* Like t_normpath(), but path is relative to given root. */ +int t_normpath_to(const char *path, const char *root, + const char **npath_r); + +/* Returns path as the real normalized absolute path, which means that all + symbolic links in the path are resolved, that './' and '../' components + are resolved, and that duplicate and trailing slashes are removed. If it's + not already the absolute path, it's assumed to be relative to the current + working directory. + + NOTE: This function calls stat() for each path component and more when + there are symbolic links (just like POSIX realpath()). + */ +int t_realpath(const char *path, const char **npath_r); +/* Like t_realpath(), but path is relative to given root. */ +int t_realpath_to(const char *path, const char *root, + const char **npath_r); + +#endif + From pigeonhole at rename-it.nl Sat Mar 14 13:49:44 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 14 Mar 2015 14:49:44 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: file storage: Forgot to compa... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/38689335cc93 changeset: 2009:38689335cc93 user: Stephan Bosch date: Thu Mar 12 22:14:44 2015 +0100 description: lib-sieve: file storage: Forgot to compare stat.st_dev in equals() method. diffstat: src/lib-sieve/storage/file/sieve-file-script.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 16dfb44e0c1b -r 38689335cc93 src/lib-sieve/storage/file/sieve-file-script.c --- a/src/lib-sieve/storage/file/sieve-file-script.c Thu Mar 12 21:42:31 2015 +0100 +++ b/src/lib-sieve/storage/file/sieve-file-script.c Thu Mar 12 22:14:44 2015 +0100 @@ -784,7 +784,8 @@ struct sieve_file_script *fother = (struct sieve_file_script *)other; - return ( fscript->st.st_ino == fother->st.st_ino ); + return ( CMP_DEV_T(fscript->st.st_dev, fother->st.st_dev) && + fscript->st.st_ino == fother->st.st_ino ); } /* From pigeonhole at rename-it.nl Sat Mar 14 14:32:07 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 14 Mar 2015 15:32:07 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: dict: Fixed memory allocation... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/adbd9fc695d1 changeset: 2010:adbd9fc695d1 user: Stephan Bosch date: Sat Mar 14 15:31:53 2015 +0100 description: lib-sieve: dict: Fixed memory allocation bug in script object. diffstat: src/lib-sieve/storage/dict/sieve-dict-script.c | 12 +++++++----- 1 files changed, 7 insertions(+), 5 deletions(-) diffs (57 lines): diff -r 38689335cc93 -r adbd9fc695d1 src/lib-sieve/storage/dict/sieve-dict-script.c --- a/src/lib-sieve/storage/dict/sieve-dict-script.c Thu Mar 12 22:14:44 2015 +0100 +++ b/src/lib-sieve/storage/dict/sieve-dict-script.c Sat Mar 14 15:31:53 2015 +0100 @@ -70,7 +70,7 @@ struct sieve_dict_storage *dstorage = (struct sieve_dict_storage *)storage; const char *name = script->name; - const char *path; + const char *path, *data_id; int ret; if ( sieve_dict_storage_get_dict @@ -81,7 +81,7 @@ (DICT_SIEVE_NAME_PATH, dict_escape_string(name), NULL); ret = dict_lookup - (dscript->dict, script->pool, path, &dscript->data_id); + (dscript->dict, script->pool, path, &data_id); if ( ret <= 0 ) { if ( ret < 0 ) { sieve_script_set_critical(script, @@ -98,6 +98,7 @@ return -1; } + dscript->data_id = p_strdup(script->pool, data_id); return 0; } @@ -107,7 +108,7 @@ { struct sieve_dict_script *dscript = (struct sieve_dict_script *)script; - const char *path, *name = script->name; + const char *path, *name = script->name, *data; int ret; dscript->data_pool = @@ -117,7 +118,7 @@ (DICT_SIEVE_DATA_PATH, dict_escape_string(dscript->data_id), NULL); ret = dict_lookup - (dscript->dict, dscript->data_pool, path, &dscript->data); + (dscript->dict, dscript->data_pool, path, &data); if ( ret <= 0 ) { if ( ret < 0 ) { sieve_script_set_critical(script, @@ -133,7 +134,8 @@ *error_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } - + + dscript->data = p_strdup(script->pool, data); *stream_r = i_stream_create_from_data(dscript->data, strlen(dscript->data)); return 0; } From pigeonhole at rename-it.nl Sat Mar 14 14:52:23 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 14 Mar 2015 15:52:23 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: Improved debug messages about... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/0226882e55e1 changeset: 2011:0226882e55e1 user: Stephan Bosch date: Sat Mar 14 15:52:15 2015 +0100 description: lib-sieve: Improved debug messages about up-to-date status of a loaded binary. diffstat: src/lib-sieve/sieve-script.c | 36 +++++++++++---------- src/lib-sieve/storage/dict/sieve-dict-script.c | 8 ++++- src/lib-sieve/storage/file/sieve-file-script.c | 6 ++- src/lib-sieve/storage/ldap/sieve-ldap-script.c | 40 +++++++++++++++++++++--- src/lib-sieve/storage/ldap/sieve-ldap-storage.c | 1 + src/lib-sieve/storage/ldap/sieve-ldap-storage.h | 1 + 6 files changed, 67 insertions(+), 25 deletions(-) diffs (227 lines): diff -r adbd9fc695d1 -r 0226882e55e1 src/lib-sieve/sieve-script.c --- a/src/lib-sieve/sieve-script.c Sat Mar 14 15:31:53 2015 +0100 +++ b/src/lib-sieve/sieve-script.c Sat Mar 14 15:52:15 2015 +0100 @@ -337,7 +337,6 @@ { struct sieve_binary *sbin = sieve_binary_block_get_binary(sblock); string_t *storage_class, *location; - const char *script_location; unsigned int version; if ( sieve_binary_block_get_size(sblock) - *offset == 0 ) @@ -346,15 +345,16 @@ /* storage class */ if ( !sieve_binary_read_string(sblock, offset, &storage_class) ) { sieve_script_sys_error(script, - "Binary %s has invalid metadata for script %s: " + "Binary `%s' has invalid metadata for script `%s': " "Invalid storage class", - sieve_binary_path(sbin), sieve_script_location(script)); + sieve_binary_path(sbin), script->location); return -1; } if ( strcmp(str_c(storage_class), script->driver_name) != 0 ) { sieve_script_sys_debug(script, - "Binary reports unexpected driver name " + "Binary `%s' reports unexpected driver name for script `%s' " "(`%s' rather than `%s')", + sieve_binary_path(sbin), script->location, str_c(storage_class), script->driver_name); return 0; } @@ -362,34 +362,36 @@ /* version */ if ( !sieve_binary_read_unsigned(sblock, offset, &version) ) { sieve_script_sys_error(script, - "Binary %s has invalid metadata for script %s: " + "Binary `%s' has invalid metadata for script `%s': " "Invalid version", - sieve_binary_path(sbin), sieve_script_location(script)); + sieve_binary_path(sbin), script->location); return -1; } if ( script->storage->version != version ) { sieve_script_sys_debug(script, - "Binary %s was compiled with different version " - "of the `%s' script storage class (compiled v%d, expected v%d;" - "automatically fixed when re-compiled)", sieve_binary_path(sbin), - script->driver_name, version, script->storage->version); + "Binary `%s' was compiled with " + "a different version of the `%s' script storage class " + "(compiled v%d, expected v%d; " + "automatically fixed when re-compiled)", + sieve_binary_path(sbin), script->driver_name, + version, script->storage->version); return 0; } /* location */ if ( !sieve_binary_read_string(sblock, offset, &location) ) { sieve_script_sys_error(script, - "Binary %s has invalid metadata for script %s: " + "Binary `%s' has invalid metadata for script `%s': " "Invalid location", - sieve_binary_path(sbin), sieve_script_location(script)); + sieve_binary_path(sbin), script->location); return -1; } - script_location = ( script->location == NULL ? "" : script->location); - if ( strcmp(str_c(location), script_location) != 0 ) { + i_assert( script->location != NULL ); + if ( strcmp(str_c(location), script->location) != 0 ) { sieve_script_sys_debug(script, - "Binary reports different script location " - "(`%s' rather than `%s')", - str_c(location), script_location); + "Binary `%s' reports different location " + "for script `%s' (binary points to `%s')", + sieve_binary_path(sbin), script->location, str_c(location)); return 0; } diff -r adbd9fc695d1 -r 0226882e55e1 src/lib-sieve/storage/dict/sieve-dict-script.c --- a/src/lib-sieve/storage/dict/sieve-dict-script.c Sat Mar 14 15:31:53 2015 +0100 +++ b/src/lib-sieve/storage/dict/sieve-dict-script.c Sat Mar 14 15:52:15 2015 +0100 @@ -161,8 +161,14 @@ return -1; } i_assert( dscript->data_id != NULL ); - if ( strcmp(str_c(data_id), dscript->data_id) != 0 ) + if ( strcmp(str_c(data_id), dscript->data_id) != 0 ) { + sieve_script_sys_debug(script, + "Binary `%s' reports different data ID for script `%s' " + "(`%s' rather than `%s')", + sieve_binary_path(sbin), sieve_script_location(script), + str_c(data_id), dscript->data_id); return 0; + } return 1; } diff -r adbd9fc695d1 -r 0226882e55e1 src/lib-sieve/storage/file/sieve-file-script.c --- a/src/lib-sieve/storage/file/sieve-file-script.c Sat Mar 14 15:31:53 2015 +0100 +++ b/src/lib-sieve/storage/file/sieve-file-script.c Sat Mar 14 15:52:15 2015 +0100 @@ -483,9 +483,11 @@ fscript->st.st_mtime : fscript->lnk_st.st_mtime ); if ( bmtime <= smtime ) { - if (svinst->debug) { + if ( svinst->debug ) { sieve_script_sys_debug(script, - "Sieve binary is not newer than the Sieve script (%s <= %s)", + "Sieve binary `%s' is not newer " + "than the Sieve script `%s' (%s <= %s)", + sieve_binary_path(sbin), sieve_script_location(script), t_strflocaltime("%Y-%m-%d %H:%M:%S", bmtime), t_strflocaltime("%Y-%m-%d %H:%M:%S", smtime)); } diff -r adbd9fc695d1 -r 0226882e55e1 src/lib-sieve/storage/ldap/sieve-ldap-script.c --- a/src/lib-sieve/storage/ldap/sieve-ldap-script.c Sat Mar 14 15:31:53 2015 +0100 +++ b/src/lib-sieve/storage/ldap/sieve-ldap-script.c Sat Mar 14 15:52:15 2015 +0100 @@ -2,6 +2,7 @@ */ #include "lib.h" +#include "time-util.h" #include "istream.h" #include "sieve-ldap-storage.h" @@ -121,24 +122,41 @@ { struct sieve_ldap_script *lscript = (struct sieve_ldap_script *)script; + struct sieve_instance *svinst = script->storage->svinst; struct sieve_ldap_storage *lstorage = (struct sieve_ldap_storage *)script->storage; struct sieve_binary *sbin = sieve_binary_block_get_binary(sblock); + time_t bmtime = sieve_binary_mtime(sbin); string_t *dn, *modattr; /* config file changed? */ - if ( sieve_binary_mtime(sbin) <= lstorage->set_mtime ) + if ( bmtime <= lstorage->set_mtime ) { + if ( svinst->debug ) { + sieve_script_sys_debug(script, + "Sieve binary `%s' is not newer " + "than the LDAP configuration `%s' (%s <= %s)", + sieve_binary_path(sbin), lstorage->config_file, + t_strflocaltime("%Y-%m-%d %H:%M:%S", bmtime), + t_strflocaltime("%Y-%m-%d %H:%M:%S", lstorage->set_mtime)); + } return 0; + } /* open script if not open already */ if ( lscript->dn == NULL && sieve_script_open(script, NULL) < 0 ) return 0; - /* if modattr not found recompile always */ - if ( lscript->modattr == NULL || *lscript->modattr == '\0' ) + /* if modattr not found, recompile always */ + if ( lscript->modattr == NULL || *lscript->modattr == '\0' ) { + sieve_script_sys_error(script, + "LDAP entry for script `%s' " + "has no modified attribute `%s'", + sieve_script_location(script), + lstorage->set.sieve_ldap_mod_attr); return 0; + } /* compare DN in binary and from search result */ if ( !sieve_binary_read_string(sblock, offset, &dn) ) { @@ -149,8 +167,14 @@ return -1; } i_assert( lscript->dn != NULL ); - if ( strcmp(str_c(dn), lscript->dn) != 0 ) + if ( strcmp(str_c(dn), lscript->dn) != 0 ) { + sieve_script_sys_debug(script, + "Binary `%s' reports different LDAP DN for script `%s' " + "(`%s' rather than `%s')", + sieve_binary_path(sbin), sieve_script_location(script), + str_c(dn), lscript->dn); return 0; + } /* compare modattr in binary and from search result */ if ( !sieve_binary_read_string(sblock, offset, &modattr) ) { @@ -160,8 +184,14 @@ sieve_binary_path(sbin), sieve_script_location(script)); return -1; } - if ( strcmp(str_c(modattr), lscript->modattr) != 0 ) + if ( strcmp(str_c(modattr), lscript->modattr) != 0 ) { + sieve_script_sys_debug(script, + "Binary `%s' reports different modified attribute content " + "for script `%s' (`%s' rather than `%s')", + sieve_binary_path(sbin), sieve_script_location(script), + str_c(modattr), lscript->modattr); return 0; + } return 1; } diff -r adbd9fc695d1 -r 0226882e55e1 src/lib-sieve/storage/ldap/sieve-ldap-storage.c --- a/src/lib-sieve/storage/ldap/sieve-ldap-storage.c Sat Mar 14 15:31:53 2015 +0100 +++ b/src/lib-sieve/storage/ldap/sieve-ldap-storage.c Sat Mar 14 15:52:15 2015 +0100 @@ -82,6 +82,7 @@ return -1; lstorage->username = p_strdup(storage->pool, username); + lstorage->config_file = p_strdup(storage->pool, storage->location); lstorage->conn = sieve_ldap_db_init(lstorage); storage->location = p_strconcat(storage->pool, diff -r adbd9fc695d1 -r 0226882e55e1 src/lib-sieve/storage/ldap/sieve-ldap-storage.h --- a/src/lib-sieve/storage/ldap/sieve-ldap-storage.h Sat Mar 14 15:31:53 2015 +0100 +++ b/src/lib-sieve/storage/ldap/sieve-ldap-storage.h Sat Mar 14 15:52:15 2015 +0100 @@ -68,6 +68,7 @@ struct sieve_ldap_storage_settings set; time_t set_mtime; + const char *config_file; const char *username; // FIXME: needed? struct ldap_connection *conn; From pigeonhole at rename-it.nl Sat Mar 14 17:22:45 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 14 Mar 2015 18:22:45 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: Added script metadata to bina... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/5506ad4315b9 changeset: 2012:5506ad4315b9 user: Stephan Bosch date: Sat Mar 14 18:20:22 2015 +0100 description: lib-sieve: Added script metadata to binary dump output. diffstat: src/lib-sieve/sieve-binary-dumper.c | 24 ++++++++++++- src/lib-sieve/sieve-script-private.h | 3 + src/lib-sieve/sieve-script.c | 44 ++++++++++++++++++++++++++ src/lib-sieve/sieve-script.h | 4 ++ src/lib-sieve/storage/dict/sieve-dict-script.c | 15 ++++++++ src/lib-sieve/storage/ldap/sieve-ldap-script.c | 19 +++++++++++ 6 files changed, 106 insertions(+), 3 deletions(-) diffs (238 lines): diff -r 0226882e55e1 -r 5506ad4315b9 src/lib-sieve/sieve-binary-dumper.c --- a/src/lib-sieve/sieve-binary-dumper.c Sat Mar 14 15:52:15 2015 +0100 +++ b/src/lib-sieve/sieve-binary-dumper.c Sat Mar 14 18:20:22 2015 +0100 @@ -10,6 +10,7 @@ #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-dump.h" +#include "sieve-script.h" #include "sieve-binary-private.h" @@ -96,12 +97,17 @@ (struct sieve_binary_dumper *dumper, struct ostream *stream, bool verbose) { struct sieve_binary *sbin = dumper->dumpenv.sbin; + struct sieve_script *script = sieve_binary_script(sbin); struct sieve_dumptime_env *denv = &(dumper->dumpenv); + struct sieve_binary_block *sblock; + bool success = TRUE; + sieve_size_t offset; int count, i; dumper->dumpenv.stream = stream; /* Dump list of binary blocks */ + if ( verbose ) { count = sieve_binary_block_count(sbin); @@ -117,6 +123,19 @@ } } + /* Dump script metadata */ + + sieve_binary_dump_sectionf + (denv, "Script metadata (block: %d)", SBIN_SYSBLOCK_SCRIPT_DATA); + sblock = sieve_binary_block_get(sbin, SBIN_SYSBLOCK_SCRIPT_DATA); + + T_BEGIN { + offset = 0; + success = sieve_script_binary_dump_metadata + (script, denv, sblock, &offset); + } T_END; + if ( !success ) return FALSE; + /* Dump list of used extensions */ count = sieve_binary_extensions_count(sbin); @@ -128,8 +147,7 @@ const struct sieve_extension *ext = sieve_binary_extension_get_by_index (sbin, i); - struct sieve_binary_block *sblock = sieve_binary_extension_get_block - (sbin, ext); + sblock = sieve_binary_extension_get_block(sbin, ext); if ( sblock == NULL ) { sieve_binary_dumpf(denv, "%3d: %s (id: %d)\n", @@ -147,7 +165,7 @@ count = sieve_binary_extensions_count(sbin); if ( count > 0 ) { for ( i = 0; i < count; i++ ) { - bool success = TRUE; + success = TRUE; T_BEGIN { const struct sieve_extension *ext = sieve_binary_extension_get_by_index diff -r 0226882e55e1 -r 5506ad4315b9 src/lib-sieve/sieve-script-private.h --- a/src/lib-sieve/sieve-script-private.h Sat Mar 14 15:52:15 2015 +0100 +++ b/src/lib-sieve/sieve-script-private.h Sat Mar 14 18:20:22 2015 +0100 @@ -27,6 +27,9 @@ sieve_size_t *offset); void (*binary_write_metadata) (struct sieve_script *script, struct sieve_binary_block *sblock); + int (*binary_dump_metadata) + (struct sieve_script *script, struct sieve_dumptime_env *denv, + struct sieve_binary_block *sblock, sieve_size_t *offset); struct sieve_binary *(*binary_load) (struct sieve_script *script, enum sieve_error *error_r); int (*binary_save) diff -r 0226882e55e1 -r 5506ad4315b9 src/lib-sieve/sieve-script.c --- a/src/lib-sieve/sieve-script.c Sat Mar 14 15:52:15 2015 +0100 +++ b/src/lib-sieve/sieve-script.c Sat Mar 14 18:20:22 2015 +0100 @@ -15,6 +15,7 @@ #include "sieve-limits.h" #include "sieve-settings.h" #include "sieve-error.h" +#include "sieve-dump.h" #include "sieve-binary.h" #include "sieve-storage-private.h" @@ -415,6 +416,49 @@ script->v.binary_write_metadata(script, sblock); } +bool sieve_script_binary_dump_metadata +(struct sieve_script *script, struct sieve_dumptime_env *denv, + struct sieve_binary_block *sblock, sieve_size_t *offset) +{ + struct sieve_binary *sbin = sieve_binary_block_get_binary(sblock); + struct sieve_instance *svinst = sieve_binary_svinst(sbin); + string_t *storage_class, *location; + struct sieve_script *adhoc_script = NULL; + unsigned int version; + bool result = TRUE; + + /* storage class */ + if ( !sieve_binary_read_string(sblock, offset, &storage_class) ) + return FALSE; + sieve_binary_dumpf(denv, "class = %s\n", str_c(storage_class)); + + /* version */ + if ( !sieve_binary_read_unsigned(sblock, offset, &version) ) + return FALSE; + sieve_binary_dumpf(denv, "class.version = %d\n", version); + + /* location */ + if ( !sieve_binary_read_string(sblock, offset, &location) ) + return FALSE; + sieve_binary_dumpf(denv, "location = %s\n", str_c(location)); + + if ( script == NULL ) { + script = adhoc_script = sieve_script_create + (svinst, str_c(location), NULL, NULL); + } + + if ( script != NULL ) { + if ( script->v.binary_dump_metadata == NULL ) + return TRUE; + + result = script->v.binary_dump_metadata(script, denv, sblock, offset); + } + + if ( adhoc_script != NULL ) + sieve_script_unref(&adhoc_script); + return result; +} + struct sieve_binary *sieve_script_binary_load (struct sieve_script *script, enum sieve_error *error_r) { diff -r 0226882e55e1 -r 5506ad4315b9 src/lib-sieve/sieve-script.h --- a/src/lib-sieve/sieve-script.h Sat Mar 14 15:52:15 2015 +0100 +++ b/src/lib-sieve/sieve-script.h Sat Mar 14 18:20:22 2015 +0100 @@ -67,6 +67,10 @@ sieve_size_t *offset); void sieve_script_binary_write_metadata (struct sieve_script *script, struct sieve_binary_block *sblock); +bool sieve_script_binary_dump_metadata + (struct sieve_script *script, struct sieve_dumptime_env *denv, + struct sieve_binary_block *sblock, sieve_size_t *offset) + ATTR_NULL(1); struct sieve_binary *sieve_script_binary_load (struct sieve_script *script, enum sieve_error *error_r); diff -r 0226882e55e1 -r 5506ad4315b9 src/lib-sieve/storage/dict/sieve-dict-script.c --- a/src/lib-sieve/storage/dict/sieve-dict-script.c Sat Mar 14 15:52:15 2015 +0100 +++ b/src/lib-sieve/storage/dict/sieve-dict-script.c Sat Mar 14 18:20:22 2015 +0100 @@ -9,6 +9,7 @@ #include "sieve-common.h" #include "sieve-error.h" +#include "sieve-dump.h" #include "sieve-binary.h" #include "sieve-dict-storage.h" @@ -181,6 +182,19 @@ sieve_binary_emit_cstring(sblock, dscript->data_id); } +static int sieve_dict_script_binary_dump_metadata +(struct sieve_script *script ATTR_UNUSED, struct sieve_dumptime_env *denv, + struct sieve_binary_block *sblock, sieve_size_t *offset) +{ + string_t *data_id; + + if ( !sieve_binary_read_string(sblock, offset, &data_id) ) + return FALSE; + sieve_binary_dumpf(denv, "dict.data_id = %s\n", str_c(data_id)); + + return TRUE; +} + static const char * sieve_dict_script_get_binpath (struct sieve_dict_script *dscript) { @@ -252,6 +266,7 @@ .binary_read_metadata =sieve_dict_script_binary_read_metadata, .binary_write_metadata = sieve_dict_script_binary_write_metadata, + .binary_dump_metadata = sieve_dict_script_binary_dump_metadata, .binary_load = sieve_dict_script_binary_load, .binary_save = sieve_dict_script_binary_save, diff -r 0226882e55e1 -r 5506ad4315b9 src/lib-sieve/storage/ldap/sieve-ldap-script.c --- a/src/lib-sieve/storage/ldap/sieve-ldap-script.c Sat Mar 14 15:52:15 2015 +0100 +++ b/src/lib-sieve/storage/ldap/sieve-ldap-script.c Sat Mar 14 18:20:22 2015 +0100 @@ -13,6 +13,7 @@ #include "strfuncs.h" #include "sieve-error.h" +#include "sieve-dump.h" #include "sieve-binary.h" /* @@ -208,6 +209,23 @@ sieve_binary_emit_cstring(sblock, lscript->modattr); } +static int sieve_ldap_script_binary_dump_metadata +(struct sieve_script *script ATTR_UNUSED, struct sieve_dumptime_env *denv, + struct sieve_binary_block *sblock, sieve_size_t *offset) +{ + string_t *dn, *modattr; + + if ( !sieve_binary_read_string(sblock, offset, &dn) ) + return FALSE; + sieve_binary_dumpf(denv, "ldap.dn = %s\n", str_c(dn)); + + if ( !sieve_binary_read_string(sblock, offset, &modattr) ) + return FALSE; + sieve_binary_dumpf(denv, "ldap.mod_attr = %s\n", str_c(modattr)); + + return TRUE; +} + static const char *sieve_ldap_script_get_binpath (struct sieve_ldap_script *lscript) { @@ -279,6 +297,7 @@ .binary_read_metadata = sieve_ldap_script_binary_read_metadata, .binary_write_metadata = sieve_ldap_script_binary_write_metadata, + .binary_dump_metadata = sieve_ldap_script_binary_dump_metadata, .binary_load = sieve_ldap_script_binary_load, .binary_save = sieve_ldap_script_binary_save, From pigeonhole at rename-it.nl Sat Mar 14 22:07:24 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 14 Mar 2015 23:07:24 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: file storage: Improved backwa... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/1b09618ca88d changeset: 2013:1b09618ca88d user: Stephan Bosch date: Sat Mar 14 23:06:37 2015 +0100 description: lib-sieve: file storage: Improved backwards compatibility with respect to the active script being a regular file. diffstat: src/lib-sieve/storage/file/sieve-file-storage.c | 103 ++++++++++++++--------- 1 files changed, 63 insertions(+), 40 deletions(-) diffs (171 lines): diff -r 5506ad4315b9 -r 1b09618ca88d src/lib-sieve/storage/file/sieve-file-storage.c --- a/src/lib-sieve/storage/file/sieve-file-storage.c Sat Mar 14 18:20:22 2015 +0100 +++ b/src/lib-sieve/storage/file/sieve-file-storage.c Sat Mar 14 23:06:37 2015 +0100 @@ -295,7 +295,8 @@ ATTR_NULL(2, 3) { struct sieve_storage *storage = &fstorage->storage; - const char *tmp_dir, *link_path, *active_fname; + const char *tmp_dir, *link_path, *active_fname, *storage_dir; + bool have_link = FALSE; int ret; fstorage->prev_mtime = (time_t)-1; @@ -351,43 +352,23 @@ /* Determine storage path */ - if (storage_path != NULL && *storage_path != '\0') { - if (t_realpath(storage_path, &storage_path) < 0) { - sieve_storage_sys_error(storage, - "Failed to normalize storage path (path=%s): %m", - active_path); + storage_dir = storage_path; + if ( storage_path != NULL && *storage_path != '\0' ) { + sieve_storage_sys_debug(storage, + "Using script storage path: %s", storage_path); + have_link = TRUE; + + } else { + if ((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0 ) { + sieve_storage_set_critical(storage, + "Storage path cannot be empty for write access"); *error_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } - sieve_storage_sys_debug(storage, - "Using script storage path: %s", storage_path); - - if ( active_path != NULL && *active_path != '\0' ) { - /* Get the path to be prefixed to the script name in the symlink pointing - * to the active script. - */ - link_path = sieve_storage_get_relative_link_path - (fstorage->active_path, storage_path); - - sieve_storage_sys_debug(storage, - "Relative path to sieve storage in active link: %s", - link_path); - - fstorage->link_path = p_strdup(storage->pool, link_path); - } - - } else if ((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0 ) { - sieve_storage_set_critical(storage, - "Storage path cannot be empty for write access"); - *error_r = SIEVE_ERROR_TEMP_FAILURE; - return -1; + storage_path = active_path; } - fstorage->path = ( storage_path != NULL ? - p_strdup(storage->pool, storage_path) : - p_strdup(storage->pool, active_path) ); - /* Prepare for write access */ if ( (storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0 ) { @@ -405,7 +386,7 @@ if ( exists ) { file_create_mode = (fstorage->st.st_mode & 0666) | 0600; dir_create_mode = (fstorage->st.st_mode & 0777) | 0700; - file_create_gid_origin = storage_path; + file_create_gid_origin = storage_dir; if ( !S_ISDIR(fstorage->st.st_mode) ) { /* We're getting permissions from a file. @@ -431,7 +412,7 @@ sieve_storage_sys_debug(storage, "Using permissions from %s: mode=0%o gid=%ld", - storage_path, (int)dir_create_mode, + file_create_gid_origin, (int)dir_create_mode, file_create_gid == (gid_t)-1 ? -1L : (long)file_create_gid); /* @@ -439,7 +420,7 @@ * This currently only consists of a ./tmp direcory */ - tmp_dir = t_strconcat(fstorage->path, "/tmp", NULL); + tmp_dir = t_strconcat(storage_path, "/tmp", NULL); /* Try to find and clean up tmp dir */ if ( (ret=check_tmp(storage, tmp_dir)) < 0 ) { @@ -460,9 +441,32 @@ } if ( !exists && sieve_file_storage_stat - (fstorage, fstorage->path, error_r) < 0 ) + (fstorage, storage_path, error_r) < 0 ) return -1; + if ( !have_link ) { + if ( t_realpath(storage_path, &storage_path) < 0 ) { + sieve_storage_sys_error(storage, + "Failed to normalize storage path (path=%s): %m", + storage_path); + *error_r = SIEVE_ERROR_TEMP_FAILURE; + return -1; + } + } else if ( active_path != NULL && *active_path != '\0' ) { + /* Get the path to be prefixed to the script name in the symlink + * pointing to the active script. + */ + link_path = sieve_storage_get_relative_link_path + (fstorage->active_path, storage_path); + + sieve_storage_sys_debug(storage, + "Relative path to sieve storage in active link: %s", + link_path); + + fstorage->link_path = p_strdup(storage->pool, link_path); + } + + fstorage->path = p_strdup(storage->pool, storage_path); storage->location = fstorage->path; return 0; @@ -504,10 +508,30 @@ /* Stat storage directory */ if ( storage_path != NULL && *storage_path != '\0' ) { - if ( sieve_file_storage_stat (fstorage, storage_path, error_r) < 0 ) { - if ( (*error_r != SIEVE_ERROR_NOT_FOUND) || - (storage->flags & SIEVE_STORAGE_FLAG_READWRITE) == 0 ) + if ( sieve_file_storage_stat(fstorage, storage_path, error_r) < 0 ) { + if ( *error_r != SIEVE_ERROR_NOT_FOUND ) return -1; + if ( (storage->flags & SIEVE_STORAGE_FLAG_READWRITE) == 0 ) { + /* For backwards compatibility, recognize when storage directory + does not exist while active script exists and is a regular + file. */ + if ( active_path == NULL || *active_path == '\0' ) + return -1; + if ( sieve_file_storage_get_full_active_path + (fstorage, &active_path, error_r) < 0 ) + return -1; + if ( sieve_file_storage_stat + (fstorage, active_path, error_r) < 0 ) + return -1; + if ( !S_ISREG(fstorage->lnk_st.st_mode) ) + return -1; + sieve_storage_sys_debug(storage, + "Sieve storage path `%s' not found, " + "but the active script `%s' is a regular file, " + "so this is used for backwards compatibility.", + storage_path, active_path); + storage_path = NULL; + } } else { exists = TRUE; @@ -527,7 +551,6 @@ } active_path = storage_path; storage_path = NULL; - } } } From pigeonhole at rename-it.nl Sat Mar 14 22:21:56 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 14 Mar 2015 23:21:56 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: file storage: Fixed handling ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/a99606c0f9bc changeset: 2014:a99606c0f9bc user: Stephan Bosch date: Sat Mar 14 23:21:06 2015 +0100 description: lib-sieve: file storage: Fixed handling of invalid active script link. The error status code wasn't set, so this was handled as an error rather than a warning in the LDA plugin. diffstat: src/lib-sieve/storage/file/sieve-file-storage-active.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 1b09618ca88d -r a99606c0f9bc src/lib-sieve/storage/file/sieve-file-storage-active.c --- a/src/lib-sieve/storage/file/sieve-file-storage-active.c Sat Mar 14 23:06:37 2015 +0100 +++ b/src/lib-sieve/storage/file/sieve-file-storage-active.c Sat Mar 14 23:21:06 2015 +0100 @@ -277,6 +277,8 @@ * ignore this situation and report 'no active script'. * Activation should fix this situation. */ + sieve_storage_set_error(storage, SIEVE_ERROR_NOT_FOUND, + "Active script is invalid"); return NULL; } From pigeonhole at rename-it.nl Sat Mar 14 23:06:01 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 15 Mar 2015 00:06:01 +0100 Subject: dovecot-2.2-pigeonhole: Added tag 0.4.7.rc2 for changeset fd050f... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/b3439a979c2e changeset: 2016:b3439a979c2e user: Stephan Bosch date: Sun Mar 15 00:05:39 2015 +0100 description: Added tag 0.4.7.rc2 for changeset fd050f466314 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r fd050f466314 -r b3439a979c2e .hgtags --- a/.hgtags Sun Mar 15 00:05:14 2015 +0100 +++ b/.hgtags Sun Mar 15 00:05:39 2015 +0100 @@ -24,3 +24,4 @@ f5e3ef477a32498584ac924963ff2e11c75cd477 0.4.5 99d796a8cd26f5f64d56b02c1f0e720ffd6131e7 0.4.6 27ad95fd05a039c39f7fec5d76bf28eac20362ce 0.4.7.rc1 +fd050f466314f911900027720dcafaa86e3cd537 0.4.7.rc2 From pigeonhole at rename-it.nl Sat Mar 14 23:06:01 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 15 Mar 2015 00:06:01 +0100 Subject: dovecot-2.2-pigeonhole: Released v0.4.7.rc2 for Dovecot v2.2.16. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/fd050f466314 changeset: 2015:fd050f466314 user: Stephan Bosch date: Sun Mar 15 00:05:14 2015 +0100 description: Released v0.4.7.rc2 for Dovecot v2.2.16. diffstat: NEWS | 14 +++++++++----- configure.ac | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diffs (42 lines): diff -r a99606c0f9bc -r fd050f466314 NEWS --- a/NEWS Sat Mar 14 23:21:06 2015 +0100 +++ b/NEWS Sun Mar 15 00:05:14 2015 +0100 @@ -11,20 +11,24 @@ + Implemented new sieve commands for the doveadm command line utility. These commands are currently limited to ManageSieve operations, but the other current sieve tools will be migrated to doveadm in the near future as well. - + Added more debug output to binary up-to-date checking. - - The Sieve interpreter now flushes duplicate database during start phase of - result execution rather than commit phase. This makes sure locks on the + + Added more debug output about binary up-to-date checking. + + Added script metadata to binary dump output. + - Fixed Sieve script binary up-to-date checking by normalizing the script + location. + - The Sieve interpreter now flushes the duplicate database during start phase + of result execution rather than commit phase. This makes sure locks on the duplicate database are released as soon as possible, preventing contention. - Performed a few optimizations in the lexical scanner of the language. - Fixed bug in `:matches' match-type that made a pattern without wildcards match as if there were a '*' at the beginning. - - file storage: Restructured storage initialization to address backwards - compatibility issues. - Fixed crash in validation of the string parameter of the comparator tag. - extprograms extension: Made sure supplemental group privileges are also dropped. This was a problem reported by Debian lintian. - Fixed bug in handling of binary errors for action side-effects and message overrides. + - file script storage: Restructured storage initialization to address backwards + compatibility issues. + - dict script storage: Fixed small memory allocation bug. v0.4.6 02-11-2014 Stephan Bosch diff -r a99606c0f9bc -r fd050f466314 configure.ac --- a/configure.ac Sat Mar 14 23:21:06 2015 +0100 +++ b/configure.ac Sun Mar 15 00:05:14 2015 +0100 @@ -1,4 +1,4 @@ -AC_INIT([Pigeonhole], [0.4.7.rc1], [dovecot at dovecot.org], [dovecot-2.2-pigeonhole]) +AC_INIT([Pigeonhole], [0.4.7.rc2], [dovecot at dovecot.org], [dovecot-2.2-pigeonhole]) AC_CONFIG_AUX_DIR([.]) AC_CONFIG_SRCDIR([src]) AC_CONFIG_MACRO_DIR([m4]) From pigeonhole at rename-it.nl Sat Mar 14 23:07:27 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 15 Mar 2015 00:07:27 +0100 Subject: dovecot-2.2-pigeonhole: Added signature for changeset b3439a979c2e Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/d6fb8945e4cd changeset: 2017:d6fb8945e4cd user: Stephan Bosch date: Sun Mar 15 00:07:20 2015 +0100 description: Added signature for changeset b3439a979c2e diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r b3439a979c2e -r d6fb8945e4cd .hgsigs --- a/.hgsigs Sun Mar 15 00:05:39 2015 +0100 +++ b/.hgsigs Sun Mar 15 00:07:20 2015 +0100 @@ -18,3 +18,4 @@ f5e3ef477a32498584ac924963ff2e11c75cd477 0 iQEcBAABAgAGBQJUUrtaAAoJEATWKx49+7T0C+AH+QGUi15egTON1XwJ0aZEuI3qQScDif04EoteSwjRN+RYFLSkMPnkjG+4kx0tAG2RahlZ9gdyr4TW5a95aQhAxYS7j0bbEyJNIAektYtVniWhuxxxo5m1LjNbI6yYIYjqAqnyfzI55E15tNT2O2VkUBxgExdWACMcv0YiMGidQ+7JVox1QFwFMrJPK17NiCsboByZN9J0xj4tg0hibkt2MZ1TaYj10TMmyYDxVvZPedwa71YRNz/T3T+reroqhUYqAL2XszSX+PSMwdcxyo8+qoErBQyacD4zNAcXhwUmhTjw2g4QtwSk1WK0FDC/BunIlb6ccFoZ6FpQhO/8lu74Wjc= 99d796a8cd26f5f64d56b02c1f0e720ffd6131e7 0 iQEcBAABAgAGBQJUVmtZAAoJEATWKx49+7T0/wgH/0GyApuqHfn/PtKhZUhX78wvZ5t6IdU7Rs905qC/j4Y1u5JRg3EhvXs/JJUDlDsJBAVU9EwQRi37erF+LPIm+1W9ZuNr4H4kgea2QM+lnEFhmmt7tqgXUhPnpufkPP1pfnyjDOq5oeMeA8i/Ecic9pdBIIY+YEU80knf0PbqFxGzpA4gbX2dXOPQlqs+9h0hEUjg8t8hUXtqxSkO2qoJIbWQIFqGaqXCUCnLQ4LZYxLOGMki3I8Nrjaa/objgDlH+bsNe2zGyUdICQgcyKc4ZeeZcEpnJBZvVhlhfzDlCaJIXxGmZjRF1lt382dvObNhlDEOi0NzapCwF0xE4WtOPIw= 27ad95fd05a039c39f7fec5d76bf28eac20362ce 0 iQEcBAABAgAGBQJU/lS3AAoJEATWKx49+7T0yJ8IAKsrq2CuRLRiH9YMPWJJzIwVTOudE+H14vUCkeR5/RAAyrBDkf9H3FKda8fTOIqhPoRKwoiKp7cMfTJfU28MkUAic/709bTAMwX+QHEr2g44dSZvRlAzh6CrOZSB/Q39FU8s67U9WDPoz9e0kluIuh7QeLwWdJSklSGw7cpDjAQ2wtFyCK4kSA44JNoTK2KnXiy+Pqu2GEZC5YrnBNuOGXJaX2eIIou8Udf2qnYwX+7UAp0Kgn+uveiY1AMdax/DC7+RSVFyneFHt0Fgx+ZvTLVZMLfLu/a9GDb4LV5gON1ZRYSg/LjQKzs243T1FwTT0Y6ujDvkgw1BoCYWjmvql/o= +b3439a979c2e30a066a463bf6add86e54f6ad02a 0 iQEcBAABAgAGBQJVBL8kAAoJEATWKx49+7T0bVcIAIEOsGJ46gWlPhCeoKAZrLZ+vXTFp2EBSEKWJZ3uQ7AlW/iTzfT3kdfUcs/qSrXBgfWrl3ttj/lMVznzxFlYsZSF9XpbyuBen3yJ26eKBdlfPVIzVhKMW5A8cWNtPuU0zDVlY+RYh5Z9n+s2uXWdIqG4qVKmbkCjN9JEOnGq0SSTajy2n5oP0kL4+5xNH0AZfWyZp5btsHCD/oCQaw0aCIqii4OmZWInNAwZ1TzapeN0TE3uR+dH9qr0eJxJpduGZu7JQ5GTBnKq3ithG62z+Q16L3bnajXPXe06dh8ibnN/f+cltYGq4tdwiiCL8ry5Poc9dUIIPae0zCnfWMbwwmc= From pigeonhole at rename-it.nl Sat Mar 14 23:18:53 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 15 Mar 2015 00:18:53 +0100 Subject: dovecot-2.2-pigeonhole: Added signature for changeset fd050f466314 Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/28710e1201e9 changeset: 2018:28710e1201e9 user: Stephan Bosch date: Sun Mar 15 00:15:54 2015 +0100 description: Added signature for changeset fd050f466314 Messed up the previous attempt. diffstat: .hgsigs | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (9 lines): diff -r d6fb8945e4cd -r 28710e1201e9 .hgsigs --- a/.hgsigs Sun Mar 15 00:07:20 2015 +0100 +++ b/.hgsigs Sun Mar 15 00:15:54 2015 +0100 @@ -18,4 +18,4 @@ f5e3ef477a32498584ac924963ff2e11c75cd477 0 iQEcBAABAgAGBQJUUrtaAAoJEATWKx49+7T0C+AH+QGUi15egTON1XwJ0aZEuI3qQScDif04EoteSwjRN+RYFLSkMPnkjG+4kx0tAG2RahlZ9gdyr4TW5a95aQhAxYS7j0bbEyJNIAektYtVniWhuxxxo5m1LjNbI6yYIYjqAqnyfzI55E15tNT2O2VkUBxgExdWACMcv0YiMGidQ+7JVox1QFwFMrJPK17NiCsboByZN9J0xj4tg0hibkt2MZ1TaYj10TMmyYDxVvZPedwa71YRNz/T3T+reroqhUYqAL2XszSX+PSMwdcxyo8+qoErBQyacD4zNAcXhwUmhTjw2g4QtwSk1WK0FDC/BunIlb6ccFoZ6FpQhO/8lu74Wjc= 99d796a8cd26f5f64d56b02c1f0e720ffd6131e7 0 iQEcBAABAgAGBQJUVmtZAAoJEATWKx49+7T0/wgH/0GyApuqHfn/PtKhZUhX78wvZ5t6IdU7Rs905qC/j4Y1u5JRg3EhvXs/JJUDlDsJBAVU9EwQRi37erF+LPIm+1W9ZuNr4H4kgea2QM+lnEFhmmt7tqgXUhPnpufkPP1pfnyjDOq5oeMeA8i/Ecic9pdBIIY+YEU80knf0PbqFxGzpA4gbX2dXOPQlqs+9h0hEUjg8t8hUXtqxSkO2qoJIbWQIFqGaqXCUCnLQ4LZYxLOGMki3I8Nrjaa/objgDlH+bsNe2zGyUdICQgcyKc4ZeeZcEpnJBZvVhlhfzDlCaJIXxGmZjRF1lt382dvObNhlDEOi0NzapCwF0xE4WtOPIw= 27ad95fd05a039c39f7fec5d76bf28eac20362ce 0 iQEcBAABAgAGBQJU/lS3AAoJEATWKx49+7T0yJ8IAKsrq2CuRLRiH9YMPWJJzIwVTOudE+H14vUCkeR5/RAAyrBDkf9H3FKda8fTOIqhPoRKwoiKp7cMfTJfU28MkUAic/709bTAMwX+QHEr2g44dSZvRlAzh6CrOZSB/Q39FU8s67U9WDPoz9e0kluIuh7QeLwWdJSklSGw7cpDjAQ2wtFyCK4kSA44JNoTK2KnXiy+Pqu2GEZC5YrnBNuOGXJaX2eIIou8Udf2qnYwX+7UAp0Kgn+uveiY1AMdax/DC7+RSVFyneFHt0Fgx+ZvTLVZMLfLu/a9GDb4LV5gON1ZRYSg/LjQKzs243T1FwTT0Y6ujDvkgw1BoCYWjmvql/o= -b3439a979c2e30a066a463bf6add86e54f6ad02a 0 iQEcBAABAgAGBQJVBL8kAAoJEATWKx49+7T0bVcIAIEOsGJ46gWlPhCeoKAZrLZ+vXTFp2EBSEKWJZ3uQ7AlW/iTzfT3kdfUcs/qSrXBgfWrl3ttj/lMVznzxFlYsZSF9XpbyuBen3yJ26eKBdlfPVIzVhKMW5A8cWNtPuU0zDVlY+RYh5Z9n+s2uXWdIqG4qVKmbkCjN9JEOnGq0SSTajy2n5oP0kL4+5xNH0AZfWyZp5btsHCD/oCQaw0aCIqii4OmZWInNAwZ1TzapeN0TE3uR+dH9qr0eJxJpduGZu7JQ5GTBnKq3ithG62z+Q16L3bnajXPXe06dh8ibnN/f+cltYGq4tdwiiCL8ry5Poc9dUIIPae0zCnfWMbwwmc= +fd050f466314f911900027720dcafaa86e3cd537 0 iQEcBAABAgAGBQJVBMEkAAoJEATWKx49+7T0RcMH/2Hyfa0M7oBB0M8gY9jVtGoIXC2U37+crLduKSEsJWkchW2/SkuTLbxbVPb4oBXbJJOiDVNVVvjhHefqxbVDJlWVdcTz8hdZam0Wl2LKX4OlvpsLBiCil/gNoQSCABd5Q4zUCa18mBU9PIltlG61IgTxXtz0A5IiCI7N34l3FAwkxSvaCUVR82y5M7dTat7OEDOpVVUIucf9DPrLcGwTFJ/TuOxiI9lH/MKrbRVeOyrs+3hNAzcArBfvvMy7cVyUV85u8EqgFIL6V5mrp4YNOgkuqvvdTDThs14w1GV1ILl9Y4ycUzYDDqqbXnfK/j5mvTNSelnV/JBZC+moJozptmI= From dovecot at dovecot.org Mon Mar 16 11:54:51 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Mar 2015 11:54:51 +0000 Subject: dovecot-2.2: stats: Initial stats refresh timeout callback wasn'... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d88af513a942 changeset: 18352:d88af513a942 user: Timo Sirainen date: Mon Mar 16 13:53:54 2015 +0200 description: stats: Initial stats refresh timeout callback wasn't set. This broke after the ioloop change that caused stats_io_deactivate() not to be called immediately anymore. diffstat: src/plugins/stats/stats-plugin.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r b4dbe64c0032 -r d88af513a942 src/plugins/stats/stats-plugin.c --- a/src/plugins/stats/stats-plugin.c Fri Mar 13 20:08:34 2015 +0200 +++ b/src/plugins/stats/stats-plugin.c Mon Mar 16 13:53:54 2015 +0200 @@ -432,6 +432,9 @@ MODULE_CONTEXT_SET(user, stats_user_module, suser); stats_connection_connect(suser->stats_conn, user); + suser->to_stats_timeout = + timeout_add(suser->refresh_secs*1000, + session_stats_refresh_timeout, user); } static struct mail_storage_hooks stats_mail_storage_hooks = { From dovecot at dovecot.org Mon Mar 16 11:55:42 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Mar 2015 11:55:42 +0000 Subject: dovecot-2.2: stats: Don't allow stats_refresh setting to be set ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3d8a054a93a9 changeset: 18353:3d8a054a93a9 user: Timo Sirainen date: Mon Mar 16 13:54:50 2015 +0200 description: stats: Don't allow stats_refresh setting to be set too large. diffstat: src/plugins/stats/stats-plugin.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r d88af513a942 -r 3d8a054a93a9 src/plugins/stats/stats-plugin.c --- a/src/plugins/stats/stats-plugin.c Mon Mar 16 13:53:54 2015 +0200 +++ b/src/plugins/stats/stats-plugin.c Mon Mar 16 13:54:50 2015 +0200 @@ -375,6 +375,11 @@ } if (refresh_secs == 0) return; + if (refresh_secs > SESSION_STATS_FORCE_REFRESH_SECS) { + i_warning("stats: stats_refresh too large, changing to %u", + SESSION_STATS_FORCE_REFRESH_SECS); + refresh_secs = SESSION_STATS_FORCE_REFRESH_SECS; + } if (global_stats_conn == NULL) { path = t_strconcat(user->set->base_dir, From dovecot at dovecot.org Mon Mar 16 20:47:07 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Mar 2015 20:47:07 +0000 Subject: dovecot-2.2: auth ldap: Include LDAP config path in all fatal er... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fe05443b3cd6 changeset: 18354:fe05443b3cd6 user: Timo Sirainen date: Mon Mar 16 22:46:16 2015 +0200 description: auth ldap: Include LDAP config path in all fatal errors. Also moved all such error checks to db_ldap_init(). diffstat: src/auth/db-ldap.c | 28 +++++++++++++++++----------- 1 files changed, 17 insertions(+), 11 deletions(-) diffs (70 lines): diff -r 3d8a054a93a9 -r fe05443b3cd6 src/auth/db-ldap.c --- a/src/auth/db-ldap.c Mon Mar 16 13:54:50 2015 +0200 +++ b/src/auth/db-ldap.c Mon Mar 16 22:46:16 2015 +0200 @@ -1139,8 +1139,7 @@ if (ldap_initialize(&conn->ld, conn->set.uris) != LDAP_SUCCESS) conn->ld = NULL; #else - i_fatal("LDAP: Your LDAP library doesn't support " - "'uris' setting, use 'hosts' instead."); + i_unreached(); /* already checked at init */ #endif } else conn->ld = ldap_init(conn->set.hosts, LDAP_PORT); @@ -1167,8 +1166,7 @@ return -1; } #else - i_error("LDAP: Your LDAP library doesn't support TLS"); - return -1; + i_unreached(); /* already checked at init */ #endif } @@ -1191,7 +1189,7 @@ if (db_ldap_connect_finish(conn, ret) < 0) return -1; #else - i_fatal("LDAP: sasl_bind=yes but no SASL support compiled in"); + i_unreached(); /* already checked at init */ #endif conn->conn_state = LDAP_CONN_STATE_BOUND_DEFAULT; } else { @@ -1777,23 +1775,31 @@ i_fatal("ldap %s: %s", config_path, error); if (conn->set.base == NULL) - i_fatal("LDAP: No base given"); + i_fatal("LDAP %s: No base given", config_path); if (conn->set.uris == NULL && conn->set.hosts == NULL) - i_fatal("LDAP: No uris or hosts set"); + i_fatal("LDAP %s: No uris or hosts set", config_path); #ifndef LDAP_HAVE_INITIALIZE if (conn->set.uris != NULL) { - i_fatal("LDAP: Dovecot compiled without support for LDAP uris " - "(ldap_initialize not found)"); + i_fatal("LDAP %s: uris set, but Dovecot compiled without support for LDAP uris " + "(ldap_initialize() not supported by LDAP library)", config_path); } #endif +#ifndef LDAP_HAVE_START_TLS_S + if (conn->set.tls) + i_fatal("LDAP %s: tls=yes, but your LDAP library doesn't support TLS", config_path); +#endif +#ifndef HAVE_LDAP_SASL + if (conn->set.sasl_bind) + i_fatal("LDAP: sasl_bind=yes but no SASL support compiled in"); +#endif if (*conn->set.ldaprc_path != '\0') { str = getenv("LDAPRC"); if (str != NULL && strcmp(str, conn->set.ldaprc_path) != 0) { - i_fatal("LDAP: Multiple different ldaprc_path " + i_fatal("LDAP %s: Multiple different ldaprc_path " "settings not allowed (%s and %s)", - str, conn->set.ldaprc_path); + config_path, str, conn->set.ldaprc_path); } env_put(t_strconcat("LDAPRC=", conn->set.ldaprc_path, NULL)); } From dovecot at dovecot.org Mon Mar 16 20:49:30 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Mar 2015 20:49:30 +0000 Subject: dovecot-2.2: auth ldap: Improved ldap_initialize() failure's err... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8c77d80e014c changeset: 18355:8c77d80e014c user: Timo Sirainen date: Mon Mar 16 22:48:39 2015 +0200 description: auth ldap: Improved ldap_initialize() failure's error logging. diffstat: src/auth/db-ldap.c | 18 +++++++++++------- 1 files changed, 11 insertions(+), 7 deletions(-) diffs (33 lines): diff -r fe05443b3cd6 -r 8c77d80e014c src/auth/db-ldap.c --- a/src/auth/db-ldap.c Mon Mar 16 22:46:16 2015 +0200 +++ b/src/auth/db-ldap.c Mon Mar 16 22:48:39 2015 +0200 @@ -1136,18 +1136,22 @@ if (conn->ld == NULL) { if (conn->set.uris != NULL) { #ifdef LDAP_HAVE_INITIALIZE - if (ldap_initialize(&conn->ld, conn->set.uris) != LDAP_SUCCESS) + ret = ldap_initialize(&conn->ld, conn->set.uris); + if (ret != LDAP_SUCCESS) { + i_fatal("LDAP: ldap_initialize() failed with uris %s: %s", + conn->set.uris, ldap_err2string(ret)); conn->ld = NULL; + } #else i_unreached(); /* already checked at init */ #endif - } else + } else { conn->ld = ldap_init(conn->set.hosts, LDAP_PORT); - - if (conn->ld == NULL) - i_fatal("LDAP: ldap_init() failed with hosts: %s", - conn->set.hosts); - + if (conn->ld == NULL) { + i_fatal("LDAP: ldap_init() failed with hosts: %s", + conn->set.hosts); + } + } db_ldap_set_options(conn); } From dovecot at dovecot.org Mon Mar 16 20:56:37 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Mar 2015 20:56:37 +0000 Subject: dovecot-2.2: auth ldap: Moved more LDAP fatal checks to db_ldap_... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/226d34f3a54a changeset: 18356:226d34f3a54a user: Timo Sirainen date: Mon Mar 16 22:55:47 2015 +0200 description: auth ldap: Moved more LDAP fatal checks to db_ldap_init() diffstat: src/auth/db-ldap.c | 13 ++++++------- 1 files changed, 6 insertions(+), 7 deletions(-) diffs (30 lines): diff -r 8c77d80e014c -r 226d34f3a54a src/auth/db-ldap.c --- a/src/auth/db-ldap.c Mon Mar 16 22:48:39 2015 +0200 +++ b/src/auth/db-ldap.c Mon Mar 16 22:55:47 2015 +0200 @@ -1106,13 +1106,6 @@ } #endif - if (conn->set.ldap_version < 3) { - if (conn->set.sasl_bind) - i_fatal("LDAP: sasl_bind=yes requires ldap_version=3"); - if (conn->set.tls) - i_fatal("LDAP: tls=yes requires ldap_version=3"); - } - ldap_version = conn->set.ldap_version; db_ldap_set_opt(conn, LDAP_OPT_PROTOCOL_VERSION, &ldap_version, "protocol_version", dec2str(ldap_version)); @@ -1797,6 +1790,12 @@ if (conn->set.sasl_bind) i_fatal("LDAP: sasl_bind=yes but no SASL support compiled in"); #endif + if (conn->set.ldap_version < 3) { + if (conn->set.sasl_bind) + i_fatal("LDAP %s: sasl_bind=yes requires ldap_version=3", config_path); + if (conn->set.tls) + i_fatal("LDAP %s: tls=yes requires ldap_version=3", config_path); + } if (*conn->set.ldaprc_path != '\0') { str = getenv("LDAPRC"); From dovecot at dovecot.org Mon Mar 16 21:04:01 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Mar 2015 21:04:01 +0000 Subject: dovecot-2.2: auth ldap: More concentration of i_fatal() calls to... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b3fd99432298 changeset: 18357:b3fd99432298 user: Timo Sirainen date: Mon Mar 16 23:03:10 2015 +0200 description: auth ldap: More concentration of i_fatal() calls to db_ldap_init() diffstat: src/auth/db-ldap.c | 80 +++++++++++++++++++++++++++++++---------------------- src/auth/db-ldap.h | 2 +- 2 files changed, 47 insertions(+), 35 deletions(-) diffs (134 lines): diff -r 226d34f3a54a -r b3fd99432298 src/auth/db-ldap.c --- a/src/auth/db-ldap.c Mon Mar 16 22:55:47 2015 +0200 +++ b/src/auth/db-ldap.c Mon Mar 16 23:03:10 2015 +0200 @@ -170,47 +170,50 @@ LDAPMessage *res, bool skip_null_values, bool iter_dn_values); -static int deref2str(const char *str) +static int deref2str(const char *str, int *ref_r) { if (strcasecmp(str, "never") == 0) - return LDAP_DEREF_NEVER; - if (strcasecmp(str, "searching") == 0) - return LDAP_DEREF_SEARCHING; - if (strcasecmp(str, "finding") == 0) - return LDAP_DEREF_FINDING; - if (strcasecmp(str, "always") == 0) - return LDAP_DEREF_ALWAYS; - - i_fatal("LDAP: Unknown deref option '%s'", str); + *ref_r = LDAP_DEREF_NEVER; + else if (strcasecmp(str, "searching") == 0) + *ref_r = LDAP_DEREF_SEARCHING; + else if (strcasecmp(str, "finding") == 0) + *ref_r = LDAP_DEREF_FINDING; + else if (strcasecmp(str, "always") == 0) + *ref_r = LDAP_DEREF_ALWAYS; + else + return -1; + return 0; } -static int scope2str(const char *str) +static int scope2str(const char *str, int *scope_r) { if (strcasecmp(str, "base") == 0) - return LDAP_SCOPE_BASE; - if (strcasecmp(str, "onelevel") == 0) - return LDAP_SCOPE_ONELEVEL; - if (strcasecmp(str, "subtree") == 0) - return LDAP_SCOPE_SUBTREE; - - i_fatal("LDAP: Unknown scope option '%s'", str); + *scope_r = LDAP_SCOPE_BASE; + else if (strcasecmp(str, "onelevel") == 0) + *scope_r = LDAP_SCOPE_ONELEVEL; + else if (strcasecmp(str, "subtree") == 0) + *scope_r = LDAP_SCOPE_SUBTREE; + else + return -1; + return 0; } #ifdef OPENLDAP_TLS_OPTIONS -static int tls_require_cert2str(const char *str) +static int tls_require_cert2str(const char *str, int *value_r) { if (strcasecmp(str, "never") == 0) - return LDAP_OPT_X_TLS_NEVER; - if (strcasecmp(str, "hard") == 0) - return LDAP_OPT_X_TLS_HARD; - if (strcasecmp(str, "demand") == 0) - return LDAP_OPT_X_TLS_DEMAND; - if (strcasecmp(str, "allow") == 0) - return LDAP_OPT_X_TLS_ALLOW; - if (strcasecmp(str, "try") == 0) - return LDAP_OPT_X_TLS_TRY; - - i_fatal("LDAP: Unknown tls_require_cert value '%s'", str); + *value_r = LDAP_OPT_X_TLS_NEVER; + else if (strcasecmp(str, "hard") == 0) + *value_r = LDAP_OPT_X_TLS_HARD; + else if (strcasecmp(str, "demand") == 0) + *value_r = LDAP_OPT_X_TLS_DEMAND; + else if (strcasecmp(str, "allow") == 0) + *value_r = LDAP_OPT_X_TLS_ALLOW; + else if (strcasecmp(str, "try") == 0) + *value_r = LDAP_OPT_X_TLS_TRY; + else + return -1; + return 0; } #endif @@ -1076,8 +1079,7 @@ db_ldap_set_opt_str(NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, conn->set.tls_cipher_suite, "tls_cipher_suite"); if (conn->set.tls_require_cert != NULL) { - int value = tls_require_cert2str(conn->set.tls_require_cert); - db_ldap_set_opt(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &value, + db_ldap_set_opt(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &conn->set.ldap_tls_require_cert_parsed, "tls_require_cert", conn->set.tls_require_cert); } #else @@ -1796,6 +1798,14 @@ if (conn->set.tls) i_fatal("LDAP %s: tls=yes requires ldap_version=3", config_path); } +#ifdef OPENLDAP_TLS_OPTIONS + if (conn->set.tls_require_cert != NULL) { + if (tls_require_cert2str(conn->set.tls_require_cert, + &conn->set.ldap_tls_require_cert_parsed) < 0) + i_fatal("LDAP %s: Unknown tls_require_cert value '%s'", + config_path, conn->set.tls_require_cert); + } +#endif if (*conn->set.ldaprc_path != '\0') { str = getenv("LDAPRC"); @@ -1807,8 +1817,10 @@ env_put(t_strconcat("LDAPRC=", conn->set.ldaprc_path, NULL)); } - conn->set.ldap_deref = deref2str(conn->set.deref); - conn->set.ldap_scope = scope2str(conn->set.scope); + if (deref2str(conn->set.deref, &conn->set.ldap_deref) < 0) + i_fatal("LDAP %s: Unknown deref option '%s'", config_path, conn->set.deref); + if (scope2str(conn->set.scope, &conn->set.ldap_scope) < 0) + i_fatal("LDAP %s: Unknown scope option '%s'", config_path, conn->set.scope); i_array_init(&conn->request_array, 512); conn->request_queue = aqueue_init(&conn->request_array.arr); diff -r 226d34f3a54a -r b3fd99432298 src/auth/db-ldap.h --- a/src/auth/db-ldap.h Mon Mar 16 22:55:47 2015 +0200 +++ b/src/auth/db-ldap.h Mon Mar 16 23:03:10 2015 +0200 @@ -67,7 +67,7 @@ bool blocking; /* ... */ - int ldap_deref, ldap_scope; + int ldap_deref, ldap_scope, ldap_tls_require_cert_parsed; uid_t uid; gid_t gid; }; From pigeonhole at rename-it.nl Mon Mar 16 21:10:02 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Mon, 16 Mar 2015 22:10:02 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: file storage: Fixed bug in st... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/07e25d04d8f2 changeset: 2019:07e25d04d8f2 user: Stephan Bosch date: Mon Mar 16 22:09:55 2015 +0100 description: lib-sieve: file storage: Fixed bug in storage path normalization. A conditional expression was inverted, causing the path to remain unnormalized. diffstat: src/lib-sieve/storage/file/sieve-file-storage.c | 23 ++++++++++++----------- 1 files changed, 12 insertions(+), 11 deletions(-) diffs (42 lines): diff -r 28710e1201e9 -r 07e25d04d8f2 src/lib-sieve/storage/file/sieve-file-storage.c --- a/src/lib-sieve/storage/file/sieve-file-storage.c Sun Mar 15 00:15:54 2015 +0100 +++ b/src/lib-sieve/storage/file/sieve-file-storage.c Mon Mar 16 22:09:55 2015 +0100 @@ -444,7 +444,7 @@ (fstorage, storage_path, error_r) < 0 ) return -1; - if ( !have_link ) { + if ( have_link ) { if ( t_realpath(storage_path, &storage_path) < 0 ) { sieve_storage_sys_error(storage, "Failed to normalize storage path (path=%s): %m", @@ -452,18 +452,19 @@ *error_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } - } else if ( active_path != NULL && *active_path != '\0' ) { - /* Get the path to be prefixed to the script name in the symlink - * pointing to the active script. - */ - link_path = sieve_storage_get_relative_link_path - (fstorage->active_path, storage_path); + if ( active_path != NULL && *active_path != '\0' ) { + /* Get the path to be prefixed to the script name in the symlink + * pointing to the active script. + */ + link_path = sieve_storage_get_relative_link_path + (fstorage->active_path, storage_path); - sieve_storage_sys_debug(storage, - "Relative path to sieve storage in active link: %s", - link_path); + sieve_storage_sys_debug(storage, + "Relative path to sieve storage in active link: %s", + link_path); - fstorage->link_path = p_strdup(storage->pool, link_path); + fstorage->link_path = p_strdup(storage->pool, link_path); + } } fstorage->path = p_strdup(storage->pool, storage_path); From dovecot at dovecot.org Mon Mar 16 21:15:40 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Mar 2015 21:15:40 +0000 Subject: dovecot-2.2: auth ldap: Call ldap_init*() already at db_ldap_ini... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/804dc641f448 changeset: 18358:804dc641f448 user: Timo Sirainen date: Mon Mar 16 23:14:49 2015 +0200 description: auth ldap: Call ldap_init*() already at db_ldap_init(). ldap_init*() doesn't start connecting yet, but this way we can verify that all the settings are correct. diffstat: src/auth/db-ldap.c | 49 ++++++++++++++++++++++++++++--------------------- 1 files changed, 28 insertions(+), 21 deletions(-) diffs (73 lines): diff -r b3fd99432298 -r 804dc641f448 src/auth/db-ldap.c --- a/src/auth/db-ldap.c Mon Mar 16 23:03:10 2015 +0200 +++ b/src/auth/db-ldap.c Mon Mar 16 23:14:49 2015 +0200 @@ -1114,6 +1114,30 @@ db_ldap_set_tls_options(conn); } +static void db_ldap_init_ld(struct ldap_connection *conn) +{ + int ret; + + if (conn->set.uris != NULL) { +#ifdef LDAP_HAVE_INITIALIZE + ret = ldap_initialize(&conn->ld, conn->set.uris); + if (ret != LDAP_SUCCESS) { + i_fatal("LDAP: ldap_initialize() failed with uris %s: %s", + conn->set.uris, ldap_err2string(ret)); + } +#else + i_unreached(); /* already checked at init */ +#endif + } else { + conn->ld = ldap_init(conn->set.hosts, LDAP_PORT); + if (conn->ld == NULL) { + i_fatal("LDAP: ldap_init() failed with hosts: %s", + conn->set.hosts); + } + } + db_ldap_set_options(conn); +} + int db_ldap_connect(struct ldap_connection *conn) { bool debug = atoi(conn->set.debug_level) > 0; @@ -1128,27 +1152,8 @@ memset(&start, 0, sizeof(start)); } i_assert(conn->pending_count == 0); - if (conn->ld == NULL) { - if (conn->set.uris != NULL) { -#ifdef LDAP_HAVE_INITIALIZE - ret = ldap_initialize(&conn->ld, conn->set.uris); - if (ret != LDAP_SUCCESS) { - i_fatal("LDAP: ldap_initialize() failed with uris %s: %s", - conn->set.uris, ldap_err2string(ret)); - conn->ld = NULL; - } -#else - i_unreached(); /* already checked at init */ -#endif - } else { - conn->ld = ldap_init(conn->set.hosts, LDAP_PORT); - if (conn->ld == NULL) { - i_fatal("LDAP: ldap_init() failed with hosts: %s", - conn->set.hosts); - } - } - db_ldap_set_options(conn); - } + if (conn->ld == NULL) + db_ldap_init_ld(conn); if (conn->set.tls) { #ifdef LDAP_HAVE_START_TLS_S @@ -1827,6 +1832,8 @@ conn->next = ldap_connections; ldap_connections = conn; + + db_ldap_init_ld(conn); return conn; } From dovecot at dovecot.org Mon Mar 16 21:18:29 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Mar 2015 21:18:29 +0000 Subject: dovecot-2.2: auth ldap: If any tls_* settings are given when the... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ec2e7ae958c5 changeset: 18359:ec2e7ae958c5 user: Timo Sirainen date: Mon Mar 16 23:17:39 2015 +0200 description: auth ldap: If any tls_* settings are given when they're not supported, fail with fatal instead of just warning. These may be important for intended security, especially tls_cipher_suite. We shouldn't allow setting them and then somewhat silently just ignore them. diffstat: src/auth/db-ldap.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diffs (17 lines): diff -r 804dc641f448 -r ec2e7ae958c5 src/auth/db-ldap.c --- a/src/auth/db-ldap.c Mon Mar 16 23:14:49 2015 +0200 +++ b/src/auth/db-ldap.c Mon Mar 16 23:17:39 2015 +0200 @@ -1087,9 +1087,10 @@ conn->set.tls_ca_cert_dir != NULL || conn->set.tls_cert_file != NULL || conn->set.tls_key_file != NULL || - conn->set.tls_cipher_suite != NULL) - i_warning("LDAP: tls_* settings ignored, " - "your LDAP library doesn't seem to support them"); + conn->set.tls_cipher_suite != NULL) { + i_fatal("LDAP %s: tls_* settings aren't supported by your LDAP library - they must not be set", + conn->config_path); + } #endif } From dovecot at dovecot.org Mon Mar 16 21:21:55 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Mar 2015 21:21:55 +0000 Subject: dovecot-2.2: auth ldap: Make sure config file path is included i... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d9a0d4f4f4b6 changeset: 18360:d9a0d4f4f4b6 user: Timo Sirainen date: Mon Mar 16 23:21:05 2015 +0200 description: auth ldap: Make sure config file path is included in all fatal error messages. diffstat: src/auth/db-ldap.c | 36 +++++++++++++++++++----------------- 1 files changed, 19 insertions(+), 17 deletions(-) diffs (99 lines): diff -r ec2e7ae958c5 -r d9a0d4f4f4b6 src/auth/db-ldap.c --- a/src/auth/db-ldap.c Mon Mar 16 23:17:39 2015 +0200 +++ b/src/auth/db-ldap.c Mon Mar 16 23:21:05 2015 +0200 @@ -989,7 +989,8 @@ { i_assert(conn->conn_state == LDAP_CONN_STATE_BINDING); - i_error("LDAP: Initial binding to LDAP server timed out"); + i_error("LDAP %s: Initial binding to LDAP server timed out", + conn->config_path); db_ldap_conn_close(conn); } @@ -1029,13 +1030,13 @@ /* get the connection's fd */ ret = ldap_get_option(conn->ld, LDAP_OPT_DESC, (void *)&conn->fd); if (ret != LDAP_SUCCESS) { - i_fatal("LDAP: Can't get connection fd: %s", - ldap_err2string(ret)); + i_fatal("LDAP %s: Can't get connection fd: %s", + conn->config_path, ldap_err2string(ret)); } if (conn->fd <= STDERR_FILENO) { /* Solaris LDAP library seems to be broken */ - i_fatal("LDAP: Buggy LDAP library returned wrong fd: %d", - conn->fd); + i_fatal("LDAP %s: Buggy LDAP library returned wrong fd: %d", + conn->config_path, conn->fd); } i_assert(conn->fd != -1); net_set_nonblock(conn->fd, TRUE); @@ -1049,8 +1050,8 @@ ret = ldap_set_option(conn == NULL ? NULL : conn->ld, opt, value); if (ret != LDAP_SUCCESS) { - i_fatal("LDAP: Can't set option %s to %s: %s", - optname, value_str, ldap_err2string(ret)); + i_fatal("LDAP %s: Can't set option %s to %s: %s", + conn->config_path, optname, value_str, ldap_err2string(ret)); } } @@ -1123,8 +1124,9 @@ #ifdef LDAP_HAVE_INITIALIZE ret = ldap_initialize(&conn->ld, conn->set.uris); if (ret != LDAP_SUCCESS) { - i_fatal("LDAP: ldap_initialize() failed with uris %s: %s", - conn->set.uris, ldap_err2string(ret)); + i_fatal("LDAP %s: ldap_initialize() failed with uris %s: %s", + conn->config_path, conn->set.uris, + ldap_err2string(ret)); } #else i_unreached(); /* already checked at init */ @@ -1132,8 +1134,8 @@ } else { conn->ld = ldap_init(conn->set.hosts, LDAP_PORT); if (conn->ld == NULL) { - i_fatal("LDAP: ldap_init() failed with hosts: %s", - conn->set.hosts); + i_fatal("LDAP %s: ldap_init() failed with hosts: %s", + conn->config_path, conn->set.hosts); } } db_ldap_set_options(conn); @@ -1163,11 +1165,11 @@ if (ret == LDAP_OPERATIONS_ERROR && conn->set.uris != NULL && strncmp(conn->set.uris, "ldaps:", 6) == 0) { - i_fatal("LDAP: Don't use both tls=yes " - "and ldaps URI"); + i_fatal("LDAP %s: Don't use both tls=yes " + "and ldaps URI", conn->config_path); } - i_error("LDAP: ldap_start_tls_s() failed: %s", - ldap_err2string(ret)); + i_error("LDAP %s: ldap_start_tls_s() failed: %s", + conn->config_path, ldap_err2string(ret)); return -1; } #else @@ -1358,7 +1360,7 @@ } if (*name == '\0') - i_error("ldap: Invalid attrs entry: %s", attr_data); + i_error("LDAP %s: Invalid attrs entry: %s", conn->config_path, attr_data); else if (skip_attr == NULL || strcmp(skip_attr, name) != 0) { field = array_append_space(attr_map); if (name[0] == '@') { @@ -1796,7 +1798,7 @@ #endif #ifndef HAVE_LDAP_SASL if (conn->set.sasl_bind) - i_fatal("LDAP: sasl_bind=yes but no SASL support compiled in"); + i_fatal("LDAP %s: sasl_bind=yes but no SASL support compiled in", conn->config_path); #endif if (conn->set.ldap_version < 3) { if (conn->set.sasl_bind) From dovecot at dovecot.org Mon Mar 16 21:26:24 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Mar 2015 21:26:24 +0000 Subject: dovecot-2.2: auth ldap: Start LDAP connection only after auth pr... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0a17875f0ece changeset: 18361:0a17875f0ece user: Timo Sirainen date: Mon Mar 16 23:25:34 2015 +0200 description: auth ldap: Start LDAP connection only after auth process initialization is finished. This way even if connecting to LDAP takes a while it won't cause the master process to kill the auth process due to it not sending the startup "I'm ok" notification early enough. diffstat: src/auth/db-ldap.c | 15 +++++++++++++++ src/auth/db-ldap.h | 1 + src/auth/passdb-ldap.c | 2 +- src/auth/userdb-ldap.c | 2 +- 4 files changed, 18 insertions(+), 2 deletions(-) diffs (67 lines): diff -r d9a0d4f4f4b6 -r 0a17875f0ece src/auth/db-ldap.c --- a/src/auth/db-ldap.c Mon Mar 16 23:21:05 2015 +0200 +++ b/src/auth/db-ldap.c Mon Mar 16 23:25:34 2015 +0200 @@ -1155,6 +1155,8 @@ memset(&start, 0, sizeof(start)); } i_assert(conn->pending_count == 0); + if (conn->to != NULL) + timeout_remove(&conn->to); if (conn->ld == NULL) db_ldap_init_ld(conn); @@ -1215,6 +1217,19 @@ return 0; } +static void db_ldap_connect_callback(struct ldap_connection *conn) +{ + timeout_remove(&conn->to); + (void)db_ldap_connect(conn); +} + +void db_ldap_connect_delayed(struct ldap_connection *conn) +{ + i_assert(conn->to == NULL); + + conn->to = timeout_add_short(0, db_ldap_connect_callback, conn); +} + void db_ldap_enable_input(struct ldap_connection *conn, bool enable) { if (!enable) { diff -r d9a0d4f4f4b6 -r 0a17875f0ece src/auth/db-ldap.h --- a/src/auth/db-ldap.h Mon Mar 16 23:21:05 2015 +0200 +++ b/src/auth/db-ldap.h Mon Mar 16 23:25:34 2015 +0200 @@ -190,6 +190,7 @@ void db_ldap_unref(struct ldap_connection **conn); int db_ldap_connect(struct ldap_connection *conn); +void db_ldap_connect_delayed(struct ldap_connection *conn); void db_ldap_enable_input(struct ldap_connection *conn, bool enable); diff -r d9a0d4f4f4b6 -r 0a17875f0ece src/auth/passdb-ldap.c --- a/src/auth/passdb-ldap.c Mon Mar 16 23:21:05 2015 +0200 +++ b/src/auth/passdb-ldap.c Mon Mar 16 23:25:34 2015 +0200 @@ -449,7 +449,7 @@ struct ldap_passdb_module *module = (struct ldap_passdb_module *)_module; - (void)db_ldap_connect(module->conn); + db_ldap_connect_delayed(module->conn); } static void passdb_ldap_deinit(struct passdb_module *_module) diff -r d9a0d4f4f4b6 -r 0a17875f0ece src/auth/userdb-ldap.c --- a/src/auth/userdb-ldap.c Mon Mar 16 23:21:05 2015 +0200 +++ b/src/auth/userdb-ldap.c Mon Mar 16 23:25:34 2015 +0200 @@ -285,7 +285,7 @@ struct ldap_userdb_module *module = (struct ldap_userdb_module *)_module; - (void)db_ldap_connect(module->conn); + db_ldap_connect_delayed(module->conn); } static void userdb_ldap_deinit(struct userdb_module *_module) From pigeonhole at rename-it.nl Mon Mar 16 21:28:10 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Mon, 16 Mar 2015 22:28:10 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: file storage: Fixed bug that ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/cf8007c9a74f changeset: 2020:cf8007c9a74f user: Stephan Bosch date: Mon Mar 16 22:27:17 2015 +0100 description: lib-sieve: file storage: Fixed bug that caused missing active symlink to cause a temporary error in some cases. diffstat: src/lib-sieve/storage/file/sieve-file-storage.c | 19 +++++++++++++------ 1 files changed, 13 insertions(+), 6 deletions(-) diffs (30 lines): diff -r 07e25d04d8f2 -r cf8007c9a74f src/lib-sieve/storage/file/sieve-file-storage.c --- a/src/lib-sieve/storage/file/sieve-file-storage.c Mon Mar 16 22:09:55 2015 +0100 +++ b/src/lib-sieve/storage/file/sieve-file-storage.c Mon Mar 16 22:27:17 2015 +0100 @@ -333,13 +333,20 @@ } if (t_realpath(active_dir, &active_dir) < 0) { - sieve_storage_sys_error(storage, - "Failed to normalize active script directory (path=%s): %m", - active_dir); - *error_r = SIEVE_ERROR_TEMP_FAILURE; - return -1; + if (errno != ENOENT) { + sieve_storage_sys_error(storage, + "Failed to normalize active script directory (path=%s): %m", + active_dir); + *error_r = SIEVE_ERROR_TEMP_FAILURE; + return -1; + } + sieve_storage_sys_debug(storage, + "Failed to normalize active script directory (path=%s): " + "Part of the path does not exist (yet)", + active_dir); + } else { + active_path = t_abspath_to(active_fname, active_dir); } - active_path = t_abspath_to(active_fname, active_dir); sieve_storage_sys_debug(storage, "Using %sSieve script path: %s", From pigeonhole at rename-it.nl Tue Mar 17 01:29:49 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 17 Mar 2015 02:29:49 +0100 Subject: dovecot-2.2-pigeonhole: Added tag 0.4.7.rc3 for changeset 87b2d3... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/f15f765b07de changeset: 2022:f15f765b07de user: Stephan Bosch date: Tue Mar 17 02:29:33 2015 +0100 description: Added tag 0.4.7.rc3 for changeset 87b2d3e43a44 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 87b2d3e43a44 -r f15f765b07de .hgtags --- a/.hgtags Tue Mar 17 02:29:22 2015 +0100 +++ b/.hgtags Tue Mar 17 02:29:33 2015 +0100 @@ -25,3 +25,4 @@ 99d796a8cd26f5f64d56b02c1f0e720ffd6131e7 0.4.6 27ad95fd05a039c39f7fec5d76bf28eac20362ce 0.4.7.rc1 fd050f466314f911900027720dcafaa86e3cd537 0.4.7.rc2 +87b2d3e43a447f000b06ce1ee1ab73456c7357b3 0.4.7.rc3 From pigeonhole at rename-it.nl Tue Mar 17 01:29:49 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 17 Mar 2015 02:29:49 +0100 Subject: dovecot-2.2-pigeonhole: Released v0.4.7.rc3 for Dovecot v2.2.16. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/87b2d3e43a44 changeset: 2021:87b2d3e43a44 user: Stephan Bosch date: Tue Mar 17 02:29:22 2015 +0100 description: Released v0.4.7.rc3 for Dovecot v2.2.16. diffstat: NEWS | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diffs (23 lines): diff -r cf8007c9a74f -r 87b2d3e43a44 NEWS --- a/NEWS Mon Mar 16 22:27:17 2015 +0100 +++ b/NEWS Tue Mar 17 02:29:22 2015 +0100 @@ -26,8 +26,8 @@ dropped. This was a problem reported by Debian lintian. - Fixed bug in handling of binary errors for action side-effects and message overrides. - - file script storage: Restructured storage initialization to address backwards - compatibility issues. + - file script storage: Restructured storage initialization to address + backwards compatibility issues. - dict script storage: Fixed small memory allocation bug. v0.4.6 02-11-2014 Stephan Bosch diff -r cf8007c9a74f -r 87b2d3e43a44 configure.ac --- a/configure.ac Mon Mar 16 22:27:17 2015 +0100 +++ b/configure.ac Tue Mar 17 02:29:22 2015 +0100 @@ -1,4 +1,4 @@ -AC_INIT([Pigeonhole], [0.4.7.rc2], [dovecot at dovecot.org], [dovecot-2.2-pigeonhole]) +AC_INIT([Pigeonhole], [0.4.7.rc3], [dovecot at dovecot.org], [dovecot-2.2-pigeonhole]) AC_CONFIG_AUX_DIR([.]) AC_CONFIG_SRCDIR([src]) AC_CONFIG_MACRO_DIR([m4]) From pigeonhole at rename-it.nl Tue Mar 17 01:31:50 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 17 Mar 2015 02:31:50 +0100 Subject: dovecot-2.2-pigeonhole: Added signature for changeset 87b2d3e43a44 Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/579a43f2dd0f changeset: 2023:579a43f2dd0f user: Stephan Bosch date: Tue Mar 17 02:31:57 2015 +0100 description: Added signature for changeset 87b2d3e43a44 diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r f15f765b07de -r 579a43f2dd0f .hgsigs --- a/.hgsigs Tue Mar 17 02:29:33 2015 +0100 +++ b/.hgsigs Tue Mar 17 02:31:57 2015 +0100 @@ -19,3 +19,4 @@ 99d796a8cd26f5f64d56b02c1f0e720ffd6131e7 0 iQEcBAABAgAGBQJUVmtZAAoJEATWKx49+7T0/wgH/0GyApuqHfn/PtKhZUhX78wvZ5t6IdU7Rs905qC/j4Y1u5JRg3EhvXs/JJUDlDsJBAVU9EwQRi37erF+LPIm+1W9ZuNr4H4kgea2QM+lnEFhmmt7tqgXUhPnpufkPP1pfnyjDOq5oeMeA8i/Ecic9pdBIIY+YEU80knf0PbqFxGzpA4gbX2dXOPQlqs+9h0hEUjg8t8hUXtqxSkO2qoJIbWQIFqGaqXCUCnLQ4LZYxLOGMki3I8Nrjaa/objgDlH+bsNe2zGyUdICQgcyKc4ZeeZcEpnJBZvVhlhfzDlCaJIXxGmZjRF1lt382dvObNhlDEOi0NzapCwF0xE4WtOPIw= 27ad95fd05a039c39f7fec5d76bf28eac20362ce 0 iQEcBAABAgAGBQJU/lS3AAoJEATWKx49+7T0yJ8IAKsrq2CuRLRiH9YMPWJJzIwVTOudE+H14vUCkeR5/RAAyrBDkf9H3FKda8fTOIqhPoRKwoiKp7cMfTJfU28MkUAic/709bTAMwX+QHEr2g44dSZvRlAzh6CrOZSB/Q39FU8s67U9WDPoz9e0kluIuh7QeLwWdJSklSGw7cpDjAQ2wtFyCK4kSA44JNoTK2KnXiy+Pqu2GEZC5YrnBNuOGXJaX2eIIou8Udf2qnYwX+7UAp0Kgn+uveiY1AMdax/DC7+RSVFyneFHt0Fgx+ZvTLVZMLfLu/a9GDb4LV5gON1ZRYSg/LjQKzs243T1FwTT0Y6ujDvkgw1BoCYWjmvql/o= fd050f466314f911900027720dcafaa86e3cd537 0 iQEcBAABAgAGBQJVBMEkAAoJEATWKx49+7T0RcMH/2Hyfa0M7oBB0M8gY9jVtGoIXC2U37+crLduKSEsJWkchW2/SkuTLbxbVPb4oBXbJJOiDVNVVvjhHefqxbVDJlWVdcTz8hdZam0Wl2LKX4OlvpsLBiCil/gNoQSCABd5Q4zUCa18mBU9PIltlG61IgTxXtz0A5IiCI7N34l3FAwkxSvaCUVR82y5M7dTat7OEDOpVVUIucf9DPrLcGwTFJ/TuOxiI9lH/MKrbRVeOyrs+3hNAzcArBfvvMy7cVyUV85u8EqgFIL6V5mrp4YNOgkuqvvdTDThs14w1GV1ILl9Y4ycUzYDDqqbXnfK/j5mvTNSelnV/JBZC+moJozptmI= +87b2d3e43a447f000b06ce1ee1ab73456c7357b3 0 iQEcBAABAgAGBQJVB4QIAAoJEATWKx49+7T0MKcH/0Wg6xazPO9Q3v8rYZe4PFSlWoXv4P8ixy275pouHyLWKDltg2zVPq3ieDNLkOfNiQvBClWppQa5LPzgTN/9x5MmIYU/IpdXCKvl8i9G3qzRaGUL1oMtp3JocI8JyKx3R61V8u4VyJ+qBg0kLCs85ilNdo1ia9uFCYbZh7QOnM5FHJAsGzDPEriZyrcf3D/CTGDedYfoELEJXpSzW19Ov1qPIq501mBfrxXSd/MTUFkm8DExYW7i/YTBEsJNn58y1tsdC6FxuP8bZJRQlS/4PRR5euACxKpEV38Ig7b22a6P/MoZphCvZkIMBIxIB9RIEIljRyXSKESvssgUoA/v1Q8= From dovecot at dovecot.org Tue Mar 17 07:59:07 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 17 Mar 2015 07:59:07 +0000 Subject: dovecot-2.2: auth ldap: Fixed assert-crash when both passdb ldap... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/870cb73e5960 changeset: 18362:870cb73e5960 user: Timo Sirainen date: Tue Mar 17 09:58:03 2015 +0200 description: auth ldap: Fixed assert-crash when both passdb ldap and userdb ldap was used diffstat: src/auth/db-ldap.c | 10 ++++++++-- src/auth/db-ldap.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diffs (40 lines): diff -r 0a17875f0ece -r 870cb73e5960 src/auth/db-ldap.c --- a/src/auth/db-ldap.c Mon Mar 16 23:25:34 2015 +0200 +++ b/src/auth/db-ldap.c Tue Mar 17 09:58:03 2015 +0200 @@ -1155,8 +1155,11 @@ memset(&start, 0, sizeof(start)); } i_assert(conn->pending_count == 0); - if (conn->to != NULL) + + if (conn->delayed_connect) { + conn->delayed_connect = FALSE; timeout_remove(&conn->to); + } if (conn->ld == NULL) db_ldap_init_ld(conn); @@ -1225,8 +1228,11 @@ void db_ldap_connect_delayed(struct ldap_connection *conn) { + if (conn->delayed_connect) + return; + conn->delayed_connect = TRUE; + i_assert(conn->to == NULL); - conn->to = timeout_add_short(0, db_ldap_connect_callback, conn); } diff -r 0a17875f0ece -r 870cb73e5960 src/auth/db-ldap.h --- a/src/auth/db-ldap.h Mon Mar 16 23:25:34 2015 +0200 +++ b/src/auth/db-ldap.h Tue Mar 17 09:58:03 2015 +0200 @@ -176,6 +176,7 @@ char **pass_attr_names, **user_attr_names, **iterate_attr_names; ARRAY_TYPE(ldap_field) pass_attr_map, user_attr_map, iterate_attr_map; bool userdb_used; + bool delayed_connect; }; /* Send/queue request */ From dovecot at dovecot.org Tue Mar 17 08:50:12 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 17 Mar 2015 08:50:12 +0000 Subject: dovecot-2.2: auth ldap: Fixed crash when handling invalid SSL op... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a4acf88b0c91 changeset: 18363:a4acf88b0c91 user: Timo Sirainen date: Tue Mar 17 10:49:20 2015 +0200 description: auth ldap: Fixed crash when handling invalid SSL option. diffstat: src/auth/db-ldap.c | 30 +++++++++++++++--------------- 1 files changed, 15 insertions(+), 15 deletions(-) diffs (81 lines): diff -r 870cb73e5960 -r a4acf88b0c91 src/auth/db-ldap.c --- a/src/auth/db-ldap.c Tue Mar 17 09:58:03 2015 +0200 +++ b/src/auth/db-ldap.c Tue Mar 17 10:49:20 2015 +0200 @@ -1043,12 +1043,12 @@ } static void ATTR_NULL(1) -db_ldap_set_opt(struct ldap_connection *conn, int opt, const void *value, - const char *optname, const char *value_str) +db_ldap_set_opt(struct ldap_connection *conn, LDAP *ld, int opt, + const void *value, const char *optname, const char *value_str) { int ret; - ret = ldap_set_option(conn == NULL ? NULL : conn->ld, opt, value); + ret = ldap_set_option(ld, opt, value); if (ret != LDAP_SUCCESS) { i_fatal("LDAP %s: Can't set option %s to %s: %s", conn->config_path, optname, value_str, ldap_err2string(ret)); @@ -1056,11 +1056,11 @@ } static void ATTR_NULL(1) -db_ldap_set_opt_str(struct ldap_connection *conn, int opt, const char *value, - const char *optname) +db_ldap_set_opt_str(struct ldap_connection *conn, LDAP *ld, int opt, + const char *value, const char *optname) { if (value != NULL) - db_ldap_set_opt(conn, opt, value, optname, value); + db_ldap_set_opt(conn, ld, opt, value, optname, value); } static void db_ldap_set_tls_options(struct ldap_connection *conn) @@ -1069,18 +1069,18 @@ return; #ifdef OPENLDAP_TLS_OPTIONS - db_ldap_set_opt_str(NULL, LDAP_OPT_X_TLS_CACERTFILE, + db_ldap_set_opt_str(conn, NULL, LDAP_OPT_X_TLS_CACERTFILE, conn->set.tls_ca_cert_file, "tls_ca_cert_file"); - db_ldap_set_opt_str(NULL, LDAP_OPT_X_TLS_CACERTDIR, + db_ldap_set_opt_str(conn, NULL, LDAP_OPT_X_TLS_CACERTDIR, conn->set.tls_ca_cert_dir, "tls_ca_cert_dir"); - db_ldap_set_opt_str(NULL, LDAP_OPT_X_TLS_CERTFILE, + db_ldap_set_opt_str(conn, NULL, LDAP_OPT_X_TLS_CERTFILE, conn->set.tls_cert_file, "tls_cert_file"); - db_ldap_set_opt_str(NULL, LDAP_OPT_X_TLS_KEYFILE, + db_ldap_set_opt_str(conn, NULL, LDAP_OPT_X_TLS_KEYFILE, conn->set.tls_key_file, "tls_key_file"); - db_ldap_set_opt_str(NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, + db_ldap_set_opt_str(conn, NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, conn->set.tls_cipher_suite, "tls_cipher_suite"); if (conn->set.tls_require_cert != NULL) { - db_ldap_set_opt(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &conn->set.ldap_tls_require_cert_parsed, + db_ldap_set_opt(conn, NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &conn->set.ldap_tls_require_cert_parsed, "tls_require_cert", conn->set.tls_require_cert); } #else @@ -1100,18 +1100,18 @@ unsigned int ldap_version; int value; - db_ldap_set_opt(conn, LDAP_OPT_DEREF, &conn->set.ldap_deref, + db_ldap_set_opt(conn, conn->ld, LDAP_OPT_DEREF, &conn->set.ldap_deref, "deref", conn->set.deref); #ifdef LDAP_OPT_DEBUG_LEVEL value = atoi(conn->set.debug_level); if (value != 0) { - db_ldap_set_opt(NULL, LDAP_OPT_DEBUG_LEVEL, &value, + db_ldap_set_opt(conn, NULL, LDAP_OPT_DEBUG_LEVEL, &value, "debug_level", conn->set.debug_level); } #endif ldap_version = conn->set.ldap_version; - db_ldap_set_opt(conn, LDAP_OPT_PROTOCOL_VERSION, &ldap_version, + db_ldap_set_opt(conn, conn->ld, LDAP_OPT_PROTOCOL_VERSION, &ldap_version, "protocol_version", dec2str(ldap_version)); db_ldap_set_tls_options(conn); } From dovecot at dovecot.org Tue Mar 17 15:31:27 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 17 Mar 2015 15:31:27 +0000 Subject: dovecot-2.2: auth ldap: Crashfixes for earlier changes. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3546457ae3fb changeset: 18364:3546457ae3fb user: Timo Sirainen date: Tue Mar 17 17:30:33 2015 +0200 description: auth ldap: Crashfixes for earlier changes. Hopefully works correctly now diffstat: src/auth/db-ldap.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (20 lines): diff -r a4acf88b0c91 -r 3546457ae3fb src/auth/db-ldap.c --- a/src/auth/db-ldap.c Tue Mar 17 10:49:20 2015 +0200 +++ b/src/auth/db-ldap.c Tue Mar 17 17:30:33 2015 +0200 @@ -1222,7 +1222,7 @@ static void db_ldap_connect_callback(struct ldap_connection *conn) { - timeout_remove(&conn->to); + i_assert(conn->conn_state == LDAP_CONN_STATE_DISCONNECTED); (void)db_ldap_connect(conn); } @@ -1267,6 +1267,7 @@ unsigned int i; conn->conn_state = LDAP_CONN_STATE_DISCONNECTED; + conn->delayed_connect = FALSE; conn->default_bind_msgid = -1; if (conn->to != NULL) From dovecot at dovecot.org Wed Mar 18 11:44:28 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 18 Mar 2015 11:44:28 +0000 Subject: dovecot-2.2: fts: Fixed assert-crash if fts-parser was created f... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/128115b3807c changeset: 18365:128115b3807c user: Timo Sirainen date: Wed Mar 18 13:43:35 2015 +0200 description: fts: Fixed assert-crash if fts-parser was created for a body part that backend didn't want to index. diffstat: src/plugins/fts/fts-build-mail.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diffs (17 lines): diff -r 3546457ae3fb -r 128115b3807c src/plugins/fts/fts-build-mail.c --- a/src/plugins/fts/fts-build-mail.c Tue Mar 17 17:30:33 2015 +0200 +++ b/src/plugins/fts/fts-build-mail.c Wed Mar 18 13:43:35 2015 +0200 @@ -184,7 +184,12 @@ } key.body_content_type = content_type; key.body_content_disposition = ctx->content_disposition; - return fts_backend_update_set_build_key(ctx->update_ctx, &key); + if (!fts_backend_update_set_build_key(ctx->update_ctx, &key)) { + if (ctx->body_parser != NULL) + (void)fts_parser_deinit(&ctx->body_parser); + return FALSE; + } + return TRUE; } static int fts_build_body_block(struct fts_mail_build_context *ctx, From dovecot at dovecot.org Wed Mar 18 15:11:17 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 18 Mar 2015 15:11:17 +0000 Subject: dovecot-2.2: lib: bits - Add macro for '1 << i' Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/305f5c2cf13e changeset: 18366:305f5c2cf13e user: Phil Carmody date: Wed Mar 18 17:09:30 2015 +0200 description: lib: bits - Add macro for '1 << i' It's used all over the place. It feels weird not having access to such a macro. Signed-off-by: Phil Carmody diffstat: src/lib/bits.h | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 128115b3807c -r 305f5c2cf13e src/lib/bits.h --- a/src/lib/bits.h Wed Mar 18 13:43:35 2015 +0200 +++ b/src/lib/bits.h Wed Mar 18 17:09:30 2015 +0200 @@ -15,6 +15,8 @@ #define UINT64_SUM_OVERFLOWS(a, b) \ (a > (uint64_t)-1 - b) +#define BIT(n) (1u << (n)) + size_t nearest_power(size_t num) ATTR_CONST; unsigned int bits_required8(uint8_t num) ATTR_CONST; From dovecot at dovecot.org Wed Mar 18 15:11:17 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 18 Mar 2015 15:11:17 +0000 Subject: dovecot-2.2: lib: bits - improve bits_required to recurse downwa... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/30953774f034 changeset: 18367:30953774f034 user: Phil Carmody date: Wed Mar 18 17:10:03 2015 +0200 description: lib: bits - improve bits_required to recurse downwards, not sideways Ooops. Signed-off-by: Phil Carmody diffstat: src/lib/bits.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 305f5c2cf13e -r 30953774f034 src/lib/bits.h --- a/src/lib/bits.h Wed Mar 18 17:09:30 2015 +0200 +++ b/src/lib/bits.h Wed Mar 18 17:10:03 2015 +0200 @@ -25,7 +25,7 @@ unsigned int bits_required16(uint16_t num) { return (num <= 0xff) ? bits_required8(num) - : 8 + bits_required16(num >> 8); + : 8 + bits_required8(num >> 8); } static inline unsigned int bits_required32(uint32_t num) From dovecot at dovecot.org Wed Mar 18 15:11:22 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 18 Mar 2015 15:11:22 +0000 Subject: dovecot-2.2: lib: buffer - paranoid compile-time check for struc... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3ed51d56e2a3 changeset: 18368:3ed51d56e2a3 user: Phil Carmody date: Wed Mar 18 17:10:23 2015 +0200 description: lib: buffer - paranoid compile-time check for struct sizes At the moment, nothing guarantees that the public struct is big enough to contain the private struct. Signed-off-by: Phil Carmody diffstat: src/lib/buffer.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 30953774f034 -r 3ed51d56e2a3 src/lib/buffer.c --- a/src/lib/buffer.c Wed Mar 18 17:10:03 2015 +0200 +++ b/src/lib/buffer.c Wed Mar 18 17:10:23 2015 +0200 @@ -19,6 +19,7 @@ unsigned int alloced:1; unsigned int dynamic:1; }; +typedef int buffer_check_sizes[COMPILE_ERROR_IF_TRUE(sizeof(struct real_buffer) > sizeof(buffer_t)) ?1:1]; static void buffer_alloc(struct real_buffer *buf, size_t size) { From dovecot at dovecot.org Wed Mar 18 23:25:26 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 18 Mar 2015 23:25:26 +0000 Subject: dovecot-2.2: lib-storage: mailbox_list_mailbox() now copies the ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fca7232724dd changeset: 18369:fca7232724dd user: Timo Sirainen date: Thu Mar 19 00:32:44 2015 +0200 description: lib-storage: mailbox_list_mailbox() now copies the mailbox_exists() error. Instead of assuming it has to be an internal error. diffstat: src/lib-storage/mailbox-list.c | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-) diffs (26 lines): diff -r 3ed51d56e2a3 -r fca7232724dd src/lib-storage/mailbox-list.c --- a/src/lib-storage/mailbox-list.c Wed Mar 18 17:10:23 2015 +0200 +++ b/src/lib-storage/mailbox-list.c Thu Mar 19 00:32:44 2015 +0200 @@ -1417,12 +1417,18 @@ list=Maildir++ (for indexes), but list->ns->list=imapc */ box = mailbox_alloc(list->ns->list, "INBOX", 0); ret = mailbox_exists(box, FALSE, &existence); + if (ret < 0) { + const char *errstr; + enum mail_error error; + + /* internal error or with imapc we can get here with + login failures */ + errstr = mailbox_get_last_error(box, &error); + mailbox_list_set_error(list, error, errstr); + } mailbox_free(&box); - if (ret < 0) { - /* this can only be an internal error */ - mailbox_list_set_internal_error(list); + if (ret < 0) return -1; - } switch (existence) { case MAILBOX_EXISTENCE_NONE: case MAILBOX_EXISTENCE_NOSELECT: From dovecot at dovecot.org Wed Mar 18 23:25:26 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 18 Mar 2015 23:25:26 +0000 Subject: dovecot-2.2: imapc: If authentication fails, preserve the error ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b28de884c470 changeset: 18370:b28de884c470 user: Timo Sirainen date: Thu Mar 19 00:38:01 2015 +0200 description: imapc: If authentication fails, preserve the error message as storage/list error. This isn't very helpful yet, because the mailbox list creation itself fails. diffstat: src/lib-storage/index/imapc/imapc-list.c | 6 +++++ src/lib-storage/index/imapc/imapc-storage.c | 32 ++++++++++++++++++++++++++++- src/lib-storage/index/imapc/imapc-storage.h | 2 + 3 files changed, 39 insertions(+), 1 deletions(-) diffs (112 lines): diff -r fca7232724dd -r b28de884c470 src/lib-storage/index/imapc/imapc-list.c --- a/src/lib-storage/index/imapc/imapc-list.c Thu Mar 19 00:32:44 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-list.c Thu Mar 19 00:38:01 2015 +0200 @@ -140,6 +140,8 @@ imapc_list_copy_error_from_reply(ctx->client->_list, MAIL_ERROR_PARAMS, reply); ctx->ret = -1; + } else if (ctx->client->auth_failed) { + ctx->ret = -1; } else { mailbox_list_set_critical(&ctx->client->_list->list, "imapc: Command failed: %s", reply->text_full); @@ -270,6 +272,8 @@ imapc_list_sep_verify(list); else if (reply->state == IMAPC_COMMAND_STATE_NO) imapc_list_copy_error_from_reply(list, MAIL_ERROR_PARAMS, reply); + else if (list->client->auth_failed) + ; else if (!list->list.ns->user->deinitializing) { mailbox_list_set_critical(&list->list, "imapc: Command failed: %s", reply->text_full); @@ -293,6 +297,8 @@ int imapc_list_try_get_root_sep(struct imapc_mailbox_list *list, char *sep_r) { if (list->root_sep == '\0') { + if (list->client->auth_failed) + return -1; imapc_list_send_hierarcy_sep_lookup(list); while (list->root_sep_pending) imapc_client_run(list->client->client); diff -r fca7232724dd -r b28de884c470 src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Thu Mar 19 00:32:44 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-storage.c Thu Mar 19 00:38:01 2015 +0200 @@ -110,6 +110,10 @@ void imapc_simple_run(struct imapc_simple_context *sctx) { + if (sctx->client->auth_failed) { + imapc_client_disconnect(sctx->client->client); + sctx->ret = -1; + } while (sctx->ret == -2) imapc_client_run(sctx->client->client); } @@ -138,6 +142,8 @@ imapc_copy_error_from_reply(ctx->client->_storage, MAIL_ERROR_PARAMS, reply); ctx->ret = -1; + } else if (ctx->client->auth_failed) { + ctx->ret = -1; } else { mail_storage_set_critical(&ctx->client->_storage->storage, "imapc: Command failed: %s", reply->text_full); @@ -193,6 +199,28 @@ } } +static void +imapc_storage_client_login(const struct imapc_command_reply *reply, + void *context) +{ + struct imapc_storage_client *client = context; + + if (reply->state == IMAPC_COMMAND_STATE_OK) + return; + + i_error("imapc: Authentication failed: %s", reply->text_full); + client->auth_failed = TRUE; + + if (client->_storage != NULL) { + mail_storage_set_error(&client->_storage->storage, + MAIL_ERROR_PERM, reply->text_full); + } + if (client->_list != NULL) { + mailbox_list_set_error(&client->_list->list, + MAIL_ERROR_PERM, reply->text_full); + } +} + int imapc_storage_client_create(struct mail_namespace *ns, const struct imapc_settings *imapc_set, const struct mail_storage_settings *mail_set, @@ -257,7 +285,7 @@ imapc_client_register_untagged(client->client, imapc_storage_client_untagged_cb, client); /* start logging in immediately */ - imapc_client_login(client->client, NULL, NULL); + imapc_client_login(client->client, imapc_storage_client_login, client); *client_r = client; return 0; @@ -449,6 +477,8 @@ imapc_copy_error_from_reply(ctx->mbox->storage, MAIL_ERROR_NOTFOUND, reply); ctx->ret = -1; + } else if (ctx->mbox->storage->client->auth_failed) { + ctx->ret = -1; } else { mail_storage_set_critical(ctx->mbox->box.storage, "imapc: Opening mailbox '%s' failed: %s", diff -r fca7232724dd -r b28de884c470 src/lib-storage/index/imapc/imapc-storage.h --- a/src/lib-storage/index/imapc/imapc-storage.h Thu Mar 19 00:32:44 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-storage.h Thu Mar 19 00:38:01 2015 +0200 @@ -50,6 +50,8 @@ struct imapc_client *client; ARRAY(struct imapc_storage_event_callback) untagged_callbacks; + + unsigned int auth_failed:1; }; struct imapc_storage { From dovecot at dovecot.org Wed Mar 18 23:25:27 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 18 Mar 2015 23:25:27 +0000 Subject: dovecot-2.2: dsync: Use storage's mail_error to choose the dovea... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b900b50085fc changeset: 18371:b900b50085fc user: Timo Sirainen date: Thu Mar 19 00:41:19 2015 +0200 description: dsync: Use storage's mail_error to choose the doveadm exit code. Instead of always assuming that all errors are EX_TEMPFAIL. diffstat: src/doveadm/doveadm-dsync.c | 28 ++++++--- src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c | 24 +++++--- src/doveadm/dsync/dsync-brain-mailbox-tree.c | 10 ++- src/doveadm/dsync/dsync-brain-mailbox.c | 57 ++++++++++++-------- src/doveadm/dsync/dsync-brain-mails.c | 11 ++- src/doveadm/dsync/dsync-brain-private.h | 8 ++- src/doveadm/dsync/dsync-brain.c | 16 ++++- src/doveadm/dsync/dsync-brain.h | 3 +- src/doveadm/dsync/dsync-ibc-pipe.c | 17 ++++- src/doveadm/dsync/dsync-ibc-private.h | 6 +- src/doveadm/dsync/dsync-ibc-stream.c | 21 ++++++- src/doveadm/dsync/dsync-ibc.c | 10 ++- src/doveadm/dsync/dsync-ibc.h | 7 +- src/doveadm/dsync/dsync-mailbox-export.c | 30 +++++++-- src/doveadm/dsync/dsync-mailbox-export.h | 2 +- src/doveadm/dsync/dsync-mailbox-import.c | 64 ++++++++++++++++------ src/doveadm/dsync/dsync-mailbox-import.h | 5 +- src/doveadm/dsync/dsync-mailbox-tree-fill.c | 34 +++++++---- src/doveadm/dsync/dsync-mailbox-tree.h | 4 +- 19 files changed, 245 insertions(+), 112 deletions(-) diffs (truncated from 1291 to 300 lines): diff -r b28de884c470 -r b900b50085fc src/doveadm/doveadm-dsync.c --- a/src/doveadm/doveadm-dsync.c Thu Mar 19 00:38:01 2015 +0200 +++ b/src/doveadm/doveadm-dsync.c Thu Mar 19 00:41:19 2015 +0200 @@ -322,7 +322,7 @@ static int cmd_dsync_run_local(struct dsync_cmd_context *ctx, struct mail_user *user, struct dsync_brain *brain, struct dsync_ibc *ibc2, - bool *changes_during_sync_r) + bool *changes_during_sync_r, enum mail_error *mail_error_r) { struct dsync_brain *brain2; struct mail_user *user2; @@ -331,6 +331,8 @@ bool brain1_running, brain2_running, changed1, changed2; int ret; + *mail_error_r = 0; + if (ctx->local_location_from_arg) location = ctx->ctx.args[0]; else { @@ -389,11 +391,7 @@ brain2_running = dsync_brain_run(brain2, &changed2); } *changes_during_sync_r = dsync_brain_has_unexpected_changes(brain2); - if (dsync_brain_deinit(&brain2) < 0) { - ctx->ctx.exit_code = EX_TEMPFAIL; - return -1; - } - return 0; + return dsync_brain_deinit(&brain2, mail_error_r); } static void cmd_dsync_wait_remote(struct dsync_cmd_context *ctx, @@ -534,6 +532,7 @@ struct mail_namespace *ns; const char *const *strp; enum dsync_brain_flags brain_flags; + enum mail_error mail_error = 0, mail_error2; bool remote_errors_logged = FALSE; bool changes_during_sync = FALSE; int status = 0, ret = 0; @@ -605,7 +604,7 @@ if (ctx->run_type == DSYNC_RUN_TYPE_LOCAL) { if (cmd_dsync_run_local(ctx, user, brain, ibc2, - &changes_during_sync) < 0) + &changes_during_sync, &mail_error) < 0) ret = -1; } else { cmd_dsync_run_remote(user); @@ -626,9 +625,15 @@ } ctx->ctx.exit_code = 2; } - if (dsync_brain_deinit(&brain) < 0) { - ctx->ctx.exit_code = EX_TEMPFAIL; + if (dsync_brain_deinit(&brain, &mail_error2) < 0) ret = -1; + if (ret < 0) { + /* tempfail is the default error. prefer to use a non-tempfail + if that exists. */ + if (mail_error2 != 0 && + (mail_error == 0 || mail_error == MAIL_ERROR_TEMP)) + mail_error = mail_error2; + doveadm_mail_failed_error(&ctx->ctx, mail_error); } dsync_ibc_deinit(&ibc); if (ibc2 != NULL) @@ -1039,6 +1044,7 @@ string_t *temp_prefix, *state_str = NULL; enum dsync_brain_sync_type sync_type; const char *name, *process_title_prefix = ""; + enum mail_error mail_error; if (_ctx->conn != NULL) { /* doveadm-server connection. start with a success reply. @@ -1078,8 +1084,8 @@ } sync_type = dsync_brain_get_sync_type(brain); - if (dsync_brain_deinit(&brain) < 0) - _ctx->exit_code = EX_TEMPFAIL; + if (dsync_brain_deinit(&brain, &mail_error) < 0) + doveadm_mail_failed_error(_ctx, mail_error); dsync_ibc_deinit(&ibc); if (_ctx->conn != NULL) { diff -r b28de884c470 -r b900b50085fc src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c --- a/src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c Thu Mar 19 00:38:01 2015 +0200 +++ b/src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c Thu Mar 19 00:41:19 2015 +0200 @@ -8,7 +8,8 @@ static int sync_create_box(struct dsync_brain *brain, struct mailbox *box, - const guid_128_t mailbox_guid, uint32_t uid_validity) + const guid_128_t mailbox_guid, uint32_t uid_validity, + enum mail_error *error_r) { struct mailbox_metadata metadata; struct mailbox_update update; @@ -25,6 +26,7 @@ if (error != MAIL_ERROR_EXISTS) { i_error("Can't create mailbox %s: %s", mailbox_get_vname(box), errstr); + *error_r = error; return -1; } } @@ -37,7 +39,7 @@ if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) { i_error("Can't sync mailbox %s: %s", mailbox_get_vname(box), - mailbox_get_last_error(box, NULL)); + mailbox_get_last_error(box, error_r)); return -1; } @@ -50,7 +52,7 @@ if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) < 0) { i_error("Can't get mailbox GUID %s: %s", mailbox_get_vname(box), - mailbox_get_last_error(box, NULL)); + mailbox_get_last_error(box, error_r)); return -1; } @@ -69,7 +71,7 @@ if (mailbox_update(box, &update) < 0) { i_error("Can't update mailbox GUID %s: %s", mailbox_get_vname(box), - mailbox_get_last_error(box, NULL)); + mailbox_get_last_error(box, error_r)); return -1; } /* verify that the update worked */ @@ -77,13 +79,14 @@ &metadata) < 0) { i_error("Can't get mailbox GUID %s: %s", mailbox_get_vname(box), - mailbox_get_last_error(box, NULL)); + mailbox_get_last_error(box, error_r)); return -1; } if (memcmp(mailbox_guid, metadata.guid, sizeof(metadata.guid)) != 0) { i_error("Backend didn't update mailbox %s GUID", mailbox_get_vname(box)); + *error_r = MAIL_ERROR_TEMP; return -1; } } else if (ret < 0) { @@ -100,7 +103,8 @@ } int dsync_brain_mailbox_tree_sync_change(struct dsync_brain *brain, - const struct dsync_mailbox_tree_sync_change *change) + const struct dsync_mailbox_tree_sync_change *change, + enum mail_error *error_r) { struct mailbox *box = NULL, *destbox; const char *errstr, *func_name = NULL, *storage_name; @@ -116,7 +120,7 @@ case DSYNC_MAILBOX_TREE_SYNC_TYPE_DELETE_BOX: /* make sure we're deleting the correct mailbox */ ret = dsync_brain_mailbox_alloc(brain, change->mailbox_guid, - &box, &errstr); + &box, &errstr, error_r); if (ret < 0) { i_error("Mailbox sync: Couldn't allocate mailbox GUID %s: %s", guid_128_to_string(change->mailbox_guid), errstr); @@ -130,7 +134,7 @@ guid_128_to_string(change->mailbox_guid), errstr); } brain->changes_during_sync = TRUE; - return ret; + return 0; } break; case DSYNC_MAILBOX_TREE_SYNC_TYPE_DELETE_DIR: @@ -153,6 +157,7 @@ } else { i_error("Mailbox sync: mailbox_list_delete_dir failed: %s", errstr); + *error_r = error; return -1; } default: @@ -162,7 +167,7 @@ switch (change->type) { case DSYNC_MAILBOX_TREE_SYNC_TYPE_CREATE_BOX: ret = sync_create_box(brain, box, change->mailbox_guid, - change->uid_validity); + change->uid_validity, error_r); mailbox_free(&box); return ret; case DSYNC_MAILBOX_TREE_SYNC_TYPE_CREATE_DIR: @@ -218,6 +223,7 @@ } else { i_error("Mailbox %s sync: %s failed: %s", mailbox_get_vname(box), func_name, errstr); + *error_r = error; } } mailbox_free(&box); diff -r b28de884c470 -r b900b50085fc src/doveadm/dsync/dsync-brain-mailbox-tree.c --- a/src/doveadm/dsync/dsync-brain-mailbox-tree.c Thu Mar 19 00:38:01 2015 +0200 +++ b/src/doveadm/dsync/dsync-brain-mailbox-tree.c Thu Mar 19 00:41:19 2015 +0200 @@ -58,8 +58,11 @@ if (dsync_mailbox_tree_fill(brain->local_mailbox_tree, ns, brain->sync_box, brain->sync_box_guid, - brain->exclude_mailboxes) < 0) + brain->exclude_mailboxes, + &brain->mail_error) < 0) { brain->failed = TRUE; + break; + } } brain->local_tree_iter = @@ -300,8 +303,11 @@ brain->remote_mailbox_tree, sync_type, sync_flags); while ((change = dsync_mailbox_trees_sync_next(ctx)) != NULL) { - if (dsync_brain_mailbox_tree_sync_change(brain, change) < 0) + if (dsync_brain_mailbox_tree_sync_change(brain, change, + &brain->mail_error) < 0) { brain->failed = TRUE; + break; + } } dsync_mailbox_trees_sync_deinit(&ctx); } diff -r b28de884c470 -r b900b50085fc src/doveadm/dsync/dsync-brain-mailbox.c --- a/src/doveadm/dsync/dsync-brain-mailbox.c Thu Mar 19 00:38:01 2015 +0200 +++ b/src/doveadm/dsync/dsync-brain-mailbox.c Thu Mar 19 00:41:19 2015 +0200 @@ -16,12 +16,11 @@ static int ns_mailbox_try_alloc(struct dsync_brain *brain, struct mail_namespace *ns, const guid_128_t guid, struct mailbox **box_r, - const char **error_r) + const char **errstr_r, enum mail_error *error_r) { enum mailbox_flags flags = 0; struct mailbox *box; enum mailbox_existence existence; - enum mail_error err; int ret; if (brain->backup_send) { @@ -32,13 +31,13 @@ box = mailbox_alloc_guid(ns->list, guid, flags); ret = mailbox_exists(box, FALSE, &existence); if (ret < 0) { - *error_r = mailbox_get_last_error(box, &err); + *errstr_r = mailbox_get_last_error(box, error_r); mailbox_free(&box); return -1; } if (existence != MAILBOX_EXISTENCE_SELECT) { mailbox_free(&box); - *error_r = existence == MAILBOX_EXISTENCE_NONE ? + *errstr_r = existence == MAILBOX_EXISTENCE_NONE ? "Mailbox was already deleted" : "Mailbox is no longer selectable"; return 0; @@ -48,7 +47,8 @@ } int dsync_brain_mailbox_alloc(struct dsync_brain *brain, const guid_128_t guid, - struct mailbox **box_r, const char **error_r) + struct mailbox **box_r, const char **errstr_r, + enum mail_error *error_r) { struct mail_namespace *ns; int ret; @@ -58,11 +58,9 @@ for (ns = brain->user->namespaces; ns != NULL; ns = ns->next) { if (!dsync_brain_want_namespace(brain, ns)) continue; - if ((ret = ns_mailbox_try_alloc(brain, ns, guid, box_r, error_r)) != 0) { - if (ret < 0) - brain->failed = TRUE; + if ((ret = ns_mailbox_try_alloc(brain, ns, guid, box_r, + errstr_r, error_r)) != 0) return ret; - } } return 0; } @@ -329,6 +327,8 @@ void dsync_brain_sync_mailbox_deinit(struct dsync_brain *brain) { + enum mail_error error; + i_assert(brain->box != NULL); if (brain->require_full_resync) { From dovecot at dovecot.org Wed Mar 18 23:25:27 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 18 Mar 2015 23:25:27 +0000 Subject: dovecot-2.2: imap: If mailbox list is unusable at startup, retur... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cbdfca7d24a6 changeset: 18372:cbdfca7d24a6 user: Timo Sirainen date: Thu Mar 19 01:20:38 2015 +0200 description: imap: If mailbox list is unusable at startup, return failure immediately. This is currently used only by imapc when login fails. diffstat: src/imap/main.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-) diffs (38 lines): diff -r b900b50085fc -r cbdfca7d24a6 src/imap/main.c --- a/src/imap/main.c Thu Mar 19 00:41:19 2015 +0200 +++ b/src/imap/main.c Thu Mar 19 01:20:38 2015 +0200 @@ -209,15 +209,34 @@ { struct mail_storage_service_user *user; struct mail_user *mail_user; + struct mail_namespace *ns; struct client *client; struct imap_settings *set; enum mail_auth_request_flags flags; + const char *errstr; + enum mail_error mail_error; if (mail_storage_service_lookup_next(storage_service, input, &user, &mail_user, error_r) <= 0) return -1; restrict_access_allow_coredumps(TRUE); + /* this is mainly for imapc: make sure we can do at least minimal + access to the mailbox list or fail immediately. otherwise the IMAP + client could be trying a lot of commands and we'd return failures + for all of them. FIXME: There should be a bit less kludgy way to + check this, but I'm not sure if it's worth the trouble just for + imapc. */ + ns = mail_namespace_find_inbox(mail_user->namespaces); + (void)mailbox_list_get_hierarchy_sep(ns->list); + errstr = mailbox_list_get_last_error(ns->list, &mail_error); + if (mail_error != MAIL_ERROR_NONE) { + *error_r = t_strdup(errstr); + mail_user_unref(&mail_user); + mail_storage_service_user_free(&user); + return -1; + } + set = mail_storage_service_user_get_set(user)[1]; if (set->verbose_proctitle) verbose_proctitle = TRUE; From dovecot at dovecot.org Wed Mar 18 23:25:37 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 18 Mar 2015 23:25:37 +0000 Subject: dovecot-2.2: imapc: Don't crash in mailbox_is_inconsistent() wit... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/995df5989e56 changeset: 18373:995df5989e56 user: Timo Sirainen date: Thu Mar 19 01:21:20 2015 +0200 description: imapc: Don't crash in mailbox_is_inconsistent() with unopened mailbox. diffstat: src/lib-storage/index/imapc/imapc-storage.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (18 lines): diff -r cbdfca7d24a6 -r 995df5989e56 src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Thu Mar 19 01:20:38 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-storage.c Thu Mar 19 01:21:20 2015 +0200 @@ -941,10 +941,12 @@ { struct imapc_mailbox *mbox = (struct imapc_mailbox *)box; - if (mail_index_view_is_inconsistent(box->view)) + if (box->view != NULL && + mail_index_view_is_inconsistent(box->view)) return TRUE; - return !imapc_client_mailbox_is_opened(mbox->client_box); + return mbox->client_box == NULL ? FALSE : + !imapc_client_mailbox_is_opened(mbox->client_box); } struct mail_storage imapc_storage = { From dovecot at dovecot.org Wed Mar 18 23:25:37 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 18 Mar 2015 23:25:37 +0000 Subject: dovecot-2.2: imapc: Don't wait for login to succeed at mailbox l... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9c7c345f2b2a changeset: 18374:9c7c345f2b2a user: Timo Sirainen date: Thu Mar 19 01:24:32 2015 +0200 description: imapc: Don't wait for login to succeed at mailbox list creation. The failure will be visible in the next command. This wait was here mainly for imap, but cbdfca7d24a6 implements the wait in imap process directly. Other (current) protocols don't need such wait at all. Most importantly this change allows doveadm to handle imapc login failures by seeing them as MAIL_ERROR_PERM errors when listing mailboxes or opening a mailbox. This allows it to return a different exit code from temporary failure (which it is not). diffstat: src/lib-storage/index/imapc/imapc-list.c | 12 ------------ 1 files changed, 0 insertions(+), 12 deletions(-) diffs (29 lines): diff -r 995df5989e56 -r 9c7c345f2b2a src/lib-storage/index/imapc/imapc-list.c --- a/src/lib-storage/index/imapc/imapc-list.c Thu Mar 19 01:21:20 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-list.c Thu Mar 19 01:24:32 2015 +0200 @@ -66,7 +66,6 @@ static int imapc_list_init(struct mailbox_list *_list, const char **error_r) { struct imapc_mailbox_list *list = (struct imapc_mailbox_list *)_list; - char sep; list->set = mail_user_set_get_driver_settings(_list->ns->user->set_info, _list->ns->user->set, @@ -81,17 +80,6 @@ imapc_storage_client_register_untagged(list->client, "LSUB", imapc_untagged_lsub); imapc_list_send_hierarcy_sep_lookup(list); - if ((_list->ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) { - /* we're using imapc for the INBOX namespace. wait and make - sure we can successfully access the IMAP server (so if the - username is invalid we don't just keep failing every - command). */ - if (imapc_list_try_get_root_sep(list, &sep) < 0) { - imapc_storage_client_unref(&list->client); - *error_r = "Failed to access imapc backend"; - return -1; - } - } return 0; } From dovecot at dovecot.org Thu Mar 19 08:02:13 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 19 Mar 2015 08:02:13 +0000 Subject: dovecot-2.2: dsync: Fixed returning wrong mail_error in some rem... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cf74e2179dce changeset: 18375:cf74e2179dce user: Timo Sirainen date: Thu Mar 19 10:01:18 2015 +0200 description: dsync: Fixed returning wrong mail_error in some remote dsync. diffstat: src/doveadm/dsync/dsync-ibc-stream.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 9c7c345f2b2a -r cf74e2179dce src/doveadm/dsync/dsync-ibc-stream.c --- a/src/doveadm/dsync/dsync-ibc-stream.c Thu Mar 19 01:24:32 2015 +0200 +++ b/src/doveadm/dsync/dsync-ibc-stream.c Thu Mar 19 10:01:18 2015 +0200 @@ -1854,7 +1854,7 @@ struct dsync_deserializer_decoder *decoder; const char *value; enum dsync_ibc_recv_ret ret; - int i; + int i = 0; *error_r = NULL; *mail_error_r = 0; From pigeonhole at rename-it.nl Thu Mar 19 22:25:33 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 19 Mar 2015 23:25:33 +0100 Subject: dovecot-2.2-pigeonhole: Added tag 0.4.7 for changeset f2323a90c202 Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/f2474358118d changeset: 2025:f2474358118d user: Stephan Bosch date: Thu Mar 19 23:18:35 2015 +0100 description: Added tag 0.4.7 for changeset f2323a90c202 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r f2323a90c202 -r f2474358118d .hgtags --- a/.hgtags Thu Mar 19 23:18:17 2015 +0100 +++ b/.hgtags Thu Mar 19 23:18:35 2015 +0100 @@ -26,3 +26,4 @@ 27ad95fd05a039c39f7fec5d76bf28eac20362ce 0.4.7.rc1 fd050f466314f911900027720dcafaa86e3cd537 0.4.7.rc2 87b2d3e43a447f000b06ce1ee1ab73456c7357b3 0.4.7.rc3 +f2323a90c202c4e9708a0c87e81a1b06d267a5c5 0.4.7 From pigeonhole at rename-it.nl Thu Mar 19 22:25:32 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 19 Mar 2015 23:25:32 +0100 Subject: dovecot-2.2-pigeonhole: Released v0.4.7 for Dovecot v2.2.16. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/f2323a90c202 changeset: 2024:f2323a90c202 user: Stephan Bosch date: Thu Mar 19 23:18:17 2015 +0100 description: Released v0.4.7 for Dovecot v2.2.16. diffstat: NEWS | 2 +- configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diffs (18 lines): diff -r 579a43f2dd0f -r f2323a90c202 NEWS --- a/NEWS Tue Mar 17 02:31:57 2015 +0100 +++ b/NEWS Thu Mar 19 23:18:17 2015 +0100 @@ -1,4 +1,4 @@ -v0.4.7 xx-03-2015 Stephan Bosch +v0.4.7 19-03-2015 Stephan Bosch * editheader extension: Made protection against addition and deletion of headers configurable separately. Also, the `Received' and `Auto-Submitted' diff -r 579a43f2dd0f -r f2323a90c202 configure.ac --- a/configure.ac Tue Mar 17 02:31:57 2015 +0100 +++ b/configure.ac Thu Mar 19 23:18:17 2015 +0100 @@ -1,4 +1,4 @@ -AC_INIT([Pigeonhole], [0.4.7.rc3], [dovecot at dovecot.org], [dovecot-2.2-pigeonhole]) +AC_INIT([Pigeonhole], [0.4.7], [dovecot at dovecot.org], [dovecot-2.2-pigeonhole]) AC_CONFIG_AUX_DIR([.]) AC_CONFIG_SRCDIR([src]) AC_CONFIG_MACRO_DIR([m4]) From pigeonhole at rename-it.nl Thu Mar 19 22:27:36 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 19 Mar 2015 23:27:36 +0100 Subject: dovecot-2.2-pigeonhole: Added signature for changeset f2323a90c202 Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/971969e1671d changeset: 2026:971969e1671d user: Stephan Bosch date: Thu Mar 19 23:27:48 2015 +0100 description: Added signature for changeset f2323a90c202 diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r f2474358118d -r 971969e1671d .hgsigs --- a/.hgsigs Thu Mar 19 23:18:35 2015 +0100 +++ b/.hgsigs Thu Mar 19 23:27:48 2015 +0100 @@ -20,3 +20,4 @@ 27ad95fd05a039c39f7fec5d76bf28eac20362ce 0 iQEcBAABAgAGBQJU/lS3AAoJEATWKx49+7T0yJ8IAKsrq2CuRLRiH9YMPWJJzIwVTOudE+H14vUCkeR5/RAAyrBDkf9H3FKda8fTOIqhPoRKwoiKp7cMfTJfU28MkUAic/709bTAMwX+QHEr2g44dSZvRlAzh6CrOZSB/Q39FU8s67U9WDPoz9e0kluIuh7QeLwWdJSklSGw7cpDjAQ2wtFyCK4kSA44JNoTK2KnXiy+Pqu2GEZC5YrnBNuOGXJaX2eIIou8Udf2qnYwX+7UAp0Kgn+uveiY1AMdax/DC7+RSVFyneFHt0Fgx+ZvTLVZMLfLu/a9GDb4LV5gON1ZRYSg/LjQKzs243T1FwTT0Y6ujDvkgw1BoCYWjmvql/o= fd050f466314f911900027720dcafaa86e3cd537 0 iQEcBAABAgAGBQJVBMEkAAoJEATWKx49+7T0RcMH/2Hyfa0M7oBB0M8gY9jVtGoIXC2U37+crLduKSEsJWkchW2/SkuTLbxbVPb4oBXbJJOiDVNVVvjhHefqxbVDJlWVdcTz8hdZam0Wl2LKX4OlvpsLBiCil/gNoQSCABd5Q4zUCa18mBU9PIltlG61IgTxXtz0A5IiCI7N34l3FAwkxSvaCUVR82y5M7dTat7OEDOpVVUIucf9DPrLcGwTFJ/TuOxiI9lH/MKrbRVeOyrs+3hNAzcArBfvvMy7cVyUV85u8EqgFIL6V5mrp4YNOgkuqvvdTDThs14w1GV1ILl9Y4ycUzYDDqqbXnfK/j5mvTNSelnV/JBZC+moJozptmI= 87b2d3e43a447f000b06ce1ee1ab73456c7357b3 0 iQEcBAABAgAGBQJVB4QIAAoJEATWKx49+7T0MKcH/0Wg6xazPO9Q3v8rYZe4PFSlWoXv4P8ixy275pouHyLWKDltg2zVPq3ieDNLkOfNiQvBClWppQa5LPzgTN/9x5MmIYU/IpdXCKvl8i9G3qzRaGUL1oMtp3JocI8JyKx3R61V8u4VyJ+qBg0kLCs85ilNdo1ia9uFCYbZh7QOnM5FHJAsGzDPEriZyrcf3D/CTGDedYfoELEJXpSzW19Ov1qPIq501mBfrxXSd/MTUFkm8DExYW7i/YTBEsJNn58y1tsdC6FxuP8bZJRQlS/4PRR5euACxKpEV38Ig7b22a6P/MoZphCvZkIMBIxIB9RIEIljRyXSKESvssgUoA/v1Q8= +f2323a90c202c4e9708a0c87e81a1b06d267a5c5 0 iQEcBAABAgAGBQJVC01gAAoJEATWKx49+7T0eNQH/iHUSapqKCaPoZByc1UHpp/FS7IEzbXUWTa71uTHN7z+/Gr6vKm4/xl0k10N6XhpY5aJImLt31dd8jSDg6hqhVwDlqIImJzCjf+flG4dZu5MIL2vibjEn7InYvMli5EcafQ08EkTWGm7IPOcqfnZheevU64piqaUr1YfNaR0g/cQcffvT9qXNovlqFQe+hDB2/wUj6zKiHx0rqUzAOh4dAcrfq1jCpXhpGChjezxyiGzFpLPopbEHQU9M9Fr6VFgY+v/mDVp6hj8DpE7Q84BxPvxJKi0il+h0/lliDZUA+XtZsVjckih5WBDC5tLgNRKujMzkAc2UNEU/1vJxkPkldI= From dovecot at dovecot.org Fri Mar 20 11:28:11 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 20 Mar 2015 11:28:11 +0000 Subject: dovecot-2.2: Removed mountpoint checking and updating code. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ef1a64509d68 changeset: 18376:ef1a64509d68 user: Timo Sirainen date: Fri Mar 20 13:27:00 2015 +0200 description: Removed mountpoint checking and updating code. After a few years it seems like it has just caused more problems than it has actually fixed. The only thing it's been used for is to make sure that Dovecot can't create empty user directories when the user's mail filesystem isn't mounted. But that's supposed to be normally prevented already if the mount root directory permissions are only writable by root. For now the mountpoint listing code and doveadm mount code still exists just in case people have some scripts using those. Those could be removed in v2.3. If we somehow figured out which mountpoints existed (not so easy because they could be only visible in userdb lookups for different users), we could maybe create some kind of a script that checks the permissions at startup. This would work with Linux at least: mkdir test mount / -o bind test ls -ld test/var/mail # assuming /var/mail mountpoint umount test diffstat: src/lib-storage/mail-user.c | 35 ----------------------------------- src/lib-storage/mail-user.h | 7 ------- src/lib-storage/mailbox-list.c | 8 ++------ src/master/main.c | 36 ------------------------------------ 4 files changed, 2 insertions(+), 84 deletions(-) diffs (171 lines): diff -r cf74e2179dce -r ef1a64509d68 src/lib-storage/mail-user.c --- a/src/lib-storage/mail-user.c Thu Mar 19 10:01:18 2015 +0200 +++ b/src/lib-storage/mail-user.c Fri Mar 20 13:27:00 2015 +0200 @@ -15,7 +15,6 @@ #include "fs-api.h" #include "auth-master.h" #include "master-service.h" -#include "mountpoint-list.h" #include "dict.h" #include "mail-storage-settings.h" #include "mail-storage-private.h" @@ -36,8 +35,6 @@ dict_deinit(&user->_attr_dict); } mail_namespaces_deinit(&user->namespaces); - if (user->mountpoints != NULL) - mountpoint_list_deinit(&user->mountpoints); } static void mail_user_stats_fill_base(struct mail_user *user ATTR_UNUSED, @@ -440,38 +437,6 @@ str_tabescape(user->username), NULL); } -bool mail_user_is_path_mounted(struct mail_user *user, const char *path, - const char **error_r) -{ - struct mountpoint_list_rec *rec; - const char *mounts_path; - - *error_r = NULL; - - if (user->mountpoints == NULL) { - mounts_path = t_strdup_printf("%s/"MOUNTPOINT_LIST_FNAME, - user->set->base_dir); - user->mountpoints = mountpoint_list_init_readonly(mounts_path); - } else { - (void)mountpoint_list_refresh(user->mountpoints); - } - rec = mountpoint_list_find(user->mountpoints, path); - if (rec == NULL || strcmp(rec->state, MOUNTPOINT_STATE_IGNORE) == 0) { - /* we don't have any knowledge of this path's mountpoint. - assume it's fine. */ - return TRUE; - } - /* record exists for this mountpoint. see if it's mounted */ - if (mountpoint_list_update_mounted(user->mountpoints) == 0 && - !rec->mounted) { - *error_r = t_strdup_printf("Mountpoint %s isn't mounted. " - "Mount it or remove it with doveadm mount remove", - rec->mount_path); - return FALSE; - } - return TRUE; -} - static void mail_user_try_load_class_plugin(struct mail_user *user, const char *name) { diff -r cf74e2179dce -r ef1a64509d68 src/lib-storage/mail-user.h --- a/src/lib-storage/mail-user.h Thu Mar 19 10:01:18 2015 +0200 +++ b/src/lib-storage/mail-user.h Fri Mar 20 13:27:00 2015 +0200 @@ -47,7 +47,6 @@ struct mail_storage *storages; ARRAY(const struct mail_storage_hooks *) hooks; - struct mountpoint_list *mountpoints; normalizer_func_t *default_normalizer; /* Filled lazily by mailbox_attribute_*() when accessing attributes. */ struct dict *_attr_dict; @@ -151,12 +150,6 @@ int mail_user_try_home_expand(struct mail_user *user, const char **path); /* Returns unique user+ip identifier for anvil. */ const char *mail_user_get_anvil_userip_ident(struct mail_user *user); -/* Returns FALSE if path is in a mountpoint that should be mounted, - but isn't mounted. In such a situation it's better to fail than to attempt - any kind of automatic file/dir creations. error_r gives an error about which - mountpoint should be mounted. */ -bool mail_user_is_path_mounted(struct mail_user *user, const char *path, - const char **error_r); /* Basically the same as mail_storage_find_class(), except automatically load storage plugins when needed. */ diff -r cf74e2179dce -r ef1a64509d68 src/lib-storage/mailbox-list.c --- a/src/lib-storage/mailbox-list.c Thu Mar 19 10:01:18 2015 +0200 +++ b/src/lib-storage/mailbox-list.c Fri Mar 20 13:27:00 2015 +0200 @@ -1109,7 +1109,7 @@ enum mailbox_list_path_type type, const char **error_r) { - const char *root_dir, *error; + const char *root_dir; struct stat st; struct mailbox_permissions perm; @@ -1127,14 +1127,10 @@ if (strcmp(root_dir, path) != 0 && stat(root_dir, &st) == 0) { /* creating a subdirectory under an already existing root dir. use the root's permissions */ - } else if (mail_user_is_path_mounted(list->ns->user, path, &error)) { + } else { if (mailbox_list_try_mkdir_root_parent(list, type, &perm, error_r) < 0) return -1; - } else { - *error_r = t_strdup_printf( - "Can't create mailbox root dir %s: %s", path, error); - return -1; } /* the rest of the directories exist only for one user. create them diff -r cf74e2179dce -r ef1a64509d68 src/master/main.c --- a/src/master/main.c Thu Mar 19 10:01:18 2015 +0200 +++ b/src/master/main.c Fri Mar 20 13:27:00 2015 +0200 @@ -12,7 +12,6 @@ #include "ipwd.h" #include "str.h" #include "execv-const.h" -#include "mountpoint-list.h" #include "restrict-process-size.h" #include "master-instance.h" #include "master-service.h" @@ -295,40 +294,6 @@ } } -static void mountpoints_warn_missing(struct mountpoint_list *mountpoints) -{ - struct mountpoint_list_iter *iter; - struct mountpoint_list_rec *rec; - - /* warn about mountpoints that no longer exist */ - iter = mountpoint_list_iter_init(mountpoints); - while ((rec = mountpoint_list_iter_next(iter)) != NULL) { - if (MOUNTPOINT_WRONGLY_NOT_MOUNTED(rec)) { - i_warning("%s is no longer mounted. " - "See http://wiki2.dovecot.org/Mountpoints", - rec->mount_path); - } - } - mountpoint_list_iter_deinit(&iter); -} - -static void mountpoints_update(const struct master_settings *set) -{ - struct mountpoint_list *mountpoints; - const char *perm_path, *state_path; - - perm_path = t_strconcat(set->state_dir, "/"MOUNTPOINT_LIST_FNAME, NULL); - state_path = t_strconcat(set->base_dir, "/"MOUNTPOINT_LIST_FNAME, NULL); - mountpoints = mountpoint_list_init(perm_path, state_path); - - if (mountpoint_list_add_missing(mountpoints, MOUNTPOINT_STATE_DEFAULT, - mountpoint_list_default_ignore_prefixes, - mountpoint_list_default_ignore_types) == 0) - mountpoints_warn_missing(mountpoints); - (void)mountpoint_list_save(mountpoints); - mountpoint_list_deinit(&mountpoints); -} - static void instance_update_now(struct master_instance_list *list) { int ret; @@ -557,7 +522,6 @@ create_pid_file(pidfile_path); create_config_symlink(set); - mountpoints_update(set); instance_update(set); services_monitor_start(services); From dovecot at dovecot.org Fri Mar 20 18:47:54 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 20 Mar 2015 18:47:54 +0000 Subject: dovecot-2.2: doveadm: Added -h parameter to hide header line fro... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b84f4b881b88 changeset: 18377:b84f4b881b88 user: Timo Sirainen date: Fri Mar 20 20:46:52 2015 +0200 description: doveadm: Added -h parameter to hide header line from tab and table formatter output. diffstat: src/doveadm/doveadm-print-tab.c | 27 ++++++++++++++------------- src/doveadm/doveadm-print-table.c | 3 +++ src/doveadm/doveadm-print.c | 2 ++ src/doveadm/doveadm-print.h | 1 + src/doveadm/doveadm.c | 5 ++++- 5 files changed, 24 insertions(+), 14 deletions(-) diffs (118 lines): diff -r ef1a64509d68 -r b84f4b881b88 src/doveadm/doveadm-print-tab.c --- a/src/doveadm/doveadm-print-tab.c Fri Mar 20 13:27:00 2015 +0200 +++ b/src/doveadm/doveadm-print-tab.c Fri Mar 20 20:46:52 2015 +0200 @@ -14,20 +14,27 @@ static struct doveadm_print_tab_context ctx; +static void doveadm_print_tab_flush_header(void) +{ + if (!ctx.header_written) { + if (!doveadm_print_hide_titles) + printf("\n"); + ctx.header_written = TRUE; + } +} + static void doveadm_print_tab_header(const struct doveadm_print_header *hdr) { if (ctx.header_count++ > 0) printf("\t"); - printf("%s", hdr->title); + if (!doveadm_print_hide_titles) + printf("%s", hdr->title); } static void doveadm_print_tab_print(const char *value) { - if (!ctx.header_written) { - printf("\n"); - ctx.header_written = TRUE; - } + doveadm_print_tab_flush_header(); if (ctx.header_idx > 0) printf("\t"); printf("%s", value); @@ -45,10 +52,7 @@ doveadm_print_tab_print(""); return; } - if (!ctx.header_written) { - printf("\n"); - ctx.header_written = TRUE; - } + doveadm_print_tab_flush_header(); if (ctx.header_idx > 0) printf("\t"); fwrite(value, 1, size, stdout); @@ -56,10 +60,7 @@ static void doveadm_print_tab_flush(void) { - if (!ctx.header_written) { - printf("\n"); - ctx.header_written = TRUE; - } + doveadm_print_tab_flush_header(); } struct doveadm_print_vfuncs doveadm_print_tab_vfuncs = { diff -r ef1a64509d68 -r b84f4b881b88 src/doveadm/doveadm-print-table.c --- a/src/doveadm/doveadm-print-table.c Fri Mar 20 13:27:00 2015 +0200 +++ b/src/doveadm/doveadm-print-table.c Fri Mar 20 20:46:52 2015 +0200 @@ -154,6 +154,9 @@ const struct doveadm_print_table_header *headers; unsigned int i, count; + if (doveadm_print_hide_titles) + return; + headers = array_get(&ctx->headers, &count); /* if all headers are hidden, don't print any of them */ for (i = 0; i < count; i++) { diff -r ef1a64509d68 -r b84f4b881b88 src/doveadm/doveadm-print.c --- a/src/doveadm/doveadm-print.c Fri Mar 20 13:27:00 2015 +0200 +++ b/src/doveadm/doveadm-print.c Fri Mar 20 20:46:52 2015 +0200 @@ -22,6 +22,8 @@ bool print_stream_open; }; +bool doveadm_print_hide_titles = FALSE; + static struct doveadm_print_context *ctx; bool doveadm_print_is_initialized(void) diff -r ef1a64509d68 -r b84f4b881b88 src/doveadm/doveadm-print.h --- a/src/doveadm/doveadm-print.h Fri Mar 20 13:27:00 2015 +0200 +++ b/src/doveadm/doveadm-print.h Fri Mar 20 20:46:52 2015 +0200 @@ -13,6 +13,7 @@ }; extern const struct doveadm_print_vfuncs *doveadm_print_vfuncs_all[]; +extern bool doveadm_print_hide_titles; bool doveadm_print_is_initialized(void); diff -r ef1a64509d68 -r b84f4b881b88 src/doveadm/doveadm.c --- a/src/doveadm/doveadm.c Fri Mar 20 13:27:00 2015 +0200 +++ b/src/doveadm/doveadm.c Fri Mar 20 20:46:52 2015 +0200 @@ -271,7 +271,7 @@ /* "+" is GNU extension to stop at the first non-option. others just accept -+ option. */ master_service = master_service_init("doveadm", service_flags, - &argc, &argv, "+Df:v"); + &argc, &argv, "+Df:hv"); while ((c = master_getopt(master_service)) > 0) { switch (c) { case 'D': @@ -281,6 +281,9 @@ case 'f': doveadm_print_init(optarg); break; + case 'h': + doveadm_print_hide_titles = TRUE; + break; case 'v': doveadm_verbose = TRUE; break; From dovecot at dovecot.org Fri Mar 20 19:02:04 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 20 Mar 2015 19:02:04 +0000 Subject: dovecot-2.2: lib: o_stream_create_rawlog_from_stream() should pr... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ebc2672a30f6 changeset: 18378:ebc2672a30f6 user: Timo Sirainen date: Fri Mar 20 21:01:08 2015 +0200 description: lib: o_stream_create_rawlog_from_stream() should preserve the output stream fd. ostream-rawlog is just a passthrough stream after all. diffstat: src/lib/ostream-rawlog.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (11 lines): diff -r b84f4b881b88 -r ebc2672a30f6 src/lib/ostream-rawlog.c --- a/src/lib/ostream-rawlog.c Fri Mar 20 20:46:52 2015 +0200 +++ b/src/lib/ostream-rawlog.c Fri Mar 20 21:01:08 2015 +0200 @@ -80,5 +80,6 @@ rstream->riostream.rawlog_output = rawlog_output; iostream_rawlog_init(&rstream->riostream, flags, FALSE); - return o_stream_create(&rstream->ostream, output, -1); + return o_stream_create(&rstream->ostream, output, + o_stream_get_fd(output)); } From dovecot at dovecot.org Fri Mar 20 19:14:18 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 20 Mar 2015 19:14:18 +0000 Subject: dovecot-2.2: lib-dict: Fixed crash when transaction failed due t... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d8f24038d3cb changeset: 18379:d8f24038d3cb user: Timo Sirainen date: Fri Mar 20 21:13:21 2015 +0200 description: lib-dict: Fixed crash when transaction failed due to dict server disconnection. diffstat: src/lib-dict/dict-client.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (16 lines): diff -r ebc2672a30f6 -r d8f24038d3cb src/lib-dict/dict-client.c --- a/src/lib-dict/dict-client.c Fri Mar 20 21:01:08 2015 +0200 +++ b/src/lib-dict/dict-client.c Fri Mar 20 21:13:21 2015 +0200 @@ -270,8 +270,10 @@ /* the callback may call the dict code again, so remove this transaction before calling it */ i_assert(dict->async_commits > 0); - if (--dict->async_commits == 0) - io_remove(&dict->io); + if (--dict->async_commits == 0) { + if (dict->io != NULL) + io_remove(&dict->io); + } DLLIST_REMOVE(&dict->transactions, ctx); if (ctx->callback != NULL) From dovecot at dovecot.org Fri Mar 20 19:59:12 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 20 Mar 2015 19:59:12 +0000 Subject: dovecot-2.2: lib: Fixed potential build error when building with... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1bbde199a6e3 changeset: 18380:1bbde199a6e3 user: Timo Sirainen date: Fri Mar 20 21:58:16 2015 +0200 description: lib: Fixed potential build error when building without modules. diffstat: src/lib/module-dir.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (14 lines): diff -r d8f24038d3cb -r 1bbde199a6e3 src/lib/module-dir.c --- a/src/lib/module-dir.c Fri Mar 20 21:13:21 2015 +0200 +++ b/src/lib/module-dir.c Fri Mar 20 21:58:16 2015 +0200 @@ -598,6 +598,10 @@ #else +#ifndef MODULE_SUFFIX +# define MODULE_SUFFIX ".so" /* just to avoid build failure */ +#endif + struct module * module_dir_load_missing(struct module *old_modules ATTR_UNUSED, const char *dir ATTR_UNUSED, From dovecot at dovecot.org Sun Mar 22 17:00:49 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 22 Mar 2015 17:00:49 +0000 Subject: dovecot-2.2: Cleanup for libcharset's iconv linking. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/36ca0e03bd06 changeset: 18381:36ca0e03bd06 user: Timo Sirainen date: Sun Mar 22 18:59:51 2015 +0200 description: Cleanup for libcharset's iconv linking. Linking libcharset.la now automatically links with the necessary iconv libraries. diffstat: src/lib-charset/Makefile.am | 1 + src/lib-dovecot/Makefile.am | 3 +-- src/lib-mail/Makefile.am | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diffs (36 lines): diff -r 1bbde199a6e3 -r 36ca0e03bd06 src/lib-charset/Makefile.am --- a/src/lib-charset/Makefile.am Fri Mar 20 21:58:16 2015 +0200 +++ b/src/lib-charset/Makefile.am Sun Mar 22 18:59:51 2015 +0200 @@ -3,6 +3,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib +libcharset_la_LIBADD = $(LTLIBICONV) libcharset_la_SOURCES = \ charset-iconv.c \ charset-utf8.c diff -r 1bbde199a6e3 -r 36ca0e03bd06 src/lib-dovecot/Makefile.am --- a/src/lib-dovecot/Makefile.am Fri Mar 20 21:58:16 2015 +0200 +++ b/src/lib-dovecot/Makefile.am Sun Mar 22 18:59:51 2015 +0200 @@ -22,8 +22,7 @@ libdovecot_la_LIBADD = \ $(libs) \ - $(MODULE_LIBS) \ - $(LTLIBICONV) + $(MODULE_LIBS) libdovecot_la_DEPENDENCIES = $(libs) libdovecot_la_LDFLAGS = -export-dynamic diff -r 1bbde199a6e3 -r 36ca0e03bd06 src/lib-mail/Makefile.am --- a/src/lib-mail/Makefile.am Fri Mar 20 21:58:16 2015 +0200 +++ b/src/lib-mail/Makefile.am Sun Mar 22 18:59:51 2015 +0200 @@ -142,7 +142,7 @@ test_message_date_DEPENDENCIES = $(test_deps) test_message_decoder_SOURCES = test-message-decoder.c -test_message_decoder_LDADD = message-decoder.lo quoted-printable.lo rfc822-parser.lo rfc2231-parser.lo ../lib-charset/libcharset.la $(test_libs) $(LIBICONV) +test_message_decoder_LDADD = message-decoder.lo quoted-printable.lo rfc822-parser.lo rfc2231-parser.lo ../lib-charset/libcharset.la $(test_libs) test_message_decoder_DEPENDENCIES = ../lib-charset/libcharset.la $(test_deps) test_message_header_decode_SOURCES = test-message-header-decode.c From dovecot at dovecot.org Sun Mar 22 18:55:45 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 22 Mar 2015 18:55:45 +0000 Subject: dovecot-2.2: lib-fs: When autoloading fs plugins with '-' in the... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/35a4828d11f7 changeset: 18382:35a4828d11f7 user: Timo Sirainen date: Sun Mar 22 20:52:16 2015 +0200 description: lib-fs: When autoloading fs plugins with '-' in the name, translate them to '_' It's not possible for the function names to contain '-' in any case. Also Dovecot in general uses '-' instead of '_' in the configuration names. This change actually allows using either of them. diffstat: src/lib-fs/fs-api.c | 24 ++++++++++++++++++++++-- 1 files changed, 22 insertions(+), 2 deletions(-) diffs (43 lines): diff -r 36ca0e03bd06 -r 35a4828d11f7 src/lib-fs/fs-api.c --- a/src/lib-fs/fs-api.c Sun Mar 22 18:59:51 2015 +0200 +++ b/src/lib-fs/fs-api.c Sun Mar 22 20:52:16 2015 +0200 @@ -81,9 +81,28 @@ module_dir_unload(&fs_modules); } +static const char *fs_driver_module_name(const char *driver) +{ + string_t *str; + unsigned int i; + + if (strchr(driver, '-') == NULL) + return driver; + + str = t_str_new(32); + for (i = 0; driver[i] != '\0'; i++) { + if (driver[i] == '-') + str_append_c(str, '_'); + else + str_append_c(str, driver[i]); + } + return str_c(str); +} + static void fs_class_try_load_plugin(const char *driver) { - const char *module_name = t_strdup_printf("fs_%s", driver); + const char *module_name = + t_strdup_printf("fs_%s", fs_driver_module_name(driver)); struct module *module; struct module_dir_load_settings mod_set; const struct fs *fs_class; @@ -98,7 +117,8 @@ module = module_dir_find(fs_modules, module_name); fs_class = module == NULL ? NULL : - module_get_symbol(module, t_strdup_printf("fs_class_%s", driver)); + module_get_symbol(module, t_strdup_printf( + "fs_class_%s", fs_driver_module_name(driver))); if (fs_class != NULL) fs_class_register(fs_class); From dovecot at dovecot.org Sun Mar 22 18:55:45 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 22 Mar 2015 18:55:45 +0000 Subject: dovecot-2.2: lib-fs: Added support for module_contexts in fs. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/66689aaa85de changeset: 18383:66689aaa85de user: Timo Sirainen date: Sun Mar 22 20:52:56 2015 +0200 description: lib-fs: Added support for module_contexts in fs. They could also be added to fs_file if needed, but for now I didn't bother adding it. diffstat: src/lib-fs/fs-api-private.h | 13 +++++++++++++ src/lib-fs/fs-api.c | 5 +++++ 2 files changed, 18 insertions(+), 0 deletions(-) diffs (66 lines): diff -r 35a4828d11f7 -r 66689aaa85de src/lib-fs/fs-api-private.h --- a/src/lib-fs/fs-api-private.h Sun Mar 22 20:52:16 2015 +0200 +++ b/src/lib-fs/fs-api-private.h Sun Mar 22 20:52:56 2015 +0200 @@ -2,6 +2,17 @@ #define FS_API_PRIVATE_H #include "fs-api.h" +#include "module-context.h" + +struct fs_api_module_register { + unsigned int id; +}; + +union fs_api_module_context { + struct fs_api_module_register *reg; +}; + +extern struct fs_api_module_register fs_api_module_register; struct fs_vfuncs { struct fs *(*alloc)(void); @@ -72,6 +83,8 @@ struct fs_iter *iters; struct fs_stats stats; + + ARRAY(union fs_api_module_context *) module_contexts; }; struct fs_file { diff -r 35a4828d11f7 -r 66689aaa85de src/lib-fs/fs-api.c --- a/src/lib-fs/fs-api.c Sun Mar 22 20:52:16 2015 +0200 +++ b/src/lib-fs/fs-api.c Sun Mar 22 20:52:56 2015 +0200 @@ -11,6 +11,8 @@ #include "ostream.h" #include "fs-api-private.h" +struct fs_api_module_register fs_api_module_register = { 0 }; + static struct module *fs_modules = NULL; static ARRAY(const struct fs *) fs_classes; @@ -23,6 +25,7 @@ fs = fs_class->v.alloc(); fs->last_error = str_new(default_pool, 64); + i_array_init(&fs->module_contexts, 5); T_BEGIN { ret = fs_class->v.init(fs, args, set); @@ -157,6 +160,7 @@ { struct fs *fs = *_fs; string_t *last_error = fs->last_error; + struct array module_contexts_arr = fs->module_contexts.arr; *_fs = NULL; @@ -172,6 +176,7 @@ T_BEGIN { fs->v.deinit(fs); } T_END; + array_free_i(&module_contexts_arr); str_free(&last_error); } From dovecot at dovecot.org Sun Mar 22 18:55:50 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 22 Mar 2015 18:55:50 +0000 Subject: dovecot-2.2: lib-storage: Added mailbox_list_fs_get_list() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0bbdc413285e changeset: 18384:0bbdc413285e user: Timo Sirainen date: Sun Mar 22 20:54:29 2015 +0200 description: lib-storage: Added mailbox_list_fs_get_list() Using mailbox_list_init_fs() now sets the mailbox_list pointer to root fs, which allows the fs backends to lookup the list. Although this can't be done in the init() function since the list is set only afterwards. diffstat: src/lib-storage/mailbox-list-private.h | 4 --- src/lib-storage/mailbox-list.c | 38 ++++++++++++++++++++++++++++++++- src/lib-storage/mailbox-list.h | 9 ++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) diffs (106 lines): diff -r 66689aaa85de -r 0bbdc413285e src/lib-storage/mailbox-list-private.h --- a/src/lib-storage/mailbox-list-private.h Sun Mar 22 20:52:56 2015 +0200 +++ b/src/lib-storage/mailbox-list-private.h Sun Mar 22 20:54:29 2015 +0200 @@ -213,8 +213,4 @@ void mailbox_list_set_internal_error(struct mailbox_list *list); bool mailbox_list_set_error_from_errno(struct mailbox_list *list); -int mailbox_list_init_fs(struct mailbox_list *list, const char *driver, - const char *args, const char *root_dir, - struct fs **fs_r, const char **error_r); - #endif diff -r 66689aaa85de -r 0bbdc413285e src/lib-storage/mailbox-list.c --- a/src/lib-storage/mailbox-list.c Sun Mar 22 20:52:56 2015 +0200 +++ b/src/lib-storage/mailbox-list.c Sun Mar 22 20:54:29 2015 +0200 @@ -13,7 +13,7 @@ #include "unichar.h" #include "settings-parser.h" #include "iostream-ssl.h" -#include "fs-api.h" +#include "fs-api-private.h" #include "imap-utf7.h" #include "mailbox-log.h" #include "mailbox-tree.h" @@ -36,9 +36,19 @@ #define MAILBOX_MAX_HIERARCHY_LEVELS 16 #define MAILBOX_MAX_HIERARCHY_NAME_LENGTH 255 +#define MAILBOX_LIST_FS_CONTEXT(obj) \ + MODULE_CONTEXT(obj, mailbox_list_fs_module) + +struct mailbox_list_fs_context { + union fs_api_module_context module_ctx; + struct mailbox_list *list; +}; + struct mailbox_list_module_register mailbox_list_module_register = { 0 }; static ARRAY(const struct mailbox_list *) mailbox_list_drivers; +static MODULE_CONTEXT_DEFINE_INIT(mailbox_list_fs_module, + &fs_api_module_register); void mailbox_lists_init(void) { @@ -1831,6 +1841,8 @@ { struct fs_settings fs_set; struct ssl_iostream_settings ssl_set; + struct mailbox_list_fs_context *ctx; + struct fs *parent_fs; memset(&ssl_set, 0, sizeof(ssl_set)); memset(&fs_set, 0, sizeof(fs_set)); @@ -1838,5 +1850,27 @@ fs_set.root_path = root_dir; fs_set.temp_file_prefix = mailbox_list_get_global_temp_prefix(list); - return fs_init(driver, args, &fs_set, fs_r, error_r); + if (fs_init(driver, args, &fs_set, fs_r, error_r) < 0) + return -1; + + /* add mailbox_list context to the parent fs, which allows + mailbox_list_fs_get_list() to work */ + for (parent_fs = *fs_r; parent_fs->parent != NULL; + parent_fs = parent_fs->parent) ; + + ctx = p_new(list->pool, struct mailbox_list_fs_context, 1); + ctx->list = list; + MODULE_CONTEXT_SET(parent_fs, mailbox_list_fs_module, ctx); + return 0; } + +struct mailbox_list *mailbox_list_fs_get_list(struct fs *fs) +{ + struct mailbox_list_fs_context *ctx; + + while (fs->parent != NULL) + fs = fs->parent; + + ctx = MAILBOX_LIST_FS_CONTEXT(fs); + return ctx->list; +} diff -r 66689aaa85de -r 0bbdc413285e src/lib-storage/mailbox-list.h --- a/src/lib-storage/mailbox-list.h Sun Mar 22 20:52:56 2015 +0200 +++ b/src/lib-storage/mailbox-list.h Sun Mar 22 20:54:29 2015 +0200 @@ -9,6 +9,7 @@ # define MAILBOX_LIST_NAME_MAX_LENGTH 4096 #endif +struct fs; struct mail_namespace; struct mail_storage; struct mailbox_list; @@ -257,4 +258,12 @@ mailbox_list_get_last_error(struct mailbox_list *list, enum mail_error *error_r); +/* Create a fs based on the settings in the given mailbox_list. */ +int mailbox_list_init_fs(struct mailbox_list *list, const char *driver, + const char *args, const char *root_dir, + struct fs **fs_r, const char **error_r); +/* Return mailbox_list that was used to create the fs via + mailbox_list_init_fs(). */ +struct mailbox_list *mailbox_list_fs_get_list(struct fs *fs); + #endif From dovecot at dovecot.org Tue Mar 24 09:15:54 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 24 Mar 2015 09:15:54 +0000 Subject: dovecot-2.2: imapc: Ignore \Muted GMail label Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/41985233e1e8 changeset: 18385:41985233e1e8 user: Timo Sirainen date: Tue Mar 24 10:14:58 2015 +0100 description: imapc: Ignore \Muted GMail label diffstat: src/lib-storage/index/imapc/imapc-mailbox.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diffs (18 lines): diff -r 0bbdc413285e -r 41985233e1e8 src/lib-storage/index/imapc/imapc-mailbox.c --- a/src/lib-storage/index/imapc/imapc-mailbox.c Sun Mar 22 20:54:29 2015 +0200 +++ b/src/lib-storage/index/imapc/imapc-mailbox.c Tue Mar 24 10:14:58 2015 +0100 @@ -315,8 +315,12 @@ IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_GMAIL_MIGRATION)) { if (!imap_arg_get_list(&list[i+1], &flags_list)) return; - if (flags_list[0].type != IMAP_ARG_EOL) - have_labels = TRUE; + for (j = 0; flags_list[j].type != IMAP_ARG_EOL; j++) { + if (!imap_arg_get_atom(&flags_list[j], &atom)) + return; + if (strcasecmp(atom, "\\Muted") != 0) + have_labels = TRUE; + } } } From dovecot at dovecot.org Tue Mar 24 09:28:26 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 24 Mar 2015 09:28:26 +0000 Subject: dovecot-2.2: imapc: Fix to previous change - labels are strings ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/acb0590787a0 changeset: 18386:acb0590787a0 user: Timo Sirainen date: Tue Mar 24 11:27:26 2015 +0200 description: imapc: Fix to previous change - labels are strings and not atoms. Allow also atoms just in case diffstat: src/lib-storage/index/imapc/imapc-mailbox.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diffs (22 lines): diff -r 41985233e1e8 -r acb0590787a0 src/lib-storage/index/imapc/imapc-mailbox.c --- a/src/lib-storage/index/imapc/imapc-mailbox.c Tue Mar 24 10:14:58 2015 +0100 +++ b/src/lib-storage/index/imapc/imapc-mailbox.c Tue Mar 24 11:27:26 2015 +0200 @@ -315,12 +315,17 @@ IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_GMAIL_MIGRATION)) { if (!imap_arg_get_list(&list[i+1], &flags_list)) return; +#if 0 + if (flags_list[0].type != IMAP_ARG_EOL) + have_labels = TRUE; +#else for (j = 0; flags_list[j].type != IMAP_ARG_EOL; j++) { - if (!imap_arg_get_atom(&flags_list[j], &atom)) + if (!imap_arg_get_astring(&flags_list[j], &atom)) return; if (strcasecmp(atom, "\\Muted") != 0) have_labels = TRUE; } +#endif } } From pigeonhole at rename-it.nl Thu Mar 26 22:32:31 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 26 Mar 2015 23:32:31 +0100 Subject: dovecot-2.2-pigeonhole: Updated configuration-related documentat... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/5547d6d1778c changeset: 2027:5547d6d1778c user: Stephan Bosch date: Thu Mar 26 23:32:21 2015 +0100 description: Updated configuration-related documentation. diffstat: INSTALL | 46 ++++++++----- doc/extensions/duplicate.txt | 4 - doc/locations/dict.txt | 145 +++++++++++++++++++++++++++++++++++++++++++ doc/locations/file.txt | 48 ++++++++++++++ doc/locations/ldap.txt | 73 +++++++++++++++++++++ doc/script-location-dict.txt | 143 ------------------------------------------ doc/script-location-ldap.txt | 73 --------------------- 7 files changed, 293 insertions(+), 239 deletions(-) diffs (truncated from 600 to 300 lines): diff -r 971969e1671d -r 5547d6d1778c INSTALL --- a/INSTALL Thu Mar 19 23:27:48 2015 +0100 +++ b/INSTALL Thu Mar 26 23:32:21 2015 +0100 @@ -86,14 +86,17 @@ The following script location types are implemented by default: - file - The location path is a file system path pointing to the script file - or a directory containing script files with names structured as - `.sieve'. - dict - Dovecot dict lookup. The location path is a dict uri. Read - doc/scipt-location-dict.txt for more information and examples. - ldap - LDAP database lookup. The location path is a configuration file with - LDAP options. Read doc/scipt-location-ldap.txt for more information - and examples. + file - The location path is a file system path pointing to the script file + or a directory containing script files with names structured as + `.sieve'. Read doc/locations/file.txt for more + information and examples. + + dict - The location path is a Dovecot dict uri. Read doc/locations/dict.txt + for more information and examples. + + ldap - LDAP database lookup. The location path is a configuration file with + LDAP options. Read doc/locations/ldap.txt for more information + and examples. If the type prefix is omitted, the script location type is 'file' and the location is interpreted as a local filesystem path pointing to a Sieve script @@ -144,12 +147,18 @@ The Sieve interpreter recognizes the following configuration options in the plugin section of the config file (default values are shown if applicable): - sieve = ~/.dovecot.sieve + sieve = file:~/sieve;active=~/.dovecot.sieve The location of the user's main Sieve script or script storage. The LDA Sieve plugin uses this to find the active script for Sieve filtering at delivery. The "include" extension uses this location for retrieving - :personal" scripts. This is also where the ManageSieve service will store - the user's scripts, if supported by the location type. + :personal" scripts. + + This location is also where the ManageSieve service will store the user's + scripts, if supported by the location type. For the 'file' location type, the + location will then be the path to the storage directory for all the user's + personal Sieve scripts. ManageSieve maintains a symbolic link pointing to + the currently active script (the script executed at delivery). The location + of this symbolic link can be configured using the `;active=' option. sieve_default = The location of the default personal sieve script file, which gets executed @@ -425,16 +434,15 @@ configuration and are not enabled for use by default. Refer to doc/extensions/spamtest-virustest.txt for configuration information. -- Vnd.dovecot.duplicate extension: +- Duplicate extension: - The vnd.dovecot.duplicate extension augments the Sieve filtering - implementation with a test that allows detecting and handling duplicate - message deliveries, e.g. as caused by mailinglists when people reply both to - the mailinglist and the user directly. + The duplicate extension augments the Sieve filtering implementation with a + test that facilitates detecting and handling duplicate message deliveries, + e.g. as caused by mailinglists when people reply both to the mailinglist and + the user directly. - The vnd.dovecot.duplicate extension requires explicit configuration and is not - enabled for use by default. Refer to doc/extensions/vnd.dovecot.duplicate.txt - for configuration information. + Refer to doc/extensions/vnd.dovecot.duplicate.txt for configuration + information. - Extprograms plugin; vnd.dovovecot.pipe, vnd.dovecot.filter, vnd.dovecot.execute extensions: diff -r 971969e1671d -r 5547d6d1778c doc/extensions/duplicate.txt --- a/doc/extensions/duplicate.txt Thu Mar 19 23:27:48 2015 +0100 +++ b/doc/extensions/duplicate.txt Thu Mar 26 23:32:21 2015 +0100 @@ -23,8 +23,6 @@ Configuration ============= -The "duplicate" extension is not enabled by default. - The following configuration settings are used: sieve_duplicate_default_period = 14d @@ -40,8 +38,6 @@ plugin { sieve = ~/.dovecot.sieve - sieve_extensions = +vnd.dovecot.duplicate - sieve_duplicate_default_period = 1h sieve_duplicate_max_period = 1d }d diff -r 971969e1671d -r 5547d6d1778c doc/locations/dict.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/locations/dict.txt Thu Mar 26 23:32:21 2015 +0100 @@ -0,0 +1,145 @@ +DICT Sieve Script Location Type + +Description +=========== + +This location type is used to retrieve Sieve scripts from a Dovecot dict lookup. +Such dictionaries use a file or an SQL database as backend. Refer to the Dovecot +dict documentation for more information on dict lookups. + +To retrieve a Sieve script from the dict database, two lookups are performed. +First, the name of the Sieve script is queried from the dict path +`/priv/sieve/name/'. If the Sieve script exists, this yields a data ID +which in turn points to the actual script text. The script text is subsequently +queried from the dict path '/priv/sieve/data/'. + +The second query is only necessary when no compiled binary is available or when +the script has changed and needs to be recompiled. The data ID is used to detect +changes in the dict's underlying database. Changing a Sieve script in the +database must be done by first making a new script data item with a new data ID. +Then, the mapping from name to data ID must be changed to point to the new +script text, thereby changing the data ID returned from the name lookup, i.e. +the first query mentioned above. Script binaries compiled from Sieve scripts +contained in a dict database record the data ID. While the data ID contained in +the binary is identical to the one returned from the dict lookup, the binary is +assumed up-to-date. When the returned data ID is different, the new script text +is retrieved using the second query and compiled into a new binary containing +the updated data ID. + +Note that, by default, compiled binaries are not stored at all for Sieve scripts +retrieved from a dict database. The bindir= option needs to be specified in the +location specification. Refer to the INSTALL file for more general information +about configuration of script locations. + +Configuration +============= + +The script location syntax is specified as follows: + +location = dict:[;