From dovecot at dovecot.org Mon Jun 2 01:01:26 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jun 2014 01:01:26 +0000 Subject: dovecot-2.2: doveadm director kick command added. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/64808a9703db changeset: 17418:64808a9703db user: Timo Sirainen date: Mon Jun 02 04:00:19 2014 +0300 description: doveadm director kick command added. The kick gets sent to all the proxies within the director ring. diffstat: src/director/director-connection.c | 21 +++++++++++++++++++++ src/director/director.c | 26 ++++++++++++++++++++++++++ src/director/director.h | 13 +++++++++---- src/director/doveadm-connection.c | 18 ++++++++++++++++++ src/doveadm/doveadm-director.c | 28 ++++++++++++++++++++++++++++ 5 files changed, 102 insertions(+), 4 deletions(-) diffs (188 lines): diff -r de9b10f2e168 -r 64808a9703db src/director/director-connection.c --- a/src/director/director-connection.c Wed May 28 18:17:52 2014 +0300 +++ b/src/director/director-connection.c Mon Jun 02 04:00:19 2014 +0300 @@ -939,6 +939,25 @@ } static bool +director_cmd_user_kick(struct director_connection *conn, + const char *const *args) +{ + struct director_host *dir_host; + int ret; + + if ((ret = director_cmd_is_seen(conn, &args, &dir_host)) != 0) + return ret > 0; + + if (str_array_length(args) != 1) { + director_cmd_error(conn, "Invalid parameters"); + return FALSE; + } + + director_kick_user(conn->dir, conn->host, dir_host, args[0]); + return TRUE; +} + +static bool director_cmd_user_killed(struct director_connection *conn, const char *const *args) { @@ -1316,6 +1335,8 @@ return director_cmd_host_flush(conn, args); if (strcmp(cmd, "USER-MOVE") == 0) return director_cmd_user_move(conn, args); + if (strcmp(cmd, "USER-KICK") == 0) + return director_cmd_user_kick(conn, args); if (strcmp(cmd, "USER-KILLED") == 0) return director_cmd_user_killed(conn, args); if (strcmp(cmd, "USER-KILLED-EVERYWHERE") == 0) diff -r de9b10f2e168 -r 64808a9703db src/director/director.c --- a/src/director/director.c Wed May 28 18:17:52 2014 +0300 +++ b/src/director/director.c Mon Jun 02 04:00:19 2014 +0300 @@ -756,6 +756,32 @@ user->username_hash, net_ip2addr(&user->host->ip))); } +static void +director_kick_user_callback(enum ipc_client_cmd_state state ATTR_UNUSED, + const char *data ATTR_UNUSED, + void *context ATTR_UNUSED) +{ +} + +void director_kick_user(struct director *dir, struct director_host *src, + struct director_host *orig_src, const char *username) +{ + const char *cmd; + + cmd = t_strdup_printf("proxy\t*\tKICK\t%s", username); + ipc_client_cmd(dir->ipc_proxy, cmd, + director_kick_user_callback, (void *)NULL); + + if (orig_src == NULL) { + orig_src = dir->self_host; + orig_src->last_seq++; + } + cmd = t_strdup_printf("USER-KICK\t%s\t%u\t%u\t%s\n", + net_ip2addr(&orig_src->ip), orig_src->port, orig_src->last_seq, + username); + director_update_send_version(dir, src, DIRECTOR_VERSION_USER_KICK, cmd); +} + void director_user_killed(struct director *dir, unsigned int username_hash) { struct user *user; diff -r de9b10f2e168 -r 64808a9703db src/director/director.h --- a/src/director/director.h Wed May 28 18:17:52 2014 +0300 +++ b/src/director/director.h Mon Jun 02 04:00:19 2014 +0300 @@ -6,14 +6,16 @@ #define DIRECTOR_VERSION_NAME "director" #define DIRECTOR_VERSION_MAJOR 1 -#define DIRECTOR_VERSION_MINOR 3 +#define DIRECTOR_VERSION_MINOR 4 -/* weak users supported in protocol v1.1+ */ +/* weak users supported in protocol */ #define DIRECTOR_VERSION_WEAK_USERS 1 -/* director removes supported in v1.2+ */ +/* director ring remove supported */ #define DIRECTOR_VERSION_RING_REMOVE 2 -/* quit reason supported in v1.3+ */ +/* quit reason supported */ #define DIRECTOR_VERSION_QUIT 3 +/* user-kick supported */ +#define DIRECTOR_VERSION_USER_KICK 4 /* Minimum time between even attempting to communicate with a director that failed due to a protocol error. */ @@ -131,6 +133,9 @@ struct director_host *orig_src, unsigned int username_hash, struct mail_host *host) ATTR_NULL(3); +void director_kick_user(struct director *dir, struct director_host *src, + struct director_host *orig_src, const char *username) + ATTR_NULL(3); void director_user_killed(struct director *dir, unsigned int username_hash); void director_user_killed_everywhere(struct director *dir, struct director_host *src, diff -r de9b10f2e168 -r 64808a9703db src/director/doveadm-connection.c --- a/src/director/doveadm-connection.c Wed May 28 18:17:52 2014 +0300 +++ b/src/director/doveadm-connection.c Mon Jun 02 04:00:19 2014 +0300 @@ -380,6 +380,22 @@ return TRUE; } +static bool +doveadm_cmd_user_kick(struct doveadm_connection *conn, const char *line) +{ + const char *const *args; + + args = t_strsplit_tab(line); + if (args[0] == NULL) { + i_error("doveadm sent invalid USER-KICK parameters: %s", line); + return FALSE; + } + + director_kick_user(conn->dir, conn->dir->self_host, NULL, args[0]); + o_stream_nsend(conn->output, "OK\n", 3); + return TRUE; +} + static void doveadm_connection_input(struct doveadm_connection *conn) { const char *line, *cmd, *args; @@ -434,6 +450,8 @@ ret = doveadm_cmd_user_list(conn, args); else if (strcmp(cmd, "USER-MOVE") == 0) ret = doveadm_cmd_user_move(conn, args); + else if (strcmp(cmd, "USER-KICK") == 0) + ret = doveadm_cmd_user_kick(conn, args); else { i_error("doveadm sent unknown command: %s", line); ret = FALSE; diff -r de9b10f2e168 -r 64808a9703db src/doveadm/doveadm-director.c --- a/src/doveadm/doveadm-director.c Wed May 28 18:17:52 2014 +0300 +++ b/src/doveadm/doveadm-director.c Mon Jun 02 04:00:19 2014 +0300 @@ -500,6 +500,32 @@ director_disconnect(ctx); } +static void cmd_director_kick(int argc, char *argv[]) +{ + struct director_context *ctx; + const char *username, *line; + + ctx = cmd_director_init(argc, argv, "a:", cmd_director_kick); + if (argv[optind] == NULL || argv[optind+1] != NULL) + director_cmd_help(cmd_director_kick); + + username = argv[optind]; + + director_send(ctx, t_strdup_printf("USER-KICK\t%s\n", username)); + line = i_stream_read_next_line(ctx->input); + if (line == NULL) { + i_error("failed"); + doveadm_exit_code = EX_TEMPFAIL; + } else if (strcmp(line, "OK") == 0) { + if (doveadm_verbose) + printf("User %s kicked\n", username); + } else { + i_error("failed: %s", line); + doveadm_exit_code = EX_TEMPFAIL; + } + director_disconnect(ctx); +} + static void cmd_director_flush_all(struct director_context *ctx) { const char *line; @@ -729,6 +755,8 @@ "[-a ] " }, { cmd_director_move, "director move", "[-a ] " }, + { cmd_director_kick, "director kick", + "[-a ] " }, { cmd_director_flush, "director flush", "[-a ] |all" }, { cmd_director_dump, "director dump", From dovecot at dovecot.org Mon Jun 2 01:17:51 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jun 2014 01:17:51 +0000 Subject: dovecot-2.2: director: If we detect that a user is being proxied... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8aa0cd95d6a8 changeset: 17419:8aa0cd95d6a8 user: Timo Sirainen date: Mon Jun 02 04:16:08 2014 +0300 description: director: If we detect that a user is being proxied to multiple backends, disconnect wrong connections. Especially IMAP connections can otherwise stay alive for a long time and cause problems. diffstat: src/director/director-connection.c | 31 +++++++++++++++++++++++++++++++ src/director/director.c | 22 ++++++++++++++++++++++ src/director/director.h | 5 +++++ src/login-common/login-proxy.c | 15 +++++++++++++-- 4 files changed, 71 insertions(+), 2 deletions(-) diffs (144 lines): diff -r 64808a9703db -r 8aa0cd95d6a8 src/director/director-connection.c --- a/src/director/director-connection.c Mon Jun 02 04:00:19 2014 +0300 +++ b/src/director/director-connection.c Mon Jun 02 04:16:08 2014 +0300 @@ -531,6 +531,11 @@ /* keep the host */ host = user->host; } + /* especially IMAP connections can take a long time to die. + make sure we kill off the connections in the wrong + backends. */ + director_kick_user_hash(dir, dir->self_host, NULL, + username_hash, &host->ip); ret = TRUE; } if (user->host != host) { @@ -958,6 +963,30 @@ } static bool +director_cmd_user_kick_hash(struct director_connection *conn, + const char *const *args) +{ + struct director_host *dir_host; + unsigned int username_hash; + struct ip_addr except_ip; + int ret; + + if ((ret = director_cmd_is_seen(conn, &args, &dir_host)) != 0) + return ret > 0; + + if (str_array_length(args) != 2 || + str_to_uint(args[0], &username_hash) < 0 || + net_addr2ip(args[1], &except_ip) < 0) { + director_cmd_error(conn, "Invalid parameters"); + return FALSE; + } + + director_kick_user_hash(conn->dir, conn->host, dir_host, + username_hash, &except_ip); + return TRUE; +} + +static bool director_cmd_user_killed(struct director_connection *conn, const char *const *args) { @@ -1337,6 +1366,8 @@ return director_cmd_user_move(conn, args); if (strcmp(cmd, "USER-KICK") == 0) return director_cmd_user_kick(conn, args); + if (strcmp(cmd, "USER-KICK-HASH") == 0) + return director_cmd_user_kick_hash(conn, args); if (strcmp(cmd, "USER-KILLED") == 0) return director_cmd_user_killed(conn, args); if (strcmp(cmd, "USER-KILLED-EVERYWHERE") == 0) diff -r 64808a9703db -r 8aa0cd95d6a8 src/director/director.c --- a/src/director/director.c Mon Jun 02 04:00:19 2014 +0300 +++ b/src/director/director.c Mon Jun 02 04:16:08 2014 +0300 @@ -782,6 +782,28 @@ director_update_send_version(dir, src, DIRECTOR_VERSION_USER_KICK, cmd); } +void director_kick_user_hash(struct director *dir, struct director_host *src, + struct director_host *orig_src, + unsigned int username_hash, + const struct ip_addr *except_ip) +{ + const char *cmd; + + cmd = t_strdup_printf("proxy\t*\tKICK-DIRECTOR-HASH\t%u\t%s", + username_hash, net_ip2addr(except_ip)); + ipc_client_cmd(dir->ipc_proxy, cmd, + director_kick_user_callback, (void *)NULL); + + if (orig_src == NULL) { + orig_src = dir->self_host; + orig_src->last_seq++; + } + cmd = t_strdup_printf("USER-KICK-HASH\t%s\t%u\t%u\t%u\t%s\n", + net_ip2addr(&orig_src->ip), orig_src->port, orig_src->last_seq, + username_hash, net_ip2addr(except_ip)); + director_update_send_version(dir, src, DIRECTOR_VERSION_USER_KICK, cmd); +} + void director_user_killed(struct director *dir, unsigned int username_hash) { struct user *user; diff -r 64808a9703db -r 8aa0cd95d6a8 src/director/director.h --- a/src/director/director.h Mon Jun 02 04:00:19 2014 +0300 +++ b/src/director/director.h Mon Jun 02 04:16:08 2014 +0300 @@ -136,6 +136,11 @@ void director_kick_user(struct director *dir, struct director_host *src, struct director_host *orig_src, const char *username) ATTR_NULL(3); +void director_kick_user_hash(struct director *dir, struct director_host *src, + struct director_host *orig_src, + unsigned int username_hash, + const struct ip_addr *except_ip) + ATTR_NULL(3); void director_user_killed(struct director *dir, unsigned int username_hash); void director_user_killed_everywhere(struct director *dir, struct director_host *src, diff -r 64808a9703db -r 8aa0cd95d6a8 src/login-common/login-proxy.c --- a/src/login-common/login-proxy.c Mon Jun 02 04:00:19 2014 +0300 +++ b/src/login-common/login-proxy.c Mon Jun 02 04:16:08 2014 +0300 @@ -650,17 +650,27 @@ login_proxy_cmd_kick_director_hash(struct ipc_cmd *cmd, const char *const *args) { struct login_proxy *proxy, *next; + struct ip_addr except_ip; unsigned int hash, count = 0; if (args[0] == NULL || str_to_uint(args[0], &hash) < 0) { ipc_cmd_fail(&cmd, "Invalid parameters"); return; } + /* optional except_ip parameter specifies that we're not killing the + connections that are proxying to the except_ip backend */ + except_ip.family = 0; + if (args[1] != NULL && args[1][0] != '\0' && + net_addr2ip(args[1], &except_ip) < 0) { + ipc_cmd_fail(&cmd, "Invalid except_ip parameter"); + return; + } for (proxy = login_proxies; proxy != NULL; proxy = next) { next = proxy->next; - if (director_username_hash(proxy->client) == hash) { + if (director_username_hash(proxy->client) == hash && + !net_ip_compare(&proxy->ip, &except_ip)) { login_proxy_free_reason(&proxy, KILLED_BY_ADMIN_REASON); count++; } @@ -668,7 +678,8 @@ for (proxy = login_proxies_pending; proxy != NULL; proxy = next) { next = proxy->next; - if (director_username_hash(proxy->client) == hash) { + if (director_username_hash(proxy->client) == hash && + !net_ip_compare(&proxy->ip, &except_ip)) { client_destroy(proxy->client, "Connection kicked"); count++; } From dovecot at dovecot.org Mon Jun 2 11:53:49 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jun 2014 11:53:49 +0000 Subject: dovecot-2.2: mail-index: move expunge handler init into helper f... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/211c9493aaa4 changeset: 17420:211c9493aaa4 user: Phil Carmody date: Mon Jun 02 14:50:34 2014 +0300 description: mail-index: move expunge handler init into helper function Preparatory for later optimisation patches where the call to this will be lifted out of the expunge(seq1,seq2) inner function and done once for the whole range of seqs in one go. Based on draft patch by Timo Sirainen. Signed-off-by: Phil Carmody diffstat: src/lib-index/mail-index-sync-update.c | 28 +++++++++++++++++----------- 1 files changed, 17 insertions(+), 11 deletions(-) diffs (52 lines): diff -r 8aa0cd95d6a8 -r 211c9493aaa4 src/lib-index/mail-index-sync-update.c --- a/src/lib-index/mail-index-sync-update.c Mon Jun 02 04:16:08 2014 +0300 +++ b/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 @@ -206,16 +206,6 @@ struct mail_index_record *rec; uint32_t seq; - /* call expunge handlers only when syncing index file */ - if (ctx->type != MAIL_INDEX_SYNC_HANDLER_FILE) - return; - - if (!ctx->expunge_handlers_set) - mail_index_sync_init_expunge_handlers(ctx); - - if (!array_is_created(&ctx->expunge_handlers)) - return; - array_foreach(&ctx->expunge_handlers, eh) { for (seq = seq1; seq <= seq2; seq++) { rec = MAIL_INDEX_MAP_IDX(ctx->view->map, seq-1); @@ -230,6 +220,21 @@ } } +static bool +sync_expunge_handlers_init(struct mail_index_sync_map_ctx *ctx) +{ + /* call expunge handlers only when syncing index file */ + if (ctx->type != MAIL_INDEX_SYNC_HANDLER_FILE) + return FALSE; + + if (!ctx->expunge_handlers_set) + mail_index_sync_init_expunge_handlers(ctx); + + if (!array_is_created(&ctx->expunge_handlers)) + return FALSE; + return TRUE; +} + static void sync_expunge(struct mail_index_sync_map_ctx *ctx, uint32_t seq1, uint32_t seq2) { @@ -237,7 +242,8 @@ struct mail_index_record *rec; uint32_t seq_count, seq; - sync_expunge_call_handlers(ctx, seq1, seq2); + if (sync_expunge_handlers_init(ctx)) + sync_expunge_call_handlers(ctx, seq1, seq2); map = mail_index_sync_get_atomic_map(ctx); for (seq = seq1; seq <= seq2; seq++) { From dovecot at dovecot.org Mon Jun 2 11:53:49 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jun 2014 11:53:49 +0000 Subject: dovecot-2.2: mail-index: call all expunge handlers first Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/aa6e69727edb changeset: 17421:aa6e69727edb user: Phil Carmody date: Mon Jun 02 14:50:34 2014 +0300 description: mail-index: call all expunge handlers first Firstly, the init checking only needs to be done once. More importantly, moving this preparatory stage into its own per-seqs loop means there's less to juggle when we optimise the memmoving loop in subequent patches. Based on draft patch by Timo Sirainen. Signed-off-by: Phil Carmody diffstat: src/lib-index/mail-index-sync-update.c | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-) diffs (32 lines): diff -r 211c9493aaa4 -r aa6e69727edb src/lib-index/mail-index-sync-update.c --- a/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 @@ -242,9 +242,6 @@ struct mail_index_record *rec; uint32_t seq_count, seq; - if (sync_expunge_handlers_init(ctx)) - sync_expunge_call_handlers(ctx, seq1, seq2); - map = mail_index_sync_get_atomic_map(ctx); for (seq = seq1; seq <= seq2; seq++) { rec = MAIL_INDEX_MAP_IDX(map, seq-1); @@ -268,8 +265,17 @@ const struct seq_range *range; unsigned int i, count; + /* call the expunge handlers first */ + range = array_get(seqs, &count); + i_assert(count > 0); + if (sync_expunge_handlers_init(ctx)) { + for (i = 0; i < count; i++) { + sync_expunge_call_handlers(ctx, + range[i].seq1, range[i].seq2); + } + } + /* do this in reverse so the memmove()s are smaller */ - range = array_get(seqs, &count); for (i = count; i > 0; i--) sync_expunge(ctx, range[i-1].seq1, range[i-1].seq2); } From dovecot at dovecot.org Mon Jun 2 11:53:50 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jun 2014 11:53:50 +0000 Subject: dovecot-2.2: mail-index: explicitly inline contents of sync_expu... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/25ce8f635980 changeset: 17422:25ce8f635980 user: Phil Carmody date: Mon Jun 02 14:50:34 2014 +0300 description: mail-index: explicitly inline contents of sync_expunge() To later optimise the memmoves, we will need to be aware of previous seqs. It's easier to just have the guts inlined, so too much state doesn't need to be passed around. For review, this change is best viewed with a whitespace-insensitive diff, to verify that the new contents of the loop are identical to the contents of the now-absorbed function. Based on draft patch by Timo Sirainen. Signed-off-by: Phil Carmody diffstat: src/lib-index/mail-index-sync-update.c | 49 +++++++++++++++------------------ 1 files changed, 23 insertions(+), 26 deletions(-) diffs (66 lines): diff -r aa6e69727edb -r 25ce8f635980 src/lib-index/mail-index-sync-update.c --- a/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 @@ -236,30 +236,6 @@ } static void -sync_expunge(struct mail_index_sync_map_ctx *ctx, uint32_t seq1, uint32_t seq2) -{ - struct mail_index_map *map; - struct mail_index_record *rec; - uint32_t seq_count, seq; - - map = mail_index_sync_get_atomic_map(ctx); - for (seq = seq1; seq <= seq2; seq++) { - rec = MAIL_INDEX_MAP_IDX(map, seq-1); - mail_index_sync_header_update_counts(ctx, rec->uid, rec->flags, 0); - } - - /* @UNSAFE */ - memmove(MAIL_INDEX_MAP_IDX(map, seq1-1), - MAIL_INDEX_MAP_IDX(map, seq2), - (map->rec_map->records_count - seq2) * map->hdr.record_size); - - seq_count = seq2 - seq1 + 1; - map->rec_map->records_count -= seq_count; - map->hdr.messages_count -= seq_count; - mail_index_modseq_expunge(ctx->modseq_ctx, seq1, seq2); -} - -static void sync_expunge_range(struct mail_index_sync_map_ctx *ctx, const ARRAY_TYPE(seq_range) *seqs) { const struct seq_range *range; @@ -276,8 +252,29 @@ } /* do this in reverse so the memmove()s are smaller */ - for (i = count; i > 0; i--) - sync_expunge(ctx, range[i-1].seq1, range[i-1].seq2); + for (i = count; i > 0; i--) { + uint32_t seq1 = range[i-1].seq1; + uint32_t seq2 = range[i-1].seq2; + struct mail_index_map *map; + struct mail_index_record *rec; + uint32_t seq_count, seq; + + map = mail_index_sync_get_atomic_map(ctx); + for (seq = seq1; seq <= seq2; seq++) { + rec = MAIL_INDEX_MAP_IDX(map, seq-1); + mail_index_sync_header_update_counts(ctx, rec->uid, rec->flags, 0); + } + + /* @UNSAFE */ + memmove(MAIL_INDEX_MAP_IDX(map, seq1-1), + MAIL_INDEX_MAP_IDX(map, seq2), + (map->rec_map->records_count - seq2) * map->hdr.record_size); + + seq_count = seq2 - seq1 + 1; + map->rec_map->records_count -= seq_count; + map->hdr.messages_count -= seq_count; + mail_index_modseq_expunge(ctx->modseq_ctx, seq1, seq2); + } } static void *sync_append_record(struct mail_index_map *map) From dovecot at dovecot.org Mon Jun 2 11:53:50 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jun 2014 11:53:50 +0000 Subject: dovecot-2.2: mail-index: hoist initialisation of mail index map ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/74a726930ca8 changeset: 17423:74a726930ca8 user: Phil Carmody date: Mon Jun 02 14:50:34 2014 +0300 description: mail-index: hoist initialisation of mail index map out of expunge loop Based on draft patch by Timo Sirainen. Signed-off-by: Phil Carmody diffstat: src/lib-index/mail-index-sync-update.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (28 lines): diff -r 25ce8f635980 -r 74a726930ca8 src/lib-index/mail-index-sync-update.c --- a/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 @@ -238,9 +238,12 @@ static void sync_expunge_range(struct mail_index_sync_map_ctx *ctx, const ARRAY_TYPE(seq_range) *seqs) { + struct mail_index_map *map; const struct seq_range *range; unsigned int i, count; + map = mail_index_sync_get_atomic_map(ctx); + /* call the expunge handlers first */ range = array_get(seqs, &count); i_assert(count > 0); @@ -255,11 +258,9 @@ for (i = count; i > 0; i--) { uint32_t seq1 = range[i-1].seq1; uint32_t seq2 = range[i-1].seq2; - struct mail_index_map *map; struct mail_index_record *rec; uint32_t seq_count, seq; - map = mail_index_sync_get_atomic_map(ctx); for (seq = seq1; seq <= seq2; seq++) { rec = MAIL_INDEX_MAP_IDX(map, seq-1); mail_index_sync_header_update_counts(ctx, rec->uid, rec->flags, 0); From dovecot at dovecot.org Mon Jun 2 11:53:50 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jun 2014 11:53:50 +0000 Subject: dovecot-2.2: mail-index: Preparatory HACK - reverse the loop ord... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b4c630542488 changeset: 17424:b4c630542488 user: Phil Carmody date: Mon Jun 02 14:50:34 2014 +0300 description: mail-index: Preparatory HACK - reverse the loop order in the expunge This is the final step before the actual optimisation of the memmoves. HACK, as it it de-optimises the moves so as much as possible gets moved as many times as possible. It clears the path for a later patch which optimises them far better. Based on draft patch by Timo Sirainen. Signed-off-by: Phil Carmody diffstat: src/lib-index/mail-index-sync-update.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diffs (18 lines): diff -r 74a726930ca8 -r b4c630542488 src/lib-index/mail-index-sync-update.c --- a/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 @@ -254,10 +254,10 @@ } } - /* do this in reverse so the memmove()s are smaller */ - for (i = count; i > 0; i--) { - uint32_t seq1 = range[i-1].seq1; - uint32_t seq2 = range[i-1].seq2; + /* Preparatory HACK - do this in forward order so the memmove()s are pessimal! */ + for (i = 0; i < count; i++) { + uint32_t seq1 = range[i].seq1; + uint32_t seq2 = range[i].seq2; struct mail_index_record *rec; uint32_t seq_count, seq; From dovecot at dovecot.org Mon Jun 2 11:53:55 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jun 2014 11:53:55 +0000 Subject: dovecot-2.2: mail-index: trivial paranoia check in expunge loop Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1466daa29957 changeset: 17425:1466daa29957 user: Phil Carmody date: Mon Jun 02 14:50:34 2014 +0300 description: mail-index: trivial paranoia check in expunge loop We will later be moving the zone between the current seqs and the (end of the) previous seqs - this check ensures that the range is indeed monotonic, and thus that zone is positive in size. It can be zero right at the start, if the first seqs is (1,...) Based on draft patch by Timo Sirainen. Signed-off-by: Phil Carmody diffstat: src/lib-index/mail-index-sync-update.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (35 lines): diff -r b4c630542488 -r 1466daa29957 src/lib-index/mail-index-sync-update.c --- a/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 @@ -241,6 +241,7 @@ struct mail_index_map *map; const struct seq_range *range; unsigned int i, count; + uint32_t prev_seq2; map = mail_index_sync_get_atomic_map(ctx); @@ -255,12 +256,15 @@ } /* Preparatory HACK - do this in forward order so the memmove()s are pessimal! */ + prev_seq2 = 0; for (i = 0; i < count; i++) { uint32_t seq1 = range[i].seq1; uint32_t seq2 = range[i].seq2; struct mail_index_record *rec; uint32_t seq_count, seq; + i_assert(seq1 > prev_seq2); + for (seq = seq1; seq <= seq2; seq++) { rec = MAIL_INDEX_MAP_IDX(map, seq-1); mail_index_sync_header_update_counts(ctx, rec->uid, rec->flags, 0); @@ -275,6 +279,7 @@ map->rec_map->records_count -= seq_count; map->hdr.messages_count -= seq_count; mail_index_modseq_expunge(ctx->modseq_ctx, seq1, seq2); + prev_seq2 = seq2; } } From dovecot at dovecot.org Mon Jun 2 11:53:55 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jun 2014 11:53:55 +0000 Subject: dovecot-2.2: mail-index: optimise memmoves in expunge, only move... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0b653039d3b9 changeset: 17426:0b653039d3b9 user: Phil Carmody date: Mon Jun 02 14:50:34 2014 +0300 description: mail-index: optimise memmoves in expunge, only move each region once Rather than shifting things back and back and back with potentially O(N^2) (more precisely O(count*rec_count')) work factor, move each slice of memory only once, directly where we want it to end up (O(rec_count') work factor). Based on draft patch by Timo Sirainen. Signed-off-by: Phil Carmody diffstat: src/lib-index/mail-index-sync-update.c | 27 ++++++++++++++++++++------- 1 files changed, 20 insertions(+), 7 deletions(-) diffs (58 lines): diff -r 1466daa29957 -r 0b653039d3b9 src/lib-index/mail-index-sync-update.c --- a/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 @@ -241,7 +241,7 @@ struct mail_index_map *map; const struct seq_range *range; unsigned int i, count; - uint32_t prev_seq2; + uint32_t dest_seq1, prev_seq2, orig_rec_count; map = mail_index_sync_get_atomic_map(ctx); @@ -255,8 +255,9 @@ } } - /* Preparatory HACK - do this in forward order so the memmove()s are pessimal! */ prev_seq2 = 0; + dest_seq1 = 1; + orig_rec_count = map->rec_map->records_count; for (i = 0; i < count; i++) { uint32_t seq1 = range[i].seq1; uint32_t seq2 = range[i].seq2; @@ -270,17 +271,29 @@ mail_index_sync_header_update_counts(ctx, rec->uid, rec->flags, 0); } - /* @UNSAFE */ - memmove(MAIL_INDEX_MAP_IDX(map, seq1-1), - MAIL_INDEX_MAP_IDX(map, seq2), - (map->rec_map->records_count - seq2) * map->hdr.record_size); - + if (prev_seq2+1 <= seq1-1) { + /* @UNSAFE: move (prev_seq2+1) .. (seq1-1) to its + final location in the map if necessary */ + uint32_t move_count = (seq1-1) - (prev_seq2+1) + 1; + if (prev_seq2+1-1 != dest_seq1-1) + memmove(MAIL_INDEX_MAP_IDX(map, dest_seq1-1), + MAIL_INDEX_MAP_IDX(map, prev_seq2+1-1), + move_count * map->hdr.record_size); + dest_seq1 += move_count; + } seq_count = seq2 - seq1 + 1; map->rec_map->records_count -= seq_count; map->hdr.messages_count -= seq_count; mail_index_modseq_expunge(ctx->modseq_ctx, seq1, seq2); prev_seq2 = seq2; } + /* Final stragglers */ + if (orig_rec_count > prev_seq2) { + uint32_t final_move_count = orig_rec_count - prev_seq2; + memmove(MAIL_INDEX_MAP_IDX(map, dest_seq1-1), + MAIL_INDEX_MAP_IDX(map, prev_seq2+1-1), + final_move_count * map->hdr.record_size); + } } static void *sync_append_record(struct mail_index_map *map) From dovecot at dovecot.org Mon Jun 2 11:53:55 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jun 2014 11:53:55 +0000 Subject: dovecot-2.2: mail-index: new helper macro with more user-friendl... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c83ef1042679 changeset: 17427:c83ef1042679 user: Phil Carmody date: Mon Jun 02 14:50:34 2014 +0300 description: mail-index: new helper macro with more user-friendly semantics As the record ids range from 1..records_count, but the data is stored as if in a C-style 0-based array, current clients of MAIL_INDEX_MAP_IDX() must subtract 1 from the index themselved. New MAIL_INDEX_REC_AT_SEQ() macro does the subtraction for you, it gives you (the address of) the record from a seq number. Uglified users of the former will be migrated to the latter. Signed-off-by: Phil Carmody diffstat: src/lib-index/mail-index-private.h | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r 0b653039d3b9 -r c83ef1042679 src/lib-index/mail-index-private.h --- a/src/lib-index/mail-index-private.h Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-private.h Mon Jun 02 14:50:34 2014 +0300 @@ -37,6 +37,9 @@ #define MAIL_INDEX_MAP_IDX(map, idx) \ ((struct mail_index_record *) \ PTR_OFFSET((map)->rec_map->records, (idx) * (map)->hdr.record_size)) +#define MAIL_INDEX_REC_AT_SEQ(map, seq) \ + ((struct mail_index_record *) \ + PTR_OFFSET((map)->rec_map->records, ((seq)-1) * (map)->hdr.record_size)) #define MAIL_TRANSACTION_FLAG_UPDATE_IS_INTERNAL(u) \ ((((u)->add_flags | (u)->remove_flags) & MAIL_INDEX_FLAGS_MASK) == 0 && \ From dovecot at dovecot.org Mon Jun 2 11:53:56 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jun 2014 11:53:56 +0000 Subject: dovecot-2.2: mail-index: trivial robomatic migration from _MAP_I... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4b1117b5cd8e changeset: 17428:4b1117b5cd8e user: Phil Carmody date: Mon Jun 02 14:50:34 2014 +0300 description: mail-index: trivial robomatic migration from _MAP_IDX to new helper All users which have a '-1' in their MAIL_INDEX_MAP_IDX have been changed to the new mail_index_rec_at_seq() helper using this sed script: $ sed -ie 's/MAIL_INDEX_MAP_IDX(\([^,]*[^)]*[^ ]\) \?- \?1)/MAIL_INDEX_REC_AT_SEQ(\1)/' src/lib-index/*.[ch] No other users have been changed. Signed-off-by: Phil Carmody diffstat: src/lib-index/mail-index-map-hdr.c | 2 +- src/lib-index/mail-index-map.c | 4 ++-- src/lib-index/mail-index-modseq.c | 4 ++-- src/lib-index/mail-index-sync-ext.c | 4 ++-- src/lib-index/mail-index-sync-update.c | 12 ++++++------ src/lib-index/mail-index-transaction-finish.c | 2 +- src/lib-index/mail-index-view-sync.c | 4 ++-- src/lib-index/mail-index-view.c | 10 +++++----- 8 files changed, 21 insertions(+), 21 deletions(-) diffs (192 lines): diff -r c83ef1042679 -r 4b1117b5cd8e src/lib-index/mail-index-map-hdr.c --- a/src/lib-index/mail-index-map-hdr.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-map-hdr.c Mon Jun 02 14:50:34 2014 +0300 @@ -290,7 +290,7 @@ also make sure it's not zero. */ const struct mail_index_record *rec; - rec = MAIL_INDEX_MAP_IDX(map, hdr->messages_count-1); + rec = MAIL_INDEX_REC_AT_SEQ(map, hdr->messages_count); if (rec->uid == 0 || rec->uid >= hdr->next_uid) return 0; } diff -r c83ef1042679 -r 4b1117b5cd8e src/lib-index/mail-index-map.c --- a/src/lib-index/mail-index-map.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-map.c Mon Jun 02 14:50:34 2014 +0300 @@ -444,7 +444,7 @@ if (new_map->records_count == 0) new_map->last_appended_uid = 0; else { - rec = MAIL_INDEX_MAP_IDX(map, new_map->records_count-1); + rec = MAIL_INDEX_REC_AT_SEQ(map, new_map->records_count); new_map->last_appended_uid = rec->uid; } buffer_set_used_size(new_map->buffer, new_map->records_count * @@ -554,7 +554,7 @@ *first_seq_r = mail_index_bsearch_uid(map, first_uid, 0, 1); if (*first_seq_r == 0 || - MAIL_INDEX_MAP_IDX(map, *first_seq_r-1)->uid > last_uid) { + MAIL_INDEX_REC_AT_SEQ(map, *first_seq_r)->uid > last_uid) { *first_seq_r = *last_seq_r = 0; return; } diff -r c83ef1042679 -r 4b1117b5cd8e src/lib-index/mail-index-modseq.c --- a/src/lib-index/mail-index-modseq.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-modseq.c Mon Jun 02 14:50:34 2014 +0300 @@ -200,7 +200,7 @@ if (mmap == NULL) return -1; - rec = MAIL_INDEX_MAP_IDX(view->map, seq-1); + rec = MAIL_INDEX_REC_AT_SEQ(view->map, seq); if (!mail_index_map_get_ext_idx(view->map, view->index->modseq_ext_id, &ext_map_idx)) return -1; @@ -304,7 +304,7 @@ ext = array_idx(&ctx->view->map->extensions, ext_map_idx); for (; seq1 <= seq2; seq1++) { - rec = MAIL_INDEX_MAP_IDX(ctx->view->map, seq1-1); + rec = MAIL_INDEX_REC_AT_SEQ(ctx->view->map, seq1); modseqp = PTR_OFFSET(rec, ext->record_offset); if (*modseqp == 0 || (nonzeros && *modseqp < modseq)) *modseqp = modseq; diff -r c83ef1042679 -r 4b1117b5cd8e src/lib-index/mail-index-sync-ext.c --- a/src/lib-index/mail-index-sync-ext.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-sync-ext.c Mon Jun 02 14:50:34 2014 +0300 @@ -674,7 +674,7 @@ i_assert(ext->record_offset + ext->record_size <= view->map->hdr.record_size); - rec = MAIL_INDEX_MAP_IDX(view->map, seq-1); + rec = MAIL_INDEX_REC_AT_SEQ(view->map, seq); old_data = PTR_OFFSET(rec, ext->record_offset); rext = array_idx(&view->index->extensions, ext->index_idx); @@ -723,7 +723,7 @@ i_assert(ext->record_offset + ext->record_size <= view->map->hdr.record_size); - rec = MAIL_INDEX_MAP_IDX(view->map, seq-1); + rec = MAIL_INDEX_REC_AT_SEQ(view->map, seq); data = PTR_OFFSET(rec, ext->record_offset); min_value = u->diff >= 0 ? 0 : (uint64_t)(-(int64_t)u->diff); diff -r c83ef1042679 -r 4b1117b5cd8e src/lib-index/mail-index-sync-update.c --- a/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 @@ -208,7 +208,7 @@ array_foreach(&ctx->expunge_handlers, eh) { for (seq = seq1; seq <= seq2; seq++) { - rec = MAIL_INDEX_MAP_IDX(ctx->view->map, seq-1); + rec = MAIL_INDEX_REC_AT_SEQ(ctx->view->map, seq); /* FIXME: does expunge handler's return value matter? we probably shouldn't disallow expunges if the handler returns failure.. should it be just changed @@ -267,7 +267,7 @@ i_assert(seq1 > prev_seq2); for (seq = seq1; seq <= seq2; seq++) { - rec = MAIL_INDEX_MAP_IDX(map, seq-1); + rec = MAIL_INDEX_REC_AT_SEQ(map, seq); mail_index_sync_header_update_counts(ctx, rec->uid, rec->flags, 0); } @@ -276,8 +276,8 @@ final location in the map if necessary */ uint32_t move_count = (seq1-1) - (prev_seq2+1) + 1; if (prev_seq2+1-1 != dest_seq1-1) - memmove(MAIL_INDEX_MAP_IDX(map, dest_seq1-1), - MAIL_INDEX_MAP_IDX(map, prev_seq2+1-1), + memmove(MAIL_INDEX_REC_AT_SEQ(map, dest_seq1), + MAIL_INDEX_REC_AT_SEQ(map, prev_seq2+1), move_count * map->hdr.record_size); dest_seq1 += move_count; } @@ -290,8 +290,8 @@ /* Final stragglers */ if (orig_rec_count > prev_seq2) { uint32_t final_move_count = orig_rec_count - prev_seq2; - memmove(MAIL_INDEX_MAP_IDX(map, dest_seq1-1), - MAIL_INDEX_MAP_IDX(map, prev_seq2+1-1), + memmove(MAIL_INDEX_REC_AT_SEQ(map, dest_seq1), + MAIL_INDEX_REC_AT_SEQ(map, prev_seq2+1), final_move_count * map->hdr.record_size); } } diff -r c83ef1042679 -r 4b1117b5cd8e src/lib-index/mail-index-transaction-finish.c --- a/src/lib-index/mail-index-transaction-finish.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-transaction-finish.c Mon Jun 02 14:50:34 2014 +0300 @@ -182,7 +182,7 @@ rec = mail_index_transaction_lookup(t, seq); else { i_assert(seq <= t->view->map->hdr.messages_count); - rec = MAIL_INDEX_MAP_IDX(t->view->map, seq - 1); + rec = MAIL_INDEX_REC_AT_SEQ(t->view->map, seq); } i_assert(rec->uid != 0); return rec->uid; diff -r c83ef1042679 -r 4b1117b5cd8e src/lib-index/mail-index-view-sync.c --- a/src/lib-index/mail-index-view-sync.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-view-sync.c Mon Jun 02 14:50:34 2014 +0300 @@ -328,8 +328,8 @@ uint64_t new_modseq; bool changed = FALSE; - old_rec = MAIL_INDEX_MAP_IDX(old_map, old_seq - 1); - new_rec = MAIL_INDEX_MAP_IDX(new_map, new_seq - 1); + old_rec = MAIL_INDEX_REC_AT_SEQ(old_map, old_seq); + new_rec = MAIL_INDEX_REC_AT_SEQ(new_map, new_seq); memset(&thdr, 0, sizeof(thdr)); if (old_rec->flags != new_rec->flags) { diff -r c83ef1042679 -r 4b1117b5cd8e src/lib-index/mail-index-view.c --- a/src/lib-index/mail-index-view.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-view.c Mon Jun 02 14:50:34 2014 +0300 @@ -170,7 +170,7 @@ i_assert(seq > 0 && seq <= mail_index_view_get_messages_count(view)); /* look up the record */ - rec = MAIL_INDEX_MAP_IDX(view->map, seq-1); + rec = MAIL_INDEX_REC_AT_SEQ(view->map, seq); if (unlikely(rec->uid == 0)) { if (!view->inconsistent) { mail_index_set_error(view->index, @@ -243,7 +243,7 @@ { i_assert(seq > 0 && seq <= mail_index_view_get_messages_count(view)); - *uid_r = MAIL_INDEX_MAP_IDX(view->map, seq-1)->uid; + *uid_r = MAIL_INDEX_REC_AT_SEQ(view->map, seq)->uid; } static void view_lookup_seq_range(struct mail_index_view *view, @@ -281,7 +281,7 @@ i_assert(hdr->messages_count <= view->map->rec_map->records_count); for (; seq <= hdr->messages_count; seq++) { - rec = MAIL_INDEX_MAP_IDX(view->map, seq-1); + rec = MAIL_INDEX_REC_AT_SEQ(view->map, seq); if ((rec->flags & flags_mask) == (uint8_t)flags) { *seq_r = seq; break; @@ -470,7 +470,7 @@ if (!mail_index_map_get_ext_idx(map, map->index->keywords_ext_id, &idx)) data = NULL; else { - rec = MAIL_INDEX_MAP_IDX(map, seq-1); + rec = MAIL_INDEX_REC_AT_SEQ(map, seq); ext = array_idx(&map->extensions, idx); data = ext->record_offset == 0 ? NULL : CONST_PTR_OFFSET(rec, ext->record_offset); @@ -493,7 +493,7 @@ i_assert(seq > 0 && seq <= mail_index_view_get_messages_count(view)); - rec = MAIL_INDEX_MAP_IDX(view->map, seq-1); + rec = MAIL_INDEX_REC_AT_SEQ(view->map, seq); *flags_r = rec->flags; keyword_data = view_map_lookup_ext_full(view->map, rec, From dovecot at dovecot.org Mon Jun 2 11:53:56 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jun 2014 11:53:56 +0000 Subject: dovecot-2.2: mail-index: use _REC_AT_SEQ not _MAP_IDX in loops o... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/293966cc6e39 changeset: 17429:293966cc6e39 user: Phil Carmody date: Mon Jun 02 14:50:34 2014 +0300 description: mail-index: use _REC_AT_SEQ not _MAP_IDX in loops over every record Just change the loop bounds from [0..count) to [1..count], and make the loop variale explicitly a seq. Signed-off-by: Phil Carmody diffstat: src/lib-index/mail-index-map-hdr.c | 6 +++--- src/lib-index/mail-index-sync-ext.c | 6 +++--- src/lib-index/mail-index-sync-update.c | 14 +++++++------- 3 files changed, 13 insertions(+), 13 deletions(-) diffs (78 lines): diff -r 4b1117b5cd8e -r 293966cc6e39 src/lib-index/mail-index-map-hdr.c --- a/src/lib-index/mail-index-map-hdr.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-map-hdr.c Mon Jun 02 14:50:34 2014 +0300 @@ -225,10 +225,10 @@ static void mail_index_map_clear_recent_flags(struct mail_index_map *map) { struct mail_index_record *rec; - unsigned int i; + uint32_t seq; - for (i = 0; i < map->hdr.messages_count; i++) { - rec = MAIL_INDEX_MAP_IDX(map, i); + for (seq = 1; seq <= map->hdr.messages_count; seq++) { + rec = MAIL_INDEX_REC_AT_SEQ(map, seq); rec->flags &= ~MAIL_RECENT; } } diff -r 4b1117b5cd8e -r 293966cc6e39 src/lib-index/mail-index-sync-ext.c --- a/src/lib-index/mail-index-sync-ext.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-sync-ext.c Mon Jun 02 14:50:34 2014 +0300 @@ -565,14 +565,14 @@ struct mail_index_ext *ext) { struct mail_index_record *rec; - uint32_t i; + uint32_t seq; memset(buffer_get_space_unsafe(map->hdr_copy_buf, ext->hdr_offset, ext->hdr_size), 0, ext->hdr_size); map->hdr_base = map->hdr_copy_buf->data; - for (i = 0; i < view->map->rec_map->records_count; i++) { - rec = MAIL_INDEX_MAP_IDX(view->map, i); + for (seq = 1; seq <= view->map->rec_map->records_count; seq++) { + rec = MAIL_INDEX_REC_AT_SEQ(view->map, seq); memset(PTR_OFFSET(rec, ext->record_offset), 0, ext->record_size); } diff -r 4b1117b5cd8e -r 293966cc6e39 src/lib-index/mail-index-sync-update.c --- a/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 @@ -854,14 +854,14 @@ static void mail_index_sync_update_hdr_dirty_flag(struct mail_index_map *map) { const struct mail_index_record *rec; - unsigned int i; + uint32_t seq; if ((map->hdr.flags & MAIL_INDEX_HDR_FLAG_HAVE_DIRTY) != 0) return; /* do we have dirty flags anymore? */ - for (i = 0; i < map->rec_map->records_count; i++) { - rec = MAIL_INDEX_MAP_IDX(map, i); + for (seq = 1; seq <= map->rec_map->records_count; seq++) { + rec = MAIL_INDEX_REC_AT_SEQ(map, seq); if ((rec->flags & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0) { map->hdr.flags |= MAIL_INDEX_HDR_FLAG_HAVE_DIRTY; break; @@ -873,14 +873,14 @@ void mail_index_map_check(struct mail_index_map *map) { const struct mail_index_header *hdr = &map->hdr; - unsigned int i, del = 0, seen = 0; - uint32_t prev_uid = 0; + unsigned int del = 0, seen = 0; + uint32_t seq, prev_uid = 0; i_assert(hdr->messages_count <= map->rec_map->records_count); - for (i = 0; i < hdr->messages_count; i++) { + for (seq = 1; seq <= hdr->messages_count; seq++) { const struct mail_index_record *rec; - rec = MAIL_INDEX_MAP_IDX(map, i); + rec = MAIL_INDEX_REC_AT_SEQ(map, seq); i_assert(rec->uid > prev_uid); prev_uid = rec->uid; From dovecot at dovecot.org Mon Jun 2 11:53:56 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jun 2014 11:53:56 +0000 Subject: dovecot-2.2: mail-index: use _REC_AT_SEQ not _MAP_IDX in loops f... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d3564b417e77 changeset: 17430:d3564b417e77 user: Phil Carmody date: Mon Jun 02 14:50:34 2014 +0300 description: mail-index: use _REC_AT_SEQ not _MAP_IDX in loops from [seq1..seq2] [seq1-1..seq2) becomes [seq1..seq2] Don't decrement before starting, and include the upper bound. Signed-off-by: Phil Carmody diffstat: src/lib-index/mail-index-sync-keywords.c | 12 ++++++------ src/lib-index/mail-index-sync-update.c | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diffs (65 lines): diff -r 293966cc6e39 -r d3564b417e77 src/lib-index/mail-index-sync-keywords.c --- a/src/lib-index/mail-index-sync-keywords.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-sync-keywords.c Mon Jun 02 14:50:34 2014 +0300 @@ -228,16 +228,16 @@ switch (type) { case MODIFY_ADD: - for (seq1--; seq1 < seq2; seq1++) { - rec = MAIL_INDEX_MAP_IDX(view->map, seq1); + for (; seq1 <= seq2; seq1++) { + rec = MAIL_INDEX_REC_AT_SEQ(view->map, seq1); data = PTR_OFFSET(rec, data_offset); *data |= data_mask; } break; case MODIFY_REMOVE: data_mask = ~data_mask; - for (seq1--; seq1 < seq2; seq1++) { - rec = MAIL_INDEX_MAP_IDX(view->map, seq1); + for (; seq1 <= seq2; seq1++) { + rec = MAIL_INDEX_REC_AT_SEQ(view->map, seq1); data = PTR_OFFSET(rec, data_offset); *data &= data_mask; } @@ -337,8 +337,8 @@ continue; mail_index_modseq_reset_keywords(ctx->modseq_ctx, seq1, seq2); - for (seq1--; seq1 < seq2; seq1++) { - rec = MAIL_INDEX_MAP_IDX(map, seq1); + for (; seq1 <= seq2; seq1++) { + rec = MAIL_INDEX_REC_AT_SEQ(map, seq1); memset(PTR_OFFSET(rec, ext->record_offset), 0, ext->record_size); } diff -r 293966cc6e39 -r d3564b417e77 src/lib-index/mail-index-sync-update.c --- a/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-sync-update.c Mon Jun 02 14:50:34 2014 +0300 @@ -434,7 +434,7 @@ struct mail_index_view *view = ctx->view; struct mail_index_record *rec; uint8_t flag_mask, old_flags; - uint32_t idx, seq1, seq2; + uint32_t seq, seq1, seq2; if (!mail_index_lookup_seq_range(view, u->uid1, u->uid2, &seq1, &seq2)) return 1; @@ -453,13 +453,13 @@ if (((u->add_flags | u->remove_flags) & (MAIL_SEEN | MAIL_DELETED)) == 0) { /* we're not modifying any counted/lowwatered flags */ - for (idx = seq1-1; idx < seq2; idx++) { - rec = MAIL_INDEX_MAP_IDX(view->map, idx); + for (seq = seq1; seq <= seq2; seq++) { + rec = MAIL_INDEX_REC_AT_SEQ(view->map, seq); rec->flags = (rec->flags & flag_mask) | u->add_flags; } } else { - for (idx = seq1-1; idx < seq2; idx++) { - rec = MAIL_INDEX_MAP_IDX(view->map, idx); + for (seq = seq1; seq <= seq2; seq++) { + rec = MAIL_INDEX_REC_AT_SEQ(view->map, seq); old_flags = rec->flags; rec->flags = (rec->flags & flag_mask) | u->add_flags; From dovecot at dovecot.org Mon Jun 2 11:53:56 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jun 2014 11:53:56 +0000 Subject: dovecot-2.2: mail-index: use _REC_AT_SEQ not _MAP_IDX in backwar... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b579e315d9a8 changeset: 17431:b579e315d9a8 user: Phil Carmody date: Mon Jun 02 14:50:34 2014 +0300 description: mail-index: use _REC_AT_SEQ not _MAP_IDX in backward loops [seq-1 .. 0] becomes [seq .. 1] Don't pre-decrement, and terminate before you process seq=0. Signed-off-by: Phil Carmody diffstat: src/lib-index/mail-index-view.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diffs (17 lines): diff -r d3564b417e77 -r b579e315d9a8 src/lib-index/mail-index-view.c --- a/src/lib-index/mail-index-view.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-view.c Mon Jun 02 14:50:34 2014 +0300 @@ -215,11 +215,10 @@ map = view->index->map; do { - seq--; - head_rec = MAIL_INDEX_MAP_IDX(map, seq); + head_rec = MAIL_INDEX_REC_AT_SEQ(map, seq); if (head_rec->uid <= rec->uid) break; - } while (seq > 0); + } while (--seq > 0); if (head_rec->uid == rec->uid) { /* found it. use it. reference the index mapping so that the From dovecot at dovecot.org Mon Jun 2 11:53:56 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jun 2014 11:53:56 +0000 Subject: dovecot-2.2: mail-index: use _REC_AT_SEQ not _MAP_IDX in view_sy... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/26e097feb136 changeset: 17432:26e097feb136 user: Phil Carmody date: Mon Jun 02 14:50:34 2014 +0300 description: mail-index: use _REC_AT_SEQ not _MAP_IDX in view_sync_get_log_lost_changes Shifting i and j up by one to use in the new macro means we don't need the +1's in the calls to view_sync_apply_lost_changes and mail_index_map_lookup_keywords. Rename them as seq variables too. Signed-off-by: Phil Carmody diffstat: src/lib-index/mail-index-view-sync.c | 26 +++++++++++++------------- 1 files changed, 13 insertions(+), 13 deletions(-) diffs (64 lines): diff -r b579e315d9a8 -r 26e097feb136 src/lib-index/mail-index-view-sync.c --- a/src/lib-index/mail-index-view-sync.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-view-sync.c Mon Jun 02 14:50:34 2014 +0300 @@ -410,7 +410,7 @@ const unsigned int new_count = new_map->hdr.messages_count; const struct mail_index_record *old_rec, *new_rec; struct mail_transaction_header thdr; - unsigned int i, j; + uint32_t seqi, seqj; /* we don't update the map in the same order as it's typically done. map->rec_map may already have some messages appended that we don't @@ -427,19 +427,19 @@ ctx->lost_kw_buf = buffer_create_dynamic(pool_datastack_create(), 128); /* handle expunges and sync flags */ - i = j = 0; - while (i < old_count && j < new_count) { - old_rec = MAIL_INDEX_MAP_IDX(old_map, i); - new_rec = MAIL_INDEX_MAP_IDX(new_map, j); + seqi = seqj = 1; + while (seqi < old_count && seqj < new_count) { + old_rec = MAIL_INDEX_REC_AT_SEQ(old_map, seqi); + new_rec = MAIL_INDEX_REC_AT_SEQ(new_map, seqj); if (old_rec->uid == new_rec->uid) { /* message found - check if flags have changed */ - if (view_sync_apply_lost_changes(ctx, i + 1, j + 1) < 0) + if (view_sync_apply_lost_changes(ctx, seqi, seqj) < 0) return -1; - i++; j++; + seqi++; seqj++; } else if (old_rec->uid < new_rec->uid) { /* message expunged */ seq_range_array_add(&ctx->expunges, old_rec->uid); - i++; + seqi++; } else { /* new message appeared out of nowhere */ mail_index_set_error(view->index, @@ -450,19 +450,19 @@ } } /* if there are old messages left, they're all expunged */ - for (; i < old_count; i++) { - old_rec = MAIL_INDEX_MAP_IDX(old_map, i); + for (; seqi <= old_count; seqi++) { + old_rec = MAIL_INDEX_REC_AT_SEQ(old_map, seqi); seq_range_array_add(&ctx->expunges, old_rec->uid); } /* if there are new messages left, they're all new messages */ thdr.type = MAIL_TRANSACTION_APPEND | MAIL_TRANSACTION_EXTERNAL; thdr.size = sizeof(*new_rec); - for (; j < new_count; j++) { - new_rec = MAIL_INDEX_MAP_IDX(new_map, j); + for (; seqj <= new_count; seqj++) { + new_rec = MAIL_INDEX_REC_AT_SEQ(new_map, seqj); if (mail_index_sync_record(&ctx->sync_map_ctx, &thdr, new_rec) < 0) return -1; - mail_index_map_lookup_keywords(new_map, j + 1, + mail_index_map_lookup_keywords(new_map, seqj, &ctx->lost_new_kw); if (view_sync_update_keywords(ctx, new_rec->uid) < 0) return -1; From dovecot at dovecot.org Mon Jun 2 11:53:56 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jun 2014 11:53:56 +0000 Subject: dovecot-2.2: mail-index: make uid_lookup_idx hold a sequence num... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2d5c66e8d77c changeset: 17433:2d5c66e8d77c user: Phil Carmody date: Mon Jun 02 14:50:34 2014 +0300 description: mail-index: make uid_lookup_idx hold a sequence number, not a 0-based C array index Rename it to _seq, and make it hold values 1.. rather than 0.. . Several uses of the value are simplified by this change, and none are made more confusing, so I think it helps improve maintainability of the code. Signed-off-by: Phil Carmody diffstat: src/lib-index/mail-index-strmap.c | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) diffs (51 lines): diff -r 26e097feb136 -r 2d5c66e8d77c src/lib-index/mail-index-strmap.c --- a/src/lib-index/mail-index-strmap.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-index/mail-index-strmap.c Mon Jun 02 14:50:34 2014 +0300 @@ -57,7 +57,7 @@ struct istream *input; uoff_t end_offset; uint32_t highest_str_idx; - uint32_t uid_lookup_idx; + uint32_t uid_lookup_seq; uint32_t lost_expunged_uid; const unsigned char *data, *end, *str_idx_base; @@ -381,7 +381,7 @@ { const struct mail_index_record *rec; - if (ctx->uid_lookup_idx >= ctx->view->view->map->hdr.messages_count) { + if (ctx->uid_lookup_seq > ctx->view->view->map->hdr.messages_count) { if (uid >= ctx->view->view->map->hdr.next_uid) { /* thread index has larger UIDs than what we've seen in our view. we'll have to read them again later @@ -391,9 +391,9 @@ return 0; } - rec = MAIL_INDEX_MAP_IDX(ctx->view->view->map, ctx->uid_lookup_idx); + rec = MAIL_INDEX_REC_AT_SEQ(ctx->view->view->map, ctx->uid_lookup_seq); if (rec->uid == uid) { - ctx->uid_lookup_idx++; + ctx->uid_lookup_seq++; return 1; } else if (rec->uid > uid) { return 0; @@ -404,7 +404,7 @@ been expunged. */ mail_index_refresh(ctx->view->view->index); if (mail_index_is_expunged(ctx->view->view, - ctx->uid_lookup_idx + 1)) + ctx->uid_lookup_seq)) ctx->lost_expunged_uid = rec->uid; return -1; } @@ -541,7 +541,7 @@ if (!mail_index_lookup_seq_range(view->view, ctx->rec.uid, (uint32_t)-1, &seq1, &seq2)) seq1 = mail_index_view_get_messages_count(view->view) + 1; - ctx->uid_lookup_idx = seq1 - 1; + ctx->uid_lookup_seq = seq1; return 1; } From dovecot at dovecot.org Mon Jun 2 20:59:30 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jun 2014 20:59:30 +0000 Subject: dovecot-2.2: lib-ssl-iostream: Use SSL_MODE_RELEASE_BUFFERS if i... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5c877bca95e5 changeset: 17434:5c877bca95e5 user: Timo Sirainen date: Mon Jun 02 23:58:26 2014 +0300 description: lib-ssl-iostream: Use SSL_MODE_RELEASE_BUFFERS if it exists to reduce memory usage. diffstat: src/lib-ssl-iostream/iostream-openssl-context.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r 2d5c66e8d77c -r 5c877bca95e5 src/lib-ssl-iostream/iostream-openssl-context.c --- a/src/lib-ssl-iostream/iostream-openssl-context.c Mon Jun 02 14:50:34 2014 +0300 +++ b/src/lib-ssl-iostream/iostream-openssl-context.c Mon Jun 02 23:58:26 2014 +0300 @@ -505,6 +505,9 @@ makes SSL more vulnerable against attacks */ SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2 | (SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)); +#ifdef SSL_MODE_RELEASE_BUFFERS + SSL_CTX_set_mode(ctx->ssl_ctx, SSL_MODE_RELEASE_BUFFERS); +#endif if (ssl_proxy_ctx_set_crypto_params(ctx->ssl_ctx, set, error_r) < 0) return -1; From dovecot at dovecot.org Tue Jun 3 20:53:40 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 03 Jun 2014 20:53:40 +0000 Subject: dovecot-2.2: dsync: Fixed renaming duplicate mailbox GUIDs. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9b2900369a72 changeset: 17435:9b2900369a72 user: Timo Sirainen date: Tue Jun 03 23:52:39 2014 +0300 description: dsync: Fixed renaming duplicate mailbox GUIDs. We were trying to use only the last part of the hierarchical name instead of the full name. diffstat: src/doveadm/dsync/dsync-mailbox-tree-fill.c | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) diffs (35 lines): diff -r 5c877bca95e5 -r 9b2900369a72 src/doveadm/dsync/dsync-mailbox-tree-fill.c --- a/src/doveadm/dsync/dsync-mailbox-tree-fill.c Mon Jun 02 23:58:26 2014 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-tree-fill.c Tue Jun 03 23:52:39 2014 +0300 @@ -231,6 +231,7 @@ struct mailbox *box; struct mailbox_update update; struct dsync_mailbox_node *change_node; + const char *change_vname; int ret = 0; memset(&update, 0, sizeof(update)); @@ -244,19 +245,19 @@ else change_node = node2; + change_vname = dsync_mailbox_node_get_full_name(tree, change_node); i_error("Duplicate mailbox GUID %s for mailboxes %s and %s - " "giving a new GUID %s to %s", guid_128_to_string(node1->mailbox_guid), dsync_mailbox_node_get_full_name(tree, node1), dsync_mailbox_node_get_full_name(tree, node2), - guid_128_to_string(update.mailbox_guid), - dsync_mailbox_node_get_full_name(tree, change_node)); + guid_128_to_string(update.mailbox_guid), change_vname); i_assert(node1->ns != NULL && node2->ns != NULL); - box = mailbox_alloc(change_node->ns->list, change_node->name, 0); + box = mailbox_alloc(change_node->ns->list, change_vname, 0); if (mailbox_update(box, &update) < 0) { i_error("Couldn't update mailbox %s GUID: %s", - change_node->name, mailbox_get_last_error(box, NULL)); + change_vname, mailbox_get_last_error(box, NULL)); ret = -1; } else { memcpy(change_node->mailbox_guid, update.mailbox_guid, From dovecot at dovecot.org Tue Jun 3 21:36:30 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 03 Jun 2014 21:36:30 +0000 Subject: dovecot-2.2: doveadm fs delete: When doing recursive deletion, d... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/304d545927d2 changeset: 17436:304d545927d2 user: Timo Sirainen date: Wed Jun 04 00:35:27 2014 +0300 description: doveadm fs delete: When doing recursive deletion, delete also the directories if needed. diffstat: src/doveadm/doveadm-fs.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diffs (16 lines): diff -r 9b2900369a72 -r 304d545927d2 src/doveadm/doveadm-fs.c --- a/src/doveadm/doveadm-fs.c Tue Jun 03 23:52:39 2014 +0300 +++ b/src/doveadm/doveadm-fs.c Wed Jun 04 00:35:27 2014 +0300 @@ -243,7 +243,11 @@ /* delete files. again because we're doing this asynchronously finish the iteration first. */ - array_clear(&fnames); + if ((fs_get_properties(fs) & FS_PROPERTY_DIRECTORIES) != 0) { + /* we need to explicitly delete also the directories */ + } else { + array_clear(&fnames); + } iter = fs_iter_init(fs, path, 0); while ((fname = fs_iter_next(iter)) != NULL) { fname = t_strdup(fname); From dovecot at dovecot.org Thu Jun 5 08:31:37 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 05 Jun 2014 08:31:37 +0000 Subject: dovecot-2.2: *-login: Flush SSL output when logging out. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/09d3c9c6f0ad changeset: 17437:09d3c9c6f0ad user: Timo Sirainen date: Thu Jun 05 11:30:19 2014 +0300 description: *-login: Flush SSL output when logging out. The BYE and LOGOUT replies weren't being sent when they were sent from imap-login process (before logging in). diffstat: src/login-common/client-common.c | 1 + src/login-common/ssl-proxy-openssl.c | 9 +++++++++ 2 files changed, 10 insertions(+), 0 deletions(-) diffs (34 lines): diff -r 304d545927d2 -r 09d3c9c6f0ad src/login-common/client-common.c --- a/src/login-common/client-common.c Wed Jun 04 00:35:27 2014 +0300 +++ b/src/login-common/client-common.c Thu Jun 05 11:30:19 2014 +0300 @@ -172,6 +172,7 @@ last_client = client->prev; DLLIST_REMOVE(&clients, client); + o_stream_uncork(client->output); if (!client->login_success && client->ssl_proxy != NULL) ssl_proxy_destroy(client->ssl_proxy); if (client->input != NULL) diff -r 304d545927d2 -r 09d3c9c6f0ad src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Wed Jun 04 00:35:27 2014 +0300 +++ b/src/login-common/ssl-proxy-openssl.c Thu Jun 05 11:30:19 2014 +0300 @@ -806,10 +806,19 @@ i_free(proxy); } +static void ssl_proxy_flush(struct ssl_proxy *proxy) +{ + /* this is pretty kludgy. mainly this is just for flushing the final + LOGOUT command output. */ + plain_read(proxy); + ssl_step(proxy); +} + void ssl_proxy_destroy(struct ssl_proxy *proxy) { if (proxy->destroyed) return; + ssl_proxy_flush(proxy); proxy->destroyed = TRUE; ssl_proxy_count--; From dovecot at dovecot.org Thu Jun 5 09:36:23 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 05 Jun 2014 09:36:23 +0000 Subject: dovecot-2.1: *-login: Flush SSL output when logging out. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/1afc053e0f88 changeset: 15018:1afc053e0f88 user: Timo Sirainen date: Thu Jun 05 11:30:19 2014 +0300 description: *-login: Flush SSL output when logging out. The BYE and LOGOUT replies weren't being sent when they were sent from imap-login process (before logging in). diffstat: src/login-common/client-common.c | 1 + src/login-common/ssl-proxy-openssl.c | 9 +++++++++ 2 files changed, 10 insertions(+), 0 deletions(-) diffs (34 lines): diff -r 89c0689ab00b -r 1afc053e0f88 src/login-common/client-common.c --- a/src/login-common/client-common.c Wed Apr 23 23:26:49 2014 +0300 +++ b/src/login-common/client-common.c Thu Jun 05 11:30:19 2014 +0300 @@ -142,6 +142,7 @@ last_client = client->prev; DLLIST_REMOVE(&clients, client); + o_stream_uncork(client->output); if (!client->login_success && client->ssl_proxy != NULL) ssl_proxy_destroy(client->ssl_proxy); if (client->input != NULL) diff -r 89c0689ab00b -r 1afc053e0f88 src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Wed Apr 23 23:26:49 2014 +0300 +++ b/src/login-common/ssl-proxy-openssl.c Thu Jun 05 11:30:19 2014 +0300 @@ -782,10 +782,19 @@ i_free(proxy); } +static void ssl_proxy_flush(struct ssl_proxy *proxy) +{ + /* this is pretty kludgy. mainly this is just for flushing the final + LOGOUT command output. */ + plain_read(proxy); + ssl_step(proxy); +} + void ssl_proxy_destroy(struct ssl_proxy *proxy) { if (proxy->destroyed) return; + ssl_proxy_flush(proxy); proxy->destroyed = TRUE; ssl_proxy_count--; From dovecot at dovecot.org Fri Jun 6 13:33:20 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 06 Jun 2014 13:33:20 +0000 Subject: dovecot-2.2: maildir: Mailbox list index refreshing shouldn't ch... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6b9699ab7576 changeset: 17438:6b9699ab7576 user: Timo Sirainen date: Thu Jun 05 13:38:36 2014 +0300 description: maildir: Mailbox list index refreshing shouldn't check cur/new dirs with maildir_very_dirty_syncs=yes The recent mailbox_list_index_very_dirty_syncs change broke this. Just because maildir_very_dirty_syncs=yes, it doesn't mean that mailbox_list_index_very_dirty_syncs=yes also. diffstat: src/lib-storage/index/maildir/maildir-sync-index.c | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletions(-) diffs (26 lines): diff -r 09d3c9c6f0ad -r 6b9699ab7576 src/lib-storage/index/maildir/maildir-sync-index.c --- a/src/lib-storage/index/maildir/maildir-sync-index.c Thu Jun 05 11:30:19 2014 +0300 +++ b/src/lib-storage/index/maildir/maildir-sync-index.c Thu Jun 05 13:38:36 2014 +0300 @@ -717,6 +717,10 @@ ret = index_storage_list_index_has_changed(box, list_view, seq); if (ret != 0 || box->storage->set->mailbox_list_index_very_dirty_syncs) return ret; + if (mbox->storage->set->maildir_very_dirty_syncs) { + /* we don't track cur/new directories with dirty syncs */ + return 0; + } ext_id = maildir_list_get_ext_id(mbox, list_view); mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged); @@ -770,8 +774,10 @@ bool expunged; index_storage_list_index_update_sync(box, trans, seq); - if (mbox->storage->set->maildir_very_dirty_syncs) + if (mbox->storage->set->maildir_very_dirty_syncs) { + /* we don't track cur/new directories with dirty syncs */ return; + } /* get the current record */ list_view = mail_index_transaction_get_view(trans); From dovecot at dovecot.org Fri Jun 6 13:33:21 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 06 Jun 2014 13:33:21 +0000 Subject: dovecot-2.2: lib-storage: Mailbox list index updating didn't che... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/feea8645c4d7 changeset: 17439:feea8645c4d7 user: Timo Sirainen date: Thu Jun 05 13:43:11 2014 +0300 description: lib-storage: Mailbox list index updating didn't check properly if modseq tracking is enabled. mail_index_modseq_enable() can be enabled (e.g. by virtual plugin) without enabling MAILBOX_FEATURE_CONDSTORE. (Actually the MAILBOX_FEATURE_* probably should be removed from lib-storage entirely. They're too much of an IMAP feature.) diffstat: src/lib-storage/list/mailbox-list-index-status.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diffs (13 lines): diff -r 6b9699ab7576 -r feea8645c4d7 src/lib-storage/list/mailbox-list-index-status.c --- a/src/lib-storage/list/mailbox-list-index-status.c Thu Jun 05 13:38:36 2014 +0300 +++ b/src/lib-storage/list/mailbox-list-index-status.c Thu Jun 05 13:43:11 2014 +0300 @@ -313,8 +313,7 @@ /* update highest-modseq only if they're ever been used */ if (old_status.highest_modseq == changes->status.highest_modseq) { changes->hmodseq_changed = FALSE; - } else if ((box->enabled_features & MAILBOX_FEATURE_CONDSTORE) != 0 || - old_status.highest_modseq != 0) { + } else if (mail_index_have_modseq_tracking(box->index)) { changes->hmodseq_changed = TRUE; } else { const void *data; From dovecot at dovecot.org Mon Jun 9 09:14:08 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Jun 2014 09:14:08 +0000 Subject: dovecot-2.2: login proxy: Fixed connection hanging due to wrong ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6a9508d28d34 changeset: 17440:6a9508d28d34 user: Timo Sirainen date: Mon Jun 09 12:12:58 2014 +0300 description: login proxy: Fixed connection hanging due to wrong ostream cork pairing diffstat: src/login-common/login-proxy.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r feea8645c4d7 -r 6a9508d28d34 src/login-common/login-proxy.c --- a/src/login-common/login-proxy.c Thu Jun 05 13:43:11 2014 +0300 +++ b/src/login-common/login-proxy.c Mon Jun 09 12:12:58 2014 +0300 @@ -123,7 +123,7 @@ login_proxy_free_errno(&proxy, errno, "client"); return; } - o_stream_cork(proxy->client_output); + o_stream_cork(proxy->server_output); ret2 = o_stream_send(proxy->server_output, buf, ret); o_stream_uncork(proxy->server_output); if (ret2 != ret) { From dovecot at dovecot.org Mon Jun 9 09:18:36 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Jun 2014 09:18:36 +0000 Subject: dovecot-2.2: login-common: Fixed infinite loop in ssl proxy flus... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7129fe8bc260 changeset: 17441:7129fe8bc260 user: Teemu Huovila date: Mon Jun 09 12:14:42 2014 +0300 description: login-common: Fixed infinite loop in ssl proxy flushing. diffstat: src/login-common/ssl-proxy-openssl.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (22 lines): diff -r 6a9508d28d34 -r 7129fe8bc260 src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Mon Jun 09 12:12:58 2014 +0300 +++ b/src/login-common/ssl-proxy-openssl.c Mon Jun 09 12:14:42 2014 +0300 @@ -79,6 +79,7 @@ unsigned int cert_received:1; unsigned int cert_broken:1; unsigned int client_proxy:1; + unsigned int flushing:1; }; struct ssl_parameters { @@ -816,8 +817,9 @@ void ssl_proxy_destroy(struct ssl_proxy *proxy) { - if (proxy->destroyed) + if (proxy->destroyed || proxy->flushing) return; + proxy->flushing = TRUE; ssl_proxy_flush(proxy); proxy->destroyed = TRUE; From dovecot at dovecot.org Mon Jun 9 10:43:03 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Jun 2014 10:43:03 +0000 Subject: dovecot-2.2: login-common: Fixed potential crash at client disco... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5259f6320e52 changeset: 17442:5259f6320e52 user: Timo Sirainen date: Mon Jun 09 13:41:59 2014 +0300 description: login-common: Fixed potential crash at client disconnect. Broken by recent change diffstat: src/login-common/client-common.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 7129fe8bc260 -r 5259f6320e52 src/login-common/client-common.c --- a/src/login-common/client-common.c Mon Jun 09 12:14:42 2014 +0300 +++ b/src/login-common/client-common.c Mon Jun 09 13:41:59 2014 +0300 @@ -172,7 +172,8 @@ last_client = client->prev; DLLIST_REMOVE(&clients, client); - o_stream_uncork(client->output); + if (client->output != NULL) + o_stream_uncork(client->output); if (!client->login_success && client->ssl_proxy != NULL) ssl_proxy_destroy(client->ssl_proxy); if (client->input != NULL) From dovecot at dovecot.org Mon Jun 9 12:12:55 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Jun 2014 12:12:55 +0000 Subject: dovecot-2.2: lib-ssl-iostream: Implement get_used_size() method. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3e78375be391 changeset: 17443:3e78375be391 user: Timo Sirainen date: Mon Jun 09 15:11:50 2014 +0300 description: lib-ssl-iostream: Implement get_used_size() method. Previously we were always returning that we didn't have anything buffered, which could have caused huge memory usage (or malloc failures) with its users (e.g. dsync). diffstat: src/lib-ssl-iostream/ostream-openssl.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diffs (25 lines): diff -r 5259f6320e52 -r 3e78375be391 src/lib-ssl-iostream/ostream-openssl.c --- a/src/lib-ssl-iostream/ostream-openssl.c Mon Jun 09 13:41:59 2014 +0300 +++ b/src/lib-ssl-iostream/ostream-openssl.c Mon Jun 09 15:11:50 2014 +0300 @@ -188,6 +188,13 @@ return ret > 0 && ret2 > 0 ? 1 : 0; } +static size_t o_stream_ssl_get_used_size(const struct ostream_private *stream) +{ + struct ssl_ostream *sstream = (struct ssl_ostream *)stream; + + return o_stream_get_buffer_used_size(sstream->ssl_io->plain_output); +} + static void o_stream_ssl_flush_pending(struct ostream_private *_stream, bool set) { @@ -221,6 +228,7 @@ sstream->ostream.flush = o_stream_ssl_flush; sstream->ostream.switch_ioloop = o_stream_ssl_switch_ioloop; + sstream->ostream.get_used_size = o_stream_ssl_get_used_size; sstream->ostream.flush_pending = o_stream_ssl_flush_pending; sstream->ostream.iostream.set_max_buffer_size = o_stream_ssl_set_max_buffer_size; From dovecot at dovecot.org Mon Jun 9 15:16:59 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Jun 2014 15:16:59 +0000 Subject: dovecot-2.2: lib: Added some kind of a unit test for hash table. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ff8402fe378e changeset: 17444:ff8402fe378e user: Timo Sirainen date: Mon Jun 09 18:15:51 2014 +0300 description: lib: Added some kind of a unit test for hash table. Just try out some insert+deletes randomly. Mainly I wrote this to check if there is some obvious problem, but looks like not. diffstat: src/lib/Makefile.am | 1 + src/lib/test-hash.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/test-lib.c | 1 + src/lib/test-lib.h | 1 + 4 files changed, 51 insertions(+), 0 deletions(-) diffs (85 lines): diff -r 3e78375be391 -r ff8402fe378e src/lib/Makefile.am --- a/src/lib/Makefile.am Mon Jun 09 15:11:50 2014 +0300 +++ b/src/lib/Makefile.am Mon Jun 09 18:15:51 2014 +0300 @@ -274,6 +274,7 @@ test-bsearch-insert-pos.c \ test-buffer.c \ test-crc32.c \ + test-hash.c \ test-hash-format.c \ test-hash-method.c \ test-hex-binary.c \ diff -r 3e78375be391 -r ff8402fe378e src/lib/test-hash.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/test-hash.c Mon Jun 09 18:15:51 2014 +0300 @@ -0,0 +1,48 @@ +/* Copyright (c) 2014 Dovecot authors, see the included COPYING file */ + +#include "test-lib.h" +#include "hash.h" + +#include + +static void test_hash_random_pool(pool_t pool) +{ +#define KEYMAX 100000 + HASH_TABLE(void *, void *) hash; + unsigned int *keys; + unsigned int i, key, keyidx, delidx; + + keys = i_new(unsigned int, KEYMAX); keyidx = 0; + hash_table_create_direct(&hash, pool, 0); + for (i = 0; i < KEYMAX; i++) { + key = (rand() % KEYMAX) + 1; + if (rand() % 5 > 0) { + if (hash_table_lookup(hash, POINTER_CAST(key)) == NULL) { + hash_table_insert(hash, POINTER_CAST(key), + POINTER_CAST(1)); + keys[keyidx++] = key; + } + } else if (keyidx > 0) { + delidx = rand() % keyidx; + hash_table_remove(hash, POINTER_CAST(keys[delidx])); + memmove(&keys[delidx], &keys[delidx+1], + (keyidx-delidx-1) * sizeof(*keys)); + keyidx--; + } + } + for (i = 0; i < keyidx; i++) + hash_table_remove(hash, POINTER_CAST(keys[i])); + hash_table_destroy(&hash); + i_free(keys); +} + +void test_hash(void) +{ + pool_t pool; + + test_hash_random_pool(default_pool); + + pool = pool_alloconly_create("test hash", 1024); + test_hash_random_pool(pool); + pool_unref(&pool); +} diff -r 3e78375be391 -r ff8402fe378e src/lib/test-lib.c --- a/src/lib/test-lib.c Mon Jun 09 15:11:50 2014 +0300 +++ b/src/lib/test-lib.c Mon Jun 09 18:15:51 2014 +0300 @@ -11,6 +11,7 @@ test_bsearch_insert_pos, test_buffer, test_crc32, + test_hash, test_hash_format, test_hash_method, test_hex_binary, diff -r 3e78375be391 -r ff8402fe378e src/lib/test-lib.h --- a/src/lib/test-lib.h Mon Jun 09 15:11:50 2014 +0300 +++ b/src/lib/test-lib.h Mon Jun 09 18:15:51 2014 +0300 @@ -10,6 +10,7 @@ void test_bsearch_insert_pos(void); void test_buffer(void); void test_crc32(void); +void test_hash(void); void test_hash_format(void); void test_hash_method(void); void test_hex_binary(void); From dovecot at dovecot.org Mon Jun 9 19:54:27 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Jun 2014 19:54:27 +0000 Subject: dovecot-2.2: lib-index: modseq -> {log file, offset} lookup ofte... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/98195220a0f7 changeset: 17445:98195220a0f7 user: Timo Sirainen date: Mon Jun 09 22:53:16 2014 +0300 description: lib-index: modseq -> {log file, offset} lookup often ignored dovecot.index.log.2 This caused the code to think that the modseq was too old and fall back into slower sync. So this change should fix the dsync "Modseq .. nom longer in transaction log" warnings as well as improve IMAP QRESYNC efficiency. diffstat: src/lib-index/mail-index-modseq.c | 19 +++++++++++++++++-- 1 files changed, 17 insertions(+), 2 deletions(-) diffs (30 lines): diff -r ff8402fe378e -r 98195220a0f7 src/lib-index/mail-index-modseq.c --- a/src/lib-index/mail-index-modseq.c Mon Jun 09 18:15:51 2014 +0300 +++ b/src/lib-index/mail-index-modseq.c Mon Jun 09 22:53:16 2014 +0300 @@ -691,9 +691,24 @@ uint64_t modseq, uint32_t *log_seq_r, uoff_t *log_offset_r) { - struct mail_transaction_log_file *file, *prev_file = NULL; + struct mail_transaction_log *log = view->index->log; + struct mail_transaction_log_file *file, *prev_file; + int ret; - for (file = view->index->log->files; file != NULL; file = file->next) { + if (log->files == NULL) { + /* we shouldn't normally get here */ + return FALSE; + } + while (modseq < log->files->hdr.initial_modseq) { + /* try to find the previous log file if it still exists */ + ret = mail_transaction_log_find_file(log, + log->files->hdr.file_seq - 1, FALSE, &file); + if (ret <= 0) + return FALSE; + } + + prev_file = NULL; + for (file = log->files; file != NULL; file = file->next) { if (modseq < file->hdr.initial_modseq) break; prev_file = file; From dovecot at dovecot.org Mon Jun 9 20:01:14 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Jun 2014 20:01:14 +0000 Subject: dovecot-2.2: lib: Fix MEM_ALIGN to cope with huge allocations Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f9349a3c2604 changeset: 17446:f9349a3c2604 user: Phil Carmody date: Mon Jun 09 22:59:59 2014 +0300 description: lib: Fix MEM_ALIGN to cope with huge allocations Attempting to allocate 2^32+1 bytes will look like it succeeds, as MEM_ALIGN will set alloc_size = 8. The caller will then think it's got 4 gig to play with. e.g. t_malloc0 will wipe vast areas of memory before segfaulting, which might include useful information we'd like in a corefile. Signed-off-by: Phil Carmody diffstat: src/lib/macros.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 98195220a0f7 -r f9349a3c2604 src/lib/macros.h --- a/src/lib/macros.h Mon Jun 09 22:53:16 2014 +0300 +++ b/src/lib/macros.h Mon Jun 09 22:59:59 2014 +0300 @@ -19,7 +19,7 @@ (sizeof(arr) / sizeof((arr)[0])) #define MEM_ALIGN(size) \ - (((size) + MEM_ALIGN_SIZE-1) & ~((unsigned int) MEM_ALIGN_SIZE-1)) + (((size) + MEM_ALIGN_SIZE-1) & ~((size_t) MEM_ALIGN_SIZE-1)) #define PTR_OFFSET(ptr, offset) \ ((void *) (((unsigned char *) (ptr)) + (offset))) From dovecot at dovecot.org Mon Jun 9 20:04:09 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Jun 2014 20:04:09 +0000 Subject: dovecot-2.2: lib: bit twiddles Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f7af15d654c3 changeset: 17447:f7af15d654c3 user: Phil Carmody date: Mon Jun 09 23:02:52 2014 +0300 description: lib: bit twiddles bits_requiredXX() gives the number of bits required to store an unsigned integer. Here, XX is 8, 16, 32, 64, reperesenting the size of the operand. It belongs in the same file as nearest_power(), which makes most sense in a separate bit twiddles file. Universal enough to stay in lib.h by inclusion. Signed-off-by: Phil Carmody diffstat: src/lib/Makefile.am | 2 ++ src/lib/bits.c | 22 ++++++++++++++++++++++ src/lib/bits.h | 38 ++++++++++++++++++++++++++++++++++++++ src/lib/lib.c | 10 ---------- src/lib/lib.h | 2 +- 5 files changed, 63 insertions(+), 11 deletions(-) diffs (123 lines): diff -r f9349a3c2604 -r f7af15d654c3 src/lib/Makefile.am --- a/src/lib/Makefile.am Mon Jun 09 22:59:59 2014 +0300 +++ b/src/lib/Makefile.am Mon Jun 09 23:02:52 2014 +0300 @@ -17,6 +17,7 @@ askpass.c \ backtrace-string.c \ base64.c \ + bits.c \ bsearch-insert-pos.c \ buffer.c \ child-wait.c \ @@ -146,6 +147,7 @@ askpass.h \ backtrace-string.h \ base64.h \ + bits.h \ bsearch-insert-pos.h \ buffer.h \ child-wait.h \ diff -r f9349a3c2604 -r f7af15d654c3 src/lib/bits.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/bits.c Mon Jun 09 23:02:52 2014 +0300 @@ -0,0 +1,22 @@ +/* Copyright (c) 2001-2014 Dovecot authors, see the included COPYING file */ + +#include "lib.h" + +size_t nearest_power(size_t num) +{ + size_t n = 1; + + i_assert(num <= ((size_t)1 << (CHAR_BIT*sizeof(size_t) - 1))); + + while (n < num) n <<= 1; + return n; +} + +unsigned int bits_required8(uint8_t num) +{ + int ret = 0; + if (num > 0xf) { ret += 4; num >>= 4; } + if (num > 0x3) { ret += 2; num >>= 2; } + num &= ~(num>>1); /* 3->2, else unchanged */ + return ret + num; +} diff -r f9349a3c2604 -r f7af15d654c3 src/lib/bits.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/bits.h Mon Jun 09 23:02:52 2014 +0300 @@ -0,0 +1,38 @@ +#ifndef BITS_H +#define BITS_H + +/* default lib includes */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "macros.h" + +#include +#include +#include + +size_t nearest_power(size_t num) ATTR_CONST; + +unsigned int bits_required8(uint8_t num) ATTR_CONST; + +static inline +unsigned int bits_required16(uint16_t num) +{ + return (num <= 0xff) ? bits_required8(num) + : 8 + bits_required16(num >> 8); +} +static inline +unsigned int bits_required32(uint32_t num) +{ + return (num <= 0xffff) ? bits_required16(num) + : 16 + bits_required16(num >> 16); +} +static inline +unsigned int bits_required64(uint64_t num) +{ + return (num <= 0xffffffff) ? bits_required32(num) + : 32 + bits_required32(num >> 32); +} + +#endif diff -r f9349a3c2604 -r f7af15d654c3 src/lib/lib.c --- a/src/lib/lib.c Mon Jun 09 22:59:59 2014 +0300 +++ b/src/lib/lib.c Mon Jun 09 23:02:52 2014 +0300 @@ -13,16 +13,6 @@ static ARRAY(lib_atexit_callback_t *) atexit_callbacks = ARRAY_INIT; -size_t nearest_power(size_t num) -{ - size_t n = 1; - - i_assert(num <= ((size_t)1 << (CHAR_BIT*sizeof(size_t) - 1))); - - while (n < num) n <<= 1; - return n; -} - int close_keep_errno(int *fd) { int ret, old_errno = errno; diff -r f9349a3c2604 -r f7af15d654c3 src/lib/lib.h --- a/src/lib/lib.h Mon Jun 09 22:59:59 2014 +0300 +++ b/src/lib/lib.h Mon Jun 09 23:02:52 2014 +0300 @@ -38,11 +38,11 @@ typedef void lib_atexit_callback_t(void); #include "array-decl.h" /* ARRAY*()s may exist in any header */ +#include "bits.h" #include "hash-decl.h" /* HASH_TABLE*()s may exist in any header */ #include "strfuncs.h" #include "strnum.h" -size_t nearest_power(size_t num) ATTR_CONST; int close_keep_errno(int *fd); /* Call the given callback at the beginning of lib_deinit(). The main From dovecot at dovecot.org Mon Jun 9 20:04:09 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Jun 2014 20:04:09 +0000 Subject: dovecot-2.2: lib-test: test_assert helper for loops Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ed9e50227250 changeset: 17448:ed9e50227250 user: Phil Carmody date: Mon Jun 09 23:02:52 2014 +0300 description: lib-test: test_assert helper for loops If you're repeatedly testing the same expression in a loop, it's good to know where you are in the loop. Add an additional parameter for these cases. Signed-off-by: Phil Carmody diffstat: src/lib-test/test-common.c | 6 ++++++ src/lib-test/test-common.h | 7 +++++++ 2 files changed, 13 insertions(+), 0 deletions(-) diffs (34 lines): diff -r f7af15d654c3 -r ed9e50227250 src/lib-test/test-common.c --- a/src/lib-test/test-common.c Mon Jun 09 23:02:52 2014 +0300 +++ b/src/lib-test/test-common.c Mon Jun 09 23:02:52 2014 +0300 @@ -136,6 +136,12 @@ test_success = FALSE; } +void test_assert_failed_idx(const char *code, const char *file, unsigned int line, long long i) +{ + printf("%s:%u: Assert(#%lld) failed: %s\n", file, line, i, code); + test_success = FALSE; +} + void test_end(void) { i_assert(test_prefix != NULL); diff -r f7af15d654c3 -r ed9e50227250 src/lib-test/test-common.h --- a/src/lib-test/test-common.h Mon Jun 09 23:02:52 2014 +0300 +++ b/src/lib-test/test-common.h Mon Jun 09 23:02:52 2014 +0300 @@ -11,7 +11,14 @@ #define test_assert(code) STMT_START { \ if (!(code)) test_assert_failed(#code, __FILE__, __LINE__); \ } STMT_END +/* Additional parameter may be int or unsigned int, to indicate which of + * a barrage of tests have failed (such as in a loop). + */ +#define test_assert_idx(code, i) STMT_START { \ + if (!(code)) test_assert_failed_idx(#code, __FILE__, __LINE__, i); \ + } STMT_END void test_assert_failed(const char *code, const char *file, unsigned int line); +void test_assert_failed_idx(const char *code, const char *file, unsigned int line, long long i); void test_end(void); void test_out(const char *name, bool success); From dovecot at dovecot.org Mon Jun 9 20:04:14 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Jun 2014 20:04:14 +0000 Subject: dovecot-2.2: lib: unit tests for lib/bits Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/bc4f09a5cb11 changeset: 17449:bc4f09a5cb11 user: Phil Carmody date: Mon Jun 09 23:02:52 2014 +0300 description: lib: unit tests for lib/bits Signed-off-by: Phil Carmody diffstat: src/lib/Makefile.am | 1 + src/lib/test-bits.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/test-lib.c | 1 + src/lib/test-lib.h | 1 + 4 files changed, 64 insertions(+), 0 deletions(-) diffs (98 lines): diff -r ed9e50227250 -r bc4f09a5cb11 src/lib/Makefile.am --- a/src/lib/Makefile.am Mon Jun 09 23:02:52 2014 +0300 +++ b/src/lib/Makefile.am Mon Jun 09 23:02:52 2014 +0300 @@ -273,6 +273,7 @@ test-array.c \ test-aqueue.c \ test-base64.c \ + test-bits.c \ test-bsearch-insert-pos.c \ test-buffer.c \ test-crc32.c \ diff -r ed9e50227250 -r bc4f09a5cb11 src/lib/test-bits.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/test-bits.c Mon Jun 09 23:02:52 2014 +0300 @@ -0,0 +1,61 @@ +/* Copyright (c) 2001-2014 Dovecot authors, see the included COPYING file */ + +/* Unit tests for bit twiddles library */ + +#include "test-lib.h" + +#include + +/* nearest_power(0) = error bits_requiredXX(0) = 0 + nearest_power(1) = 1 = 1<<0 bits_requiredXX(1) = 1 + nearest_power(2) = 2 = 1<<1 bits_requiredXX(2) = 2 + nearest_power(3) = 4 = 1<<2 bits_requiredXX(3) = 2 + nearest_power(4) = 4 = 1<<2 bits_requiredXX(4) = 3 + nearest_power(5) = 8 = 1<<3 bits_requiredXX(5) = 3 + nearest_power(7) = 8 = 1<<3 bits_requiredXX(7) = 3 + nearest_power(8) = 8 = 1<<3 bits_requiredXX(8) = 4 +*/ + +/* nearest_power(num) == 1ULL << bits_required64(num-1) */ +static void test_nearest_power(void) +{ + unsigned int b; + test_begin("nearest_power()"); + test_assert(nearest_power(1)==1); + test_assert(nearest_power(2)==2); + for (b = 2; b < 63; ++b) { + /* b=2 tests 3,4,5; b=3 tests 7,8,9; ... */ + uint64_t num = 1ULL << b; + test_assert_idx(nearest_power(num-1) == num, b); + test_assert_idx(nearest_power(num ) == num, b); + test_assert_idx(nearest_power(num+1) == num<<1, b); + } + test_end(); +} + +static void test_bits_requiredXX(void) +{ + /* As ..64 depends on ..32 and tests it twice, + * and ..32 depends on ..16 and tests it twice, + * etc., we only test ..64 + */ + unsigned int b; + test_begin("bits_requiredXX()"); + test_assert(bits_required64(0) == 0); + test_assert(bits_required64(1) == 1); + test_assert(bits_required64(2) == 2); + for (b = 2; b < 64; ++b) { + /* b=2 tests 3,4,5; b=3 tests 7,8,9; ... */ + uint64_t num = 1ULL << b; + test_assert_idx(bits_required64(num-1) == b, b); + test_assert_idx(bits_required64(num ) == b+1, b); + test_assert_idx(bits_required64(num+1) == b+1, b); + } + test_end(); +} + +void test_bits() +{ + test_nearest_power(); + test_bits_requiredXX(); +} diff -r ed9e50227250 -r bc4f09a5cb11 src/lib/test-lib.c --- a/src/lib/test-lib.c Mon Jun 09 23:02:52 2014 +0300 +++ b/src/lib/test-lib.c Mon Jun 09 23:02:52 2014 +0300 @@ -8,6 +8,7 @@ test_aqueue, test_array, test_base64, + test_bits, test_bsearch_insert_pos, test_buffer, test_crc32, diff -r ed9e50227250 -r bc4f09a5cb11 src/lib/test-lib.h --- a/src/lib/test-lib.h Mon Jun 09 23:02:52 2014 +0300 +++ b/src/lib/test-lib.h Mon Jun 09 23:02:52 2014 +0300 @@ -7,6 +7,7 @@ void test_aqueue(void); void test_array(void); void test_base64(void); +void test_bits(void); void test_bsearch_insert_pos(void); void test_buffer(void); void test_crc32(void); From dovecot at dovecot.org Mon Jun 9 20:04:15 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Jun 2014 20:04:15 +0000 Subject: dovecot-2.2: lib: fix numpack overflow checking Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1c276f2e59a5 changeset: 17450:1c276f2e59a5 user: Phil Carmody date: Mon Jun 09 23:02:52 2014 +0300 description: lib: fix numpack overflow checking As on broken input, bits may grow without limit, so << bits becomes Undefined Behaviour. Add a simple check to the while loop to prevent this. Also, the (presumably) final byte adds something to the bit length, so include that in the tally. If we didn't get to a final byte due to the above while() condition, then this extra addition does no harm Now we can precisely check for overflow conditions. Note that 64 bits is perfectly OK, only 65+ is an overflow. Note - no longer moving *p if there was a decode error. Expand the test suite to check for overflow cases. Also checked for short-input cases too, while I was there. Signed-off-by: Phil Carmody diffstat: src/lib/numpack.c | 8 +++----- src/lib/test-numpack.c | 39 ++++++++++++++++++++++++++++++--------- 2 files changed, 33 insertions(+), 14 deletions(-) diffs (93 lines): diff -r bc4f09a5cb11 -r 1c276f2e59a5 src/lib/numpack.c --- a/src/lib/numpack.c Mon Jun 09 23:02:52 2014 +0300 +++ b/src/lib/numpack.c Mon Jun 09 23:02:52 2014 +0300 @@ -21,7 +21,7 @@ uint64_t value = 0; unsigned int bits = 0; - for (;;) { + while (bits < 64) { if (c == end) return -1; @@ -33,11 +33,9 @@ c++; } - if (bits >= 64) { - /* overflow */ - *p = end; + bits += bits_required8(*c); + if (bits > 64) /* overflow */ return -1; - } *p = c + 1; *num_r = value; diff -r bc4f09a5cb11 -r 1c276f2e59a5 src/lib/test-numpack.c --- a/src/lib/test-numpack.c Mon Jun 09 23:02:52 2014 +0300 +++ b/src/lib/test-numpack.c Mon Jun 09 23:02:52 2014 +0300 @@ -10,7 +10,7 @@ uint64_t input; uint8_t output[10]; unsigned int output_size; -} tests[] = { +} enc_tests[] = { { 0xffffffff, { 0xff, 0xff, 0xff, 0xff, 0xf }, 5 }, { 0, { 0 }, 1 }, { 0x7f, { 0x7f }, 1 }, @@ -20,6 +20,16 @@ { 0xffffffffffffffff, { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1 }, 10 }, { 0xfffffffe, { 0xfe, 0xff, 0xff, 0xff, 0xf }, 5 }, }; +static struct fail { + uint8_t input[11]; + unsigned int input_size; +} dec_fails[] = { + { { 0 }, 0 }, /* has no termination byte */ + { { 0x80 }, 1 }, /* ditto */ + { { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, 10 }, /* ditto*/ + { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 2 }, 10 }, /* overflow */ + { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }, 11 }, /* ditto */ +}; void test_numpack(void) { @@ -27,18 +37,29 @@ unsigned int i; const uint8_t *p, *end; uint64_t num; + uint64_t magic=0x9669699669969669; - test_begin("numpack"); - for (i = 0; i < N_ELEMENTS(tests); i++) { + test_begin("numpack (good)"); + for (i = 0; i < N_ELEMENTS(enc_tests); i++) { buffer_set_used_size(buf, 0); - numpack_encode(buf, tests[i].input); - test_assert(buf->used == tests[i].output_size && - memcmp(buf->data, tests[i].output, - tests[i].output_size) == 0); + numpack_encode(buf, enc_tests[i].input); + test_assert_idx(buf->used == enc_tests[i].output_size, i); + test_assert_idx(memcmp(buf->data, enc_tests[i].output, + enc_tests[i].output_size) == 0, + i); p = buf->data; end = p + buf->used; - test_assert(numpack_decode(&p, end, &num) == 0); - test_assert(num == tests[i].input); + test_assert_idx(numpack_decode(&p, end, &num) == 0, i); + test_assert_idx(num == enc_tests[i].input, i); + } + test_end(); + + test_begin("numpack (bad)"); + for (i = 0; i < N_ELEMENTS(dec_fails); i++) { + p = dec_fails[i].input; end = p + dec_fails[i].input_size; + num = magic; + test_assert_idx(numpack_decode(&p, end, &num) == -1, i); + test_assert_idx(p == dec_fails[i].input && num == magic, i); } test_end(); } From dovecot at dovecot.org Mon Jun 9 20:09:23 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 09 Jun 2014 20:09:23 +0000 Subject: dovecot-2.2: lib-fs: Fixed crash in fs-sis if hard linking failed. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7b25994a8cb7 changeset: 17451:7b25994a8cb7 user: Timo Sirainen date: Mon Jun 09 23:08:18 2014 +0300 description: lib-fs: Fixed crash in fs-sis if hard linking failed. (For example because there were too many hard links.) Pointed out by Pavel Stano diffstat: src/lib-fs/fs-sis.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 1c276f2e59a5 -r 7b25994a8cb7 src/lib-fs/fs-sis.c --- a/src/lib-fs/fs-sis.c Mon Jun 09 23:02:52 2014 +0300 +++ b/src/lib-fs/fs-sis.c Mon Jun 09 23:08:18 2014 +0300 @@ -395,7 +395,8 @@ return 1; } } - o_stream_unref(&_file->output); + if (_file->output != NULL) + o_stream_unref(&_file->output); if (fs_write_stream_finish(file->super, &file->fs_output) < 0) { fs_sis_file_copy_error(file); From dovecot at dovecot.org Tue Jun 10 14:41:55 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 10 Jun 2014 14:41:55 +0000 Subject: dovecot-2.2: rawlog: Buffer writing to rawlog files to improve p... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c8efc101826b changeset: 17452:c8efc101826b user: Timo Sirainen date: Tue Jun 10 16:40:46 2014 +0200 description: rawlog: Buffer writing to rawlog files to improve performance. diffstat: src/util/rawlog.c | 99 +++++++++++++++++++++++++----------------------------- 1 files changed, 46 insertions(+), 53 deletions(-) diffs (178 lines): diff -r 7b25994a8cb7 -r c8efc101826b src/util/rawlog.c --- a/src/util/rawlog.c Mon Jun 09 23:08:18 2014 +0300 +++ b/src/util/rawlog.c Tue Jun 10 16:40:46 2014 +0200 @@ -36,20 +36,28 @@ struct io *client_io, *server_io; struct ostream *client_output, *server_output; - int fd_in, fd_out; + struct ostream *in_output, *out_output; enum rawlog_flags flags; bool prev_lf_in, prev_lf_out; }; static void rawlog_proxy_destroy(struct rawlog_proxy *proxy) { - if (proxy->fd_in != -1) { - if (close(proxy->fd_in) < 0) - i_error("close(in) failed: %m"); + if (proxy->in_output != NULL) { + o_stream_uncork(proxy->in_output); + if (o_stream_nfinish(proxy->in_output) < 0) { + i_error("write(in) failed: %s", + o_stream_get_error(proxy->in_output)); + } + o_stream_destroy(&proxy->in_output); } - if (proxy->fd_out != -1) { - if (close(proxy->fd_out) < 0) - i_error("close(out) failed: %m"); + if (proxy->out_output != NULL) { + o_stream_uncork(proxy->out_output); + if (o_stream_nfinish(proxy->out_output) < 0) { + i_error("write(out) failed: %s", + o_stream_get_error(proxy->out_output)); + } + o_stream_destroy(&proxy->out_output); } if (proxy->client_io != NULL) io_remove(&proxy->client_io); @@ -70,12 +78,10 @@ io_loop_stop(ioloop); } -static int -write_with_timestamps(int fd, bool *prev_lf, +static void +write_with_timestamps(struct ostream *output, bool *prev_lf, const unsigned char *data, size_t size) { - int ret; - T_BEGIN { const char *timestamp = t_strdup_printf("%ld.%06lu ", (long)ioloop_timeval.tv_sec, @@ -92,57 +98,40 @@ str_append(str, timestamp); } *prev_lf = data[i-1] == '\n'; - ret = write_full(fd, str_data(str), str_len(str)); + o_stream_nsend(output, str_data(str), str_len(str)); } T_END; - return ret; } -static int proxy_write_data(struct rawlog_proxy *proxy, int fd, - bool *prev_lf, const void *data, size_t size) +static void proxy_write_data(struct rawlog_proxy *proxy, struct ostream *output, + bool *prev_lf, const void *data, size_t size) { - if (fd == -1 || size == 0) - return 0; + if (output == NULL || output->closed || size == 0) + return; - if ((proxy->flags & RAWLOG_FLAG_LOG_BOUNDARIES) != 0) { - if (write_full(fd, "<<<\n", 4) < 0) - return -1; - } + if ((proxy->flags & RAWLOG_FLAG_LOG_BOUNDARIES) != 0) + o_stream_nsend_str(output, "<<<\n"); - if ((proxy->flags & RAWLOG_FLAG_LOG_TIMESTAMPS) != 0) { - if (write_with_timestamps(fd, prev_lf, data, size) < 0) - return -1; - } else { - if (write_full(fd, data, size) < 0) - return -1; - } + if ((proxy->flags & RAWLOG_FLAG_LOG_TIMESTAMPS) != 0) + write_with_timestamps(output, prev_lf, data, size); + else + o_stream_nsend(output, data, size); - if ((proxy->flags & RAWLOG_FLAG_LOG_BOUNDARIES) != 0) { - if (write_full(fd, ">>>\n", 4) < 0) - return -1; - } - return 0; + if ((proxy->flags & RAWLOG_FLAG_LOG_BOUNDARIES) != 0) + o_stream_nsend_str(output, ">>>\n"); } static void proxy_write_in(struct rawlog_proxy *proxy, const void *data, size_t size) { - if (proxy_write_data(proxy, proxy->fd_in, &proxy->prev_lf_in, - data, size) < 0) { - /* failed, disable logging */ - i_error("write(in) failed: %m"); - i_close_fd(&proxy->fd_in); - } + proxy_write_data(proxy, proxy->in_output, &proxy->prev_lf_in, + data, size); } static void proxy_write_out(struct rawlog_proxy *proxy, const void *data, size_t size) { - if (proxy_write_data(proxy, proxy->fd_out, &proxy->prev_lf_out, - data, size) < 0) { - /* failed, disable logging */ - i_error("write(out) failed: %m"); - i_close_fd(&proxy->fd_out); - } + proxy_write_data(proxy, proxy->out_output, &proxy->prev_lf_out, + data, size); } static void server_input(struct rawlog_proxy *proxy) @@ -226,28 +215,33 @@ static void proxy_open_logs(struct rawlog_proxy *proxy, const char *path) { const char *fname, *timestamp; + int fd; timestamp = t_strflocaltime("%Y%m%d-%H%M%S", time(NULL)); if ((proxy->flags & RAWLOG_FLAG_LOG_INPUT) != 0) { fname = t_strdup_printf("%s/%s-%s.in", path, timestamp, dec2str(getpid())); - proxy->fd_in = open(fname, O_CREAT|O_EXCL|O_WRONLY, 0600); - if (proxy->fd_in == -1) { - i_error("rawlog_open: open() failed for %s: %m", fname); + fd = open(fname, O_CREAT|O_EXCL|O_WRONLY, 0600); + if (fd == -1) { + i_error("rawlog_open: creat(%s): %m", fname); return; } + proxy->in_output = o_stream_create_fd_file(fd, 0, TRUE); + o_stream_cork(proxy->in_output); } if ((proxy->flags & RAWLOG_FLAG_LOG_OUTPUT) != 0) { fname = t_strdup_printf("%s/%s-%s.out", path, timestamp, dec2str(getpid())); - proxy->fd_out = open(fname, O_CREAT|O_EXCL|O_WRONLY, 0600); - if (proxy->fd_out == -1) { - i_error("rawlog_open: open() failed for %s: %m", fname); - i_close_fd(&proxy->fd_in); + fd = open(fname, O_CREAT|O_EXCL|O_WRONLY, 0600); + if (fd == -1) { + i_error("rawlog_open: creat(%s): %m", fname); + o_stream_destroy(&proxy->in_output); return; } + proxy->out_output = o_stream_create_fd_file(fd, 0, TRUE); + o_stream_cork(proxy->out_output); } } @@ -279,7 +273,6 @@ proxy->flags = flags; proxy->prev_lf_in = proxy->prev_lf_out = TRUE; - proxy->fd_in = proxy->fd_out = -1; proxy_open_logs(proxy, path); return proxy; } From dovecot at dovecot.org Tue Jun 10 15:51:19 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 10 Jun 2014 15:51:19 +0000 Subject: dovecot-2.2: lib: test-bits - fix nearest_power for 32-bit size_t Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/655c4b63035c changeset: 17453:655c4b63035c user: Phil Carmody date: Tue Jun 10 17:49:45 2014 +0200 description: lib: test-bits - fix nearest_power for 32-bit size_t The test blindly went up to b=63, and the function correctly asserted. Signed-off-by: Phil Carmody diffstat: src/lib/test-bits.c | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-) diffs (29 lines): diff -r c8efc101826b -r 655c4b63035c src/lib/test-bits.c --- a/src/lib/test-bits.c Tue Jun 10 16:40:46 2014 +0200 +++ b/src/lib/test-bits.c Tue Jun 10 17:49:45 2014 +0200 @@ -20,16 +20,22 @@ static void test_nearest_power(void) { unsigned int b; + size_t num; test_begin("nearest_power()"); test_assert(nearest_power(1)==1); test_assert(nearest_power(2)==2); - for (b = 2; b < 63; ++b) { - /* b=2 tests 3,4,5; b=3 tests 7,8,9; ... */ - uint64_t num = 1ULL << b; + for (b = 2; b < CHAR_BIT*sizeof(size_t) - 1; ++b) { + /* b=2 tests 3,4,5; b=3 tests 7,8,9; ... b=30 tests ~1G */ + num = (size_t)1 << b; test_assert_idx(nearest_power(num-1) == num, b); test_assert_idx(nearest_power(num ) == num, b); test_assert_idx(nearest_power(num+1) == num<<1, b); } + /* With 32-bit size_t, now: b=31 tests 2G-1, 2G, not 2G+1. */ + num = (size_t)1 << b; + test_assert_idx(nearest_power(num-1) == num, b); + test_assert_idx(nearest_power(num ) == num, b); + /* i_assert()s: test_assert_idx(nearest_power(num+1) == num<<1, b); */ test_end(); } From dovecot at dovecot.org Thu Jun 12 09:52:56 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 09:52:56 +0000 Subject: dovecot-2.2: lib: Changed hash_table_remove() "key not found" pa... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5c617a5036f3 changeset: 17454:5c617a5036f3 user: Timo Sirainen date: Thu Jun 12 12:51:34 2014 +0300 description: lib: Changed hash_table_remove() "key not found" panic to be in a macro itself. This makes it much easier to find out where such crashes are coming from. Since this breaks the ABI in such a many places the ABI version number was increased immediately.. diffstat: configure.ac | 2 +- src/lib/hash.c | 7 ++++--- src/lib/hash.h | 11 ++++++++--- 3 files changed, 13 insertions(+), 7 deletions(-) diffs (72 lines): diff -r 655c4b63035c -r 5c617a5036f3 configure.ac --- a/configure.ac Tue Jun 10 17:49:45 2014 +0200 +++ b/configure.ac Thu Jun 12 12:51:34 2014 +0300 @@ -3,7 +3,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.13],[dovecot at dovecot.org]) -AC_DEFINE_UNQUOTED([DOVECOT_ABI_VERSION], "2.2.ABIv13($PACKAGE_VERSION)", [Dovecot ABI version]) +AC_DEFINE_UNQUOTED([DOVECOT_ABI_VERSION], "2.2.ABIv13.2($PACKAGE_VERSION)", [Dovecot ABI version]) AC_CONFIG_SRCDIR([src]) diff -r 655c4b63035c -r 5c617a5036f3 src/lib/hash.c --- a/src/lib/hash.c Tue Jun 10 17:49:45 2014 +0200 +++ b/src/lib/hash.c Thu Jun 12 12:51:34 2014 +0300 @@ -18,7 +18,7 @@ #undef hash_table_lookup_full #undef hash_table_insert #undef hash_table_update -#undef hash_table_remove +#undef hash_table_try_remove #undef hash_table_count #undef hash_table_iterate_init #undef hash_table_iterate @@ -326,7 +326,7 @@ table->removed_count = 0; } -void hash_table_remove(struct hash_table *table, const void *key) +bool hash_table_try_remove(struct hash_table *table, const void *key) { struct hash_node *node; unsigned int hash; @@ -335,7 +335,7 @@ node = hash_table_lookup_node(table, key, hash); if (unlikely(node == NULL)) - i_panic("key not found from hash"); + return FALSE; node->key = NULL; table->nodes_count--; @@ -344,6 +344,7 @@ table->removed_count++; else if (!hash_table_resize(table, FALSE)) hash_table_compress(table, &table->nodes[hash % table->size]); + return TRUE; } unsigned int hash_table_count(const struct hash_table *table) diff -r 655c4b63035c -r 5c617a5036f3 src/lib/hash.h --- a/src/lib/hash.h Tue Jun 10 17:49:45 2014 +0200 +++ b/src/lib/hash.h Thu Jun 12 12:51:34 2014 +0300 @@ -110,10 +110,15 @@ (void *)((char *)(key) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._key, key)), \ (void *)((char *)(value) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._value, value))) -void hash_table_remove(struct hash_table *table, const void *key); +bool hash_table_try_remove(struct hash_table *table, const void *key); +#define hash_table_try_remove(table, key) \ + hash_table_try_remove((table)._table, \ + (const void *)((const char *)(key) + COMPILE_ERROR_IF_TYPES2_NOT_COMPATIBLE((table)._const_key, (table)._key, key))) #define hash_table_remove(table, key) \ - hash_table_remove((table)._table, \ - (const void *)((const char *)(key) + COMPILE_ERROR_IF_TYPES2_NOT_COMPATIBLE((table)._const_key, (table)._key, key))) + STMT_START { \ + if (unlikely(!hash_table_try_remove(table, key))) \ + i_panic("key not found from hash"); \ + } STMT_END unsigned int hash_table_count(const struct hash_table *table) ATTR_PURE; #define hash_table_count(table) \ hash_table_count((table)._table) From dovecot at dovecot.org Thu Jun 12 20:18:12 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 20:18:12 +0000 Subject: dovecot-2.2: configure: Don't actually run the test to see if in... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0d2824d5088d changeset: 17455:0d2824d5088d user: Timo Sirainen date: Thu Jun 12 23:16:40 2014 +0300 description: configure: Don't actually run the test to see if inotify works. It's definitely no longer needed in modern Linux systems and the test itself can also unintentionally fail sometimes. diffstat: configure.ac | 46 +++++----------------------------------------- 1 files changed, 5 insertions(+), 41 deletions(-) diffs (67 lines): diff -r 5c617a5036f3 -r 0d2824d5088d configure.ac --- a/configure.ac Thu Jun 12 12:51:34 2014 +0300 +++ b/configure.ac Thu Jun 12 23:16:40 2014 +0300 @@ -441,7 +441,7 @@ strtoull strtoll strtouq strtoq getmntinfo \ setpriority quotactl getmntent kqueue kevent backtrace_symbols \ walkcontext dirfd clearenv malloc_usable_size glob fallocate \ - posix_fadvise getpeereid getpeerucred) + posix_fadvise getpeereid getpeerucred inotify_init) AC_CHECK_TYPES([struct sockpeercred],,,[ #include @@ -555,50 +555,14 @@ if test "$notify" = "" || test "$notify" = "inotify" ; then dnl * inotify? - AC_CACHE_CHECK([whether we can use inotify],i_cv_inotify_works,[ - AC_TRY_RUN([ - #define _GNU_SOURCE - #include - #include - #include - #include - - int main() - { - int wd, fd; - char * fn = "/tmp"; - - fd = inotify_init (); - if (fd < 0) - { - perror ("inotify_init"); - return 1; - } - - wd = inotify_add_watch (fd, fn, IN_ALL_EVENTS); - - if (wd < 0) - { - perror ("inotify_add_watch"); - return 2; - } - - inotify_rm_watch (fd, wd); - - close (fd); - return 0; - } - ], [ - i_cv_inotify_works=yes - ], [ - i_cv_inotify_works=no - ]) - ]) - if test $i_cv_inotify_works = yes; then + AC_MSG_CHECKING([whether we can use inotify]) + if test "$ac_cv_func_inotify_init" = yes; then have_notify=inotify notify=inotify + AC_MSG_RESULT("yes") AC_DEFINE(IOLOOP_NOTIFY_INOTIFY,, Use Linux inotify) else + AC_MSG_RESULT("no") if test "$notify" = "inotify"; then AC_MSG_ERROR([inotify requested but not available]) notify="" From dovecot at dovecot.org Thu Jun 12 20:52:56 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 20:52:56 +0000 Subject: dovecot-2.1: mbox: X-Delivery-ID: and X-IMAP: headers weren't dr... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/d50ac1b3330d changeset: 15019:d50ac1b3330d user: Timo Sirainen date: Thu Jun 12 23:51:28 2014 +0300 description: mbox: X-Delivery-ID: and X-IMAP: headers weren't dropped from incoming mails. Because of a missing comma.. Found by Coverity. diffstat: src/lib-storage/index/mbox/mbox-storage.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 1afc053e0f88 -r d50ac1b3330d src/lib-storage/index/mbox/mbox-storage.c --- a/src/lib-storage/index/mbox/mbox-storage.c Thu Jun 05 11:30:19 2014 +0300 +++ b/src/lib-storage/index/mbox/mbox-storage.c Thu Jun 12 23:51:28 2014 +0300 @@ -53,7 +53,7 @@ const char *mbox_save_drop_headers[] = { "Content-Length", "Status", - "X-Delivery-ID" + "X-Delivery-ID", "X-IMAP", "X-IMAPbase", "X-Keywords", From dovecot at dovecot.org Thu Jun 12 23:20:35 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:35 +0000 Subject: dovecot-2.2: doveadm who: Don't crash if server happens to send ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/beb44a468a73 changeset: 17456:beb44a468a73 user: Timo Sirainen date: Thu Jun 12 23:47:55 2014 +0300 description: doveadm who: Don't crash if server happens to send broken input. Found by Coverity. diffstat: src/doveadm/doveadm-who.c | 11 ++++++++--- 1 files changed, 8 insertions(+), 3 deletions(-) diffs (38 lines): diff -r 0d2824d5088d -r beb44a468a73 src/doveadm/doveadm-who.c --- a/src/doveadm/doveadm-who.c Thu Jun 12 23:16:40 2014 +0300 +++ b/src/doveadm/doveadm-who.c Thu Jun 12 23:47:55 2014 +0300 @@ -50,7 +50,7 @@ return FALSE; } -static void who_parse_line(const char *line, struct who_line *line_r) +static int who_parse_line(const char *line, struct who_line *line_r) { const char *const *args = t_strsplit_tab(line); const char *ident = args[0]; @@ -64,9 +64,12 @@ line_r->pid = strtoul(pid_str, NULL, 10); line_r->service = t_strdup_until(ident, p++); line_r->username = strchr(p, '/'); + if (line_r->username == NULL) + return -1; line_r->refcount = atoi(refcount_str); ip_str = t_strdup_until(p, line_r->username++); (void)net_addr2ip(ip_str, &line_r->ip); + return 0; } static bool who_user_has_pid(struct who_user *user, pid_t pid) @@ -146,8 +149,10 @@ T_BEGIN { struct who_line who_line; - who_parse_line(line, &who_line); - callback(ctx, &who_line); + if (who_parse_line(line, &who_line) < 0) + i_error("Invalid input: %s", line); + else + callback(ctx, &who_line); } T_END; } if (input->stream_errno != 0) From dovecot at dovecot.org Thu Jun 12 23:20:35 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:35 +0000 Subject: dovecot-2.2: mbox: X-Delivery-ID: and X-IMAP: headers weren't dr... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/362ad646e37a changeset: 17457:362ad646e37a user: Timo Sirainen date: Thu Jun 12 23:51:28 2014 +0300 description: mbox: X-Delivery-ID: and X-IMAP: headers weren't dropped from incoming mails. Because of a missing comma.. Found by Coverity. diffstat: src/lib-storage/index/mbox/mbox-storage.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r beb44a468a73 -r 362ad646e37a src/lib-storage/index/mbox/mbox-storage.c --- a/src/lib-storage/index/mbox/mbox-storage.c Thu Jun 12 23:47:55 2014 +0300 +++ b/src/lib-storage/index/mbox/mbox-storage.c Thu Jun 12 23:51:28 2014 +0300 @@ -53,7 +53,7 @@ const char *mbox_save_drop_headers[] = { "Content-Length", "Status", - "X-Delivery-ID" + "X-Delivery-ID", "X-IMAP", "X-IMAPbase", "X-Keywords", From dovecot at dovecot.org Thu Jun 12 23:20:35 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:35 +0000 Subject: dovecot-2.2: dsync: Fixed potential crash when debug logging was... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fd6d650f292e changeset: 17458:fd6d650f292e user: Timo Sirainen date: Fri Jun 13 00:00:31 2014 +0300 description: dsync: Fixed potential crash when debug logging was enabled. Found by Coverity. diffstat: src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 362ad646e37a -r fd6d650f292e src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c --- a/src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c Thu Jun 12 23:51:28 2014 +0300 +++ b/src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c Fri Jun 13 00:00:31 2014 +0300 @@ -146,7 +146,7 @@ i_debug("brain %c: Change during sync: " "Mailbox %s mailbox_list_delete_dir conflict: %s", brain->master_brain ? 'M' : 'S', - mailbox_get_vname(box), errstr); + change->full_name, errstr); } brain->changes_during_sync = TRUE; return 0; From dovecot at dovecot.org Thu Jun 12 23:20:36 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:36 +0000 Subject: dovecot-2.2: lib: Added (void) prefixes to some setsockopt() cal... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e279bd060c28 changeset: 17459:e279bd060c28 user: Timo Sirainen date: Fri Jun 13 00:03:11 2014 +0300 description: lib: Added (void) prefixes to some setsockopt() calls which we don't care if they fail. diffstat: src/lib/net.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) diffs (34 lines): diff -r fd6d650f292e -r e279bd060c28 src/lib/net.c --- a/src/lib/net.c Fri Jun 13 00:00:31 2014 +0300 +++ b/src/lib/net.c Fri Jun 13 00:03:11 2014 +0300 @@ -203,8 +203,8 @@ } /* set socket options */ - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); - setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt)); + (void)setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + (void)setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt)); if (!blocking) net_set_nonblock(fd, TRUE); @@ -418,8 +418,8 @@ } /* set socket options */ - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); - setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt)); + (void)setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + (void)setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt)); if ((*flags & NET_LISTEN_FLAG_REUSEPORT) != 0) { #ifdef SO_REUSEPORT @@ -434,7 +434,7 @@ #ifdef IPV6_V6ONLY if (so.sin.sin_family == AF_INET6) { opt = 1; - setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)); + (void)setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)); } #endif /* specify the address/port we want to listen in */ From dovecot at dovecot.org Thu Jun 12 23:20:36 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:36 +0000 Subject: dovecot-2.2: doveadm sis deduplicate: Error handling fix if open... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c699a3eb0b75 changeset: 17460:c699a3eb0b75 user: Timo Sirainen date: Fri Jun 13 00:05:16 2014 +0300 description: doveadm sis deduplicate: Error handling fix if open() fails. Found by Coverity. diffstat: src/doveadm/doveadm-sis.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r e279bd060c28 -r c699a3eb0b75 src/doveadm/doveadm-sis.c --- a/src/doveadm/doveadm-sis.c Fri Jun 13 00:03:11 2014 +0300 +++ b/src/doveadm/doveadm-sis.c Fri Jun 13 00:05:16 2014 +0300 @@ -45,7 +45,7 @@ return -1; } fd2 = open(path2, O_RDONLY); - if (fd1 == -1) { + if (fd2 == -1) { if (errno != ENOENT) i_error("open(%s) failed: %m", path2); i_close_fd(&fd1); From dovecot at dovecot.org Thu Jun 12 23:20:36 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:36 +0000 Subject: dovecot-2.2: lib: Changed net_geterror() to return errno instead... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2e239d925c09 changeset: 17461:2e239d925c09 user: Timo Sirainen date: Fri Jun 13 00:09:23 2014 +0300 description: lib: Changed net_geterror() to return errno instead of -1 if getsockopt() fails. None of the callers were actually checking for the -1 error value but instead just passing it to strerror(). Since this error should just about never happen it's better to just return a usable return value than try to remember to handle errors that can't normally even happen. Found by Coverity diffstat: src/lib/net.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diffs (18 lines): diff -r c699a3eb0b75 -r 2e239d925c09 src/lib/net.c --- a/src/lib/net.c Fri Jun 13 00:05:16 2014 +0300 +++ b/src/lib/net.c Fri Jun 13 00:09:23 2014 +0300 @@ -961,8 +961,12 @@ int data; socklen_t len = sizeof(data); - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &data, &len) == -1) - return -1; + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &data, &len) == -1) { + /* we're now really returning the getsockopt()'s error code + instead of the socket's, but normally we should never get + here anyway. */ + return errno; + } return data; } From dovecot at dovecot.org Thu Jun 12 23:20:36 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:36 +0000 Subject: dovecot-2.2: auth: passdb/userdb dict settings file parsing didn... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a07ddd1b2763 changeset: 17462:a07ddd1b2763 user: Timo Sirainen date: Fri Jun 13 00:15:47 2014 +0300 description: auth: passdb/userdb dict settings file parsing didn't handle errors correctly. Found by Coverity diffstat: src/auth/db-dict.c | 12 ++++++++---- 1 files changed, 8 insertions(+), 4 deletions(-) diffs (22 lines): diff -r 2e239d925c09 -r a07ddd1b2763 src/auth/db-dict.c --- a/src/auth/db-dict.c Fri Jun 13 00:09:23 2014 +0300 +++ b/src/auth/db-dict.c Fri Jun 13 00:15:47 2014 +0300 @@ -206,10 +206,14 @@ return FALSE; } if (strcmp(type, "key") == 0) { - if (name == NULL) - return "Key section is missing name"; - if (strchr(name, '.') != NULL) - return "Key section names must not contain '.'"; + if (name == NULL) { + *errormsg = "Key section is missing name"; + return FALSE; + } + if (strchr(name, '.') != NULL) { + *errormsg = "Key section names must not contain '.'"; + return FALSE; + } ctx->section = DICT_SETTINGS_SECTION_KEY; ctx->cur_key = array_append_space(&ctx->conn->set.keys); *ctx->cur_key = default_key_settings; From dovecot at dovecot.org Thu Jun 12 23:20:41 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:41 +0000 Subject: dovecot-2.2: auth: Invalid userdb passwd-file and userdb templat... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9b1734587b28 changeset: 17463:9b1734587b28 user: Timo Sirainen date: Fri Jun 13 00:30:27 2014 +0300 description: auth: Invalid userdb passwd-file and userdb templates may have caused crashes. Using just "key" parameter instead of "key=value" usually worked, but for some keys the code assumed that there was a value and it dereferenced NULL. We'll solve this by just using value="" instead of value=NULL. Found by Coverity diffstat: src/auth/auth-request.c | 2 ++ src/auth/userdb-passwd-file.c | 2 ++ src/auth/userdb-template.c | 2 +- 3 files changed, 5 insertions(+), 1 deletions(-) diffs (36 lines): diff -r a07ddd1b2763 -r 9b1734587b28 src/auth/auth-request.c --- a/src/auth/auth-request.c Fri Jun 13 00:15:47 2014 +0300 +++ b/src/auth/auth-request.c Fri Jun 13 00:30:27 2014 +0300 @@ -1567,6 +1567,8 @@ uid_t uid; gid_t gid; + i_assert(value != NULL); + if (strcmp(name, "uid") == 0) { uid = userdb_parse_uid(request, value); if (uid == (uid_t)-1) { diff -r a07ddd1b2763 -r 9b1734587b28 src/auth/userdb-passwd-file.c --- a/src/auth/userdb-passwd-file.c Fri Jun 13 00:15:47 2014 +0300 +++ b/src/auth/userdb-passwd-file.c Fri Jun 13 00:30:27 2014 +0300 @@ -76,6 +76,8 @@ str_truncate(str, 0); var_expand(str, value + 1, table); value = str_c(str); + } else { + value = ""; } auth_request_set_userdb_field(auth_request, key, value); } diff -r a07ddd1b2763 -r 9b1734587b28 src/auth/userdb-template.c --- a/src/auth/userdb-template.c Fri Jun 13 00:15:47 2014 +0300 +++ b/src/auth/userdb-template.c Fri Jun 13 00:30:27 2014 +0300 @@ -74,7 +74,7 @@ i_assert((count % 2) == 0); for (i = 0; i < count; i += 2) { if (args[i+1] == NULL) - value = NULL; + value = ""; else { str_truncate(str, 0); var_expand(str, args[i+1], table); From dovecot at dovecot.org Thu Jun 12 23:20:41 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:41 +0000 Subject: dovecot-2.2: Removed pointless NULL checks. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/203b3a6f508f changeset: 17464:203b3a6f508f user: Timo Sirainen date: Fri Jun 13 00:45:43 2014 +0300 description: Removed pointless NULL checks. Found by Coverity diffstat: src/director/director.c | 3 +-- src/doveadm/dsync/dsync-mailbox-import.c | 3 +-- src/lib-index/mail-index.c | 3 +-- src/plugins/acl/doveadm-acl.c | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diffs (51 lines): diff -r 9b1734587b28 -r 203b3a6f508f src/director/director.c --- a/src/director/director.c Fri Jun 13 00:30:27 2014 +0300 +++ b/src/director/director.c Fri Jun 13 00:45:43 2014 +0300 @@ -322,8 +322,7 @@ if they are, we want to know it fast. */ if (dir->left != NULL) director_connection_ping(dir->left); - if (dir->right != NULL) - director_connection_ping(dir->right); + director_connection_ping(dir->right); } bool director_resend_sync(struct director *dir) diff -r 9b1734587b28 -r 203b3a6f508f src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Fri Jun 13 00:30:27 2014 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Fri Jun 13 00:45:43 2014 +0300 @@ -530,8 +530,7 @@ } importer->cur_uid_has_change = FALSE; } - importer->cur_uid_has_change = importer->cur_mail != NULL && - importer->cur_mail->uid == wanted_uid; + importer->cur_uid_has_change = importer->cur_mail->uid == wanted_uid; if (importer->mails_have_guids) { if (mail_get_special(importer->cur_mail, MAIL_FETCH_GUID, &importer->cur_guid) < 0) { diff -r 9b1734587b28 -r 203b3a6f508f src/lib-index/mail-index.c --- a/src/lib-index/mail-index.c Fri Jun 13 00:30:27 2014 +0300 +++ b/src/lib-index/mail-index.c Fri Jun 13 00:45:43 2014 +0300 @@ -541,8 +541,7 @@ if ((index->map->hdr.flags & MAIL_INDEX_HDR_FLAG_CORRUPTED) != 0) { /* index was marked corrupted. we'll probably need to recreate the files. */ - if (index->map != NULL) - mail_index_unmap(&index->map); + mail_index_unmap(&index->map); mail_index_close_file(index); mail_transaction_log_close(index->log); if ((ret = mail_index_open_files(index, flags)) <= 0) diff -r 9b1734587b28 -r 203b3a6f508f src/plugins/acl/doveadm-acl.c --- a/src/plugins/acl/doveadm-acl.c Fri Jun 13 00:30:27 2014 +0300 +++ b/src/plugins/acl/doveadm-acl.c Fri Jun 13 00:45:43 2014 +0300 @@ -426,7 +426,7 @@ &rights) < 0) i_fatal("Failed to get rights"); - if (rights == NULL || rights[0] == NULL) + if (rights[0] == NULL) i_info("User %s has no rights for mailbox", ns->user->username); else { i_info("User %s has rights: %s", From dovecot at dovecot.org Thu Jun 12 23:20:41 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:41 +0000 Subject: dovecot-2.2: fts: Minor code cleanup: Don't increment NULL pointer. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0fc86de05ccf changeset: 17465:0fc86de05ccf user: Timo Sirainen date: Fri Jun 13 00:46:34 2014 +0300 description: fts: Minor code cleanup: Don't increment NULL pointer. diffstat: src/plugins/fts/doveadm-dump-fts-expunge-log.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (15 lines): diff -r 203b3a6f508f -r 0fc86de05ccf src/plugins/fts/doveadm-dump-fts-expunge-log.c --- a/src/plugins/fts/doveadm-dump-fts-expunge-log.c Fri Jun 13 00:45:43 2014 +0300 +++ b/src/plugins/fts/doveadm-dump-fts-expunge-log.c Fri Jun 13 00:46:34 2014 +0300 @@ -91,8 +91,9 @@ { const char *p; - p = strrchr(path, '/'); - if (p++ == NULL) + if ((p = strrchr(path, '/')) != NULL) + p++; + else p = path; return strcmp(p, "dovecot-expunges.log") == 0; } From dovecot at dovecot.org Thu Jun 12 23:20:41 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:41 +0000 Subject: dovecot-2.2: imapc: Avoid crashing if server happens to send inv... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/800a28db8116 changeset: 17466:800a28db8116 user: Timo Sirainen date: Fri Jun 13 00:51:44 2014 +0300 description: imapc: Avoid crashing if server happens to send invalid resp-text-codes. If [KEY VALUE] is missing the VALUE, just set it to "" instead of NULL. Found by Coverity diffstat: src/lib-imap-client/imapc-connection.c | 2 +- src/lib-storage/index/imapc/imapc-mailbox.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diffs (33 lines): diff -r 0fc86de05ccf -r 800a28db8116 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Fri Jun 13 00:46:34 2014 +0300 +++ b/src/lib-imap-client/imapc-connection.c Fri Jun 13 00:51:44 2014 +0300 @@ -630,7 +630,7 @@ *value_r = value + 1; } else { *key_r = text; - *value_r = NULL; + *value_r = ""; } return imapc_connection_handle_resp_text_code(conn, *key_r, *value_r); } diff -r 0fc86de05ccf -r 800a28db8116 src/lib-storage/index/imapc/imapc-mailbox.c --- a/src/lib-storage/index/imapc/imapc-mailbox.c Fri Jun 13 00:46:34 2014 +0300 +++ b/src/lib-storage/index/imapc/imapc-mailbox.c Fri Jun 13 00:51:44 2014 +0300 @@ -413,7 +413,7 @@ { uint32_t uid_validity; - if (mbox == NULL || reply->resp_text_value == NULL || + if (mbox == NULL || str_to_uint32(reply->resp_text_value, &uid_validity) < 0) return; @@ -429,7 +429,7 @@ { uint32_t uid_next; - if (mbox == NULL || reply->resp_text_value == NULL || + if (mbox == NULL || str_to_uint32(reply->resp_text_value, &uid_next) < 0) return; From dovecot at dovecot.org Thu Jun 12 23:20:42 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:42 +0000 Subject: dovecot-2.2: director: Fixed crash if master_user_separator is s... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/899cf87a687c changeset: 17467:899cf87a687c user: Timo Sirainen date: Fri Jun 13 00:57:06 2014 +0300 description: director: Fixed crash if master_user_separator is set, but we didn't do a proxy lookup. Found by Coverity diffstat: src/director/login-connection.c | 9 ++++----- 1 files changed, 4 insertions(+), 5 deletions(-) diffs (26 lines): diff -r 800a28db8116 -r 899cf87a687c src/director/login-connection.c --- a/src/director/login-connection.c Fri Jun 13 00:51:44 2014 +0300 +++ b/src/director/login-connection.c Fri Jun 13 00:57:06 2014 +0300 @@ -147,6 +147,10 @@ username = *args + 5; } } + if (!proxy || host || username == NULL) { + login_connection_send_line(conn, line); + return; + } if (*conn->dir->set->master_user_separator != '\0') { /* with master user logins we still want to use only the login username */ @@ -154,11 +158,6 @@ *conn->dir->set->master_user_separator); } - if (!proxy || host || username == NULL) { - login_connection_send_line(conn, line); - return; - } - /* we need to add the host. the lookup might be asynchronous */ request = i_new(struct login_host_request, 1); request->conn = conn; From dovecot at dovecot.org Thu Jun 12 23:20:42 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:42 +0000 Subject: dovecot-2.2: lib: Fixed file_dotlock_replace(flags=DOTLOCK_REPLA... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/aac4f4b886d2 changeset: 17468:aac4f4b886d2 user: Timo Sirainen date: Fri Jun 13 01:02:48 2014 +0300 description: lib: Fixed file_dotlock_replace(flags=DOTLOCK_REPLACE_FLAG_VERIFY_OWNER|DOTLOCK_REPLACE_FLAG_DONT_CLOSE_FD) The verification check failed because fd was already set to -1 by that time. Found by Coverity diffstat: src/lib/file-dotlock.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) diffs (32 lines): diff -r 899cf87a687c -r aac4f4b886d2 src/lib/file-dotlock.c --- a/src/lib/file-dotlock.c Fri Jun 13 00:57:06 2014 +0300 +++ b/src/lib/file-dotlock.c Fri Jun 13 01:02:48 2014 +0300 @@ -855,22 +855,25 @@ { struct dotlock *dotlock; const char *lock_path; + bool is_locked; dotlock = *dotlock_p; *dotlock_p = NULL; + is_locked = (flags & DOTLOCK_REPLACE_FLAG_VERIFY_OWNER) == 0 ? TRUE : + file_dotlock_is_locked(dotlock); + if ((flags & DOTLOCK_REPLACE_FLAG_DONT_CLOSE_FD) != 0) dotlock->fd = -1; - lock_path = file_dotlock_get_lock_path(dotlock); - if ((flags & DOTLOCK_REPLACE_FLAG_VERIFY_OWNER) != 0 && - !file_dotlock_is_locked(dotlock)) { + if (!is_locked) { dotlock_replaced_warning(dotlock, FALSE); errno = EEXIST; file_dotlock_free(&dotlock); return 0; } + lock_path = file_dotlock_get_lock_path(dotlock); if (rename(lock_path, dotlock->path) < 0) { i_error("rename(%s, %s) failed: %m", lock_path, dotlock->path); if (errno == ENOENT) From dovecot at dovecot.org Thu Jun 12 23:20:42 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:42 +0000 Subject: dovecot-2.2: fts: Improved doveadm fts dump for corrupted expung... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/54f1beb8d071 changeset: 17469:54f1beb8d071 user: Timo Sirainen date: Fri Jun 13 01:11:24 2014 +0300 description: fts: Improved doveadm fts dump for corrupted expunge log Although we may still be trying to allocate up to 2 GB of memory, but at least no more than that now. Found by Coverity diffstat: src/plugins/fts/doveadm-dump-fts-expunge-log.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r aac4f4b886d2 -r 54f1beb8d071 src/plugins/fts/doveadm-dump-fts-expunge-log.c --- a/src/plugins/fts/doveadm-dump-fts-expunge-log.c Fri Jun 13 01:02:48 2014 +0300 +++ b/src/plugins/fts/doveadm-dump-fts-expunge-log.c Fri Jun 13 01:11:24 2014 +0300 @@ -36,6 +36,11 @@ if (ret != sizeof(rec)) i_fatal("rec read() %d != %d", (int)ret, (int)sizeof(rec)); + if (rec.record_size < sizeof(rec) + sizeof(uint32_t) || + rec.record_size > INT_MAX) { + i_fatal("Invalid record_size=%u at offset %"PRIuUOFF_T, + rec.record_size, offset); + } data_size = rec.record_size - sizeof(rec); buffer_set_used_size(buf, 0); data = buffer_append_space_unsafe(buf, data_size); From dovecot at dovecot.org Thu Jun 12 23:20:42 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:42 +0000 Subject: dovecot-2.2: lib-otp: OTP_MAX_WORD_LEN wasn't actually enforced,... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ecbe9abc14e3 changeset: 17470:ecbe9abc14e3 user: Timo Sirainen date: Fri Jun 13 01:20:25 2014 +0300 description: lib-otp: OTP_MAX_WORD_LEN wasn't actually enforced, any word lengths could have been used. Doesn't look like this could have caused any real problems. Found by Coverity diffstat: src/lib-otp/otp-parse.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 54f1beb8d071 -r ecbe9abc14e3 src/lib-otp/otp-parse.c --- a/src/lib-otp/otp-parse.c Fri Jun 13 01:11:24 2014 +0300 +++ b/src/lib-otp/otp-parse.c Fri Jun 13 01:20:25 2014 +0300 @@ -106,7 +106,7 @@ } } else { if (i_isalpha(c)) { - if (len > OTP_MAX_WORD_LEN) { + if (++len > OTP_MAX_WORD_LEN) { count = 0; break; } From dovecot at dovecot.org Thu Jun 12 23:20:42 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:42 +0000 Subject: dovecot-2.2: replication plugin: Synchronous notification timeou... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f5cb6a0d615b changeset: 17471:f5cb6a0d615b user: Timo Sirainen date: Fri Jun 13 01:22:23 2014 +0300 description: replication plugin: Synchronous notification timeout error wasn't logged as intended. Found by Coverity diffstat: src/plugins/replication/replication-plugin.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r ecbe9abc14e3 -r f5cb6a0d615b src/plugins/replication/replication-plugin.c --- a/src/plugins/replication/replication-plugin.c Fri Jun 13 01:20:25 2014 +0300 +++ b/src/plugins/replication/replication-plugin.c Fri Jun 13 01:22:23 2014 +0300 @@ -147,7 +147,7 @@ /* + | - */ ret = read(fd, buf, sizeof(buf)); if (ret < 0) { - if (ret != EINTR) { + if (errno != EINTR) { i_error("read(%s) failed: %m", ruser->socket_path); } else { From dovecot at dovecot.org Thu Jun 12 23:20:42 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:42 +0000 Subject: dovecot-2.2: imap-urlauth: Fatal failure error handling wasn't d... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/da3a8fcd91db changeset: 17472:da3a8fcd91db user: Timo Sirainen date: Fri Jun 13 01:26:14 2014 +0300 description: imap-urlauth: Fatal failure error handling wasn't done correctly. Found by Coverity diffstat: src/imap-urlauth/imap-urlauth-worker.c | 17 +++++++---------- 1 files changed, 7 insertions(+), 10 deletions(-) diffs (41 lines): diff -r f5cb6a0d615b -r da3a8fcd91db src/imap-urlauth/imap-urlauth-worker.c --- a/src/imap-urlauth/imap-urlauth-worker.c Fri Jun 13 01:22:23 2014 +0300 +++ b/src/imap-urlauth/imap-urlauth-worker.c Fri Jun 13 01:26:14 2014 +0300 @@ -373,30 +373,27 @@ if ((url_flags & IMAP_URLAUTH_FETCH_FLAG_BINARY) != 0) imap_msgpart_url_set_decode_to_binary(client->url); if ((url_flags & IMAP_URLAUTH_FETCH_FLAG_BODYPARTSTRUCTURE) != 0) { - if (imap_msgpart_url_get_bodypartstructure(client->url, - bpstruct_r, - &error) <= 0) { - if (ret < 0) - return -1; + ret = imap_msgpart_url_get_bodypartstructure(client->url, + bpstruct_r, &error); + if (ret <= 0) { *errormsg_r = t_strdup_printf( "Failed to read URLAUTH \"%s\": %s", url, error); if (client->debug) i_debug("%s", *errormsg_r); - return 0; + return ret; } } /* if requested, read the message part the URL points to */ if ((url_flags & IMAP_URLAUTH_FETCH_FLAG_BODY) != 0 || (url_flags & IMAP_URLAUTH_FETCH_FLAG_BINARY) != 0) { - if (imap_msgpart_url_read_part(client->url, &mpresult, &error) <= 0) { - if (ret < 0) - return -1; + ret = imap_msgpart_url_read_part(client->url, &mpresult, &error); + if (ret <= 0) { *errormsg_r = t_strdup_printf( "Failed to read URLAUTH \"%s\": %s", url, error); if (client->debug) i_debug("%s", *errormsg_r); - return 0; + return ret; } client->msg_part_size = mpresult.size; client->msg_part_input = mpresult.input; From dovecot at dovecot.org Thu Jun 12 23:20:42 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:42 +0000 Subject: dovecot-2.2: lib-storage: Fixed parsing corrupted mailbox list i... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/69fe8462ec21 changeset: 17473:69fe8462ec21 user: Timo Sirainen date: Fri Jun 13 01:30:14 2014 +0300 description: lib-storage: Fixed parsing corrupted mailbox list index header. Duplicate IDs should have caused an error instead of being silently ignored. Found by Coverity diffstat: src/lib-storage/list/mailbox-list-index.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r da3a8fcd91db -r 69fe8462ec21 src/lib-storage/list/mailbox-list-index.c --- a/src/lib-storage/list/mailbox-list-index.c Fri Jun 13 01:26:14 2014 +0300 +++ b/src/lib-storage/list/mailbox-list-index.c Fri Jun 13 01:30:14 2014 +0300 @@ -189,6 +189,7 @@ /* allow extra space in the end as long as last id=0 */ return id == 0 ? 0 : -1; } + prev_id = id; /* get name */ p = memchr(CONST_PTR_OFFSET(data, i), '\0', size-i); From dovecot at dovecot.org Thu Jun 12 23:20:43 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:43 +0000 Subject: dovecot-2.2: Added "fall through" comments to switch statements ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1aca4e8811dc changeset: 17474:1aca4e8811dc user: Timo Sirainen date: Fri Jun 13 01:35:13 2014 +0300 description: Added "fall through" comments to switch statements where break is intentionally missing. This should make Coverity quiet about these.. diffstat: src/doveadm/doveadm-dump-index.c | 1 + src/lib-http/http-request-parser.c | 1 + src/lib/iso8601-date.c | 2 +- 3 files changed, 3 insertions(+), 1 deletions(-) diffs (34 lines): diff -r 69fe8462ec21 -r 1aca4e8811dc src/doveadm/doveadm-dump-index.c --- a/src/doveadm/doveadm-dump-index.c Fri Jun 13 01:30:14 2014 +0300 +++ b/src/doveadm/doveadm-dump-index.c Fri Jun 13 01:35:13 2014 +0300 @@ -477,6 +477,7 @@ memcpy(&value, data, sizeof(value)); str_printfa(str, "%llu ", (unsigned long long)value); } + /* fall through */ case MAIL_CACHE_FIELD_VARIABLE_SIZE: case MAIL_CACHE_FIELD_BITMASK: str_printfa(str, "(%s)", binary_to_hex(data, size)); diff -r 69fe8462ec21 -r 1aca4e8811dc src/lib-http/http-request-parser.c --- a/src/lib-http/http-request-parser.c Fri Jun 13 01:30:14 2014 +0300 +++ b/src/lib-http/http-request-parser.c Fri Jun 13 01:35:13 2014 +0300 @@ -168,6 +168,7 @@ parser->state = HTTP_REQUEST_PARSE_STATE_SKIP_LINE; if (_parser->cur == _parser->end) return 0; + /* fall through */ case HTTP_REQUEST_PARSE_STATE_SKIP_LINE: if (*_parser->cur == '\r' || *_parser->cur == '\n') { if (parser->skipping_line) { diff -r 69fe8462ec21 -r 1aca4e8811dc src/lib/iso8601-date.c --- a/src/lib/iso8601-date.c Fri Jun 13 01:30:14 2014 +0300 +++ b/src/lib/iso8601-date.c Fri Jun 13 01:35:13 2014 +0300 @@ -97,7 +97,7 @@ switch (parser->cur[0]) { case '-': tz_sign = -1; - + /* fall through */ case '+': parser->cur++; From dovecot at dovecot.org Thu Jun 12 23:20:43 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:43 +0000 Subject: dovecot-2.2: lib-mail: message_parser_parse_next_block() now ful... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d26130954761 changeset: 17475:d26130954761 user: Timo Sirainen date: Fri Jun 13 01:52:13 2014 +0300 description: lib-mail: message_parser_parse_next_block() now fully clears block_r to be safe case. I'm not away of this hitting any bugs, but better to be safe. diffstat: src/lib-mail/message-parser.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 1aca4e8811dc -r d26130954761 src/lib-mail/message-parser.c --- a/src/lib-mail/message-parser.c Fri Jun 13 01:35:13 2014 +0300 +++ b/src/lib-mail/message-parser.c Fri Jun 13 01:52:13 2014 +0300 @@ -1012,6 +1012,8 @@ int ret; bool eof = FALSE, full; + memset(block_r, 0, sizeof(*block_r)); + while ((ret = ctx->parse_next_block(ctx, block_r)) == 0) { ret = message_parser_read_more(ctx, block_r, &full); if (ret == 0) { From dovecot at dovecot.org Thu Jun 12 23:20:48 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:48 +0000 Subject: dovecot-2.2: Added various asserts to try to silence Coverity fa... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4a396f0c3b79 changeset: 17476:4a396f0c3b79 user: Timo Sirainen date: Fri Jun 13 01:57:04 2014 +0300 description: Added various asserts to try to silence Coverity false positives. diffstat: src/auth/auth-request.c | 3 +++ src/lib-imap-client/imapc-client.c | 1 + src/lib-index/mail-index-map-read.c | 1 + src/lib-settings/settings.c | 1 + src/lib-storage/index/dbox-common/dbox-save.c | 2 ++ src/lib-storage/index/mbox/mbox-save.c | 1 + src/lib-storage/list/mailbox-list-index-sync.c | 1 + src/lib/connection.c | 1 + src/lib/ioloop-notify-inotify.c | 1 + src/master/main.c | 1 + 10 files changed, 13 insertions(+), 0 deletions(-) diffs (122 lines): diff -r d26130954761 -r 4a396f0c3b79 src/auth/auth-request.c --- a/src/auth/auth-request.c Fri Jun 13 01:52:13 2014 +0300 +++ b/src/auth/auth-request.c Fri Jun 13 01:57:04 2014 +0300 @@ -2151,15 +2151,18 @@ if (subsystem == AUTH_SUBSYS_DB) { if (!auth_request->userdb_lookup) { + i_assert(auth_request->passdb != NULL); name = auth_request->passdb->set->name[0] != '\0' ? auth_request->passdb->set->name : auth_request->passdb->passdb->iface.name; } else { + i_assert(auth_request->userdb != NULL); name = auth_request->userdb->set->name[0] != '\0' ? auth_request->userdb->set->name : auth_request->userdb->userdb->iface->name; } } else if (subsystem == AUTH_SUBSYS_MECH) { + i_assert(auth_request->mech == NULL); name = t_str_lcase(auth_request->mech->mech_name); } else { name = subsystem; diff -r d26130954761 -r 4a396f0c3b79 src/lib-imap-client/imapc-client.c --- a/src/lib-imap-client/imapc-client.c Fri Jun 13 01:52:13 2014 +0300 +++ b/src/lib-imap-client/imapc-client.c Fri Jun 13 01:57:04 2014 +0300 @@ -411,6 +411,7 @@ } /* fallback to whatever exists (there always exists one) */ + i_assert(conn != NULL); return imapc_connection_get_capabilities(conn); } diff -r d26130954761 -r 4a396f0c3b79 src/lib-index/mail-index-map-read.c --- a/src/lib-index/mail-index-map-read.c Fri Jun 13 01:52:13 2014 +0300 +++ b/src/lib-index/mail-index-map-read.c Fri Jun 13 01:57:04 2014 +0300 @@ -306,6 +306,7 @@ build it from the transaction log. */ return 1; } + i_assert(index->fd != -1); if ((index->flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0) nfs_flush_attr_cache_fd_locked(index->filepath, index->fd); diff -r d26130954761 -r 4a396f0c3b79 src/lib-settings/settings.c --- a/src/lib-settings/settings.c Fri Jun 13 01:52:13 2014 +0300 +++ b/src/lib-settings/settings.c Fri Jun 13 01:57:04 2014 +0300 @@ -356,6 +356,7 @@ if (skip > 0) skip--; else { + i_assert(sect_callback != NULL); sect_callback(NULL, NULL, context, &errormsg); if (root_section == sections && diff -r d26130954761 -r 4a396f0c3b79 src/lib-storage/index/dbox-common/dbox-save.c --- a/src/lib-storage/index/dbox-common/dbox-save.c Fri Jun 13 01:52:13 2014 +0300 +++ b/src/lib-storage/index/dbox-common/dbox-save.c Fri Jun 13 01:57:04 2014 +0300 @@ -102,6 +102,8 @@ struct mail_save_data *mdata = &ctx->ctx.data; struct ostream *dbox_output = ctx->dbox_output; + i_assert(mdata->output != NULL); + if (mdata->attach != NULL && !ctx->failed) { if (index_attachment_save_finish(&ctx->ctx) < 0) ctx->failed = TRUE; diff -r d26130954761 -r 4a396f0c3b79 src/lib-storage/index/mbox/mbox-save.c --- a/src/lib-storage/index/mbox/mbox-save.c Fri Jun 13 01:52:13 2014 +0300 +++ b/src/lib-storage/index/mbox/mbox-save.c Fri Jun 13 01:57:04 2014 +0300 @@ -768,6 +768,7 @@ int ret = 0; i_assert(ctx->finished); + i_assert(mbox->mbox_fd != -1); if (fstat(mbox->mbox_fd, &st) < 0) { mbox_set_syscall_error(mbox, "fstat()"); diff -r d26130954761 -r 4a396f0c3b79 src/lib-storage/list/mailbox-list-index-sync.c --- a/src/lib-storage/list/mailbox-list-index-sync.c Fri Jun 13 01:52:13 2014 +0300 +++ b/src/lib-storage/list/mailbox-list-index-sync.c Fri Jun 13 01:57:04 2014 +0300 @@ -175,6 +175,7 @@ buffer_append(hdr_buf, id_p, sizeof(*id_p)); name = hash_table_lookup(ilist->mailbox_names, POINTER_CAST(*id_p)); + i_assert(name != NULL); buffer_append(hdr_buf, name, strlen(name) + 1); prev_id = *id_p; } diff -r d26130954761 -r 4a396f0c3b79 src/lib/connection.c --- a/src/lib/connection.c Fri Jun 13 01:52:13 2014 +0300 +++ b/src/lib/connection.c Fri Jun 13 01:57:04 2014 +0300 @@ -325,6 +325,7 @@ case CONNECTION_BEHAVIOR_ALLOW: return -2; } + i_unreached(); case -1: /* disconnected */ conn->disconnect_reason = diff -r d26130954761 -r 4a396f0c3b79 src/lib/ioloop-notify-inotify.c --- a/src/lib/ioloop-notify-inotify.c Fri Jun 13 01:52:13 2014 +0300 +++ b/src/lib/ioloop-notify-inotify.c Fri Jun 13 01:57:04 2014 +0300 @@ -61,6 +61,7 @@ break; event = (struct inotify_event *)(event_buf + pos); + i_assert(event->len < ret); pos += sizeof(*event) + event->len; io = io_notify_fd_find(&ctx->fd_ctx, event->wd); diff -r d26130954761 -r 4a396f0c3b79 src/master/main.c --- a/src/master/main.c Fri Jun 13 01:52:13 2014 +0300 +++ b/src/master/main.c Fri Jun 13 01:57:04 2014 +0300 @@ -816,6 +816,7 @@ break; } } + i_assert(optind <= argc); if (doveconf_arg != NULL) { const char **args; From dovecot at dovecot.org Thu Jun 12 23:20:48 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:48 +0000 Subject: dovecot-2.2: director-test: Fixed double-close() on admin connec... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2e7987633f8b changeset: 17477:2e7987633f8b user: Timo Sirainen date: Fri Jun 13 02:01:55 2014 +0300 description: director-test: Fixed double-close() on admin connection deinit diffstat: src/director/director-test.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 4a396f0c3b79 -r 2e7987633f8b src/director/director-test.c --- a/src/director/director-test.c Fri Jun 13 01:57:04 2014 +0300 +++ b/src/director/director-test.c Fri Jun 13 02:01:55 2014 +0300 @@ -460,7 +460,7 @@ admin_random_action, conn); net_set_nonblock(conn->fd, FALSE); - conn->input = i_stream_create_fd(conn->fd, (size_t)-1, TRUE); + conn->input = i_stream_create_fd(conn->fd, (size_t)-1, FALSE); admin_send(conn, DIRECTOR_ADMIN_HANDSHAKE); line = i_stream_read_next_line(conn->input); From dovecot at dovecot.org Thu Jun 12 23:20:48 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:48 +0000 Subject: dovecot-2.2: doveadm stats top: Fixed double-close()ing stats co... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f42dfaebdfc4 changeset: 17478:f42dfaebdfc4 user: Timo Sirainen date: Fri Jun 13 02:04:12 2014 +0300 description: doveadm stats top: Fixed double-close()ing stats connection diffstat: src/doveadm/doveadm-stats.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 2e7987633f8b -r f42dfaebdfc4 src/doveadm/doveadm-stats.c --- a/src/doveadm/doveadm-stats.c Fri Jun 13 02:01:55 2014 +0300 +++ b/src/doveadm/doveadm-stats.c Fri Jun 13 02:04:12 2014 +0300 @@ -479,7 +479,7 @@ hash_table_create(&ctx.sessions, default_pool, 0, str_hash, strcmp); net_set_nonblock(ctx.fd, FALSE); - ctx.input = i_stream_create_fd(ctx.fd, (size_t)-1, TRUE); + ctx.input = i_stream_create_fd(ctx.fd, (size_t)-1, FALSE); if (strstr(sort_type, "cpu") != NULL) ctx.lines_sort = sort_cpu; From dovecot at dovecot.org Thu Jun 12 23:20:48 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:48 +0000 Subject: dovecot-2.2: lib: Added [io]_stream_create_fd_*autoclose() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0bcb43692d91 changeset: 17479:0bcb43692d91 user: Timo Sirainen date: Fri Jun 13 02:18:53 2014 +0300 description: lib: Added [io]_stream_create_fd_*autoclose() These make it clearer that the fd parameter will be closed automatically when the stream is closed. Eventually (in v2.3) we'll want to get rid of the autoclose boolean parameter in [io]_stream_create_fd(). diffstat: src/lib/istream-file.c | 9 +++++++++ src/lib/istream.h | 2 ++ src/lib/ostream-file.c | 19 +++++++++++++++++++ src/lib/ostream.h | 3 +++ 4 files changed, 33 insertions(+), 0 deletions(-) diffs (81 lines): diff -r f42dfaebdfc4 -r 0bcb43692d91 src/lib/istream-file.c --- a/src/lib/istream-file.c Fri Jun 13 02:04:12 2014 +0300 +++ b/src/lib/istream-file.c Fri Jun 13 02:18:53 2014 +0300 @@ -229,6 +229,15 @@ return i_stream_create_file_common(fd, NULL, max_buffer_size, autoclose_fd); } +struct istream *i_stream_create_fd_autoclose(int *fd, size_t max_buffer_size) +{ + struct istream *input; + + input = i_stream_create_fd(*fd, max_buffer_size, TRUE); + *fd = -1; + return input; +} + struct istream *i_stream_create_file(const char *path, size_t max_buffer_size) { struct istream *input; diff -r f42dfaebdfc4 -r 0bcb43692d91 src/lib/istream.h --- a/src/lib/istream.h Fri Jun 13 02:04:12 2014 +0300 +++ b/src/lib/istream.h Fri Jun 13 02:18:53 2014 +0300 @@ -24,6 +24,8 @@ struct istream *i_stream_create_fd(int fd, size_t max_buffer_size, bool autoclose_fd); +/* The fd is set to -1 immediately to avoid accidentally closing it twice. */ +struct istream *i_stream_create_fd_autoclose(int *fd, size_t max_buffer_size); /* Open the given path only when something is actually tried to be read from the stream. */ struct istream *i_stream_create_file(const char *path, size_t max_buffer_size); diff -r f42dfaebdfc4 -r 0bcb43692d91 src/lib/ostream-file.c --- a/src/lib/ostream-file.c Fri Jun 13 02:04:12 2014 +0300 +++ b/src/lib/ostream-file.c Fri Jun 13 02:18:53 2014 +0300 @@ -972,6 +972,16 @@ } struct ostream * +o_stream_create_fd_autoclose(int *fd, size_t max_buffer_size) +{ + struct ostream *output; + + output = o_stream_create_fd(*fd, max_buffer_size, TRUE); + *fd = -1; + return output; +} + +struct ostream * o_stream_create_fd_file(int fd, uoff_t offset, bool autoclose_fd) { struct file_ostream *fstream; @@ -990,3 +1000,12 @@ ostream->offset = offset; return ostream; } + +struct ostream *o_stream_create_fd_file_autoclose(int *fd, uoff_t offset) +{ + struct ostream *output; + + output = o_stream_create_fd_file(*fd, offset, TRUE); + *fd = -1; + return output; +} diff -r f42dfaebdfc4 -r 0bcb43692d91 src/lib/ostream.h --- a/src/lib/ostream.h Fri Jun 13 02:04:12 2014 +0300 +++ b/src/lib/ostream.h Fri Jun 13 02:18:53 2014 +0300 @@ -30,10 +30,13 @@ If max_buffer_size is 0, an "optimal" buffer size is used (max 128kB). */ struct ostream * o_stream_create_fd(int fd, size_t max_buffer_size, bool autoclose_fd); +/* The fd is set to -1 immediately to avoid accidentally closing it twice. */ +struct ostream *o_stream_create_fd_autoclose(int *fd, size_t max_buffer_size); /* Create an output stream from a regular file which begins at given offset. If offset==(uoff_t)-1, the current offset isn't known. */ struct ostream * o_stream_create_fd_file(int fd, uoff_t offset, bool autoclose_fd); +struct ostream *o_stream_create_fd_file_autoclose(int *fd, uoff_t offset); /* Create an output stream to a buffer. */ struct ostream *o_stream_create_buffer(buffer_t *buf); /* Create an output streams that always fails the writes. */ From dovecot at dovecot.org Thu Jun 12 23:20:49 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:20:49 +0000 Subject: dovecot-2.2: Use the new [io]_stream_create_fd_*autoclose() func... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b67c1c9bf1a5 changeset: 17480:b67c1c9bf1a5 user: Timo Sirainen date: Fri Jun 13 02:19:15 2014 +0300 description: Use the new [io]_stream_create_fd_*autoclose() functions wherever possible. diffstat: src/auth/mech-winbind.c | 4 ++-- src/auth/userdb-passwd-file.c | 2 +- src/config/config-parser.c | 4 ++-- src/doveadm/doveadm-director.c | 4 ++-- src/doveadm/doveadm-dump-dbox.c | 2 +- src/doveadm/doveadm-log.c | 4 ++-- src/doveadm/doveadm-penalty.c | 4 ++-- src/doveadm/doveadm-replicator.c | 2 +- src/doveadm/doveadm-stats.c | 4 ++-- src/doveadm/doveadm-who.c | 4 ++-- src/doveadm/doveadm-zlib.c | 2 +- src/lib-compression/test-compression.c | 2 +- src/lib-imap-urlauth/imap-urlauth-connection.c | 4 ++-- src/lib-lda/smtp-client.c | 4 ++-- src/lib-master/master-instance.c | 2 +- src/lib-master/mountpoint-list.c | 2 +- src/lib-settings/settings-parser.c | 4 ++-- src/lib-settings/settings.c | 4 ++-- src/lib-storage/index/cydir/cydir-mail.c | 2 +- src/lib-storage/index/dbox-common/dbox-file.c | 7 +++++-- src/lib-storage/index/imapc/imapc-save.c | 3 +-- src/lib-storage/index/maildir/maildir-mail.c | 2 +- src/lib-storage/index/raw/raw-storage.c | 2 +- src/lib-storage/list/subscription-file.c | 12 +++++------- src/lib/iostream-temp.c | 8 ++++---- src/lib/istream-seekable.c | 2 +- src/plugins/fts/fts-parser-script.c | 2 +- src/plugins/zlib/zlib-plugin.c | 2 +- src/replication/replicator/replicator-queue.c | 4 ++-- src/ssl-params/main.c | 2 +- src/util/rawlog.c | 4 ++-- 31 files changed, 55 insertions(+), 55 deletions(-) diffs (truncated from 515 to 300 lines): diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/auth/mech-winbind.c --- a/src/auth/mech-winbind.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/auth/mech-winbind.c Fri Jun 13 02:19:15 2014 +0300 @@ -146,9 +146,9 @@ winbind->pid = pid; winbind->in_pipe = - i_stream_create_fd(infd[0], AUTH_CLIENT_MAX_LINE_LENGTH, TRUE); + i_stream_create_fd_autoclose(&infd[0], AUTH_CLIENT_MAX_LINE_LENGTH); winbind->out_pipe = - o_stream_create_fd(outfd[1], (size_t)-1, TRUE); + o_stream_create_fd_autoclose(&outfd[1], (size_t)-1); if (!sigchld_handler_set) { sigchld_handler_set = TRUE; diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/auth/userdb-passwd-file.c --- a/src/auth/userdb-passwd-file.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/auth/userdb-passwd-file.c Fri Jun 13 02:19:15 2014 +0300 @@ -115,7 +115,7 @@ i_error("open(%s) failed: %m", ctx->path); ctx->ctx.failed = TRUE; } else { - ctx->input = i_stream_create_fd(fd, (size_t)-1, TRUE); + ctx->input = i_stream_create_fd_autoclose(&fd, (size_t)-1); } return &ctx->ctx; } diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/config/config-parser.c --- a/src/config/config-parser.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/config/config-parser.c Fri Jun 13 02:19:15 2014 +0300 @@ -476,7 +476,7 @@ new_input = p_new(ctx->pool, struct input_stack, 1); new_input->prev = ctx->cur_input; new_input->path = p_strdup(ctx->pool, path); - new_input->input = i_stream_create_fd(fd, (size_t)-1, TRUE); + new_input->input = i_stream_create_fd_autoclose(&fd, (size_t)-1); i_stream_set_return_partial_line(new_input->input, TRUE); ctx->cur_input = new_input; return 0; @@ -936,7 +936,7 @@ ctx.str = str_new(ctx.pool, 256); full_line = str_new(default_pool, 512); ctx.cur_input->input = fd != -1 ? - i_stream_create_fd(fd, (size_t)-1, TRUE) : + i_stream_create_fd_autoclose(&fd, (size_t)-1) : i_stream_create_from_data("", 0); i_stream_set_return_partial_line(ctx.cur_input->input, TRUE); old_settings_init(&ctx); diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/doveadm/doveadm-director.c --- a/src/doveadm/doveadm-director.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/doveadm/doveadm-director.c Fri Jun 13 02:19:15 2014 +0300 @@ -53,7 +53,7 @@ fd = doveadm_connect(ctx->socket_path); net_set_nonblock(fd, FALSE); - ctx->input = i_stream_create_fd(fd, (size_t)-1, TRUE); + ctx->input = i_stream_create_fd_autoclose(&fd, (size_t)-1); director_send(ctx, DIRECTOR_HANDSHAKE); alarm(5); @@ -243,7 +243,7 @@ fd = open(path, O_RDONLY); if (fd == -1) i_fatal("open(%s) failed: %m", path); - input = i_stream_create_fd(fd, (size_t)-1, TRUE); + input = i_stream_create_fd_autoclose(&fd, (size_t)-1); while ((username = i_stream_read_next_line(input)) != NULL) user_list_add(username, pool, users); i_stream_unref(&input); diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/doveadm/doveadm-dump-dbox.c --- a/src/doveadm/doveadm-dump-dbox.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/doveadm/doveadm-dump-dbox.c Fri Jun 13 02:19:15 2014 +0300 @@ -200,7 +200,7 @@ if (fd < 0) i_fatal("open(%s) failed: %m", argv[1]); - input = i_stream_create_fd(fd, (size_t)-1, TRUE); + input = i_stream_create_fd_autoclose(&fd, (size_t)-1); i_stream_set_name(input, argv[1]); hdr_size = dump_file_hdr(input); do { diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/doveadm/doveadm-log.c --- a/src/doveadm/doveadm-log.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/doveadm/doveadm-log.c Fri Jun 13 02:19:15 2014 +0300 @@ -153,7 +153,7 @@ if (fd == -1) return; - input = i_stream_create_fd(fd, 1024, TRUE); + input = i_stream_create_fd_autoclose(&fd, 1024); i_stream_seek(input, file->size); while ((line = i_stream_read_next_line(input)) != NULL) { p = strstr(line, TEST_LOG_MSG_PREFIX); @@ -331,7 +331,7 @@ i_fatal("net_connect_unix(%s) failed: %m", path); net_set_nonblock(fd, FALSE); - input = i_stream_create_fd(fd, (size_t)-1, TRUE); + input = i_stream_create_fd_autoclose(&fd, (size_t)-1); while ((line = i_stream_read_next_line(input)) != NULL) T_BEGIN { args = t_strsplit_tabescaped(line); if (str_array_length(args) == 4) diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/doveadm/doveadm-penalty.c --- a/src/doveadm/doveadm-penalty.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/doveadm/doveadm-penalty.c Fri Jun 13 02:19:15 2014 +0300 @@ -70,10 +70,10 @@ fd = doveadm_connect(ctx->anvil_path); net_set_nonblock(fd, FALSE); - - input = i_stream_create_fd(fd, (size_t)-1, TRUE); if (write(fd, ANVIL_CMD, strlen(ANVIL_CMD)) < 0) i_fatal("write(%s) failed: %m", ctx->anvil_path); + + input = i_stream_create_fd_autoclose(&fd, (size_t)-1); while ((line = i_stream_read_next_line(input)) != NULL) { if (*line == '\0') break; diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/doveadm/doveadm-replicator.c --- a/src/doveadm/doveadm-replicator.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/doveadm/doveadm-replicator.c Fri Jun 13 02:19:15 2014 +0300 @@ -42,7 +42,7 @@ fd = doveadm_connect(ctx->socket_path); net_set_nonblock(fd, FALSE); - ctx->input = i_stream_create_fd(fd, (size_t)-1, TRUE); + ctx->input = i_stream_create_fd_autoclose(&fd, (size_t)-1); replicator_send(ctx, REPLICATOR_HANDSHAKE); alarm(5); diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/doveadm/doveadm-stats.c --- a/src/doveadm/doveadm-stats.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/doveadm/doveadm-stats.c Fri Jun 13 02:19:15 2014 +0300 @@ -83,11 +83,11 @@ fd = doveadm_connect(path); net_set_nonblock(fd, FALSE); - - input = i_stream_create_fd(fd, (size_t)-1, TRUE); if (write_full(fd, cmd, strlen(cmd)) < 0) i_fatal("write(%s) failed: %m", path); + input = i_stream_create_fd_autoclose(&fd, (size_t)-1); + /* read header */ args = read_next_line(input); if (args == NULL) diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/doveadm/doveadm-who.c --- a/src/doveadm/doveadm-who.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/doveadm/doveadm-who.c Fri Jun 13 02:19:15 2014 +0300 @@ -139,10 +139,10 @@ fd = doveadm_connect(ctx->anvil_path); net_set_nonblock(fd, FALSE); - - input = i_stream_create_fd(fd, (size_t)-1, TRUE); if (write(fd, ANVIL_CMD, strlen(ANVIL_CMD)) < 0) i_fatal("write(%s) failed: %m", ctx->anvil_path); + + input = i_stream_create_fd_autoclose(&fd, (size_t)-1); while ((line = i_stream_read_next_line(input)) != NULL) { if (*line == '\0') break; diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/doveadm/doveadm-zlib.c --- a/src/doveadm/doveadm-zlib.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/doveadm/doveadm-zlib.c Fri Jun 13 02:19:15 2014 +0300 @@ -52,7 +52,7 @@ fd = open(argv[1], O_RDONLY); if (fd < 0) i_fatal("open(%s) failed: %m", argv[1]); - input = i_stream_create_fd(fd, 1024*32, TRUE); + input = i_stream_create_fd_autoclose(&fd, 1024*32); while ((line = i_stream_read_next_line(input)) != NULL) { /* skip tag */ printf("%s\r\n", line); diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/lib-compression/test-compression.c --- a/src/lib-compression/test-compression.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/lib-compression/test-compression.c Fri Jun 13 02:19:15 2014 +0300 @@ -125,7 +125,7 @@ sha1_init(&sha1); file_output = o_stream_create_fd_file(fd_out, 0, FALSE); output = handler->create_ostream(file_output, 1); - input = i_stream_create_fd(fd_in, IO_BLOCK_SIZE, TRUE); + input = i_stream_create_fd_autoclose(&fd_in, IO_BLOCK_SIZE); while (i_stream_read_data(input, &data, &size, 0) > 0) { sha1_loop(&sha1, data, size); o_stream_nsend(output, data, size); diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/lib-imap-urlauth/imap-urlauth-connection.c --- a/src/lib-imap-urlauth/imap-urlauth-connection.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/lib-imap-urlauth/imap-urlauth-connection.c Fri Jun 13 02:19:15 2014 +0300 @@ -607,8 +607,8 @@ uoff_t fd_size; if (conn->literal_fd != -1) { - reply->input = i_stream_create_fd(conn->literal_fd, - (size_t)-1, TRUE); + reply->input = i_stream_create_fd_autoclose(&conn->literal_fd, + (size_t)-1); if (i_stream_get_size(reply->input, TRUE, &fd_size) < 1 || fd_size != conn->literal_size) { i_stream_unref(&reply->input); diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/lib-lda/smtp-client.c --- a/src/lib-lda/smtp-client.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/lib-lda/smtp-client.c Fri Jun 13 02:19:15 2014 +0300 @@ -144,7 +144,7 @@ } i_close_fd(&fd[0]); - client->output = o_stream_create_fd(fd[1], IO_BLOCK_SIZE, TRUE); + client->output = o_stream_create_fd_autoclose(&fd[1], IO_BLOCK_SIZE); o_stream_set_no_error_handling(client->output, TRUE); client->pid = pid; return client->output; @@ -164,7 +164,7 @@ return o_stream_create_error(errno); client->temp_path = i_strdup(path); client->temp_fd = fd; - client->output = o_stream_create_fd(fd, IO_BLOCK_SIZE, TRUE); + client->output = o_stream_create_fd_autoclose(&fd, IO_BLOCK_SIZE); o_stream_set_no_error_handling(client->output, TRUE); return client->output; } diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/lib-master/master-instance.c --- a/src/lib-master/master-instance.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/lib-master/master-instance.c Fri Jun 13 02:19:15 2014 +0300 @@ -110,7 +110,7 @@ i_error("open(%s) failed: %m", list->path); return -1; } - input = i_stream_create_fd(fd, (size_t)-1, TRUE); + input = i_stream_create_fd_autoclose(&fd, (size_t)-1); while ((line = i_stream_read_next_line(input)) != NULL) T_BEGIN { if (master_instance_list_add_line(list, line) < 0) i_error("Invalid line in %s: %s", list->path, line); diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/lib-master/mountpoint-list.c --- a/src/lib-master/mountpoint-list.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/lib-master/mountpoint-list.c Fri Jun 13 02:19:15 2014 +0300 @@ -138,7 +138,7 @@ } if (fstat(fd, &list->load_st) < 0) i_error("fstat(%s) failed: %m", list->state_path); - input = i_stream_create_fd(fd, (size_t)-1, TRUE); + input = i_stream_create_fd_autoclose(&fd, (size_t)-1); while ((line = i_stream_read_next_line(input)) != NULL) { p = strchr(line, ' '); if (p == NULL) { diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/lib-settings/settings-parser.c --- a/src/lib-settings/settings-parser.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/lib-settings/settings-parser.c Fri Jun 13 02:19:15 2014 +0300 @@ -999,7 +999,7 @@ return -1; } - input = i_stream_create_fd(fd, max_line_length, TRUE); + input = i_stream_create_fd_autoclose(&fd, max_line_length); i_stream_set_name(input, path); ret = settings_parse_stream_read(ctx, input); i_stream_unref(&input); @@ -1089,7 +1089,7 @@ } i_close_fd(&fd[1]); - input = i_stream_create_fd(fd[0], (size_t)-1, TRUE); + input = i_stream_create_fd_autoclose(&fd[0], (size_t)-1); i_stream_set_name(input, bin_path); ret = settings_parse_stream_read(ctx, input); i_stream_destroy(&input); diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/lib-settings/settings.c --- a/src/lib-settings/settings.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/lib-settings/settings.c Fri Jun 13 02:19:15 2014 +0300 @@ -119,7 +119,7 @@ new_input = t_new(struct input_stack, 1); new_input->prev = *inputp; new_input->path = t_strdup(path); - new_input->input = i_stream_create_fd(fd, (size_t)-1, TRUE); + new_input->input = i_stream_create_fd_autoclose(&fd, (size_t)-1); i_stream_set_return_partial_line(new_input->input, TRUE); *inputp = new_input; return 0; @@ -201,7 +201,7 @@ full_line = t_str_new(512); sections = 0; root_section = 0; errormsg = NULL; - input->input = i_stream_create_fd(fd, (size_t)-1, TRUE); + input->input = i_stream_create_fd_autoclose(&fd, (size_t)-1); i_stream_set_return_partial_line(input->input, TRUE); prevfile: while ((line = i_stream_read_next_line(input->input)) != NULL) { diff -r 0bcb43692d91 -r b67c1c9bf1a5 src/lib-storage/index/cydir/cydir-mail.c --- a/src/lib-storage/index/cydir/cydir-mail.c Fri Jun 13 02:18:53 2014 +0300 +++ b/src/lib-storage/index/cydir/cydir-mail.c Fri Jun 13 02:19:15 2014 +0300 @@ -115,7 +115,7 @@ } return -1; } - input = i_stream_create_fd(fd, 0, TRUE); + input = i_stream_create_fd_autoclose(&fd, 0); i_stream_set_name(input, path); index_mail_set_read_buffer_size(_mail, input); if (mail->mail.v.istream_opened != NULL) { From dovecot at dovecot.org Thu Jun 12 23:35:30 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:35:30 +0000 Subject: dovecot-2.2: Compiler warning fix Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/50889bc95f45 changeset: 17481:50889bc95f45 user: Timo Sirainen date: Fri Jun 13 02:34:19 2014 +0300 description: Compiler warning fix diffstat: src/lib/ioloop-notify-inotify.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r b67c1c9bf1a5 -r 50889bc95f45 src/lib/ioloop-notify-inotify.c --- a/src/lib/ioloop-notify-inotify.c Fri Jun 13 02:19:15 2014 +0300 +++ b/src/lib/ioloop-notify-inotify.c Fri Jun 13 02:34:19 2014 +0300 @@ -61,7 +61,7 @@ break; event = (struct inotify_event *)(event_buf + pos); - i_assert(event->len < ret); + i_assert(event->len < (size_t)ret); pos += sizeof(*event) + event->len; io = io_notify_fd_find(&ctx->fd_ctx, event->wd); From dovecot at dovecot.org Thu Jun 12 23:55:40 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 12 Jun 2014 23:55:40 +0000 Subject: dovecot-2.2: imap, pop3: Remove the client from clients-list at ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/53742463a9fe changeset: 17482:53742463a9fe user: Timo Sirainen date: Fri Jun 13 02:54:21 2014 +0300 description: imap, pop3: Remove the client from clients-list at the very end of the destroy function. Especially with imap code the process title could have been refreshed too early. diffstat: src/imap/imap-client.c | 6 +++--- src/pop3/pop3-client.c | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diffs (45 lines): diff -r 50889bc95f45 -r 53742463a9fe src/imap/imap-client.c --- a/src/imap/imap-client.c Fri Jun 13 02:34:19 2014 +0300 +++ b/src/imap/imap-client.c Fri Jun 13 02:54:21 2014 +0300 @@ -246,9 +246,6 @@ i_info("%s %s", reason, client_stats(client)); } - imap_client_count--; - DLLIST_REMOVE(&imap_clients, client); - i_stream_close(client->input); o_stream_close(client->output); @@ -305,6 +302,9 @@ array_free(&client->search_updates); pool_unref(&client->command_pool); mail_storage_service_user_free(&client->service_user); + + imap_client_count--; + DLLIST_REMOVE(&imap_clients, client); pool_unref(&client->pool); master_service_client_connection_destroyed(master_service); diff -r 50889bc95f45 -r 53742463a9fe src/pop3/pop3-client.c --- a/src/pop3/pop3-client.c Fri Jun 13 02:34:19 2014 +0300 +++ b/src/pop3/pop3-client.c Fri Jun 13 02:54:21 2014 +0300 @@ -584,8 +584,6 @@ client->cmd(client); i_assert(client->cmd == NULL); } - pop3_client_count--; - DLLIST_REMOVE(&pop3_clients, client); if (client->trans != NULL) { /* client didn't QUIT, but we still want to save any changes @@ -632,6 +630,9 @@ if (client->fd_in != client->fd_out) net_disconnect(client->fd_out); mail_storage_service_user_free(&client->service_user); + + pop3_client_count--; + DLLIST_REMOVE(&pop3_clients, client); pool_unref(&client->pool); master_service_client_connection_destroyed(master_service); From dovecot at dovecot.org Fri Jun 13 00:10:36 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 13 Jun 2014 00:10:36 +0000 Subject: dovecot-2.2: dbox: Added asserts to dbox file fixing to make sur... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/03520d887a4f changeset: 17483:03520d887a4f user: Timo Sirainen date: Fri Jun 13 03:09:26 2014 +0300 description: dbox: Added asserts to dbox file fixing to make sure it doesn't go to infinite loop. There apparently is a bug in here that will trigger this assert. diffstat: src/lib-storage/index/dbox-common/dbox-file-fix.c | 13 +++++++++---- 1 files changed, 9 insertions(+), 4 deletions(-) diffs (32 lines): diff -r 53742463a9fe -r 03520d887a4f src/lib-storage/index/dbox-common/dbox-file-fix.c --- a/src/lib-storage/index/dbox-common/dbox-file-fix.c Fri Jun 13 02:54:21 2014 +0300 +++ b/src/lib-storage/index/dbox-common/dbox-file-fix.c Fri Jun 13 03:09:26 2014 +0300 @@ -140,19 +140,24 @@ magic markers. */ struct istream *input = file->input; - uoff_t orig_offset, pre_offset, post_offset; + uoff_t orig_offset, pre_offset, post_offset, prev_offset; const unsigned char *data, *magic; - size_t size, need_bytes; + size_t size, need_bytes, prev_need_bytes; int ret, match; *pre_r = FALSE; - orig_offset = input->v_offset; - need_bytes = strlen(DBOX_MAGIC_POST); + orig_offset = prev_offset = input->v_offset; + need_bytes = strlen(DBOX_MAGIC_POST); prev_need_bytes = 0; while ((ret = i_stream_read_data(input, &data, &size, need_bytes-1)) > 0 || ret == -2) { /* search for the beginning of a potential pre/post magic */ i_assert(size > 1); + i_assert(prev_offset != input->v_offset || + need_bytes > prev_need_bytes); + prev_offset = input->v_offset; + prev_need_bytes = need_bytes; + magic = memchr(data, DBOX_MAGIC_PRE[0], size); if (magic == NULL) { i_stream_skip(input, size-1); From dovecot at dovecot.org Fri Jun 13 07:24:06 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 13 Jun 2014 07:24:06 +0000 Subject: dovecot-2.2: lib-http: Removed unnecessary for loop. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/368b8af23c3f changeset: 17484:368b8af23c3f user: Timo Sirainen date: Fri Jun 13 10:22:49 2014 +0300 description: lib-http: Removed unnecessary for loop. Found by Coverity diffstat: src/lib-http/http-transfer-chunked.c | 42 ++++++++++++++++------------------- 1 files changed, 19 insertions(+), 23 deletions(-) diffs (52 lines): diff -r 03520d887a4f -r 368b8af23c3f src/lib-http/http-transfer-chunked.c --- a/src/lib-http/http-transfer-chunked.c Fri Jun 13 03:09:26 2014 +0300 +++ b/src/lib-http/http-transfer-chunked.c Fri Jun 13 10:22:49 2014 +0300 @@ -212,29 +212,25 @@ return 0; /* fall through */ case HTTP_CHUNKED_PARSE_STATE_EXT_VALUE_STRING: - for (;;) { - if (*tcstream->cur == '"') { - tcstream->cur++; - tcstream->state = HTTP_CHUNKED_PARSE_STATE_EXT; - if (tcstream->cur >= tcstream->end) - return 0; - break; - } else if ((ret=http_transfer_chunked_skip_qdtext(tcstream)) <= 0) { - if (ret < 0) - tcstream->error = "Invalid chunked extension value"; - return ret; - } else if (*tcstream->cur == '\\') { - tcstream->cur++; - tcstream->state = HTTP_CHUNKED_PARSE_STATE_EXT_VALUE_ESCAPE; - if (tcstream->cur >= tcstream->end) - return 0; - break; - } else { - tcstream->error = t_strdup_printf( - "Invalid character %s in chunked extension value string", - _chr_sanitize(*tcstream->cur)); - return -1; - } + if (*tcstream->cur == '"') { + tcstream->cur++; + tcstream->state = HTTP_CHUNKED_PARSE_STATE_EXT; + if (tcstream->cur >= tcstream->end) + return 0; + } else if ((ret=http_transfer_chunked_skip_qdtext(tcstream)) <= 0) { + if (ret < 0) + tcstream->error = "Invalid chunked extension value"; + return ret; + } else if (*tcstream->cur == '\\') { + tcstream->cur++; + tcstream->state = HTTP_CHUNKED_PARSE_STATE_EXT_VALUE_ESCAPE; + if (tcstream->cur >= tcstream->end) + return 0; + } else { + tcstream->error = t_strdup_printf( + "Invalid character %s in chunked extension value string", + _chr_sanitize(*tcstream->cur)); + return -1; } break; case HTTP_CHUNKED_PARSE_STATE_EXT_VALUE_ESCAPE: From dovecot at dovecot.org Fri Jun 13 07:26:33 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 13 Jun 2014 07:26:33 +0000 Subject: dovecot-2.2: auth: Fixed handling userdb_userdb_import passdb ex... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/87da927c3c19 changeset: 17485:87da927c3c19 user: Timo Sirainen date: Fri Jun 13 10:25:22 2014 +0300 description: auth: Fixed handling userdb_userdb_import passdb extra field. Looks like some hg merging went wrong. Found by Coverity diffstat: src/auth/auth-request.c | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-) diffs (33 lines): diff -r 368b8af23c3f -r 87da927c3c19 src/auth/auth-request.c --- a/src/auth/auth-request.c Fri Jun 13 10:22:49 2014 +0300 +++ b/src/auth/auth-request.c Fri Jun 13 10:25:22 2014 +0300 @@ -1434,6 +1434,14 @@ request->userdb_prefetch_set = TRUE; if (request->userdb_reply == NULL) auth_request_init_userdb_reply(request); + if (strcmp(name, "userdb_userdb_import") == 0) { + /* we can't put the whole userdb_userdb_import + value to extra_cache_fields or it doesn't work + properly. so handle this explicitly. */ + auth_request_passdb_import(request, value, + "userdb_", default_scheme); + return; + } auth_request_set_userdb_field(request, name + 7, value); } else if (strcmp(name, "nopassword") == 0) { /* NULL password - anything goes */ @@ -1454,14 +1462,6 @@ } else if (strcmp(name, "passdb_import") == 0) { auth_request_passdb_import(request, value, "", default_scheme); return; - if (strcmp(name, "userdb_userdb_import") == 0) { - /* we need can't put the whole userdb_userdb_import - value to extra_cache_fields or it doesn't work - properly. so handle this explicitly. */ - auth_request_passdb_import(request, value, - "userdb_", default_scheme); - return; - } } else { /* these fields are returned to client */ auth_fields_add(request->extra_fields, name, value, 0); From dovecot at dovecot.org Fri Jun 13 08:22:23 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 13 Jun 2014 08:22:23 +0000 Subject: dovecot-2.2: dbox: Fixed potential infinite looping when scannin... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/892aee3e5a05 changeset: 17486:892aee3e5a05 user: Timo Sirainen date: Fri Jun 13 11:21:07 2014 +0300 description: dbox: Fixed potential infinite looping when scanning a broken dbox file. diffstat: src/lib-storage/index/dbox-common/dbox-file-fix.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (21 lines): diff -r 87da927c3c19 -r 892aee3e5a05 src/lib-storage/index/dbox-common/dbox-file-fix.c --- a/src/lib-storage/index/dbox-common/dbox-file-fix.c Fri Jun 13 10:25:22 2014 +0300 +++ b/src/lib-storage/index/dbox-common/dbox-file-fix.c Fri Jun 13 11:21:07 2014 +0300 @@ -20,14 +20,16 @@ const unsigned char *data; size_t size; uoff_t offset = input->v_offset; + bool have_lf = FALSE; data = i_stream_get_data(input, &size); if (data[0] == '\n') { data++; size--; offset++; + have_lf = TRUE; } i_assert(data[0] == DBOX_MAGIC_PRE[0]); if (size < sizeof(*hdr)) { - *need_bytes = sizeof(*hdr); + *need_bytes = sizeof(*hdr) + (have_lf ? 1 : 0); return -1; } hdr = (const void *)data; From dovecot at dovecot.org Fri Jun 13 08:37:03 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 13 Jun 2014 08:37:03 +0000 Subject: dovecot-2.2: Make sure we don't shift signed integers left by 24... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5416df86b603 changeset: 17487:5416df86b603 user: Timo Sirainen date: Fri Jun 13 11:35:40 2014 +0300 description: Make sure we don't shift signed integers left by 24. They should be unsigned. diffstat: src/lib-index/mailbox-log.c | 2 +- src/lib/hmac-cram-md5.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diffs (24 lines): diff -r 892aee3e5a05 -r 5416df86b603 src/lib-index/mailbox-log.c --- a/src/lib-index/mailbox-log.c Fri Jun 13 11:21:07 2014 +0300 +++ b/src/lib-index/mailbox-log.c Fri Jun 13 11:35:40 2014 +0300 @@ -154,7 +154,7 @@ time_t mailbox_log_record_get_timestamp(const struct mailbox_log_record *rec) { - return ((time_t)rec->timestamp[0] << 24) | + return (time_t)(rec->timestamp[0] << 24) | ((time_t)rec->timestamp[1] << 16) | ((time_t)rec->timestamp[2] << 8) | (time_t)rec->timestamp[3]; diff -r 892aee3e5a05 -r 5416df86b603 src/lib/hmac-cram-md5.c --- a/src/lib/hmac-cram-md5.c Fri Jun 13 11:21:07 2014 +0300 +++ b/src/lib/hmac-cram-md5.c Fri Jun 13 11:35:40 2014 +0300 @@ -48,7 +48,7 @@ (c) = (*p++); \ (c) += (*p++ << 8); \ (c) += (*p++ << 16); \ - (c) += (*p++ << 24); \ + (c) += ((uint32_t)(*p++) << 24); \ } STMT_END cdp = context_digest; CDGET(cdp, ctxo->a); From dovecot at dovecot.org Fri Jun 13 08:46:38 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 13 Jun 2014 08:46:38 +0000 Subject: dovecot-2.1: dbox: Fixed potential infinite looping when scannin... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/74037ec725d3 changeset: 15020:74037ec725d3 user: Timo Sirainen date: Fri Jun 13 11:21:07 2014 +0300 description: dbox: Fixed potential infinite looping when scanning a broken dbox file. diffstat: src/lib-storage/index/dbox-common/dbox-file-fix.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (21 lines): diff -r d50ac1b3330d -r 74037ec725d3 src/lib-storage/index/dbox-common/dbox-file-fix.c --- a/src/lib-storage/index/dbox-common/dbox-file-fix.c Thu Jun 12 23:51:28 2014 +0300 +++ b/src/lib-storage/index/dbox-common/dbox-file-fix.c Fri Jun 13 11:21:07 2014 +0300 @@ -21,14 +21,16 @@ const unsigned char *data; size_t size; uoff_t offset = input->v_offset; + bool have_lf = FALSE; data = i_stream_get_data(input, &size); if (data[0] == '\n') { data++; size--; offset++; + have_lf = TRUE; } i_assert(data[0] == DBOX_MAGIC_PRE[0]); if (size < sizeof(*hdr)) { - *need_bytes = sizeof(*hdr); + *need_bytes = sizeof(*hdr) + (have_lf ? 1 : 0); return -1; } hdr = (const void *)data; From dovecot at dovecot.org Fri Jun 13 12:16:01 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 13 Jun 2014 12:16:01 +0000 Subject: dovecot-2.2: lib-master: Fixed caching settings where both local... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1fcaa7d0b35e changeset: 17488:1fcaa7d0b35e user: Timo Sirainen date: Fri Jun 13 15:13:26 2014 +0300 description: lib-master: Fixed caching settings where both local_name and local_ip was specified. Since cache_find() didn't use local_ip for a lookup when local_name existed, cache_add() shouldn't add both of them either, otherwise it could be inserting duplicate values to the cache hash and cause crashes. diffstat: src/lib-master/master-service-settings-cache.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) diffs (32 lines): diff -r 5416df86b603 -r 1fcaa7d0b35e src/lib-master/master-service-settings-cache.c --- a/src/lib-master/master-service-settings-cache.c Fri Jun 13 11:35:40 2014 +0300 +++ b/src/lib-master/master-service-settings-cache.c Fri Jun 13 15:13:26 2014 +0300 @@ -167,7 +167,7 @@ if (entry->local_name != NULL) hash_table_remove(cache->local_name_hash, entry->local_name); - if (entry->local_ip.family != 0) + else if (entry->local_ip.family != 0) hash_table_remove(cache->local_ip_hash, &entry->local_ip); settings_parser_deinit(&entry->parser); } @@ -239,14 +239,17 @@ hash_table_create(&cache->local_name_hash, cache->pool, 0, str_hash, strcmp); } + i_assert(hash_table_lookup(cache->local_name_hash, + entry_local_name) == NULL); hash_table_insert(cache->local_name_hash, entry_local_name, entry); - } - if (input->local_ip.family != 0) { + } else if (input->local_ip.family != 0) { if (!hash_table_is_created(cache->local_ip_hash)) { hash_table_create(&cache->local_ip_hash, cache->pool, 0, net_ip_hash, net_ip_cmp); } + i_assert(hash_table_lookup(cache->local_ip_hash, + &entry->local_ip) == NULL); hash_table_insert(cache->local_ip_hash, &entry->local_ip, entry); } From dovecot at dovecot.org Fri Jun 13 12:16:02 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 13 Jun 2014 12:16:02 +0000 Subject: dovecot-2.2: Added several asserts to make sure duplicates aren'... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f6e2fa1afa45 changeset: 17489:f6e2fa1afa45 user: Timo Sirainen date: Fri Jun 13 15:14:44 2014 +0300 description: Added several asserts to make sure duplicates aren't inserted into hash table. The previous commit hopefully fixed the problem causing auth and login processes to sometimes die with "key not found from hash" error, but if not maybe one of these will catch it. diffstat: src/lib-auth/auth-server-connection.c | 1 + src/lib-master/master-auth.c | 1 + src/lib-master/master-login-auth.c | 1 + src/lib-settings/settings-parser.c | 3 +++ src/login-common/ssl-proxy-openssl.c | 1 + 5 files changed, 7 insertions(+), 0 deletions(-) diffs (71 lines): diff -r 1fcaa7d0b35e -r f6e2fa1afa45 src/lib-auth/auth-server-connection.c --- a/src/lib-auth/auth-server-connection.c Fri Jun 13 15:13:26 2014 +0300 +++ b/src/lib-auth/auth-server-connection.c Fri Jun 13 15:14:44 2014 +0300 @@ -476,6 +476,7 @@ /* wrapped - ID 0 not allowed */ id = ++conn->client->request_id_counter; } + i_assert(hash_table_lookup(conn->requests, POINTER_CAST(id)) == NULL); hash_table_insert(conn->requests, POINTER_CAST(id), request); return id; } diff -r 1fcaa7d0b35e -r f6e2fa1afa45 src/lib-master/master-auth.c --- a/src/lib-master/master-auth.c Fri Jun 13 15:13:26 2014 +0300 +++ b/src/lib-master/master-auth.c Fri Jun 13 15:14:44 2014 +0300 @@ -211,6 +211,7 @@ master_auth_connection_timeout, conn); conn->io = io_add(conn->fd, IO_READ, master_auth_connection_input, conn); + i_assert(hash_table_lookup(auth->connections, POINTER_CAST(req.tag)) == NULL); hash_table_insert(auth->connections, POINTER_CAST(req.tag), conn); *tag_r = req.tag; } diff -r 1fcaa7d0b35e -r f6e2fa1afa45 src/lib-master/master-login-auth.c --- a/src/lib-master/master-login-auth.c Fri Jun 13 15:13:26 2014 +0300 +++ b/src/lib-master/master-login-auth.c Fri Jun 13 15:14:44 2014 +0300 @@ -483,6 +483,7 @@ memcpy(login_req->cookie, req->cookie, sizeof(login_req->cookie)); login_req->callback = callback; login_req->context = context; + i_assert(hash_table_lookup(auth->requests, POINTER_CAST(id)) == NULL); hash_table_insert(auth->requests, POINTER_CAST(id), login_req); DLLIST2_APPEND(&auth->request_head, &auth->request_tail, login_req); diff -r 1fcaa7d0b35e -r f6e2fa1afa45 src/lib-settings/settings-parser.c --- a/src/lib-settings/settings-parser.c Fri Jun 13 15:13:26 2014 +0300 +++ b/src/lib-settings/settings-parser.c Fri Jun 13 15:14:44 2014 +0300 @@ -143,6 +143,7 @@ new_link->change_array = carr; new_link->set_struct = new_set; new_link->change_struct = new_changes; + i_assert(hash_table_lookup(ctx->links, full_key) == NULL); hash_table_insert(ctx->links, full_key, new_link); info.defaults = children[i]; @@ -524,6 +525,7 @@ link = p_new(ctx->parser_pool, struct setting_link, 1); *link = *link_copy; link->full_key = key; + i_assert(hash_table_lookup(ctx->links, key) == NULL); hash_table_insert(ctx->links, key, link); if (link->info->struct_size != 0) @@ -1744,6 +1746,7 @@ } i_assert(i < count); } + i_assert(hash_table_lookup(links, old_link) == NULL); hash_table_insert(links, old_link, new_link); return new_link; } diff -r 1fcaa7d0b35e -r f6e2fa1afa45 src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Fri Jun 13 15:13:26 2014 +0300 +++ b/src/login-common/ssl-proxy-openssl.c Fri Jun 13 15:14:44 2014 +0300 @@ -1318,6 +1318,7 @@ if (ctx->verify_client_cert) ssl_proxy_ctx_verify_client(ctx->ctx, xnames); + i_assert(hash_table_lookup(ssl_servers, ctx) == NULL); hash_table_insert(ssl_servers, ctx, ctx); return ctx; } From dovecot at dovecot.org Fri Jun 13 13:13:54 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 13 Jun 2014 13:13:54 +0000 Subject: dovecot-2.2: fts-lucene: Fix SnowballAnalyzer constructors Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d2ecee775c1f changeset: 17490:d2ecee775c1f user: Phil Carmody date: Fri Jun 13 16:12:27 2014 +0300 description: fts-lucene: Fix SnowballAnalyzer constructors Coverity found the uninitialised pointers in the latter constructor (which is never used - kill it?). In comparing the other constructor, the lack of strdup() jumped out at me. In fixing them both I migrated them to actual C++ initialisers, rather than dumb assignments to uninitialised members. Also migrated to dovecot's i_* functions. Also fixed indentation for the 3 functions touched. Signed-off-by: Phil Carmody diffstat: src/plugins/fts-lucene/Snowball.cc | 35 ++++++++++++++++++++--------------- 1 files changed, 20 insertions(+), 15 deletions(-) diffs (51 lines): diff -r f6e2fa1afa45 -r d2ecee775c1f src/plugins/fts-lucene/Snowball.cc --- a/src/plugins/fts-lucene/Snowball.cc Fri Jun 13 15:14:44 2014 +0300 +++ b/src/plugins/fts-lucene/Snowball.cc Fri Jun 13 16:12:27 2014 +0300 @@ -26,27 +26,32 @@ CL_NS_DEF2(analysis,snowball) /** Builds the named analyzer with no stop words. */ - SnowballAnalyzer::SnowballAnalyzer(normalizer_func_t *normalizer, const char* language) { - this->language = strdup(language); - this->normalizer = normalizer; - stopSet = NULL; - prevstream = NULL; + SnowballAnalyzer::SnowballAnalyzer(normalizer_func_t *_normalizer, const char* _language) + : language(i_strdup(_language)), + normalizer(_normalizer), + stopSet(NULL), + prevstream(NULL) + { } - SnowballAnalyzer::~SnowballAnalyzer(){ - if (prevstream) _CLDELETE(prevstream); - _CLDELETE_CARRAY(language); - if ( stopSet != NULL ) - _CLDELETE(stopSet); + SnowballAnalyzer::~SnowballAnalyzer() + { + if (prevstream) + _CLDELETE(prevstream); + i_free(language); + if ( stopSet != NULL ) + _CLDELETE(stopSet); } /** Builds the named analyzer with the given stop words. */ - SnowballAnalyzer::SnowballAnalyzer(const char* language, const TCHAR** stopWords) { - this->language = strdup(language); - - stopSet = _CLNEW CLTCSetList(true); - StopFilter::fillStopTable(stopSet,stopWords); + SnowballAnalyzer::SnowballAnalyzer(const char* language, const TCHAR** stopWords) + : language(i_strdup(language)), + normalizer(NULL), + stopSet(_CLNEW CLTCSetList(true)), + prevstream(NULL) + { + StopFilter::fillStopTable(stopSet,stopWords); } TokenStream* SnowballAnalyzer::tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader) { From dovecot at dovecot.org Sat Jun 14 09:00:22 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 14 Jun 2014 09:00:22 +0000 Subject: dovecot-2.2: trivial variable-non-use fixes Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b9886d5e2225 changeset: 17491:b9886d5e2225 user: Phil Carmody date: Sat Jun 14 11:58:57 2014 +0300 description: trivial variable-non-use fixes Flagged by coverity. In one, as we're printing an error message, we can actually put the string to use, which might aid debugging. In the other, the variable can just be killed. Signed-off-by: Phil Carmody diffstat: src/lib-imap-urlauth/imap-urlauth-connection.c | 3 ++- src/lib-storage/list/mailbox-list-subscriptions.c | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diffs (33 lines): diff -r d2ecee775c1f -r b9886d5e2225 src/lib-imap-urlauth/imap-urlauth-connection.c --- a/src/lib-imap-urlauth/imap-urlauth-connection.c Fri Jun 13 16:12:27 2014 +0300 +++ b/src/lib-imap-urlauth/imap-urlauth-connection.c Sat Jun 14 11:58:57 2014 +0300 @@ -835,7 +835,8 @@ if ((response = i_stream_next_line(conn->input)) == NULL) return 0; - i_error("imap-urlauth: Received input while no requests were pending"); + i_error("imap-urlauth: Received input while no requests were pending: %s", + str_sanitize(response, 80)); imap_urlauth_connection_abort(conn, NULL); return -1; case IMAP_URLAUTH_STATE_REQUEST_PENDING: diff -r d2ecee775c1f -r b9886d5e2225 src/lib-storage/list/mailbox-list-subscriptions.c --- a/src/lib-storage/list/mailbox-list-subscriptions.c Fri Jun 13 16:12:27 2014 +0300 +++ b/src/lib-storage/list/mailbox-list-subscriptions.c Sat Jun 14 11:58:57 2014 +0300 @@ -203,7 +203,6 @@ { struct mailbox_list_iter_update_context update_ctx; struct mailbox_tree_iterate_context *iter; - struct mailbox_node *node; const char *name; memset(&update_ctx, 0, sizeof(update_ctx)); @@ -219,7 +218,7 @@ iter = mailbox_tree_iterate_init(ctx->list->subscriptions, NULL, MAILBOX_SUBSCRIBED); - while ((node = mailbox_tree_iterate_next(iter, &name)) != NULL) + while (mailbox_tree_iterate_next(iter, &name) != NULL) mailbox_list_iter_update(&update_ctx, name); mailbox_tree_iterate_deinit(&iter); } From dovecot at dovecot.org Sun Jun 15 08:04:50 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 15 Jun 2014 08:04:50 +0000 Subject: dovecot-2.2: auth: Fixed wrong assert added by recent commit. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/854a1719c840 changeset: 17492:854a1719c840 user: Timo Sirainen date: Sun Jun 15 11:03:32 2014 +0300 description: auth: Fixed wrong assert added by recent commit. diffstat: src/auth/auth-request.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r b9886d5e2225 -r 854a1719c840 src/auth/auth-request.c --- a/src/auth/auth-request.c Sat Jun 14 11:58:57 2014 +0300 +++ b/src/auth/auth-request.c Sun Jun 15 11:03:32 2014 +0300 @@ -2162,7 +2162,7 @@ auth_request->userdb->userdb->iface->name; } } else if (subsystem == AUTH_SUBSYS_MECH) { - i_assert(auth_request->mech == NULL); + i_assert(auth_request->mech != NULL); name = t_str_lcase(auth_request->mech->mech_name); } else { name = subsystem; From dovecot at dovecot.org Mon Jun 16 10:04:45 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jun 2014 10:04:45 +0000 Subject: dovecot-2.2: lmtp: Removed some unnecessary code Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/50ede76b8d2b changeset: 17493:50ede76b8d2b user: Timo Sirainen date: Mon Jun 16 13:03:31 2014 +0300 description: lmtp: Removed some unnecessary code diffstat: src/lmtp/commands.c | 2 +- src/lmtp/lmtp-proxy.c | 2 -- src/lmtp/lmtp-proxy.h | 1 - 3 files changed, 1 insertions(+), 4 deletions(-) diffs (42 lines): diff -r 854a1719c840 -r 50ede76b8d2b src/lmtp/commands.c --- a/src/lmtp/commands.c Sun Jun 15 11:03:32 2014 +0300 +++ b/src/lmtp/commands.c Mon Jun 16 13:03:31 2014 +0300 @@ -938,7 +938,7 @@ if (array_count(&client->state.rcpt_to) != 0) client_input_data_write_local(client, input); if (client->proxy != NULL) { - lmtp_proxy_start(client->proxy, input, NULL, + lmtp_proxy_start(client->proxy, input, client_proxy_finish, client); ret = FALSE; } diff -r 854a1719c840 -r 50ede76b8d2b src/lmtp/lmtp-proxy.c --- a/src/lmtp/lmtp-proxy.c Sun Jun 15 11:03:32 2014 +0300 +++ b/src/lmtp/lmtp-proxy.c Mon Jun 16 13:03:31 2014 +0300 @@ -281,7 +281,6 @@ } void lmtp_proxy_start(struct lmtp_proxy *proxy, struct istream *data_input, - const char *header, lmtp_proxy_finish_callback_t *callback, void *context) { struct lmtp_proxy_connection *const *conns; @@ -305,7 +304,6 @@ lmtp_proxy_conn_timeout, conn); conn->data_input = i_stream_create_limit(data_input, (uoff_t)-1); - lmtp_client_set_data_header(conn->client, header); lmtp_client_send(conn->client, conn->data_input); lmtp_client_send_more(conn->client); } diff -r 854a1719c840 -r 50ede76b8d2b src/lmtp/lmtp-proxy.h --- a/src/lmtp/lmtp-proxy.h Sun Jun 15 11:03:32 2014 +0300 +++ b/src/lmtp/lmtp-proxy.h Mon Jun 16 13:03:31 2014 +0300 @@ -39,7 +39,6 @@ const struct lmtp_proxy_rcpt_settings *set); /* Start proxying */ void lmtp_proxy_start(struct lmtp_proxy *proxy, struct istream *data_input, - const char *header, lmtp_proxy_finish_callback_t *callback, void *context) ATTR_NULL(3); From dovecot at dovecot.org Mon Jun 16 10:13:56 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jun 2014 10:13:56 +0000 Subject: dovecot-2.2: lmtp: Proxying now logs successful and failed deliv... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/20e8ed98357b changeset: 17494:20e8ed98357b user: Timo Sirainen date: Mon Jun 16 13:12:40 2014 +0300 description: lmtp: Proxying now logs successful and failed deliveries after DATA. diffstat: src/lmtp/lmtp-proxy.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-) diffs (29 lines): diff -r 50ede76b8d2b -r 20e8ed98357b src/lmtp/lmtp-proxy.c --- a/src/lmtp/lmtp-proxy.c Mon Jun 16 13:03:31 2014 +0300 +++ b/src/lmtp/lmtp-proxy.c Mon Jun 16 13:12:40 2014 +0300 @@ -231,7 +231,7 @@ } static void -lmtp_proxy_conn_data(bool success ATTR_UNUSED, const char *reply, void *context) +lmtp_proxy_conn_data(bool success, const char *reply, void *context) { struct lmtp_proxy_recipient *rcpt = context; struct lmtp_proxy_connection *conn = rcpt->conn; @@ -246,6 +246,16 @@ rcpt->reply = p_strdup(conn->proxy->pool, reply); rcpt->data_reply_received = TRUE; + if (!success) { + i_error("%s: Failed to send message to <%s> at %s:%u: %s", + conn->proxy->set.session_id, rcpt->address, + conn->set.host, conn->set.port, reply); + } else { + i_info("%s: Sent message to <%s> at %s:%u: %s", + conn->proxy->set.session_id, rcpt->address, + conn->set.host, conn->set.port, reply); + } + lmtp_proxy_try_finish(conn->proxy); } From dovecot at dovecot.org Mon Jun 16 12:48:49 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jun 2014 12:48:49 +0000 Subject: dovecot-2.2: xml2text: Check for read()/write() failures and exi... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fc40b1a6e962 changeset: 17495:fc40b1a6e962 user: Timo Sirainen date: Mon Jun 16 15:35:07 2014 +0300 description: xml2text: Check for read()/write() failures and exit if they fail. diffstat: src/plugins/fts/xml2text.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diffs (27 lines): diff -r 20e8ed98357b -r fc40b1a6e962 src/plugins/fts/xml2text.c --- a/src/plugins/fts/xml2text.c Mon Jun 16 13:12:40 2014 +0300 +++ b/src/plugins/fts/xml2text.c Mon Jun 16 15:35:07 2014 +0300 @@ -23,16 +23,21 @@ block.data = buf; block.size = ret; parser->v.more(parser, &block); - write(STDOUT_FILENO, block.data, block.size); + if (write(STDOUT_FILENO, block.data, block.size) < 0) + i_fatal("write(stdout) failed: %m"); } + if (ret < 0) + i_fatal("read(stdin) failed: %m"); for (;;) { block.size = 0; parser->v.more(parser, &block); if (block.size == 0) break; - write(STDOUT_FILENO, block.data, block.size); + if (write(STDOUT_FILENO, block.data, block.size) < 0) + i_fatal("write(stdout) failed: %m"); } lib_deinit(); + return 0; } From dovecot at dovecot.org Mon Jun 16 12:48:55 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jun 2014 12:48:55 +0000 Subject: dovecot-2.2: Check for syscall errors that are quite unlikely to... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3d3796c15074 changeset: 17496:3d3796c15074 user: Timo Sirainen date: Mon Jun 16 15:41:52 2014 +0300 description: Check for syscall errors that are quite unlikely to happen. Flagged by Coverity. diffstat: src/doveadm/doveadm-dump-log.c | 8 ++++++-- src/lib-storage/index/dbox-common/dbox-file.c | 5 ++++- src/master/main.c | 2 +- src/util/maildirlock.c | 5 +++-- 4 files changed, 14 insertions(+), 6 deletions(-) diffs (81 lines): diff -r fc40b1a6e962 -r 3d3796c15074 src/doveadm/doveadm-dump-log.c --- a/src/doveadm/doveadm-dump-log.c Mon Jun 16 15:35:07 2014 +0300 +++ b/src/doveadm/doveadm-dump-log.c Mon Jun 16 15:41:52 2014 +0300 @@ -24,7 +24,8 @@ memset(PTR_OFFSET(&hdr, hdr.hdr_size), 0, sizeof(hdr) - hdr.hdr_size); } - lseek(fd, hdr.hdr_size, SEEK_SET); + if (lseek(fd, hdr.hdr_size, SEEK_SET) < 0) + i_fatal("lseek() failed: %m"); printf("version = %u.%u\n", hdr.major_version, hdr.minor_version); printf("hdr size = %u\n", hdr.hdr_size); @@ -467,6 +468,8 @@ unsigned int orig_size; offset = lseek(fd, 0, SEEK_CUR); + if (offset == -1) + i_fatal("lseek() failed: %m"); ret = read(fd, &hdr, sizeof(hdr)); if (ret == 0) @@ -504,7 +507,8 @@ } log_record_print(&hdr, buf, modseq); } else { - lseek(fd, hdr.size - sizeof(hdr), SEEK_CUR); + if (lseek(fd, hdr.size - sizeof(hdr), SEEK_CUR) < 0) + i_fatal("lseek() failed: %m"); } return 1; } diff -r fc40b1a6e962 -r 3d3796c15074 src/lib-storage/index/dbox-common/dbox-file.c --- a/src/lib-storage/index/dbox-common/dbox-file.c Mon Jun 16 15:35:07 2014 +0300 +++ b/src/lib-storage/index/dbox-common/dbox-file.c Mon Jun 16 15:41:52 2014 +0300 @@ -555,7 +555,10 @@ dbox_file_set_syscall_error(ctx->file, "ftruncate()"); return -1; } - o_stream_seek(ctx->output, ctx->last_checkpoint_offset); + if (o_stream_seek(ctx->output, ctx->last_checkpoint_offset) < 0) { + dbox_file_set_syscall_error(ctx->file, "lseek()"); + return -1; + } } if (storage->set->parsed_fsync_mode != FSYNC_MODE_NEVER) { diff -r fc40b1a6e962 -r 3d3796c15074 src/master/main.c --- a/src/master/main.c Mon Jun 16 15:35:07 2014 +0300 +++ b/src/master/main.c Mon Jun 16 15:41:52 2014 +0300 @@ -214,7 +214,7 @@ "information): %s\n", buf); } - close(fd); + i_close_fd(&fd); if (unlink(path) < 0) i_error("unlink(%s) failed: %m", path); } diff -r fc40b1a6e962 -r 3d3796c15074 src/util/maildirlock.c --- a/src/util/maildirlock.c Mon Jun 16 15:35:07 2014 +0300 +++ b/src/util/maildirlock.c Mon Jun 16 15:41:52 2014 +0300 @@ -67,7 +67,7 @@ lib_signals_set_handler(SIGTERM, LIBSIG_FLAG_DELAYED, sig_die, NULL); if (pid != 0) { - close(fd[1]); + i_close_fd(&fd[1]); ret = read(fd[0], &c, 1); if (ret < 0) { i_error("read(pipe) failed: %m"); @@ -84,7 +84,8 @@ /* child process - stdout has to be closed so that caller knows when to stop reading it. */ - dup2(STDERR_FILENO, STDOUT_FILENO); + if (dup2(STDERR_FILENO, STDOUT_FILENO) < 0) + i_fatal("dup2() failed: %m"); timeout = strtoul(argv[2], NULL, 10); if (maildir_lock(argv[1], timeout, &dotlock) <= 0) From dovecot at dovecot.org Mon Jun 16 12:48:55 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jun 2014 12:48:55 +0000 Subject: dovecot-2.2: Added (void) prefix for ignoring return values we d... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/de20b4fa60ac changeset: 17497:de20b4fa60ac user: Timo Sirainen date: Mon Jun 16 15:42:39 2014 +0300 description: Added (void) prefix for ignoring return values we don't care about. Hopefully this quiets down Coverity warnings also of them? diffstat: src/doveadm/dsync/dsync-ibc-stream.c | 2 +- src/login-common/ssl-proxy-openssl.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diffs (36 lines): diff -r 3d3796c15074 -r de20b4fa60ac src/doveadm/dsync/dsync-ibc-stream.c --- a/src/doveadm/dsync/dsync-ibc-stream.c Mon Jun 16 15:41:52 2014 +0300 +++ b/src/doveadm/dsync/dsync-ibc-stream.c Mon Jun 16 15:42:39 2014 +0300 @@ -340,7 +340,7 @@ "read() failed: EOF" errors on failing dsyncs */ o_stream_nsend_str(ibc->output, t_strdup_printf("%c\n", items[ITEM_DONE].chr)); - o_stream_nfinish(ibc->output); + (void)o_stream_nfinish(ibc->output); } timeout_remove(&ibc->to); diff -r 3d3796c15074 -r de20b4fa60ac src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Mon Jun 16 15:41:52 2014 +0300 +++ b/src/login-common/ssl-proxy-openssl.c Mon Jun 16 15:42:39 2014 +0300 @@ -333,7 +333,7 @@ } if (corked) - net_set_cork(proxy->fd_ssl, FALSE); + (void)net_set_cork(proxy->fd_ssl, FALSE); ssl_proxy_unref(proxy); } @@ -553,9 +553,9 @@ if (proxy->sslout_size == 0) ssl_set_io(proxy, SSL_REMOVE_OUTPUT); else { - net_set_cork(proxy->fd_ssl, TRUE); + (void)net_set_cork(proxy->fd_ssl, TRUE); ssl_write(proxy); - net_set_cork(proxy->fd_ssl, FALSE); + (void)net_set_cork(proxy->fd_ssl, FALSE); } } From dovecot at dovecot.org Mon Jun 16 12:48:55 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jun 2014 12:48:55 +0000 Subject: dovecot-2.2: doveadm dump log: Fixed potential crash when log he... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b2e16f0e88db changeset: 17498:b2e16f0e88db user: Timo Sirainen date: Mon Jun 16 15:47:12 2014 +0300 description: doveadm dump log: Fixed potential crash when log header size was corrupted. diffstat: src/doveadm/doveadm-dump-log.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (14 lines): diff -r de20b4fa60ac -r b2e16f0e88db src/doveadm/doveadm-dump-log.c --- a/src/doveadm/doveadm-dump-log.c Mon Jun 16 15:42:39 2014 +0300 +++ b/src/doveadm/doveadm-dump-log.c Mon Jun 16 15:47:12 2014 +0300 @@ -497,7 +497,9 @@ } printf("\n"); - if (hdr.size < 1024*1024) { + if (hdr.size < sizeof(hdr)) { + i_fatal("Invalid header size %u", hdr.size); + } else if (hdr.size < 1024*1024) { unsigned char *buf = t_malloc(hdr.size); ret = read(fd, buf, hdr.size - sizeof(hdr)); From dovecot at dovecot.org Mon Jun 16 13:27:34 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jun 2014 13:27:34 +0000 Subject: dovecot-2.2: doveadm dump: Avoid crashes with corrupted log files Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d6882dfa08d7 changeset: 17499:d6882dfa08d7 user: Timo Sirainen date: Mon Jun 16 16:26:09 2014 +0300 description: doveadm dump: Avoid crashes with corrupted log files diffstat: src/doveadm/doveadm-dump-log.c | 38 +++++++++++++++++++++++++++++--------- 1 files changed, 29 insertions(+), 9 deletions(-) diffs (94 lines): diff -r b2e16f0e88db -r d6882dfa08d7 src/doveadm/doveadm-dump-log.c --- a/src/doveadm/doveadm-dump-log.c Mon Jun 16 15:47:12 2014 +0300 +++ b/src/doveadm/doveadm-dump-log.c Mon Jun 16 16:26:09 2014 +0300 @@ -214,12 +214,18 @@ HDRF(day_stamp) }; -static void log_header_update(const struct mail_transaction_header_update *u) +static void log_header_update(const struct mail_transaction_header_update *u, + size_t data_size) { const void *data = u + 1; unsigned int offset = u->offset, size = u->size; unsigned int i; + if (sizeof(*u) + size > data_size) { + printf(" - offset = %u, size = %u (too large)\n", offset, size); + return; + } + while (size > 0) { /* don't bother trying to handle header updates that include unknown/unexpected fields offsets/sizes */ @@ -247,7 +253,8 @@ } static void log_record_print(const struct mail_transaction_header *hdr, - const void *data, uint64_t *modseq) + const void *data, size_t data_size, + uint64_t *modseq) { unsigned int size = hdr->size - sizeof(*hdr); @@ -297,7 +304,7 @@ case MAIL_TRANSACTION_HEADER_UPDATE: { const struct mail_transaction_header_update *u = data; - log_header_update(u); + log_header_update(u, data_size); break; } case MAIL_TRANSACTION_EXT_INTRO: { @@ -331,16 +338,26 @@ case MAIL_TRANSACTION_EXT_HDR_UPDATE: { const struct mail_transaction_ext_hdr_update *u = data; - printf(" - offset = %u, size = %u: ", u->offset, u->size); - print_data(u + 1, u->size); + printf(" - offset = %u, size = %u", u->offset, u->size); + if (sizeof(*u) + u->size <= data_size) { + printf(": "); + print_data(u + 1, u->size); + } else { + printf(" (too large)"); + } printf("\n"); break; } case MAIL_TRANSACTION_EXT_HDR_UPDATE32: { const struct mail_transaction_ext_hdr_update32 *u = data; - printf(" - offset = %u, size = %u: ", u->offset, u->size); - print_data(u + 1, u->size); + printf(" - offset = %u, size = %u", u->offset, u->size); + if (sizeof(*u) + u->size <= data_size) { + printf(": "); + print_data(u + 1, u->size); + } else { + printf(" (too large)"); + } printf("\n"); break; } @@ -352,7 +369,10 @@ record_size = (sizeof(*rec) + prev_intro.record_size + 3) & ~3; while (rec < end) { printf(" - uid=%u: ", rec->uid); - print_data(rec + 1, prev_intro.record_size); + if (prev_intro.record_size <= (char*)end - (char *)(rec+1)) + print_data(rec + 1, prev_intro.record_size); + else + printf("(record_size too large)"); printf("\n"); rec = CONST_PTR_OFFSET(rec, record_size); } @@ -507,7 +527,7 @@ i_fatal("rec data read() %"PRIuSIZE_T" != %"PRIuSIZE_T, ret, hdr.size - sizeof(hdr)); } - log_record_print(&hdr, buf, modseq); + log_record_print(&hdr, buf, (size_t)ret, modseq); } else { if (lseek(fd, hdr.size - sizeof(hdr), SEEK_CUR) < 0) i_fatal("lseek() failed: %m"); From dovecot at dovecot.org Mon Jun 16 13:28:31 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jun 2014 13:28:31 +0000 Subject: dovecot-2.2: doveadm who: Don't crash if server happens to send ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/24659b98b271 changeset: 17500:24659b98b271 user: Timo Sirainen date: Mon Jun 16 16:27:12 2014 +0300 description: doveadm who: Don't crash if server happens to send broken input (second try). Found by Coverity diffstat: src/doveadm/doveadm-who.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r d6882dfa08d7 -r 24659b98b271 src/doveadm/doveadm-who.c --- a/src/doveadm/doveadm-who.c Mon Jun 16 16:26:09 2014 +0300 +++ b/src/doveadm/doveadm-who.c Mon Jun 16 16:27:12 2014 +0300 @@ -61,6 +61,8 @@ memset(line_r, 0, sizeof(*line_r)); p = strchr(ident, '/'); + if (p == NULL) + return -1; line_r->pid = strtoul(pid_str, NULL, 10); line_r->service = t_strdup_until(ident, p++); line_r->username = strchr(p, '/'); From dovecot at dovecot.org Mon Jun 16 14:43:57 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jun 2014 14:43:57 +0000 Subject: dovecot-2.2: lib: Changed mempool.h to use inline functions inst... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5de6a5f241db changeset: 17501:5de6a5f241db user: Timo Sirainen date: Mon Jun 16 17:40:51 2014 +0300 description: lib: Changed mempool.h to use inline functions instead of macros. This way we can also mark p_malloc() with ATTR_MALLOC. diffstat: src/lib/mempool.h | 51 +++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 39 insertions(+), 12 deletions(-) diffs (78 lines): diff -r 24659b98b271 -r 5de6a5f241db src/lib/mempool.h --- a/src/lib/mempool.h Mon Jun 16 16:27:12 2014 +0300 +++ b/src/lib/mempool.h Mon Jun 16 17:40:51 2014 +0300 @@ -68,17 +68,19 @@ old_size + 1. */ size_t pool_get_exp_grown_size(pool_t pool, size_t old_size, size_t min_size); -/* Pools should be used through these macros: */ -#define pool_get_name(pool) (pool)->v->get_name(pool) -#define pool_ref(pool) (pool)->v->ref(pool) -#define pool_unref(pool) ((*pool))->v->unref(pool) - #define p_new(pool, type, count) \ ((type *) p_malloc(pool, sizeof(type) * (count))) +static inline void * ATTR_MALLOC +p_malloc(pool_t pool, size_t size) +{ + return pool->v->malloc(pool, size); +} -#define p_malloc(pool, size) (pool)->v->malloc(pool, size) -#define p_realloc(pool, mem, old_size, new_size) \ - (pool)->v->realloc(pool, mem, old_size, new_size) +static inline void * ATTR_WARN_UNUSED_RESULT +p_realloc(pool_t pool, void *mem, size_t old_size, size_t new_size) +{ + return pool->v->realloc(pool, mem, old_size, new_size); +} /* Free the memory. Currently it also sets memory to NULL, but that shouldn't be relied on as it's only an extra safety check. It might as well be later @@ -86,17 +88,42 @@ in some "optimization".. */ #define p_free(pool, mem) \ STMT_START { \ - (pool)->v->free(pool, mem); \ + p_free_internal(pool, mem); \ (mem) = NULL; \ } STMT_END /* A macro that's guaranteed to set mem = NULL. */ #define p_free_and_null(pool, mem) p_free(pool, mem) -#define p_clear(pool) (pool)->v->clear(pool) +static inline void p_free_internal(pool_t pool, void *mem) +{ + pool->v->free(pool, mem); +} -#define p_get_max_easy_alloc_size(pool) \ - (pool)->v->get_max_easy_alloc_size(pool) +static inline void p_clear(pool_t pool) +{ + pool->v->clear(pool); +} + +static inline size_t p_get_max_easy_alloc_size(pool_t pool) +{ + return pool->v->get_max_easy_alloc_size(pool); +} + +static inline const char *pool_get_name(pool_t pool) +{ + return pool->v->get_name(pool); +} + +static inline void pool_ref(pool_t pool) +{ + pool->v->ref(pool); +} + +static inline void pool_unref(pool_t *pool) +{ + (*pool)->v->unref(pool); +} /* These functions are only for pools created with pool_alloconly_create(): */ From dovecot at dovecot.org Mon Jun 16 15:09:13 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jun 2014 15:09:13 +0000 Subject: dovecot-2.2: lib: Use __attribute__((returns_nonnull)) for the c... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6abf982c268d changeset: 17502:6abf982c268d user: Timo Sirainen date: Mon Jun 16 18:01:58 2014 +0300 description: lib: Use __attribute__((returns_nonnull)) for the common memory/string functions. Also added a couple of missing ATTR_MALLOCs. diffstat: src/lib/data-stack.h | 8 ++++---- src/lib/imem.h | 11 ++++++----- src/lib/macros.h | 6 ++++++ src/lib/mempool.h | 8 ++++---- src/lib/strfuncs.h | 31 +++++++++++++++++-------------- 5 files changed, 37 insertions(+), 27 deletions(-) diffs (201 lines): diff -r 5de6a5f241db -r 6abf982c268d src/lib/data-stack.h --- a/src/lib/data-stack.h Mon Jun 16 17:40:51 2014 +0300 +++ b/src/lib/data-stack.h Mon Jun 16 18:01:58 2014 +0300 @@ -61,8 +61,8 @@ t_malloc() calls never fail. If there's not enough memory left, i_panic() will be called. */ -void *t_malloc(size_t size) ATTR_MALLOC; -void *t_malloc0(size_t size) ATTR_MALLOC; +void *t_malloc(size_t size) ATTR_MALLOC ATTR_RETURNS_NONNULL; +void *t_malloc0(size_t size) ATTR_MALLOC ATTR_RETURNS_NONNULL; /* Try growing allocated memory. Returns TRUE if successful. Works only for last allocated memory in current stack frame. */ @@ -84,12 +84,12 @@ new one (or do some other trickery). See t_buffer_reget(). */ #define t_buffer_get_type(type, size) \ t_buffer_get(sizeof(type) * (size)) -void *t_buffer_get(size_t size); +void *t_buffer_get(size_t size) ATTR_RETURNS_NONNULL; /* Grow the buffer, memcpy()ing the memory to new location if needed. */ #define t_buffer_reget_type(buffer, type, size) \ t_buffer_reget(buffer, sizeof(type) * (size)) -void *t_buffer_reget(void *buffer, size_t size); +void *t_buffer_reget(void *buffer, size_t size) ATTR_RETURNS_NONNULL; /* Make the last t_buffer_get()ed buffer permanent. Note that size MUST be less or equal than the size you gave with last t_buffer_get() or the diff -r 5de6a5f241db -r 6abf982c268d src/lib/imem.h --- a/src/lib/imem.h Mon Jun 16 17:40:51 2014 +0300 +++ b/src/lib/imem.h Mon Jun 16 18:01:58 2014 +0300 @@ -7,9 +7,9 @@ #define i_new(type, count) p_new(default_pool, type, count) -void *i_malloc(size_t size) ATTR_MALLOC; +void *i_malloc(size_t size) ATTR_MALLOC ATTR_RETURNS_NONNULL; void *i_realloc(void *mem, size_t old_size, size_t new_size) - ATTR_WARN_UNUSED_RESULT; + ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL; #define i_free(mem) p_free(default_pool, mem) #define i_free_and_null(mem) p_free_and_null(default_pool, mem) @@ -19,12 +19,13 @@ /* like i_strdup(), but if str == "", return NULL */ char *i_strdup_empty(const char *str) ATTR_MALLOC; /* *end isn't included */ -char *i_strdup_until(const void *str, const void *end) ATTR_MALLOC; +char *i_strdup_until(const void *str, const void *end) + ATTR_MALLOC ATTR_RETURNS_NONNULL; char *i_strndup(const void *str, size_t max_chars) ATTR_MALLOC; char *i_strdup_printf(const char *format, ...) - ATTR_FORMAT(1, 2) ATTR_MALLOC; + ATTR_FORMAT(1, 2) ATTR_MALLOC ATTR_RETURNS_NONNULL; char *i_strdup_vprintf(const char *format, va_list args) - ATTR_FORMAT(1, 0) ATTR_MALLOC; + ATTR_FORMAT(1, 0) ATTR_MALLOC ATTR_RETURNS_NONNULL; char *i_strconcat(const char *str1, ...) ATTR_SENTINEL ATTR_MALLOC; diff -r 5de6a5f241db -r 6abf982c268d src/lib/macros.h --- a/src/lib/macros.h Mon Jun 16 17:40:51 2014 +0300 +++ b/src/lib/macros.h Mon Jun 16 18:01:58 2014 +0300 @@ -140,6 +140,12 @@ # define ATTR_HOT # define ATTR_COLD #endif +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) +/* GCC 4.9 and later */ +# define ATTR_RETURNS_NONNULL __attribute__((returns_nonnull)) +#else +# define ATTR_RETURNS_NONNULL +#endif /* Macros to provide type safety for callback functions' context parameters */ #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)) diff -r 5de6a5f241db -r 6abf982c268d src/lib/mempool.h --- a/src/lib/mempool.h Mon Jun 16 17:40:51 2014 +0300 +++ b/src/lib/mempool.h Mon Jun 16 18:01:58 2014 +0300 @@ -22,13 +22,13 @@ void (*ref)(pool_t pool); void (*unref)(pool_t *pool); - void *(*malloc)(pool_t pool, size_t size); + void *(*malloc)(pool_t pool, size_t size) ATTR_RETURNS_NONNULL; void (*free)(pool_t pool, void *mem); /* memory in old_size..new_size will be zeroed */ void *(*realloc)(pool_t pool, void *mem, size_t old_size, size_t new_size) - ATTR_WARN_UNUSED_RESULT; + ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL; /* Frees all the memory in pool. NOTE: system_pool doesn't support this and crashes if it's used */ @@ -70,13 +70,13 @@ #define p_new(pool, type, count) \ ((type *) p_malloc(pool, sizeof(type) * (count))) -static inline void * ATTR_MALLOC +static inline void * ATTR_MALLOC ATTR_RETURNS_NONNULL p_malloc(pool_t pool, size_t size) { return pool->v->malloc(pool, size); } -static inline void * ATTR_WARN_UNUSED_RESULT +static inline void * ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL p_realloc(pool_t pool, void *mem, size_t old_size, size_t new_size) { return pool->v->realloc(pool, mem, old_size, new_size); diff -r 5de6a5f241db -r 6abf982c268d src/lib/strfuncs.h --- a/src/lib/strfuncs.h Mon Jun 16 17:40:51 2014 +0300 +++ b/src/lib/strfuncs.h Mon Jun 16 18:01:58 2014 +0300 @@ -14,12 +14,12 @@ char *p_strdup_empty(pool_t pool, const char *str) ATTR_MALLOC; /* *end isn't included */ char *p_strdup_until(pool_t pool, const void *start, const void *end) - ATTR_MALLOC; + ATTR_MALLOC ATTR_RETURNS_NONNULL; char *p_strndup(pool_t pool, const void *str, size_t max_chars) ATTR_MALLOC; char *p_strdup_printf(pool_t pool, const char *format, ...) - ATTR_FORMAT(2, 3) ATTR_MALLOC; + ATTR_FORMAT(2, 3) ATTR_MALLOC ATTR_RETURNS_NONNULL; char *p_strdup_vprintf(pool_t pool, const char *format, va_list args) - ATTR_FORMAT(2, 0) ATTR_MALLOC; + ATTR_FORMAT(2, 0) ATTR_MALLOC ATTR_RETURNS_NONNULL; char *p_strconcat(pool_t pool, const char *str1, ...) ATTR_SENTINEL ATTR_MALLOC; @@ -29,12 +29,13 @@ /* return NULL if str = "" */ const char *t_strdup_empty(const char *str) ATTR_MALLOC; /* *end isn't included */ -const char *t_strdup_until(const void *start, const void *end) ATTR_MALLOC; +const char *t_strdup_until(const void *start, const void *end) + ATTR_MALLOC ATTR_RETURNS_NONNULL; const char *t_strndup(const void *str, size_t max_chars) ATTR_MALLOC; const char *t_strdup_printf(const char *format, ...) - ATTR_FORMAT(1, 2) ATTR_MALLOC; + ATTR_FORMAT(1, 2) ATTR_MALLOC ATTR_RETURNS_NONNULL; const char *t_strdup_vprintf(const char *format, va_list args) - ATTR_FORMAT(1, 0) ATTR_MALLOC; + ATTR_FORMAT(1, 0) ATTR_MALLOC ATTR_RETURNS_NONNULL; const char *t_strconcat(const char *str1, ...) ATTR_SENTINEL ATTR_MALLOC; @@ -59,18 +60,18 @@ /* separators is an array of separator characters, not a separator string. an empty data string results in an array containing only NULL. */ char **p_strsplit(pool_t pool, const char *data, const char *separators) - ATTR_MALLOC; + ATTR_MALLOC ATTR_RETURNS_NONNULL; const char **t_strsplit(const char *data, const char *separators) - ATTR_MALLOC; + ATTR_MALLOC ATTR_RETURNS_NONNULL; /* like p_strsplit(), but treats multiple adjacent separators as a single separator. */ char **p_strsplit_spaces(pool_t pool, const char *data, const char *separators) - ATTR_MALLOC; + ATTR_MALLOC ATTR_RETURNS_NONNULL; const char **t_strsplit_spaces(const char *data, const char *separators) - ATTR_MALLOC; + ATTR_MALLOC ATTR_RETURNS_NONNULL; void p_strsplit_free(pool_t pool, char **arr); /* Optimized version of t_strsplit(data, "\t") */ -const char **t_strsplit_tab(const char *data); +const char **t_strsplit_tab(const char *data) ATTR_MALLOC ATTR_RETURNS_NONNULL; const char *dec2str(uintmax_t number); @@ -78,7 +79,7 @@ unsigned int str_array_length(const char *const *arr) ATTR_PURE; /* Return all strings from array joined into one string. */ const char *t_strarray_join(const char *const *arr, const char *separator) - ATTR_MALLOC; + ATTR_MALLOC ATTR_RETURNS_NONNULL; /* Removes a value from NULL-terminated string array. Returns TRUE if found. */ bool str_array_remove(const char **arr, const char *value); /* Returns TRUE if value exists in NULL-terminated string array. */ @@ -87,7 +88,8 @@ bool str_array_icase_find(const char *const *arr, const char *value); /* Duplicate array of strings. The memory can be freed by freeing the return value. */ -const char **p_strarray_dup(pool_t pool, const char *const *arr); +const char **p_strarray_dup(pool_t pool, const char *const *arr) + ATTR_MALLOC ATTR_RETURNS_NONNULL; #define i_qsort(base, nmemb, size, cmp) \ qsort(base, nmemb, size + \ @@ -103,7 +105,8 @@ /* INTERNAL */ char *t_noalloc_strdup_vprintf(const char *format, va_list args, - unsigned int *size_r) ATTR_FORMAT(1, 0); + unsigned int *size_r) + ATTR_FORMAT(1, 0) ATTR_RETURNS_NONNULL; char *vstrconcat(const char *str1, va_list args, size_t *ret_len) ATTR_MALLOC; #endif From dovecot at dovecot.org Mon Jun 16 16:22:59 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jun 2014 16:22:59 +0000 Subject: dovecot-2.2: login proxy: If passdb returns "source_ip" extra fi... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/75d254897442 changeset: 17503:75d254897442 user: Timo Sirainen date: Mon Jun 16 19:21:36 2014 +0300 description: login proxy: If passdb returns "source_ip" extra field, use it for outgoing connections. diffstat: src/login-common/client-common-auth.c | 5 +++++ src/login-common/client-common.h | 3 ++- src/login-common/login-proxy.c | 10 ++++++++-- src/login-common/login-proxy.h | 2 +- 4 files changed, 16 insertions(+), 4 deletions(-) diffs (88 lines): diff -r 6abf982c268d -r 75d254897442 src/login-common/client-common-auth.c --- a/src/login-common/client-common-auth.c Mon Jun 16 18:01:58 2014 +0300 +++ b/src/login-common/client-common-auth.c Mon Jun 16 19:21:36 2014 +0300 @@ -95,6 +95,8 @@ reply_r->host = value; else if (strcmp(key, "hostip") == 0) reply_r->hostip = value; + else if (strcmp(key, "source_ip") == 0) + reply_r->source_ip = value; else if (strcmp(key, "port") == 0) reply_r->port = atoi(value); else if (strcmp(key, "destuser") == 0) @@ -336,6 +338,9 @@ if (reply->hostip != NULL && net_addr2ip(reply->hostip, &proxy_set.ip) < 0) proxy_set.ip.family = 0; + if (reply->source_ip != NULL && + net_addr2ip(reply->source_ip, &proxy_set.source_ip) < 0) + proxy_set.source_ip.family = 0; proxy_set.port = reply->port; proxy_set.connect_timeout_msecs = reply->proxy_timeout_msecs; if (proxy_set.connect_timeout_msecs == 0) diff -r 6abf982c268d -r 75d254897442 src/login-common/client-common.h --- a/src/login-common/client-common.h Mon Jun 16 18:01:58 2014 +0300 +++ b/src/login-common/client-common.h Mon Jun 16 19:21:36 2014 +0300 @@ -55,7 +55,8 @@ struct client_auth_reply { const char *master_user, *reason; /* for proxying */ - const char *host, *hostip, *destuser, *password, *proxy_mech; + const char *host, *hostip, *source_ip; + const char *destuser, *password, *proxy_mech; unsigned int port; unsigned int proxy_timeout_msecs; unsigned int proxy_refresh_secs; diff -r 6abf982c268d -r 75d254897442 src/login-common/login-proxy.c --- a/src/login-common/login-proxy.c Mon Jun 16 18:01:58 2014 +0300 +++ b/src/login-common/login-proxy.c Mon Jun 16 19:21:36 2014 +0300 @@ -39,7 +39,7 @@ struct timeout *to, *to_notify; struct login_proxy_record *state_rec; - struct ip_addr ip; + struct ip_addr ip, source_ip; char *host; unsigned int port; unsigned int connect_timeout_msecs; @@ -229,6 +229,9 @@ net_getsockname(proxy->server_fd, &local_ip, &local_port) == 0) { str_printfa(str, ", local=%s:%u", net_ip2addr(&local_ip), local_port); + } else if (proxy->source_ip.family != 0) { + str_printfa(str, ", local=%s", + net_ip2addr(&proxy->source_ip)); } str_append_c(str, ')'); @@ -285,7 +288,9 @@ return -1; } - proxy->server_fd = net_connect_ip(&proxy->ip, proxy->port, NULL); + proxy->server_fd = net_connect_ip(&proxy->ip, proxy->port, + proxy->source_ip.family == 0 ? NULL : + &proxy->source_ip); if (proxy->server_fd == -1) { proxy_log_connect_error(proxy); login_proxy_free(&proxy); @@ -328,6 +333,7 @@ proxy->server_fd = -1; proxy->created = ioloop_timeval; proxy->ip = set->ip; + proxy->source_ip = set->source_ip; proxy->host = i_strdup(set->host); proxy->port = set->port; proxy->connect_timeout_msecs = set->connect_timeout_msecs; diff -r 6abf982c268d -r 75d254897442 src/login-common/login-proxy.h --- a/src/login-common/login-proxy.h Mon Jun 16 18:01:58 2014 +0300 +++ b/src/login-common/login-proxy.h Mon Jun 16 19:21:36 2014 +0300 @@ -24,7 +24,7 @@ struct login_proxy_settings { const char *host; - struct ip_addr ip; + struct ip_addr ip, source_ip; unsigned int port; unsigned int connect_timeout_msecs; /* send a notification about proxy connection to proxy-notify pipe From dovecot at dovecot.org Mon Jun 16 16:53:31 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jun 2014 16:53:31 +0000 Subject: dovecot-2.2: login proxy: Added login_source_ips setting. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b6733f4777f1 changeset: 17504:b6733f4777f1 user: Timo Sirainen date: Mon Jun 16 19:52:11 2014 +0300 description: login proxy: Added login_source_ips setting. The setting contains a list of IPs/hosts. The setting may be prefixed with "?" character to indicate that only those IPs should be used that exist in the current server (allowing the same config to be shared by multiple servers). The IPs are used round robin as the source IP address when proxy creates TCP connections. This becomes useful when there are a ton of connections from the proxy to the same destination IP, because TCP ports run out after ~64k connections. diffstat: src/login-common/client-common-auth.c | 12 ++++++-- src/login-common/login-common.h | 3 ++ src/login-common/login-settings.c | 2 + src/login-common/login-settings.h | 1 + src/login-common/main.c | 49 +++++++++++++++++++++++++++++++++++ 5 files changed, 64 insertions(+), 3 deletions(-) diffs (145 lines): diff -r 75d254897442 -r b6733f4777f1 src/login-common/client-common-auth.c --- a/src/login-common/client-common-auth.c Mon Jun 16 19:21:36 2014 +0300 +++ b/src/login-common/client-common-auth.c Mon Jun 16 19:52:11 2014 +0300 @@ -338,9 +338,15 @@ if (reply->hostip != NULL && net_addr2ip(reply->hostip, &proxy_set.ip) < 0) proxy_set.ip.family = 0; - if (reply->source_ip != NULL && - net_addr2ip(reply->source_ip, &proxy_set.source_ip) < 0) - proxy_set.source_ip.family = 0; + if (reply->source_ip != NULL) { + if (net_addr2ip(reply->source_ip, &proxy_set.source_ip) < 0) + proxy_set.source_ip.family = 0; + } else if (login_source_ips_count > 0) { + /* select the next source IP with round robin. */ + proxy_set.source_ip = login_source_ips[login_source_ips_idx]; + login_source_ips_idx = + (login_source_ips_idx + 1) % login_source_ips_count; + } proxy_set.port = reply->port; proxy_set.connect_timeout_msecs = reply->proxy_timeout_msecs; if (proxy_set.connect_timeout_msecs == 0) diff -r 75d254897442 -r b6733f4777f1 src/login-common/login-common.h --- a/src/login-common/login-common.h Mon Jun 16 19:21:36 2014 +0300 +++ b/src/login-common/login-common.h Mon Jun 16 19:52:11 2014 +0300 @@ -49,6 +49,9 @@ extern const struct master_service_ssl_settings *global_ssl_settings; extern void **global_other_settings; +extern const struct ip_addr *login_source_ips; +extern unsigned int login_source_ips_idx, login_source_ips_count; + void login_refresh_proctitle(void); void login_client_destroyed(void); diff -r 75d254897442 -r b6733f4777f1 src/login-common/login-settings.c --- a/src/login-common/login-settings.c Mon Jun 16 19:21:36 2014 +0300 +++ b/src/login-common/login-settings.c Mon Jun 16 19:52:11 2014 +0300 @@ -21,6 +21,7 @@ static const struct setting_define login_setting_defines[] = { DEF(SET_STR, login_trusted_networks), + DEF(SET_STR, login_source_ips), DEF(SET_STR_VARS, login_greeting), DEF(SET_STR, login_log_format_elements), DEF(SET_STR, login_log_format), @@ -45,6 +46,7 @@ static const struct login_settings login_default_settings = { .login_trusted_networks = "", + .login_source_ips = "", .login_greeting = PACKAGE_NAME" ready.", .login_log_format_elements = "user=<%u> method=%m rip=%r lip=%l mpid=%e %c session=<%{session}>", .login_log_format = "%$: %s", diff -r 75d254897442 -r b6733f4777f1 src/login-common/login-settings.h --- a/src/login-common/login-settings.h Mon Jun 16 19:21:36 2014 +0300 +++ b/src/login-common/login-settings.h Mon Jun 16 19:52:11 2014 +0300 @@ -5,6 +5,7 @@ struct login_settings { const char *login_trusted_networks; + const char *login_source_ips; const char *login_greeting; const char *login_log_format_elements, *login_log_format; const char *login_access_sockets; diff -r 75d254897442 -r b6733f4777f1 src/login-common/main.c --- a/src/login-common/main.c Mon Jun 16 19:21:36 2014 +0300 +++ b/src/login-common/main.c Mon Jun 16 19:52:11 2014 +0300 @@ -2,6 +2,7 @@ #include "login-common.h" #include "ioloop.h" +#include "array.h" #include "randgen.h" #include "process-title.h" #include "restrict-access.h" @@ -44,6 +45,9 @@ const struct master_service_ssl_settings *global_ssl_settings; void **global_other_settings; +const struct ip_addr *login_source_ips; +unsigned int login_source_ips_idx, login_source_ips_count; + static struct timeout *auth_client_to; static bool shutting_down = FALSE; static bool ssl_connections = FALSE; @@ -277,6 +281,40 @@ return FALSE; } +static const struct ip_addr * +parse_login_source_ips(const char *ips_str, unsigned int *count_r) +{ + ARRAY(struct ip_addr) ips; + const char *const *tmp; + struct ip_addr *tmp_ips; + bool skip_nonworking = FALSE; + unsigned int i, tmp_ips_count; + int ret; + + if (ips_str[0] == '?') { + /* try binding to the IP immediately. if it doesn't + work, skip it. (this allows using the same config file for + all the servers.) */ + skip_nonworking = TRUE; + ips_str++; + } + t_array_init(&ips, 4); + for (tmp = t_strsplit_spaces(ips_str, ", "); *tmp != NULL; tmp++) { + ret = net_gethostbyname(*tmp, &tmp_ips, &tmp_ips_count); + if (ret != 0) { + i_error("login_source_ips: net_gethostbyname(%s) failed: %s", + *tmp, net_gethosterror(ret)); + continue; + } + for (i = 0; i < tmp_ips_count; i++) { + if (skip_nonworking && net_try_bind(&tmp_ips[i]) < 0) + continue; + array_append(&ips, &tmp_ips[i], 1); + } + } + return array_get(&ips, count_r); +} + static void main_preinit(bool allow_core_dumps) { unsigned int max_fds; @@ -312,6 +350,17 @@ i_fatal("Couldn't connect to anvil"); } + /* read the login_source_ips before chrooting so it can access + /etc/hosts */ + login_source_ips = parse_login_source_ips(global_login_settings->login_source_ips, + &login_source_ips_count); + if (login_source_ips_count > 0) { + /* randomize the initial index in case service_count=1 + (although in that case it's unlikely this setting is + even used..) */ + login_source_ips_idx = rand() % login_source_ips_count; + } + restrict_access_by_env(NULL, TRUE); if (allow_core_dumps) restrict_access_allow_coredumps(TRUE); From pigeonhole at rename-it.nl Tue Jun 17 18:58:32 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 17 Jun 2014 20:58:32 +0200 Subject: dovecot-2.2-pigeonhole: lib: pair VA_COPY with va_end. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/a2a8fb3cea09 changeset: 1865:a2a8fb3cea09 user: Stephan Bosch date: Tue Jun 17 20:35:18 2014 +0200 description: lib: pair VA_COPY with va_end. A va_copy creates a initialised va_list, as if a va_start had been done on it. Therefore, pedantically, a va_end should also be done on it. On most platforms this is a no-op, and for those where it isn't, the pairing is important. This change matches parallel change in Dovecot. Also signalled by Coverity. diffstat: src/lib-sieve/sieve-error.c | 6 ++++-- src/testsuite/testsuite-log.c | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diffs (61 lines): diff -r 6a0376f1a7d2 -r a2a8fb3cea09 src/lib-sieve/sieve-error.c --- a/src/lib-sieve/sieve-error.c Thu May 15 19:48:27 2014 +0200 +++ b/src/lib-sieve/sieve-error.c Tue Jun 17 20:35:18 2014 +0200 @@ -96,6 +96,7 @@ (svinst->system_ehandler, 0, location, fmt, args_copy); } } + va_end(args_copy); } if (svinst->system_ehandler == ehandler) return; @@ -137,6 +138,7 @@ (svinst->system_ehandler, 0, location, fmt, args_copy); } } + va_end(args_copy); } if (svinst->system_ehandler == ehandler) return; @@ -164,9 +166,9 @@ va_list args_copy; VA_COPY(args_copy, args); - svinst->system_ehandler->vinfo (svinst->system_ehandler, 0, location, fmt, args_copy); + va_end(args_copy); } } @@ -191,9 +193,9 @@ va_list args_copy; VA_COPY(args_copy, args); - svinst->system_ehandler->vdebug (svinst->system_ehandler, 0, location, fmt, args_copy); + va_end(args_copy); } } diff -r 6a0376f1a7d2 -r a2a8fb3cea09 src/testsuite/testsuite-log.c --- a/src/testsuite/testsuite-log.c Thu May 15 19:48:27 2014 +0200 +++ b/src/testsuite/testsuite-log.c Tue Jun 17 20:35:18 2014 +0200 @@ -41,14 +41,15 @@ { if ( _testsuite_log_stdout ) { va_list args_copy; + VA_COPY(args_copy, args); - if ( location == NULL || *location == '\0' ) fprintf(stdout, "LOG: %s: %s\n", prefix, t_strdup_vprintf(fmt, args_copy)); else fprintf(stdout, "LOG: %s: %s: %s\n", prefix, location, t_strdup_vprintf(fmt, args_copy)); + va_end(args_copy); } } From pigeonhole at rename-it.nl Tue Jun 17 18:58:33 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 17 Jun 2014 20:58:33 +0200 Subject: dovecot-2.2-pigeonhole: managesieve: Remove the client from clie... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/e547bdec932f changeset: 1869:e547bdec932f user: Stephan Bosch date: Tue Jun 17 20:58:23 2014 +0200 description: managesieve: Remove the client from clients-list at the very end of the destroy function. Parallel to identical Dovecot change for imap and pop3. diffstat: src/managesieve/managesieve-client.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (23 lines): diff -r 54ccf712b9d0 -r e547bdec932f src/managesieve/managesieve-client.c --- a/src/managesieve/managesieve-client.c Tue Jun 17 20:48:50 2014 +0200 +++ b/src/managesieve/managesieve-client.c Tue Jun 17 20:58:23 2014 +0200 @@ -218,9 +218,6 @@ i_info("%s %s", reason, client_stats(client)); } - managesieve_client_count--; - DLLIST_REMOVE(&managesieve_clients, client); - if (client->command_pending) { /* try to deinitialize the command */ i_assert(client->cmd.func != NULL); @@ -263,6 +260,9 @@ sieve_deinit(&client->svinst); pool_unref(&client->cmd.pool); + + managesieve_client_count--; + DLLIST_REMOVE(&managesieve_clients, client); pool_unref(&client->pool); master_service_client_connection_destroyed(master_service); From pigeonhole at rename-it.nl Tue Jun 17 18:58:33 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 17 Jun 2014 20:58:33 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: code dumper: Fixed handling o... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/54ccf712b9d0 changeset: 1868:54ccf712b9d0 user: Stephan Bosch date: Tue Jun 17 20:48:50 2014 +0200 description: lib-sieve: code dumper: Fixed handling of undefined extensions. Reported by Coverity. diffstat: src/lib-sieve/sieve-code-dumper.c | 19 ++++++++++++------- 1 files changed, 12 insertions(+), 7 deletions(-) diffs (31 lines): diff -r d4a2d592b6f9 -r 54ccf712b9d0 src/lib-sieve/sieve-code-dumper.c --- a/src/lib-sieve/sieve-code-dumper.c Tue Jun 17 20:44:47 2014 +0200 +++ b/src/lib-sieve/sieve-code-dumper.c Tue Jun 17 20:48:50 2014 +0200 @@ -280,15 +280,20 @@ break; } - sieve_code_dumpf(denv, "%s", sieve_extension_name(ext)); + if ( ext->def == NULL) { + sieve_code_dumpf(denv, "[undefined]"); - if ( ext->def != NULL && ext->def->code_dump != NULL ) { - sieve_code_descend(denv); - if ( !ext->def->code_dump(ext, denv, address) ) { - success = FALSE; - break; + } else { + sieve_code_dumpf(denv, "%s", sieve_extension_name(ext)); + + if (ext->def->code_dump != NULL ) { + sieve_code_descend(denv); + if ( !ext->def->code_dump(ext, denv, address) ) { + success = FALSE; + break; + } + sieve_code_ascend(denv); } - sieve_code_ascend(denv); } } T_END; } From pigeonhole at rename-it.nl Tue Jun 17 18:58:32 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 17 Jun 2014 20:58:32 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: Small change in Sieve generat... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/d4a2d592b6f9 changeset: 1867:d4a2d592b6f9 user: Stephan Bosch date: Tue Jun 17 20:44:47 2014 +0200 description: lib-sieve: Small change in Sieve generator to make static analyzer happier. Reported by Coverity. diffstat: src/lib-sieve/sieve-generator.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (21 lines): diff -r 18c4b82636a4 -r d4a2d592b6f9 src/lib-sieve/sieve-generator.c --- a/src/lib-sieve/sieve-generator.c Tue Jun 17 20:41:53 2014 +0200 +++ b/src/lib-sieve/sieve-generator.c Tue Jun 17 20:44:47 2014 +0200 @@ -459,6 +459,8 @@ sbin = sieve_binary_block_get_binary(sblock); } + i_assert(sbin != NULL); + sieve_binary_ref(sbin); gentr->genenv.sbin = sbin; gentr->genenv.sblock = sblock; @@ -472,7 +474,7 @@ /* Load extensions linked to the AST and emit a list in code */ extensions = sieve_ast_extensions_get(gentr->genenv.ast, &ext_count); (void) sieve_binary_emit_unsigned(sblock, ext_count); - for ( i = 0; i < ext_count && sbin != NULL; i++ ) { + for ( i = 0; i < ext_count; i++ ) { const struct sieve_extension *ext = extensions[i]; /* Link to binary */ From pigeonhole at rename-it.nl Tue Jun 17 18:58:32 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 17 Jun 2014 20:58:32 +0200 Subject: dovecot-2.2-pigeonhole: doveadm sieve plugin: Fixed dereference ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/18c4b82636a4 changeset: 1866:18c4b82636a4 user: Stephan Bosch date: Tue Jun 17 20:41:53 2014 +0200 description: doveadm sieve plugin: Fixed dereference before NULL check problem. Found by Coverity. diffstat: src/plugins/doveadm-sieve/doveadm-sieve-plugin.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (22 lines): diff -r a2a8fb3cea09 -r 18c4b82636a4 src/plugins/doveadm-sieve/doveadm-sieve-plugin.c --- a/src/plugins/doveadm-sieve/doveadm-sieve-plugin.c Tue Jun 17 20:35:18 2014 +0200 +++ b/src/plugins/doveadm-sieve/doveadm-sieve-plugin.c Tue Jun 17 20:41:53 2014 +0200 @@ -310,8 +310,6 @@ return sieve_attribute_unset_script(storage, svstorage, scriptname); } - sieve_storage_save_set_mtime(save_ctx, value->last_change); - if (save_ctx == NULL) { /* save initialization failed */ mail_storage_set_critical(storage, @@ -319,6 +317,9 @@ sieve_storage_get_last_error(svstorage, NULL)); return -1; } + + sieve_storage_save_set_mtime(save_ctx, value->last_change); + ret = 0; while (i_stream_read(input) > 0) { if (sieve_storage_save_continue(save_ctx) < 0) { From pigeonhole at rename-it.nl Tue Jun 17 20:14:05 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 17 Jun 2014 22:14:05 +0200 Subject: dovecot-2.2-pigeonhole: Use the new [io]_stream_create_fd_*autoc... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/f81d25ef0e66 changeset: 1870:f81d25ef0e66 user: Stephan Bosch date: Tue Jun 17 22:13:52 2014 +0200 description: Use the new [io]_stream_create_fd_*autoclose() functions wherever possible. Parallel to identical Dovecot change. diffstat: src/lib-sieve-tool/sieve-tool.c | 2 +- src/lib-sieve/sieve-script-file.c | 4 ++-- src/lib-sieve/sieve-script-private.h | 2 -- src/testsuite/testsuite-smtp.c | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diffs (56 lines): diff -r e547bdec932f -r f81d25ef0e66 src/lib-sieve-tool/sieve-tool.c --- a/src/lib-sieve-tool/sieve-tool.c Tue Jun 17 20:58:23 2014 +0200 +++ b/src/lib-sieve-tool/sieve-tool.c Tue Jun 17 22:13:52 2014 +0200 @@ -515,7 +515,7 @@ i_fatal("failed to open file for writing: %m"); } - outstream = o_stream_create_fd(fd, 0, TRUE); + outstream = o_stream_create_fd_autoclose(&fd, 0); } return outstream; diff -r e547bdec932f -r f81d25ef0e66 src/lib-sieve/sieve-script-file.c --- a/src/lib-sieve/sieve-script-file.c Tue Jun 17 20:58:23 2014 +0200 +++ b/src/lib-sieve/sieve-script-file.c Tue Jun 17 22:13:52 2014 +0200 @@ -286,14 +286,14 @@ *error_r = SIEVE_ERROR_TEMP_FAILURE; result = NULL; } else { - result = i_stream_create_fd(fd, SIEVE_FILE_READ_BLOCK_SIZE, TRUE); + result = i_stream_create_fd_autoclose(&fd, SIEVE_FILE_READ_BLOCK_SIZE); script->st = script->lnk_st = st; } } if ( result == NULL ) { /* Something went wrong, close the fd */ - if ( close(fd) != 0 ) { + if ( fd >= 0 && close(fd) != 0 ) { sieve_sys_error(svinst, "failed to close sieve script: close(fd=%s) failed: %m", script->path); } diff -r e547bdec932f -r f81d25ef0e66 src/lib-sieve/sieve-script-private.h --- a/src/lib-sieve/sieve-script-private.h Tue Jun 17 20:58:23 2014 +0200 +++ b/src/lib-sieve/sieve-script-private.h Tue Jun 17 22:13:52 2014 +0200 @@ -89,8 +89,6 @@ const char *filename; const char *binpath; const char *binprefix; - - int fd; }; extern const struct sieve_script sieve_file_script; diff -r e547bdec932f -r f81d25ef0e66 src/testsuite/testsuite-smtp.c --- a/src/testsuite/testsuite-smtp.c Tue Jun 17 20:58:23 2014 +0200 +++ b/src/testsuite/testsuite-smtp.c Tue Jun 17 22:13:52 2014 +0200 @@ -95,7 +95,7 @@ smtp->msg_file); } - smtp->output = o_stream_create_fd(fd, (size_t)-1, TRUE); + smtp->output = o_stream_create_fd_autoclose(&fd, (size_t)-1); return (void *) smtp; } From pigeonhole at rename-it.nl Tue Jun 17 20:28:20 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 17 Jun 2014 22:28:20 +0200 Subject: dovecot-2.2-pigeonhole: sieve-storage: Fixed resource leak in st... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/827a317cfdc3 changeset: 1871:827a317cfdc3 user: Stephan Bosch date: Tue Jun 17 22:28:06 2014 +0200 description: sieve-storage: Fixed resource leak in storage listing implementation occuring at error. Reported by Coverity. diffstat: src/lib-sievestorage/sieve-storage-list.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r f81d25ef0e66 -r 827a317cfdc3 src/lib-sievestorage/sieve-storage-list.c --- a/src/lib-sievestorage/sieve-storage-list.c Tue Jun 17 22:13:52 2014 +0200 +++ b/src/lib-sievestorage/sieve-storage-list.c Tue Jun 17 22:28:06 2014 +0200 @@ -58,6 +58,9 @@ } } T_END; + if ( ctx == NULL && closedir(dirp) < 0) + i_error("sieve-storage: closedir(%s) failed: %m", storage->dir); + return ctx; } From pigeonhole at rename-it.nl Tue Jun 17 20:45:36 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 17 Jun 2014 22:45:36 +0200 Subject: dovecot-2.2-pigeonhole: testsuite: Fixed out-of-bounds read in (... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/961137231f07 changeset: 1872:961137231f07 user: Stephan Bosch date: Tue Jun 17 22:38:12 2014 +0200 description: testsuite: Fixed out-of-bounds read in (currently unused) string substitution implementation. Reported by Coverity. diffstat: src/testsuite/testsuite-substitutions.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 827a317cfdc3 -r 961137231f07 src/testsuite/testsuite-substitutions.c --- a/src/testsuite/testsuite-substitutions.c Tue Jun 17 22:28:06 2014 +0200 +++ b/src/testsuite/testsuite-substitutions.c Tue Jun 17 22:38:12 2014 +0200 @@ -44,7 +44,7 @@ testsuite_substitution_get (unsigned int code) { - if ( code > substitutions_count ) + if ( code >= substitutions_count ) return NULL; return substitutions[code]; From pigeonhole at rename-it.nl Tue Jun 17 20:45:37 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 17 Jun 2014 22:45:37 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: program client: Forgot break ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/247f9d1a9820 changeset: 1873:247f9d1a9820 user: Stephan Bosch date: Tue Jun 17 22:45:23 2014 +0200 description: lib-sieve: program client: Forgot break in switch statement for handling of response from script service. Reported by Coverity. diffstat: src/lib-sieve/util/program-client-remote.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 961137231f07 -r 247f9d1a9820 src/lib-sieve/util/program-client-remote.c --- a/src/lib-sieve/util/program-client-remote.c Tue Jun 17 22:38:12 2014 +0200 +++ b/src/lib-sieve/util/program-client-remote.c Tue Jun 17 22:45:23 2014 +0200 @@ -77,6 +77,7 @@ break; case '-': scstream->client->exit_code = 0; + break; default: scstream->client->exit_code = -1; } From pigeonhole at rename-it.nl Tue Jun 17 20:55:52 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 17 Jun 2014 22:55:52 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: edit mail: Fixed header unfol... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/a358a0d7af70 changeset: 1874:a358a0d7af70 user: Stephan Bosch date: Tue Jun 17 22:52:32 2014 +0200 description: lib-sieve: edit mail: Fixed header unfolding. Forgot break in switch statement. Reported by Coverity. diffstat: src/lib-sieve/util/edit-mail.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (18 lines): diff -r 247f9d1a9820 -r a358a0d7af70 src/lib-sieve/util/edit-mail.c --- a/src/lib-sieve/util/edit-mail.c Tue Jun 17 22:45:23 2014 +0200 +++ b/src/lib-sieve/util/edit-mail.c Tue Jun 17 22:52:32 2014 +0200 @@ -727,10 +727,12 @@ break; switch ( value[i] ) { + case ' ': + str_append_c(out, ' '); + break; + case '\t': default: str_append_c(out, '\t'); - case ' ': case '\t': - str_append_c(out, value[i]); } } else { if (value[i] != '\r') From pigeonhole at rename-it.nl Tue Jun 17 21:04:34 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 17 Jun 2014 23:04:34 +0200 Subject: dovecot-2.2-pigeonhole: lib-sievestorage: Fixed file path compar... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/14ca1297d52d changeset: 1875:14ca1297d52d user: Stephan Bosch date: Tue Jun 17 23:04:24 2014 +0200 description: lib-sievestorage: Fixed file path comparison function. Forgot a few '*' there. Reported by Coverity. diffstat: src/lib-sievestorage/sieve-storage-script.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (15 lines): diff -r a358a0d7af70 -r 14ca1297d52d src/lib-sievestorage/sieve-storage-script.c --- a/src/lib-sievestorage/sieve-storage-script.c Tue Jun 17 22:52:32 2014 +0200 +++ b/src/lib-sievestorage/sieve-storage-script.c Tue Jun 17 23:04:24 2014 +0200 @@ -37,9 +37,9 @@ int ret; p1 = path1; p2 = path2; - if (*p2 == '\0' && p1 != '\0') + if (*p2 == '\0' && *p1 != '\0') return 1; - if (*p1 == '\0' && p2 != '\0') + if (*p1 == '\0' && *p2 != '\0') return -1; if (*p1 == '/' && *p2 != '/') return 1; From pigeonhole at rename-it.nl Tue Jun 17 21:19:48 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 17 Jun 2014 23:19:48 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: relational extension: Fixed e... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/1c7a4ec3fd80 changeset: 1876:1c7a4ec3fd80 user: Stephan Bosch date: Tue Jun 17 23:19:37 2014 +0200 description: lib-sieve: relational extension: Fixed error handling of :value match. Switch statement item is never reached and return value was bool instead of int. Problem reported by Coverity. diffstat: src/lib-sieve/plugins/relational/mcht-value.c | 15 +++++++-------- 1 files changed, 7 insertions(+), 8 deletions(-) diffs (34 lines): diff -r 14ca1297d52d -r 1c7a4ec3fd80 src/lib-sieve/plugins/relational/mcht-value.c --- a/src/lib-sieve/plugins/relational/mcht-value.c Tue Jun 17 23:04:24 2014 +0200 +++ b/src/lib-sieve/plugins/relational/mcht-value.c Tue Jun 17 23:19:37 2014 +0200 @@ -63,23 +63,22 @@ switch ( rel_match ) { case REL_MATCH_GREATER: - return ( cmp_result > 0 ); + return ( cmp_result > 0 ? 1 : 0 ); case REL_MATCH_GREATER_EQUAL: - return ( cmp_result >= 0 ); + return ( cmp_result >= 0 ? 1 : 0 ); case REL_MATCH_LESS: - return ( cmp_result < 0 ); + return ( cmp_result < 0 ? 1 : 0 ); case REL_MATCH_LESS_EQUAL: - return ( cmp_result <= 0 ); + return ( cmp_result <= 0 ? 1 : 0 ); case REL_MATCH_EQUAL: - return ( cmp_result == 0 ); + return ( cmp_result == 0 ? 1 : 0); case REL_MATCH_NOT_EQUAL: - return ( cmp_result != 0 ); - case REL_MATCH_INVALID: + return ( cmp_result != 0 ? 1 : 0); default: break; } - return FALSE; + return -1; } From pigeonhole at rename-it.nl Tue Jun 17 21:29:35 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 17 Jun 2014 23:29:35 +0200 Subject: dovecot-2.2-pigeonhole: sieve extprograms plugin: Fixed dead cod... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/9401789c7332 changeset: 1877:9401789c7332 user: Stephan Bosch date: Tue Jun 17 23:28:53 2014 +0200 description: sieve extprograms plugin: Fixed dead code problems. Reported by Coverity. diffstat: src/plugins/sieve-extprograms/cmd-execute.c | 10 ++++------ src/plugins/sieve-extprograms/cmd-pipe.c | 3 --- 2 files changed, 4 insertions(+), 9 deletions(-) diffs (41 lines): diff -r 1c7a4ec3fd80 -r 9401789c7332 src/plugins/sieve-extprograms/cmd-execute.c --- a/src/plugins/sieve-extprograms/cmd-execute.c Tue Jun 17 23:19:37 2014 +0200 +++ b/src/plugins/sieve-extprograms/cmd-execute.c Tue Jun 17 23:28:53 2014 +0200 @@ -335,15 +335,13 @@ switch ( opt_code ) { case OPT_INPUT: - if ( (ret=sieve_opr_string_read_ex - (renv, address, "input", TRUE, &input, NULL)) <= 0 ) - return ret; + ret = sieve_opr_string_read_ex + (renv, address, "input", TRUE, &input, NULL); have_input = TRUE; break; case OPT_OUTPUT: - if ( (ret=sieve_variable_operand_read - (renv, address, "output", &var_storage, &var_index)) <= 0 ) - return ret; + ret = sieve_variable_operand_read + (renv, address, "output", &var_storage, &var_index); break; default: sieve_runtime_trace_error(renv, "unknown optional operand"); diff -r 1c7a4ec3fd80 -r 9401789c7332 src/plugins/sieve-extprograms/cmd-pipe.c --- a/src/plugins/sieve-extprograms/cmd-pipe.c Tue Jun 17 23:19:37 2014 +0200 +++ b/src/plugins/sieve-extprograms/cmd-pipe.c Tue Jun 17 23:28:53 2014 +0200 @@ -222,14 +222,11 @@ switch ( opt_code ) { case OPT_TRY: try = TRUE; - ret = SIEVE_EXEC_OK; break; default: sieve_runtime_trace_error(renv, "unknown optional operand"); return SIEVE_EXEC_BIN_CORRUPT; } - - if ( ret <= 0 ) return ret; } /* Fixed operands */ From pigeonhole at rename-it.nl Tue Jun 17 21:37:58 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 17 Jun 2014 23:37:58 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: edit mail: Fixed header itera... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/743213918b1b changeset: 1878:743213918b1b user: Stephan Bosch date: Tue Jun 17 23:37:46 2014 +0200 description: lib-sieve: edit mail: Fixed header iteration. Handling of edit_mail_header_find() result was incoherent. Problem reported by Coverity. diffstat: src/lib-sieve/util/edit-mail.c | 5 +---- 1 files changed, 1 insertions(+), 4 deletions(-) diffs (15 lines): diff -r 9401789c7332 -r 743213918b1b src/lib-sieve/util/edit-mail.c --- a/src/lib-sieve/util/edit-mail.c Tue Jun 17 23:28:53 2014 +0200 +++ b/src/lib-sieve/util/edit-mail.c Tue Jun 17 23:37:46 2014 +0200 @@ -914,10 +914,7 @@ return -1; } - if ( field_name != NULL - && (header_idx=edit_mail_header_find(edmail, field_name)) == NULL ) { - return 0; - } + header_idx = edit_mail_header_find(edmail, field_name); edhiter = i_new(struct edit_mail_header_iter, 1); edhiter->mail = edmail; From pigeonhole at rename-it.nl Tue Jun 17 21:43:21 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 17 Jun 2014 23:43:21 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: program client: Fixed copy-pa... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/60e5e65ffb01 changeset: 1879:60e5e65ffb01 user: Stephan Bosch date: Tue Jun 17 23:43:10 2014 +0200 description: lib-sieve: program client: Fixed copy-paste error in destroy function. Would cause a segfault. Reported by Coverity. diffstat: src/lib-sieve/util/program-client.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 743213918b1b -r 60e5e65ffb01 src/lib-sieve/util/program-client.c --- a/src/lib-sieve/util/program-client.c Tue Jun 17 23:37:46 2014 +0200 +++ b/src/lib-sieve/util/program-client.c Tue Jun 17 23:43:10 2014 +0200 @@ -470,7 +470,7 @@ i_stream_unref(&pclient->input); if ( pclient->output != NULL ) o_stream_unref(&pclient->output); - if ( pclient->input != NULL ) + if ( pclient->seekable_output != NULL ) i_stream_unref(&pclient->seekable_output); if ( pclient->io != NULL ) io_remove(&pclient->io); From pigeonhole at rename-it.nl Tue Jun 17 22:08:54 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Wed, 18 Jun 2014 00:08:54 +0200 Subject: dovecot-2.2-pigeonhole: Some ATTR_FORMAT additions by Timo. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/b56520e04882 changeset: 1880:b56520e04882 user: Stephan Bosch date: Wed Jun 18 00:08:03 2014 +0200 description: Some ATTR_FORMAT additions by Timo. diffstat: src/lib-sieve/sieve-error-private.h | 24 ++++++++++++------------ src/lib-sieve/sieve-error.h | 32 ++++++++++++++++---------------- 2 files changed, 28 insertions(+), 28 deletions(-) diffs (163 lines): diff -r 60e5e65ffb01 -r b56520e04882 src/lib-sieve/sieve-error-private.h --- a/src/lib-sieve/sieve-error-private.h Tue Jun 17 23:43:10 2014 +0200 +++ b/src/lib-sieve/sieve-error-private.h Wed Jun 18 00:08:03 2014 +0200 @@ -47,16 +47,16 @@ void (*verror) (struct sieve_error_handler *ehandler, unsigned int flags, - const char *location, const char *fmt, va_list args); + const char *location, const char *fmt, va_list args) ATTR_FORMAT(4, 0); void (*vwarning) (struct sieve_error_handler *ehandler, unsigned int flags, - const char *location, const char *fmt, va_list args); + const char *location, const char *fmt, va_list args) ATTR_FORMAT(4, 0);; void (*vinfo) (struct sieve_error_handler *ehandler, unsigned int flags, - const char *location, const char *fmt, va_list args); + const char *location, const char *fmt, va_list args) ATTR_FORMAT(4, 0);; void (*vdebug) (struct sieve_error_handler *ehandler, unsigned int flags, - const char *location, const char *fmt, va_list args); + const char *location, const char *fmt, va_list args) ATTR_FORMAT(4, 0);; void (*free) (struct sieve_error_handler *ehandler); @@ -76,18 +76,18 @@ void sieve_direct_verror (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, - unsigned int flags, const char *location, const char *fmt, va_list args); + unsigned int flags, const char *location, const char *fmt, va_list args) ATTR_FORMAT(5, 0); void sieve_direct_vwarning (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, - unsigned int flags, const char *location, const char *fmt, va_list args); + unsigned int flags, const char *location, const char *fmt, va_list args) ATTR_FORMAT(5, 0); void sieve_direct_vinfo (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, - unsigned int flags, const char *location, const char *fmt, va_list args); + unsigned int flags, const char *location, const char *fmt, va_list args) ATTR_FORMAT(5, 0); void sieve_direct_vdebug (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, - unsigned int flags, const char *location, const char *fmt, va_list args); + unsigned int flags, const char *location, const char *fmt, va_list args) ATTR_FORMAT(5, 0); -static inline void sieve_direct_error +static inline void ATTR_FORMAT(5, 6) sieve_direct_error (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, unsigned int flags, const char *location, const char *fmt, ...) { @@ -99,7 +99,7 @@ va_end(args); } -static inline void sieve_direct_warning +static inline void ATTR_FORMAT(5, 6) sieve_direct_warning (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, unsigned int flags, const char *location, const char *fmt, ...) { @@ -111,7 +111,7 @@ va_end(args); } -static inline void sieve_direct_info +static inline void ATTR_FORMAT(5, 6) sieve_direct_info (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, unsigned int flags, const char *location, const char *fmt, ...) { @@ -123,7 +123,7 @@ va_end(args); } -static inline void sieve_direct_debug +static inline void ATTR_FORMAT(5, 6) sieve_direct_debug (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, unsigned int flags, const char *location, const char *fmt, ...) { diff -r 60e5e65ffb01 -r b56520e04882 src/lib-sieve/sieve-error.h --- a/src/lib-sieve/sieve-error.h Tue Jun 17 23:43:10 2014 +0200 +++ b/src/lib-sieve/sieve-error.h Wed Jun 18 00:08:03 2014 +0200 @@ -25,13 +25,13 @@ typedef void (*sieve_error_vfunc_t) (struct sieve_error_handler *ehandler, const char *location, - const char *fmt, va_list args); + const char *fmt, va_list args) ATTR_FORMAT(3, 0);; typedef void (*sieve_error_func_t) (struct sieve_error_handler *ehandler, const char *location, const char *fmt, ...) ATTR_FORMAT(3, 4); typedef void (*sieve_sys_error_vfunc_t) - (struct sieve_instance *svinst, const char *fmt, va_list args); + (struct sieve_instance *svinst, const char *fmt, va_list args) ATTR_FORMAT(2, 0);; typedef void (*sieve_sys_error_func_t) (struct sieve_instance *svinst, const char *fmt, ...) ATTR_FORMAT(2, 3); @@ -40,13 +40,13 @@ */ void sieve_sys_verror - (struct sieve_instance *svinst, const char *fmt, va_list args); + (struct sieve_instance *svinst, const char *fmt, va_list args) ATTR_FORMAT(2, 0);; void sieve_sys_vwarning - (struct sieve_instance *svinst, const char *fmt, va_list args); + (struct sieve_instance *svinst, const char *fmt, va_list args) ATTR_FORMAT(2, 0);; void sieve_sys_vinfo - (struct sieve_instance *svinst, const char *fmt, va_list args); + (struct sieve_instance *svinst, const char *fmt, va_list args) ATTR_FORMAT(2, 0);; void sieve_sys_vdebug - (struct sieve_instance *svinst, const char *fmt, va_list args); + (struct sieve_instance *svinst, const char *fmt, va_list args) ATTR_FORMAT(2, 0);; void sieve_sys_error (struct sieve_instance *svinst, const char *fmt, ...) ATTR_FORMAT(2, 3); @@ -68,19 +68,19 @@ void sieve_global_verror (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, - const char *location, const char *fmt, va_list args); + const char *location, const char *fmt, va_list args) ATTR_FORMAT(4, 0); void sieve_global_vwarning (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, - const char *location, const char *fmt, va_list args); + const char *location, const char *fmt, va_list args) ATTR_FORMAT(4, 0); void sieve_global_vinfo (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, - const char *location, const char *fmt, va_list args); + const char *location, const char *fmt, va_list args) ATTR_FORMAT(4, 0); void sieve_global_info_verror (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, - const char *location, const char *fmt, va_list args); + const char *location, const char *fmt, va_list args) ATTR_FORMAT(4, 0); void sieve_global_info_vwarning (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, - const char *location, const char *fmt, va_list args); + const char *location, const char *fmt, va_list args) ATTR_FORMAT(4, 0); void sieve_global_error (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, @@ -111,20 +111,20 @@ void sieve_verror (struct sieve_error_handler *ehandler, const char *location, - const char *fmt, va_list args); + const char *fmt, va_list args) ATTR_FORMAT(3, 0); void sieve_vwarning (struct sieve_error_handler *ehandler, const char *location, - const char *fmt, va_list args); + const char *fmt, va_list args) ATTR_FORMAT(3, 0); void sieve_vinfo (struct sieve_error_handler *ehandler, const char *location, - const char *fmt, va_list args); + const char *fmt, va_list args) ATTR_FORMAT(3, 0); void sieve_vdebug (struct sieve_error_handler *ehandler, const char *location, - const char *fmt, va_list args); + const char *fmt, va_list args) ATTR_FORMAT(3, 0); void sieve_vcritical (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const char *location, const char *user_prefix, const char *fmt, - va_list args); + va_list args) ATTR_FORMAT(5, 0); void sieve_error (struct sieve_error_handler *ehandler, const char *location, From pigeonhole at rename-it.nl Wed Jun 18 22:11:12 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 19 Jun 2014 00:11:12 +0200 Subject: dovecot-2.2-pigeonhole: managesieve: Compared to imap and incorp... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/d5620195d79c changeset: 1881:d5620195d79c user: Stephan Bosch date: Thu Jun 19 00:10:53 2014 +0200 description: managesieve: Compared to imap and incorporated a few differences from there. Most important change is that mail service_user was not freed. diffstat: src/managesieve/main.c | 26 ++++++++++++++++---------- src/managesieve/managesieve-client.c | 35 +++++++++++++++++++++-------------- 2 files changed, 37 insertions(+), 24 deletions(-) diffs (173 lines): diff -r b56520e04882 -r d5620195d79c src/managesieve/main.c --- a/src/managesieve/main.c Wed Jun 18 00:08:03 2014 +0200 +++ b/src/managesieve/main.c Thu Jun 19 00:10:53 2014 +0200 @@ -12,6 +12,7 @@ #include "process-title.h" #include "restrict-access.h" #include "fd-close-on-exec.h" +#include "settings-parser.h" #include "master-interface.h" #include "master-service.h" #include "master-login.h" @@ -128,7 +129,7 @@ struct mail_storage_service_user *user; struct mail_user *mail_user; struct client *client; - const struct managesieve_settings *set; + struct managesieve_settings *set; if (mail_storage_service_lookup_next(storage_service, input, &user, &mail_user, error_r) <= 0) @@ -139,6 +140,9 @@ if (set->verbose_proctitle) verbose_proctitle = TRUE; + settings_var_expand(&managesieve_setting_parser_info, set, mail_user->pool, + mail_user_var_expand_table(mail_user)); + client = client_create (fd_in, fd_out, input->session_id, mail_user, user, set); T_BEGIN { @@ -195,13 +199,15 @@ client->auth_req.data_size); if (client_create_from_input(&input, client->fd, client->fd, &input_buf, &error) < 0) { - if (write(client->fd, MSG_BYE_INTERNAL_ERROR, + int fd = client->fd; + + if (write(fd, MSG_BYE_INTERNAL_ERROR, strlen(MSG_BYE_INTERNAL_ERROR)) < 0) { if (errno != EAGAIN && errno != EPIPE) i_error("write(client) failed: %m"); } i_error("%s", error); - (void)close(client->fd); + i_close_fd(&fd); master_service_client_connection_destroyed(master_service); } } @@ -276,13 +282,6 @@ } } - login_set.auth_socket_path = t_abspath("auth-master"); - if (argv[optind] != NULL) - login_set.postlogin_socket_path = t_abspath(argv[optind]); - login_set.callback = login_client_connected; - login_set.failure_callback = login_client_failed; - - master_service_init_finish(master_service); master_service_set_die_callback(master_service, managesieve_die); /* plugins may want to add commands, so this needs to be called early */ @@ -297,6 +296,7 @@ storage_service = mail_storage_service_init(master_service, set_roots, storage_service_flags); + master_service_init_finish(master_service); /* fake that we're running, so we know if client was destroyed while handling its initial input */ @@ -307,6 +307,12 @@ main_stdio_run(username); } T_END; } else { + login_set.auth_socket_path = t_abspath("auth-master"); + if (argv[optind] != NULL) + login_set.postlogin_socket_path = t_abspath(argv[optind]); + login_set.callback = login_client_connected; + login_set.failure_callback = login_client_failed; + master_login = master_login_init(master_service, &login_set); io_loop_set_running(current_ioloop); } diff -r b56520e04882 -r d5620195d79c src/managesieve/managesieve-client.c --- a/src/managesieve/managesieve-client.c Wed Jun 18 00:08:03 2014 +0200 +++ b/src/managesieve/managesieve-client.c Thu Jun 19 00:10:53 2014 +0200 @@ -102,11 +102,6 @@ struct sieve_storage *storage; pool_t pool; - /* Always use nonblocking I/O */ - - net_set_nonblock(fd_in, TRUE); - net_set_nonblock(fd_out, TRUE); - /* Initialize Sieve instance */ memset((void*)&svenv, 0, sizeof(svenv)); @@ -138,9 +133,13 @@ (fd_in, set->managesieve_max_line_length, FALSE); client->output = o_stream_create_fd(fd_out, (size_t)-1, FALSE); + o_stream_set_no_error_handling(client->output, TRUE); + i_stream_set_name(client->input, ""); + o_stream_set_name(client->output, ""); + o_stream_set_flush_callback(client->output, client_output, client); - client->io = io_add(fd_in, IO_READ, client_input, client); + client->io = io_add_istream(client->input, client_input, client); client->last_input = ioloop_time; client->parser = managesieve_parser_create (client->input, set->managesieve_max_line_length); @@ -185,7 +184,7 @@ tab = t_malloc(sizeof(static_tab)); memcpy(tab, static_tab, sizeof(static_tab)); - tab[0].value = dec2str(client->input->v_offset); + tab[0].value = dec2str(i_stream_get_absolute_offset(client->input)); tab[1].value = dec2str(client->output->offset); tab[2].value = client->session_id; @@ -249,17 +248,15 @@ i_stream_destroy(&client->input); o_stream_destroy(&client->output); - if (close(client->fd_in) < 0) - i_error("close(client in) failed: %m"); - if (client->fd_in != client->fd_out) { - if (close(client->fd_out) < 0) - i_error("close(client out) failed: %m"); - } + net_disconnect(client->fd_in); + if (client->fd_in != client->fd_out) + net_disconnect(client->fd_out); sieve_storage_free(client->storage); sieve_deinit(&client->svinst); pool_unref(&client->cmd.pool); + mail_storage_service_user_free(&client->service_user); managesieve_client_count--; DLLIST_REMOVE(&managesieve_clients, client); @@ -269,6 +266,11 @@ managesieve_refresh_proctitle(); } +static void client_destroy_timeout(struct client *client) +{ + client_destroy(client, NULL); +} + void client_disconnect(struct client *client, const char *reason) { i_assert(reason != NULL); @@ -278,10 +280,15 @@ i_info("Disconnected: %s %s", reason, client_stats(client)); client->disconnected = TRUE; - (void)o_stream_flush(client->output); + o_stream_flush(client->output); + o_stream_uncork(client->output); i_stream_close(client->input); o_stream_close(client->output); + + if (client->to_idle != NULL) + timeout_remove(&client->to_idle); + client->to_idle = timeout_add(0, client_destroy_timeout, client); } void client_disconnect_with_error(struct client *client, const char *msg) From dovecot at dovecot.org Thu Jun 19 09:33:10 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 19 Jun 2014 09:33:10 +0000 Subject: dovecot-2.2: lib: Fixed potential read buffer overflow in JSON p... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/07456a200816 changeset: 17505:07456a200816 user: Timo Sirainen date: Thu Jun 19 12:31:55 2014 +0300 description: lib: Fixed potential read buffer overflow in JSON parser. diffstat: src/lib/json-parser.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (14 lines): diff -r b6733f4777f1 -r 07456a200816 src/lib/json-parser.c --- a/src/lib/json-parser.c Mon Jun 16 19:52:11 2014 +0300 +++ b/src/lib/json-parser.c Thu Jun 19 12:31:55 2014 +0300 @@ -203,7 +203,9 @@ if (*parser->data != '\\') str_append_c(parser->value, *parser->data); else { - switch (*++parser->data) { + if (++parser->data == parser->end) + return 0; + switch (*parser->data) { case '"': case '\\': case '/': From dovecot at dovecot.org Thu Jun 19 09:34:17 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 19 Jun 2014 09:34:17 +0000 Subject: dovecot-2.2: lib: Fixed read buffer overflow in istream-base64-d... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c65b4c41698c changeset: 17506:c65b4c41698c user: Timo Sirainen date: Thu Jun 19 12:32:45 2014 +0300 description: lib: Fixed read buffer overflow in istream-base64-decoder error handling diffstat: src/lib/istream-base64-decoder.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 07456a200816 -r c65b4c41698c src/lib/istream-base64-decoder.c --- a/src/lib/istream-base64-decoder.c Thu Jun 19 12:31:55 2014 +0300 +++ b/src/lib/istream-base64-decoder.c Thu Jun 19 12:32:45 2014 +0300 @@ -61,7 +61,7 @@ if (base64_decode(data, size, &pos, &buf) < 0) { io_stream_set_error(&stream->iostream, "Invalid base64 data: 0x%s", - binary_to_hex(data+pos, I_MAX(size-pos, 8))); + binary_to_hex(data+pos, I_MIN(size-pos, 8))); stream->istream.stream_errno = EINVAL; return -1; } From dovecot at dovecot.org Thu Jun 19 09:39:23 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 19 Jun 2014 09:39:23 +0000 Subject: dovecot-2.2: lib-test: Improved test-istream to catch more bugs Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/627f2a2ba362 changeset: 17507:627f2a2ba362 user: Timo Sirainen date: Thu Jun 19 12:38:11 2014 +0300 description: lib-test: Improved test-istream to catch more bugs diffstat: src/lib-test/test-common.c | 29 +++++++++++++++++++++++------ 1 files changed, 23 insertions(+), 6 deletions(-) diffs (68 lines): diff -r c65b4c41698c -r 627f2a2ba362 src/lib-test/test-common.c --- a/src/lib-test/test-common.c Thu Jun 19 12:32:45 2014 +0300 +++ b/src/lib-test/test-common.c Thu Jun 19 12:38:11 2014 +0300 @@ -16,6 +16,7 @@ struct test_istream { struct istream_private istream; + const void *orig_buffer; unsigned int skip_diff; size_t max_pos; bool allow_eof; @@ -25,6 +26,7 @@ { struct test_istream *tstream = (struct test_istream *)stream; unsigned int new_skip_diff; + size_t cur_max; ssize_t ret; i_assert(stream->skip <= stream->pos); @@ -36,10 +38,9 @@ /* we seeked past the end of file. */ ret = 0; } else { - /* move around the buffer */ + /* copy data to a buffer in somewhat random place. this could + help catch bugs. */ new_skip_diff = rand() % 128; - stream->buffer = (stream->buffer + tstream->skip_diff) - - new_skip_diff; stream->skip = (stream->skip - tstream->skip_diff) + new_skip_diff; stream->pos = (stream->pos - tstream->skip_diff) + @@ -48,8 +49,24 @@ new_skip_diff; tstream->skip_diff = new_skip_diff; - ret = tstream->max_pos - stream->pos; - stream->pos = tstream->max_pos; + cur_max = tstream->max_pos; + if (stream->max_buffer_size < (size_t)-1 - stream->skip && + cur_max > stream->skip + stream->max_buffer_size) + cur_max = stream->skip + stream->max_buffer_size; + + /* use exactly correct buffer size so valgrind can catch + read overflows */ + if (stream->buffer_size != cur_max) { + stream->w_buffer = i_realloc(stream->w_buffer, 0, + cur_max); + stream->buffer = stream->w_buffer; + stream->buffer_size = cur_max; + } + memcpy(stream->w_buffer + new_skip_diff, tstream->orig_buffer, + cur_max - new_skip_diff); + + ret = cur_max - stream->pos; + stream->pos = cur_max; } if (ret > 0) @@ -78,7 +95,7 @@ struct test_istream *tstream; tstream = i_new(struct test_istream, 1); - tstream->istream.buffer = data; + tstream->orig_buffer = data; tstream->istream.read = test_read; tstream->istream.seek = test_seek; From dovecot at dovecot.org Thu Jun 19 10:54:13 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 19 Jun 2014 10:54:13 +0000 Subject: dovecot-2.2: lib: If two istreams share one parent, i_stream_get... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/01061ac25fe1 changeset: 17508:01061ac25fe1 user: Timo Sirainen date: Thu Jun 19 13:52:36 2014 +0300 description: lib: If two istreams share one parent, i_stream_get_data() may have returned corrupted data to another. This happened only for istreams that used parent's buffer directly instead of having their own buffer. For now at least we've solved this by truncating the other stream's buffer so it needs to be read again. Hopefully this is good enough. Added also unit test to check this functionality. diffstat: src/lib/Makefile.am | 1 + src/lib/istream.c | 46 ++++++++++++++++++++++++++++++++--- src/lib/test-istream.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/test-lib.c | 1 + src/lib/test-lib.h | 1 + 5 files changed, 109 insertions(+), 4 deletions(-) diffs (172 lines): diff -r 627f2a2ba362 -r 01061ac25fe1 src/lib/Makefile.am --- a/src/lib/Makefile.am Thu Jun 19 12:38:11 2014 +0300 +++ b/src/lib/Makefile.am Thu Jun 19 13:52:36 2014 +0300 @@ -282,6 +282,7 @@ test-hash-method.c \ test-hex-binary.c \ test-iso8601-date.c \ + test-istream.c \ test-istream-base64-decoder.c \ test-istream-base64-encoder.c \ test-istream-concat.c \ diff -r 627f2a2ba362 -r 01061ac25fe1 src/lib/istream.c --- a/src/lib/istream.c Thu Jun 19 12:38:11 2014 +0300 +++ b/src/lib/istream.c Thu Jun 19 13:52:36 2014 +0300 @@ -443,6 +443,26 @@ return stream->real_stream->line_crlf; } +static bool i_stream_is_buffer_invalid(const struct istream_private *stream) +{ + if (stream->parent == NULL) { + /* the buffer can't point to parent, because it doesn't exist */ + return FALSE; + } + if (stream->w_buffer != NULL) { + /* we can pretty safely assume that the stream is using its + own private buffer, so it can never become invalid. */ + return FALSE; + } + if (stream->access_counter != + stream->parent->real_stream->access_counter) { + /* parent has been modified behind this stream, we can't trust + that our buffer is valid */ + return TRUE; + } + return i_stream_is_buffer_invalid(stream->parent->real_stream); +} + const unsigned char * i_stream_get_data(const struct istream *stream, size_t *size_r) { @@ -453,6 +473,25 @@ return NULL; } + if (i_stream_is_buffer_invalid(_stream)) { + /* This stream may be using parent's buffer directly as + _stream->buffer, but the parent stream has already been + modified indirectly. This means that the buffer might no + longer point to where we assume it points to. So we'll + just return the stream as empty until it's read again. + + It's a bit ugly to suddenly drop data from the stream that + was already read, but since this happens only with shared + parent istreams the caller is hopefully aware enough that + something like this might happen. The other solutions would + be to a) try to automatically read the data back (but we + can't handle errors..) or b) always copy data to stream's + own buffer instead of pointing to parent's buffer (but this + causes data copying that is nearly always unnecessary). */ + *size_r = 0; + return NULL; + } + *size_r = _stream->pos - _stream->skip; return _stream->buffer + _stream->skip; } @@ -460,11 +499,10 @@ size_t i_stream_get_data_size(const struct istream *stream) { const struct istream_private *_stream = stream->real_stream; + size_t size; - if (_stream->skip >= _stream->pos) - return 0; - else - return _stream->pos - _stream->skip; + (void)i_stream_get_data(stream, &size); + return size; } unsigned char *i_stream_get_modifiable_data(const struct istream *stream, diff -r 627f2a2ba362 -r 01061ac25fe1 src/lib/test-istream.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/test-istream.c Thu Jun 19 13:52:36 2014 +0300 @@ -0,0 +1,64 @@ +/* Copyright (c) 2014 Dovecot authors, see the included COPYING file */ + +#include "test-lib.h" +#include "istream.h" + +static void test_istream_children(void) +{ + struct istream *parent, *child1, *child2; + const unsigned char *data; + size_t size; + + test_begin("istream children"); + + parent = test_istream_create_data("123456789", 9); + test_istream_set_max_buffer_size(parent, 3); + + child1 = i_stream_create_limit(parent, (uoff_t)-1); + child2 = i_stream_create_limit(parent, (uoff_t)-1); + + /* child1 read beginning */ + test_assert(i_stream_read(child1) == 3); + data = i_stream_get_data(child1, &size); + test_assert(size == 3 && memcmp(data, "123", 3) == 0); + i_stream_skip(child1, 3); + /* child1 read middle.. */ + test_assert(i_stream_read(child1) == 3); + data = i_stream_get_data(child1, &size); + test_assert(size == 3 && memcmp(data, "456", 3) == 0); + /* child2 read beginning.. */ + test_assert(i_stream_read(child2) == 3); + data = i_stream_get_data(child2, &size); + test_assert(size == 3 && memcmp(data, "123", 3) == 0); + /* child1 check middle again.. the parent has been modified, + so it can't return the original data (without some code changes). */ + data = i_stream_get_data(child1, &size); + test_assert(size == 0); + i_stream_skip(child1, 3); + /* child1 read end */ + test_assert(i_stream_read(child1) == 3); + data = i_stream_get_data(child1, &size); + test_assert(size == 3 && memcmp(data, "789", 3) == 0); + i_stream_skip(child1, 3); + test_assert(i_stream_read(child1) == -1); + /* child2 check beginning again.. */ + data = i_stream_get_data(child2, &size); + test_assert(size == 0); + i_stream_skip(child2, 3); + /* child2 read middle */ + test_assert(i_stream_read(child2) == 3); + data = i_stream_get_data(child2, &size); + test_assert(size == 3 && memcmp(data, "456", 3) == 0); + i_stream_skip(child2, 3); + + i_stream_destroy(&child1); + i_stream_destroy(&child2); + i_stream_destroy(&parent); + + test_end(); +} + +void test_istream(void) +{ + test_istream_children(); +} diff -r 627f2a2ba362 -r 01061ac25fe1 src/lib/test-lib.c --- a/src/lib/test-lib.c Thu Jun 19 12:38:11 2014 +0300 +++ b/src/lib/test-lib.c Thu Jun 19 13:52:36 2014 +0300 @@ -17,6 +17,7 @@ test_hash_method, test_hex_binary, test_iso8601_date, + test_istream, test_istream_base64_decoder, test_istream_base64_encoder, test_istream_concat, diff -r 627f2a2ba362 -r 01061ac25fe1 src/lib/test-lib.h --- a/src/lib/test-lib.h Thu Jun 19 12:38:11 2014 +0300 +++ b/src/lib/test-lib.h Thu Jun 19 13:52:36 2014 +0300 @@ -16,6 +16,7 @@ void test_hash_method(void); void test_hex_binary(void); void test_iso8601_date(void); +void test_istream(void); void test_istream_base64_decoder(void); void test_istream_base64_encoder(void); void test_istream_concat(void); From dovecot at dovecot.org Thu Jun 19 11:04:23 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 19 Jun 2014 11:04:23 +0000 Subject: dovecot-2.2: Compiler warning fix Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/41e8c66235cf changeset: 17509:41e8c66235cf user: Timo Sirainen date: Thu Jun 19 14:02:56 2014 +0300 description: Compiler warning fix diffstat: src/lib/istream.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diffs (11 lines): diff -r 01061ac25fe1 -r 41e8c66235cf src/lib/istream.c --- a/src/lib/istream.c Thu Jun 19 13:52:36 2014 +0300 +++ b/src/lib/istream.c Thu Jun 19 14:02:56 2014 +0300 @@ -498,7 +498,6 @@ size_t i_stream_get_data_size(const struct istream *stream) { - const struct istream_private *_stream = stream->real_stream; size_t size; (void)i_stream_get_data(stream, &size); From dovecot at dovecot.org Thu Jun 19 11:36:19 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 19 Jun 2014 11:36:19 +0000 Subject: dovecot-2.2: lib-mail: Fixed istream-dot unit test to work with ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/00df4f6b5222 changeset: 17510:00df4f6b5222 user: Timo Sirainen date: Thu Jun 19 14:34:54 2014 +0300 description: lib-mail: Fixed istream-dot unit test to work with the istream-test changes. diffstat: src/lib-mail/test-istream-dot.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r 41e8c66235cf -r 00df4f6b5222 src/lib-mail/test-istream-dot.c --- a/src/lib-mail/test-istream-dot.c Thu Jun 19 14:02:56 2014 +0300 +++ b/src/lib-mail/test-istream-dot.c Thu Jun 19 14:34:54 2014 +0300 @@ -95,6 +95,9 @@ test_assert(str_len(str) == output_len); test_assert(memcmp(str_data(str), test->output, output_len) == 0); + /* read the data after the '.' line and verify it's still there */ + i_stream_set_max_buffer_size(test_input, (size_t)-1); + (void)i_stream_read(test_input); data = i_stream_get_data(test_input, &size); test_assert(size == strlen(test->parent_input)); test_assert(memcmp(data, test->parent_input, size) == 0); From dovecot at dovecot.org Thu Jun 19 12:02:00 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 19 Jun 2014 12:02:00 +0000 Subject: dovecot-2.2: lib: i_stream_get_data() should also reset eof=FALS... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0d072ade062d changeset: 17511:0d072ade062d user: Timo Sirainen date: Thu Jun 19 14:58:26 2014 +0300 description: lib: i_stream_get_data() should also reset eof=FALSE if it truncates the output. diffstat: src/lib/istream.c | 26 ++++++++++++++------------ src/lib/istream.h | 9 ++++----- 2 files changed, 18 insertions(+), 17 deletions(-) diffs (100 lines): diff -r 00df4f6b5222 -r 0d072ade062d src/lib/istream.c --- a/src/lib/istream.c Thu Jun 19 14:34:54 2014 +0300 +++ b/src/lib/istream.c Thu Jun 19 14:58:26 2014 +0300 @@ -329,18 +329,14 @@ return _stream->get_size(_stream, exact, size_r); } -bool i_stream_have_bytes_left(const struct istream *stream) +bool i_stream_have_bytes_left(struct istream *stream) { - const struct istream_private *_stream = stream->real_stream; - - return !stream->eof || _stream->skip != _stream->pos; + return i_stream_get_data_size(stream) > 0 || !stream->eof; } bool i_stream_is_eof(struct istream *stream) { - const struct istream_private *_stream = stream->real_stream; - - if (_stream->skip == _stream->pos) + if (i_stream_get_data_size(stream) == 0) (void)i_stream_read(stream); return !i_stream_have_bytes_left(stream); } @@ -464,9 +460,9 @@ } const unsigned char * -i_stream_get_data(const struct istream *stream, size_t *size_r) +i_stream_get_data(struct istream *stream, size_t *size_r) { - const struct istream_private *_stream = stream->real_stream; + struct istream_private *_stream = stream->real_stream; if (_stream->skip >= _stream->pos) { *size_r = 0; @@ -489,6 +485,12 @@ own buffer instead of pointing to parent's buffer (but this causes data copying that is nearly always unnecessary). */ *size_r = 0; + /* if we had already read until EOF, mark the stream again as + not being at the end of file. */ + if (stream->stream_errno == 0) { + _stream->skip = _stream->pos = 0; + stream->eof = FALSE; + } return NULL; } @@ -496,7 +498,7 @@ return _stream->buffer + _stream->skip; } -size_t i_stream_get_data_size(const struct istream *stream) +size_t i_stream_get_data_size(struct istream *stream) { size_t size; @@ -504,10 +506,10 @@ return size; } -unsigned char *i_stream_get_modifiable_data(const struct istream *stream, +unsigned char *i_stream_get_modifiable_data(struct istream *stream, size_t *size_r) { - const struct istream_private *_stream = stream->real_stream; + struct istream_private *_stream = stream->real_stream; if (_stream->skip >= _stream->pos || _stream->w_buffer == NULL) { *size_r = 0; diff -r 00df4f6b5222 -r 0d072ade062d src/lib/istream.h --- a/src/lib/istream.h Thu Jun 19 14:34:54 2014 +0300 +++ b/src/lib/istream.h Thu Jun 19 14:58:26 2014 +0300 @@ -119,7 +119,7 @@ set, 0 if size is unknown, -1 if error. */ int i_stream_get_size(struct istream *stream, bool exact, uoff_t *size_r); /* Returns TRUE if there are any bytes left to be read or in buffer. */ -bool i_stream_have_bytes_left(const struct istream *stream) ATTR_PURE; +bool i_stream_have_bytes_left(struct istream *stream); /* Returns TRUE if there are no bytes buffered and read() returns EOF. */ bool i_stream_is_eof(struct istream *stream); /* Returns the absolute offset of the stream. This is the stream's current @@ -140,12 +140,11 @@ /* Returns pointer to beginning of read data, or NULL if there's no data buffered. */ -const unsigned char * -i_stream_get_data(const struct istream *stream, size_t *size_r); -size_t i_stream_get_data_size(const struct istream *stream); +const unsigned char *i_stream_get_data(struct istream *stream, size_t *size_r); +size_t i_stream_get_data_size(struct istream *stream); /* Like i_stream_get_data(), but returns non-const data. This only works with buffered streams (currently only file), others return NULL. */ -unsigned char *i_stream_get_modifiable_data(const struct istream *stream, +unsigned char *i_stream_get_modifiable_data(struct istream *stream, size_t *size_r); /* Like i_stream_get_data(), but read more when needed. Returns 1 if more than threshold bytes are available, 0 if as much or less, -1 if error or From dovecot at dovecot.org Thu Jun 19 12:16:49 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 19 Jun 2014 12:16:49 +0000 Subject: dovecot-2.2: lib: i_stream_read_copy_from_parent() now directly ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/467a4d19f873 changeset: 17512:467a4d19f873 user: Timo Sirainen date: Thu Jun 19 15:15:24 2014 +0300 description: lib: i_stream_read_copy_from_parent() now directly updates the access counter This fixes a bug in istream-mail where it called i_stream_get_data() after it and reset the stream's skip/pos. diffstat: src/lib/istream.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 0d072ade062d -r 467a4d19f873 src/lib/istream.c --- a/src/lib/istream.c Thu Jun 19 14:58:26 2014 +0300 +++ b/src/lib/istream.c Thu Jun 19 15:15:24 2014 +0300 @@ -223,6 +223,7 @@ stream->pos = pos; i_assert(ret != -1 || stream->istream.eof || stream->istream.stream_errno != 0); + i_stream_update(stream); return ret; } From dovecot at dovecot.org Thu Jun 19 12:52:00 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 19 Jun 2014 12:52:00 +0000 Subject: dovecot-2.2: lmtp: Create all proxy DATA streams before reading ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/119adb7d2479 changeset: 17513:119adb7d2479 user: Timo Sirainen date: Thu Jun 19 15:50:40 2014 +0300 description: lmtp: Create all proxy DATA streams before reading from them. I'm not sure if this actually fixes anything or not, but it's still safer to do it this way. diffstat: src/lmtp/lmtp-proxy.c | 16 +++++++++++++--- 1 files changed, 13 insertions(+), 3 deletions(-) diffs (40 lines): diff -r 467a4d19f873 -r 119adb7d2479 src/lmtp/lmtp-proxy.c --- a/src/lmtp/lmtp-proxy.c Thu Jun 19 15:15:24 2014 +0300 +++ b/src/lmtp/lmtp-proxy.c Thu Jun 19 15:50:40 2014 +0300 @@ -296,12 +296,14 @@ struct lmtp_proxy_connection *const *conns; i_assert(data_input->seekable); + i_assert(proxy->data_input == NULL); proxy->finish_callback = callback; proxy->finish_context = context; proxy->data_input = data_input; i_stream_ref(proxy->data_input); + /* create the data_input streams first */ array_foreach(&proxy->connections, conns) { struct lmtp_proxy_connection *conn = *conns; @@ -312,10 +314,18 @@ conn->to = timeout_add(proxy->max_timeout_msecs, lmtp_proxy_conn_timeout, conn); + conn->data_input = i_stream_create_limit(data_input, (uoff_t)-1); + } + /* now that all the streams are created, start reading them + (reading them earlier could have caused the data_input parent's + offset to change) */ + array_foreach(&proxy->connections, conns) { + struct lmtp_proxy_connection *conn = *conns; - conn->data_input = i_stream_create_limit(data_input, (uoff_t)-1); - lmtp_client_send(conn->client, conn->data_input); - lmtp_client_send_more(conn->client); + if (conn->data_input != NULL) { + lmtp_client_send(conn->client, conn->data_input); + lmtp_client_send_more(conn->client); + } } /* finish if all of the connections have already failed */ lmtp_proxy_try_finish(proxy); From dovecot at dovecot.org Thu Jun 19 14:17:39 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 19 Jun 2014 14:17:39 +0000 Subject: dovecot-2.2: mbox: istream-tee wasn't being used as expected wit... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5138932352d3 changeset: 17514:5138932352d3 user: Timo Sirainen date: Thu Jun 19 17:16:24 2014 +0300 description: mbox: istream-tee wasn't being used as expected with the new changes, causing crashes/hangs. After wondering about this for a while I decided this was the only fully reliable way of doing this. Although it would have been possible to change the istream-tee code to support this: child1 and child2 are tee-istream children: - i_stream_read(child1) - i_stream_read(child2) - i_stream_get_data(child1) Because reading from the parent istream-tee updates all of its childrens' buffer, there's no big problem (other than access_counter currently messing up). But if one of the children weren't a direct child of tee-istream, but there was a wrapper istream, the wrapper's buffer wouldn't have been updated by the istream-tee read. So rather than spending time figuring out to fix the access_counter it's probably better to have it clearly fail as the use case can't be fully safe anyway. diffstat: src/lib-storage/index/mbox/mbox-save.c | 11 +++++------ 1 files changed, 5 insertions(+), 6 deletions(-) diffs (44 lines): diff -r 119adb7d2479 -r 5138932352d3 src/lib-storage/index/mbox/mbox-save.c --- a/src/lib-storage/index/mbox/mbox-save.c Thu Jun 19 15:50:40 2014 +0300 +++ b/src/lib-storage/index/mbox/mbox-save.c Thu Jun 19 17:16:24 2014 +0300 @@ -554,6 +554,8 @@ ssize_t ret; while ((ret = i_stream_read(ctx->input)) != -1) { + if (mbox_save_body_input(ctx) < 0) + return -1; if (ctx->ctx.dest_mail != NULL) { /* i_stream_read() may have returned 0 at EOF because of this parser */ @@ -561,9 +563,6 @@ } if (ret == 0) return 0; - - if (mbox_save_body_input(ctx) < 0) - return -1; } i_assert(ctx->last_char == '\n'); @@ -601,9 +600,6 @@ } while ((ret = i_stream_read(ctx->input)) > 0) { - if (ctx->ctx.dest_mail != NULL) - index_mail_cache_parse_continue(ctx->ctx.dest_mail); - data = i_stream_get_data(ctx->input, &size); for (i = 0; i < size; i++) { if (data[i] == '\n' && @@ -630,8 +626,11 @@ write_error(ctx); return -1; } + i_assert(size > 0); ctx->last_char = data[size-1]; i_stream_skip(ctx->input, size); + if (ctx->ctx.dest_mail != NULL) + index_mail_cache_parse_continue(ctx->ctx.dest_mail); } if (ret == 0) return 0; From dovecot at dovecot.org Fri Jun 20 09:20:54 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 20 Jun 2014 09:20:54 +0000 Subject: dovecot-2.2: lib: fd_recv() no longer checks for msghdr.msg_cont... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/38cd37cea8b1 changeset: 17515:38cd37cea8b1 user: Timo Sirainen date: Fri Jun 20 12:18:32 2014 +0300 description: lib: fd_recv() no longer checks for msghdr.msg_controllen It doesn't work at least in OpenBSD and Tru64, and apparently it shouldn't really be needed anyway, so don't bother with it. We'll still keep checking the cmsghdr since that appears to work everywhere now. diffstat: src/lib/fdpass.c | 12 +++--------- 1 files changed, 3 insertions(+), 9 deletions(-) diffs (30 lines): diff -r 5138932352d3 -r 38cd37cea8b1 src/lib/fdpass.c --- a/src/lib/fdpass.c Thu Jun 19 17:16:24 2014 +0300 +++ b/src/lib/fdpass.c Fri Jun 20 12:18:32 2014 +0300 @@ -140,12 +140,6 @@ return sendmsg(handle, &msg, 0); } -#ifdef __osf__ -# define CHECK_MSG(msg) TRUE /* Tru64 */ -#else -# define CHECK_MSG(msg) ((msg).msg_controllen >= CMSG_SPACE(sizeof(int))) -#endif - #ifdef LINUX20 /* Linux 2.0.x doesn't set any cmsg fields. Note that this might make some attacks possible so don't do it unless you really have to. */ @@ -188,10 +182,10 @@ /* at least one byte transferred - we should have the fd now. do extra checks to make sure it really is an fd that is being transferred to avoid potential DoS conditions. some systems don't - set all these values correctly however so CHECK_MSG() and - CHECK_CMSG() are somewhat system dependent */ + set all these values correctly however so CHECK_CMSG() is somewhat + system dependent */ cmsg = CMSG_FIRSTHDR(&msg); - if (!CHECK_MSG(msg) || !CHECK_CMSG(cmsg)) + if (!CHECK_CMSG(cmsg)) *fd = -1; else memcpy(fd, CMSG_DATA(cmsg), sizeof(*fd)); From dovecot at dovecot.org Wed Jun 25 13:17:29 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 25 Jun 2014 13:17:29 +0000 Subject: dovecot-2.2: lib-test: Fixed "Trying to allocate 0 bytes" assert... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/705fd8f3f485 changeset: 17516:705fd8f3f485 user: Timo Sirainen date: Wed Jun 25 16:16:02 2014 +0300 description: lib-test: Fixed "Trying to allocate 0 bytes" assert-crash caused by recent test-istream changes. diffstat: src/lib-test/test-common.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 38cd37cea8b1 -r 705fd8f3f485 src/lib-test/test-common.c --- a/src/lib-test/test-common.c Fri Jun 20 12:18:32 2014 +0300 +++ b/src/lib-test/test-common.c Wed Jun 25 16:16:02 2014 +0300 @@ -56,7 +56,7 @@ /* use exactly correct buffer size so valgrind can catch read overflows */ - if (stream->buffer_size != cur_max) { + if (stream->buffer_size != cur_max && cur_max > 0) { stream->w_buffer = i_realloc(stream->w_buffer, 0, cur_max); stream->buffer = stream->w_buffer; From dovecot at dovecot.org Thu Jun 26 14:29:01 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 26 Jun 2014 14:29:01 +0000 Subject: dovecot-2.2: dbox: mail_get_special() may have returned MAIL_FET... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/55041cf555b7 changeset: 17517:55041cf555b7 user: Timo Sirainen date: Thu Jun 26 17:27:22 2014 +0300 description: dbox: mail_get_special() may have returned MAIL_FETCH_POP3_ORDER allocated from data stack. Although this seems to have worked for now, it shouldn't have been done. diffstat: src/lib-storage/index/dbox-common/dbox-mail.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diffs (21 lines): diff -r 705fd8f3f485 -r 55041cf555b7 src/lib-storage/index/dbox-common/dbox-mail.c --- a/src/lib-storage/index/dbox-common/dbox-mail.c Wed Jun 25 16:16:02 2014 +0300 +++ b/src/lib-storage/index/dbox-common/dbox-mail.c Thu Jun 26 17:27:22 2014 +0300 @@ -171,13 +171,13 @@ if (mail_cache_lookup_field(imail->mail.mail.transaction->cache_view, str, imail->mail.mail.seq, ibox->cache_fields[cache_field].idx) > 0) { - if (cache_field != MAIL_CACHE_POP3_ORDER) - *value_r = str_c(str); - else { + if (cache_field == MAIL_CACHE_POP3_ORDER) { i_assert(str_len(str) == sizeof(order)); memcpy(&order, str_data(str), sizeof(order)); - *value_r = order == 0 ? "" : dec2str(order); + str_truncate(str, 0); + str_printfa(str, "%u", order); } + *value_r = str_c(str); return 0; } From dovecot at dovecot.org Thu Jun 26 14:29:08 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 26 Jun 2014 14:29:08 +0000 Subject: dovecot-2.2: dsync: Fixed infinite looping on error condition. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/25326be366c5 changeset: 17518:25326be366c5 user: Timo Sirainen date: Thu Jun 26 17:27:31 2014 +0300 description: dsync: Fixed infinite looping on error condition. diffstat: src/doveadm/dsync/dsync-mailbox-import.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 55041cf555b7 -r 25326be366c5 src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Thu Jun 26 17:27:22 2014 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Thu Jun 26 17:27:31 2014 +0300 @@ -1799,7 +1799,7 @@ /* skip common local mails */ (void)importer_next_mail(importer, importer->last_common_uid+1); /* if there are any local mails left, add them to newmails list */ - while (importer->cur_mail != NULL) + while (importer->cur_mail != NULL && !importer->failed) (void)dsync_mailbox_try_save(importer, NULL); if (importer->search_ctx != NULL) { From dovecot at dovecot.org Thu Jun 26 14:52:54 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 26 Jun 2014 14:52:54 +0000 Subject: dovecot-2.2: lib-storage: BODYSTRUCTURE parsing failures weren't... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5c2bc165c5e9 changeset: 17519:5c2bc165c5e9 user: Timo Sirainen date: Thu Jun 26 17:50:57 2014 +0300 description: lib-storage: BODYSTRUCTURE parsing failures weren't treated correctly. We still assumed that the parsing succeeded and assert-crashed later or maybe returned invalid results. (This could have happened only if there was a problem reading the mail stream.) diffstat: src/lib-storage/index/index-mail.c | 16 +++++++++++----- 1 files changed, 11 insertions(+), 5 deletions(-) diffs (47 lines): diff -r 25326be366c5 -r 5c2bc165c5e9 src/lib-storage/index/index-mail.c --- a/src/lib-storage/index/index-mail.c Thu Jun 26 17:27:31 2014 +0300 +++ b/src/lib-storage/index/index-mail.c Thu Jun 26 17:50:57 2014 +0300 @@ -684,6 +684,7 @@ if (!data->parsed_bodystructure) return; + i_assert(data->parts != NULL); /* If BODY is fetched first but BODYSTRUCTURE is also wanted, we don't normally want to first cache BODY and then BODYSTRUCTURE. So check @@ -921,8 +922,6 @@ message_parser_parse_body(data->parser_ctx, parse_bodystructure_part_header, mail->mail.data_pool); - data->save_bodystructure_body = FALSE; - data->parsed_bodystructure = TRUE; } else { message_parser_parse_body(data->parser_ctx, *null_message_part_header_callback, (void *)NULL); @@ -930,6 +929,11 @@ ret = index_mail_stream_check_failure(mail); if (index_mail_parse_body_finish(mail, field, TRUE) < 0) ret = -1; + if (ret == 0 && data->save_bodystructure_body) { + data->save_bodystructure_body = FALSE; + data->parsed_bodystructure = TRUE; + i_assert(data->parts != NULL); + } i_stream_seek(data->stream, old_offset); return ret; @@ -1726,9 +1730,11 @@ mail->data.save_date = ioloop_time; } - mail->data.save_bodystructure_body = FALSE; - mail->data.parsed_bodystructure = TRUE; - (void)index_mail_parse_body_finish(mail, 0, success); + if (index_mail_parse_body_finish(mail, 0, success) == 0) { + mail->data.save_bodystructure_body = FALSE; + mail->data.parsed_bodystructure = TRUE; + i_assert(mail->data.parts != NULL); + } } static void index_mail_drop_recent_flag(struct mail *mail) From dovecot at dovecot.org Thu Jun 26 17:50:06 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 26 Jun 2014 17:50:06 +0000 Subject: dovecot-2.2: lib: iostream-rawlog now supports TCP target with "... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f3134d3a7ff1 changeset: 17520:f3134d3a7ff1 user: Timo Sirainen date: Thu Jun 26 20:46:21 2014 +0300 description: lib: iostream-rawlog now supports TCP target with "tcp:host:port" as the path. We'll use blocking sockets, so a slow rawlog server causes performance problems also for Dovecot while it's waiting on rawlog writes. diffstat: src/lib/iostream-rawlog.c | 81 ++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 66 insertions(+), 15 deletions(-) diffs (115 lines): diff -r 5c2bc165c5e9 -r f3134d3a7ff1 src/lib/iostream-rawlog.c --- a/src/lib/iostream-rawlog.c Thu Jun 26 17:50:57 2014 +0300 +++ b/src/lib/iostream-rawlog.c Thu Jun 26 20:46:21 2014 +0300 @@ -5,6 +5,7 @@ #include "ioloop.h" #include "buffer.h" #include "str.h" +#include "net.h" #include "write-full.h" #include "time-util.h" #include "istream.h" @@ -151,11 +152,72 @@ buffer_free(&rstream->buffer); } +static void +iostream_rawlog_create_fd(int fd, const char *path, struct istream **input, + struct ostream **output) +{ + struct istream *old_input; + struct ostream *old_output; + + old_input = *input; + old_output = *output; + *input = i_stream_create_rawlog(old_input, path, fd, + IOSTREAM_RAWLOG_FLAG_BUFFERED | + IOSTREAM_RAWLOG_FLAG_TIMESTAMP); + *output = o_stream_create_rawlog(old_output, path, fd, + IOSTREAM_RAWLOG_FLAG_AUTOCLOSE | + IOSTREAM_RAWLOG_FLAG_BUFFERED | + IOSTREAM_RAWLOG_FLAG_TIMESTAMP); + i_stream_unref(&old_input); + o_stream_unref(&old_output); +} + +static int +iostream_rawlog_try_create_tcp(const char *path, + struct istream **input, struct ostream **output) +{ + const char *p, *host; + struct ip_addr *ips; + unsigned int port, ips_count; + int ret, fd; + + /* tcp:host:port */ + if (strncmp(path, "tcp:", 4) != 0) + return 0; + path += 4; + + if (strchr(path, '/') != NULL) + return 0; + if ((p = strchr(path, ':')) == NULL) + return 0; + if (str_to_uint(p+1, &port) < 0 || port == 0 || port > 65535) + return 0; + host = t_strdup_until(path, p); + + ret = net_gethostbyname(host, &ips, &ips_count); + if (ret != 0) { + i_error("net_gethostbyname(%s) failed: %s", host, + net_gethosterror(ret)); + return -1; + } + fd = net_connect_ip_blocking(&ips[0], port, NULL); + if (fd == -1) { + i_error("connect(%s:%u) failed: %m", net_ip2addr(&ips[0]), port); + return -1; + } + iostream_rawlog_create_fd(fd, path, input, output); + return 1; +} + int iostream_rawlog_create(const char *dir, struct istream **input, struct ostream **output) { static unsigned int counter = 0; const char *timestamp, *prefix; + int ret; + + if ((ret = iostream_rawlog_try_create_tcp(dir, input, output)) != 0) + return ret < 0 ? -1 : 0; timestamp = t_strflocaltime("%Y%m%d-%H%M%S", ioloop_time); @@ -205,26 +267,15 @@ int iostream_rawlog_create_path(const char *path, struct istream **input, struct ostream **output) { - struct istream *old_input; - struct ostream *old_output; - int fd; + int ret, fd; + if ((ret = iostream_rawlog_try_create_tcp(path, input, output)) != 0) + return ret < 0 ? -1 : 0; fd = open(path, O_CREAT | O_APPEND | O_WRONLY, 0600); if (fd == -1) { i_error("creat(%s) failed: %m", path); return -1; } - - old_input = *input; - old_output = *output; - *input = i_stream_create_rawlog(old_input, path, fd, - IOSTREAM_RAWLOG_FLAG_BUFFERED | - IOSTREAM_RAWLOG_FLAG_TIMESTAMP); - *output = o_stream_create_rawlog(old_output, path, fd, - IOSTREAM_RAWLOG_FLAG_AUTOCLOSE | - IOSTREAM_RAWLOG_FLAG_BUFFERED | - IOSTREAM_RAWLOG_FLAG_TIMESTAMP); - i_stream_unref(&old_input); - o_stream_unref(&old_output); + iostream_rawlog_create_fd(fd, path, input, output); return 0; } From dovecot at dovecot.org Thu Jun 26 17:50:06 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 26 Jun 2014 17:50:06 +0000 Subject: dovecot-2.2: lib: Moved rawlog dir stat()s to iostream_rawlog_cr... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4bc7c1ad21a8 changeset: 17521:4bc7c1ad21a8 user: Timo Sirainen date: Thu Jun 26 20:48:13 2014 +0300 description: lib: Moved rawlog dir stat()s to iostream_rawlog_create() internally. This is required to allow TCP rawlogs to actually work. diffstat: src/lib-http/http-client-connection.c | 5 +---- src/lib-imap-client/imapc-connection.c | 8 ++------ src/lib-storage/index/pop3c/pop3c-client.c | 9 ++------- src/lib/iostream-rawlog.c | 6 ++++++ 4 files changed, 11 insertions(+), 17 deletions(-) diffs (121 lines): diff -r f3134d3a7ff1 -r 4bc7c1ad21a8 src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Thu Jun 26 20:46:21 2014 +0300 +++ b/src/lib-http/http-client-connection.c Thu Jun 26 20:48:13 2014 +0300 @@ -769,8 +769,6 @@ static void http_client_connection_ready(struct http_client_connection *conn) { - struct stat st; - /* connected */ conn->connected = TRUE; if (conn->to_connect != NULL && @@ -783,8 +781,7 @@ http_client_peer_connection_success(conn->peer); /* start raw log */ - if (conn->client->set.rawlog_dir != NULL && - stat(conn->client->set.rawlog_dir, &st) == 0) { + if (conn->client->set.rawlog_dir != NULL) { iostream_rawlog_create(conn->client->set.rawlog_dir, &conn->conn.input, &conn->conn.output); } diff -r f3134d3a7ff1 -r 4bc7c1ad21a8 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Thu Jun 26 20:46:21 2014 +0300 +++ b/src/lib-imap-client/imapc-connection.c Thu Jun 26 20:48:13 2014 +0300 @@ -1185,7 +1185,6 @@ static int imapc_connection_ssl_init(struct imapc_connection *conn) { struct ssl_iostream_settings ssl_set; - struct stat st; const char *error; if (conn->client->ssl_ctx == NULL) { @@ -1230,8 +1229,7 @@ return -1; } - if (*conn->client->set.rawlog_dir != '\0' && - stat(conn->client->set.rawlog_dir, &st) == 0) { + if (*conn->client->set.rawlog_dir != '\0') { iostream_rawlog_create(conn->client->set.rawlog_dir, &conn->input, &conn->output); } @@ -1315,7 +1313,6 @@ static void imapc_connection_connect_next_ip(struct imapc_connection *conn) { const struct ip_addr *ip; - struct stat st; int fd; i_assert(conn->client->set.max_idle_time > 0); @@ -1333,8 +1330,7 @@ o_stream_set_no_error_handling(conn->output, TRUE); if (*conn->client->set.rawlog_dir != '\0' && - conn->client->set.ssl_mode != IMAPC_CLIENT_SSL_MODE_IMMEDIATE && - stat(conn->client->set.rawlog_dir, &st) == 0) { + conn->client->set.ssl_mode != IMAPC_CLIENT_SSL_MODE_IMMEDIATE) { iostream_rawlog_create(conn->client->set.rawlog_dir, &conn->input, &conn->output); } diff -r f3134d3a7ff1 -r 4bc7c1ad21a8 src/lib-storage/index/pop3c/pop3c-client.c --- a/src/lib-storage/index/pop3c/pop3c-client.c Thu Jun 26 20:46:21 2014 +0300 +++ b/src/lib-storage/index/pop3c/pop3c-client.c Thu Jun 26 20:48:13 2014 +0300 @@ -441,7 +441,6 @@ static int pop3c_client_ssl_init(struct pop3c_client *client) { struct ssl_iostream_settings ssl_set; - struct stat st; const char *error; if (client->ssl_ctx == NULL) { @@ -485,8 +484,7 @@ return -1; } - if (*client->set.rawlog_dir != '\0' && - stat(client->set.rawlog_dir, &st) == 0) { + if (*client->set.rawlog_dir != '\0') { iostream_rawlog_create(client->set.rawlog_dir, &client->input, &client->output); } @@ -517,8 +515,6 @@ static void pop3c_client_connect_ip(struct pop3c_client *client) { - struct stat st; - client->fd = net_connect_ip(&client->ip, client->set.port, NULL); if (client->fd == -1) { pop3c_client_disconnect(client); @@ -532,8 +528,7 @@ o_stream_set_no_error_handling(client->output, TRUE); if (*client->set.rawlog_dir != '\0' && - client->set.ssl_mode != POP3C_CLIENT_SSL_MODE_IMMEDIATE && - stat(client->set.rawlog_dir, &st) == 0) { + client->set.ssl_mode != POP3C_CLIENT_SSL_MODE_IMMEDIATE) { iostream_rawlog_create(client->set.rawlog_dir, &client->input, &client->output); } diff -r f3134d3a7ff1 -r 4bc7c1ad21a8 src/lib/iostream-rawlog.c --- a/src/lib/iostream-rawlog.c Thu Jun 26 20:46:21 2014 +0300 +++ b/src/lib/iostream-rawlog.c Thu Jun 26 20:48:13 2014 +0300 @@ -214,10 +214,16 @@ { static unsigned int counter = 0; const char *timestamp, *prefix; + struct stat st; int ret; if ((ret = iostream_rawlog_try_create_tcp(dir, input, output)) != 0) return ret < 0 ? -1 : 0; + if (stat(dir, &st) < 0) { + if (errno != ENOENT && errno != EACCES) + i_error("rawlog: stat(%s) failed: %m", dir); + return -1; + } timestamp = t_strflocaltime("%Y%m%d-%H%M%S", ioloop_time); From pigeonhole at rename-it.nl Thu Jun 26 21:26:10 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 26 Jun 2014 23:26:10 +0200 Subject: dovecot-2.2-pigeonhole: doveadm sieve plugin: Fixed assert crash... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/92405f753f6a changeset: 1882:92405f753f6a user: Stephan Bosch date: Thu Jun 26 23:25:43 2014 +0200 description: doveadm sieve plugin: Fixed assert crash occuring when Sieve script attribute assignment fails. diffstat: src/plugins/doveadm-sieve/doveadm-sieve-plugin.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r d5620195d79c -r 92405f753f6a src/plugins/doveadm-sieve/doveadm-sieve-plugin.c --- a/src/plugins/doveadm-sieve/doveadm-sieve-plugin.c Thu Jun 19 00:10:53 2014 +0200 +++ b/src/plugins/doveadm-sieve/doveadm-sieve-plugin.c Thu Jun 26 23:25:43 2014 +0200 @@ -330,7 +330,7 @@ break; } } - i_assert(input->eof); + i_assert(input->eof || ret < 0); if (input->stream_errno != 0) { errno = input->stream_errno; mail_storage_set_critical(storage, From dovecot at dovecot.org Fri Jun 27 11:08:21 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 27 Jun 2014 11:08:21 +0000 Subject: dovecot-2.2: lib-lda: If DATA input stream read fails, return er... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1495857f0698 changeset: 17522:1495857f0698 user: Timo Sirainen date: Fri Jun 27 14:06:08 2014 +0300 description: lib-lda: If DATA input stream read fails, return error instead of truncating the mail. diffstat: src/lib-lda/lmtp-client.c | 24 +++++++++++++++++------- 1 files changed, 17 insertions(+), 7 deletions(-) diffs (88 lines): diff -r 4bc7c1ad21a8 -r 1495857f0698 src/lib-lda/lmtp-client.c --- a/src/lib-lda/lmtp-client.c Thu Jun 26 20:48:13 2014 +0300 +++ b/src/lib-lda/lmtp-client.c Fri Jun 27 14:06:08 2014 +0300 @@ -286,7 +286,7 @@ return -1; } -static void lmtp_client_send_data(struct lmtp_client *client) +static int lmtp_client_send_data(struct lmtp_client *client) { const unsigned char *data; unsigned char add; @@ -295,7 +295,7 @@ int ret; if (client->output_finished) - return; + return 0; while ((ret = i_stream_read_data(client->data_input, &data, &size, 0)) > 0) { @@ -331,7 +331,7 @@ if (ret == 0) { /* continue later */ o_stream_set_flush_pending(client->output, TRUE); - return; + return 0; } } @@ -342,12 +342,20 @@ client->output_last = add; } } + if (client->data_input->stream_errno != 0) { + i_error("lmtp client: read(%s) failed: %s", + i_stream_get_name(client->data_input), + i_stream_get_error(client->data_input)); + lmtp_client_fail(client, + "451 4.3.0 Internal failure while reading DATA input"); + return -1; + } if (sent_bytes && client->data_output_callback != NULL) client->data_output_callback(client->data_output_context); if (ret == 0 || ret == -2) { /* -2 can happen with tee istreams */ - return; + return 0; } if (client->output_last != '\n') { @@ -356,6 +364,7 @@ } o_stream_nsend(client->output, ".\r\n", 3); client->output_finished = TRUE; + return 0; } static void lmtp_client_send_handshake(struct lmtp_client *client) @@ -526,7 +535,8 @@ client->input_state++; if (client->data_header != NULL) o_stream_nsend_str(client->output, client->data_header); - lmtp_client_send_data(client); + if (lmtp_client_send_data(client) < 0) + return -1; break; case LMTP_INPUT_STATE_DATA: /* DATA replies */ @@ -600,7 +610,7 @@ lmtp_client_fail(client, ERRSTR_TEMP_REMOTE_FAILURE " (disconnected in output)"); else if (client->input_state == LMTP_INPUT_STATE_DATA) - lmtp_client_send_data(client); + (void)lmtp_client_send_data(client); o_stream_uncork(client->output); lmtp_client_unref(&client); return ret; @@ -748,7 +758,7 @@ { if (client->input_state == LMTP_INPUT_STATE_DATA) { o_stream_cork(client->output); - lmtp_client_send_data(client); + (void)lmtp_client_send_data(client); o_stream_uncork(client->output); } } From dovecot at dovecot.org Fri Jun 27 11:08:22 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 27 Jun 2014 11:08:22 +0000 Subject: dovecot-2.2: lmtp proxy: Make sure DATA stream size doesn't chan... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1b9356dbfca2 changeset: 17523:1b9356dbfca2 user: Timo Sirainen date: Fri Jun 27 14:06:56 2014 +0300 description: lmtp proxy: Make sure DATA stream size doesn't change unexpectedly. diffstat: src/lmtp/lmtp-proxy.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-) diffs (43 lines): diff -r 1495857f0698 -r 1b9356dbfca2 src/lmtp/lmtp-proxy.c --- a/src/lmtp/lmtp-proxy.c Fri Jun 27 14:06:08 2014 +0300 +++ b/src/lmtp/lmtp-proxy.c Fri Jun 27 14:06:56 2014 +0300 @@ -4,6 +4,7 @@ #include "array.h" #include "ioloop.h" #include "istream.h" +#include "istream-sized.h" #include "ostream.h" #include "lmtp-client.h" #include "lmtp-proxy.h" @@ -294,6 +295,7 @@ lmtp_proxy_finish_callback_t *callback, void *context) { struct lmtp_proxy_connection *const *conns; + uoff_t size; i_assert(data_input->seekable); i_assert(proxy->data_input == NULL); @@ -302,6 +304,11 @@ proxy->finish_context = context; proxy->data_input = data_input; i_stream_ref(proxy->data_input); + if (i_stream_get_size(proxy->data_input, TRUE, &size) < 0) { + i_error("i_stream_get_size(data_input) failed: %s", + i_stream_get_error(proxy->data_input)); + size = (uoff_t)-1; + } /* create the data_input streams first */ array_foreach(&proxy->connections, conns) { @@ -314,7 +321,10 @@ conn->to = timeout_add(proxy->max_timeout_msecs, lmtp_proxy_conn_timeout, conn); - conn->data_input = i_stream_create_limit(data_input, (uoff_t)-1); + if (size == (uoff_t)-1) + conn->data_input = i_stream_create_limit(data_input, (uoff_t)-1); + else + conn->data_input = i_stream_create_sized(data_input, size); } /* now that all the streams are created, start reading them (reading them earlier could have caused the data_input parent's From dovecot at dovecot.org Fri Jun 27 11:25:23 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 27 Jun 2014 11:25:23 +0000 Subject: dovecot-2.2: lmtp: Reduce corking so we get command replies more... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cfc2670398d7 changeset: 17524:cfc2670398d7 user: Timo Sirainen date: Fri Jun 27 14:23:46 2014 +0300 description: lmtp: Reduce corking so we get command replies more quickly even if they are pipelined. This may help avoid some LMTP client timeouts. diffstat: src/lmtp/client.c | 4 ++-- src/lmtp/commands.c | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diffs (33 lines): diff -r 1b9356dbfca2 -r cfc2670398d7 src/lmtp/client.c --- a/src/lmtp/client.c Fri Jun 27 14:06:56 2014 +0300 +++ b/src/lmtp/client.c Fri Jun 27 14:23:46 2014 +0300 @@ -122,15 +122,15 @@ output = client->output; o_stream_ref(output); - o_stream_cork(output); while ((line = i_stream_next_line(client->input)) != NULL) { T_BEGIN { + o_stream_cork(output); ret = client_input_line(client, line); + o_stream_uncork(output); } T_END; if (ret < 0) break; } - o_stream_uncork(output); o_stream_unref(&output); } diff -r 1b9356dbfca2 -r cfc2670398d7 src/lmtp/commands.c --- a/src/lmtp/commands.c Fri Jun 27 14:06:56 2014 +0300 +++ b/src/lmtp/commands.c Fri Jun 27 14:23:46 2014 +0300 @@ -1062,6 +1062,8 @@ i_assert(client->dot_input == NULL); client->dot_input = i_stream_create_dot(client->input, TRUE); client_send_line(client, "354 OK"); + /* send the DATA reply immediately before we start handling any data */ + o_stream_uncork(client->output); io_remove(&client->io); client_state_set(client, "DATA"); From dovecot at dovecot.org Fri Jun 27 13:22:41 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 27 Jun 2014 13:22:41 +0000 Subject: dovecot-2.2: lib-test: Enable looped tests to abort early on fir... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e1686f44f2e7 changeset: 17525:e1686f44f2e7 user: Phil Carmody date: Fri Jun 27 16:10:27 2014 +0300 description: lib-test: Enable looped tests to abort early on first failure Give them the ability to query the current failure state. Signed-off-by: Phil Carmody diffstat: src/lib-test/test-common.c | 5 +++++ src/lib-test/test-common.h | 1 + 2 files changed, 6 insertions(+), 0 deletions(-) diffs (26 lines): diff -r cfc2670398d7 -r e1686f44f2e7 src/lib-test/test-common.c --- a/src/lib-test/test-common.c Fri Jun 27 14:23:46 2014 +0300 +++ b/src/lib-test/test-common.c Fri Jun 27 16:10:27 2014 +0300 @@ -147,6 +147,11 @@ test_success = TRUE; } +bool test_has_failed(void) +{ + return !test_success; +} + void test_assert_failed(const char *code, const char *file, unsigned int line) { printf("%s:%u: Assert failed: %s\n", file, line, code); diff -r cfc2670398d7 -r e1686f44f2e7 src/lib-test/test-common.h --- a/src/lib-test/test-common.h Fri Jun 27 14:23:46 2014 +0300 +++ b/src/lib-test/test-common.h Fri Jun 27 16:10:27 2014 +0300 @@ -19,6 +19,7 @@ } STMT_END void test_assert_failed(const char *code, const char *file, unsigned int line); void test_assert_failed_idx(const char *code, const char *file, unsigned int line, long long i); +bool test_has_failed(void); void test_end(void); void test_out(const char *name, bool success); From dovecot at dovecot.org Fri Jun 27 13:22:41 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 27 Jun 2014 13:22:41 +0000 Subject: dovecot-2.2: lib: test-istream-concat - early abort test loop on... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/77f21248d29e changeset: 17526:77f21248d29e user: Phil Carmody date: Fri Jun 27 16:11:40 2014 +0300 description: lib: test-istream-concat - early abort test loop on failure No point in continuing past the first failure. Signed-off-by: Phil Carmody diffstat: src/lib/test-istream-concat.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diffs (37 lines): diff -r e1686f44f2e7 -r 77f21248d29e src/lib/test-istream-concat.c --- a/src/lib/test-istream-concat.c Fri Jun 27 16:10:27 2014 +0300 +++ b/src/lib/test-istream-concat.c Fri Jun 27 16:11:40 2014 +0300 @@ -49,7 +49,7 @@ i_stream_unref(&input); } -static void test_istream_concat_random(void) +static bool test_istream_concat_random(void) { struct istream **streams, *input, *input1, *input2; const unsigned char *data; @@ -97,11 +97,14 @@ } } } + if (test_has_failed()) + break; } for (i = 0; i < stream_count; i++) i_stream_unref(&streams[i]); i_stream_unref(&input1); i_stream_unref(&input2); + return !test_has_failed(); } void test_istream_concat(void) @@ -116,7 +119,8 @@ test_begin("istream concat random"); for (i = 0; i < 100; i++) T_BEGIN { - test_istream_concat_random(); + if(!test_istream_concat_random()) + i = 101; /* don't break a T_BEGIN */ } T_END; test_end(); } From dovecot at dovecot.org Fri Jun 27 13:22:41 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 27 Jun 2014 13:22:41 +0000 Subject: dovecot-2.2: lib: test printf_format_fix() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2c0b4244b935 changeset: 17527:2c0b4244b935 user: Phil Carmody date: Fri Jun 27 16:12:40 2014 +0300 description: lib: test printf_format_fix() Signed-off-by: Phil Carmody diffstat: src/lib/Makefile.am | 1 + src/lib/test-lib.c | 1 + src/lib/test-lib.h | 1 + src/lib/test-printf-format-fix.c | 96 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 0 deletions(-) diffs (133 lines): diff -r 77f21248d29e -r 2c0b4244b935 src/lib/Makefile.am --- a/src/lib/Makefile.am Fri Jun 27 16:11:40 2014 +0300 +++ b/src/lib/Makefile.am Fri Jun 27 16:12:40 2014 +0300 @@ -296,6 +296,7 @@ test-numpack.c \ test-ostream-file.c \ test-primes.c \ + test-printf-format-fix.c \ test-priorityq.c \ test-seq-range-array.c \ test-str.c \ diff -r 77f21248d29e -r 2c0b4244b935 src/lib/test-lib.c --- a/src/lib/test-lib.c Fri Jun 27 16:11:40 2014 +0300 +++ b/src/lib/test-lib.c Fri Jun 27 16:12:40 2014 +0300 @@ -31,6 +31,7 @@ test_numpack, test_ostream_file, test_primes, + test_printf_format_fix, test_priorityq, test_seq_range_array, test_str, diff -r 77f21248d29e -r 2c0b4244b935 src/lib/test-lib.h --- a/src/lib/test-lib.h Fri Jun 27 16:11:40 2014 +0300 +++ b/src/lib/test-lib.h Fri Jun 27 16:12:40 2014 +0300 @@ -30,6 +30,7 @@ void test_numpack(void); void test_ostream_file(void); void test_primes(void); +void test_printf_format_fix(void); void test_priorityq(void); void test_seq_range_array(void); void test_str(void); diff -r 77f21248d29e -r 2c0b4244b935 src/lib/test-printf-format-fix.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/test-printf-format-fix.c Fri Jun 27 16:12:40 2014 +0300 @@ -0,0 +1,96 @@ +/* Copyright (c) 2001-2014 Dovecot authors, see the included COPYING file */ + +/* Unit tests for printf-format-fix helper */ + +#include "test-lib.h" +#include "printf-format-fix.h" + +#include + +struct format_fix_rewrites { + const char *input; + const char *output; + size_t length; +}; + +static void test_unchanged() +{ + static const char *tests[] = { + "Hello world", + "Embedded %%, %u, %f, etc. are OK", + "%%doesn't cause confusion in %%m and %%n", + }; + unsigned int i; + + test_begin("printf_format_fix(safe)"); + for (i = 0; i < N_ELEMENTS(tests); ++i) { + unsigned int len; + T_BEGIN { + test_assert_idx(printf_format_fix(tests[i]) + == tests[i], i); + test_assert_idx(printf_format_fix_get_len(tests[i], &len) + == tests[i], i); + test_assert_idx(len == strlen(tests[i]), i); + } T_END; + } + test_end(); +} + +static void test_ok_changes() +{ + static const char *tests[] = { + "OK to have a trailing %m", + "%m can appear at the start too", + "Even %m in the middle with a confusing %%m elsewhere is OK", + }; + unsigned int i; + const char *needle; + unsigned int needlen; + int old_errno = errno; + + test_begin("printf_format_fix(rewrites)"); + + errno = EINVAL; + needle = strerror(errno); + test_assert(needle != NULL); + needlen = strlen(needle); + + for (i = 0; i < N_ELEMENTS(tests); ++i) { + unsigned int len; + char const *chgd; + char const *insert; + unsigned int offs; + + T_BEGIN { + chgd = printf_format_fix(tests[i]); + test_assert_idx(chgd != tests[i], i); + insert = strstr(chgd, needle); + test_assert_idx(insert != NULL, i); + offs = insert - chgd; + test_assert_idx(memcmp(chgd, tests[i], offs) == 0, i); + test_assert_idx(memcmp(chgd+offs, needle, needlen) == 0, i); + test_assert_idx(strcmp(chgd+offs+needlen, tests[i]+offs+2) == 0, i); + + chgd = printf_format_fix_get_len(tests[i], &len); + test_assert_idx(chgd != tests[i], i); + test_assert_idx(len == strlen(chgd), i); + insert = strstr(chgd, needle); + test_assert_idx(insert != NULL, i); + offs = insert - chgd; + test_assert_idx(memcmp(chgd, tests[i], offs) == 0, i); + test_assert_idx(memcmp(chgd+offs, needle, needlen) == 0, i); + test_assert_idx(memcmp(chgd+offs+needlen, tests[i]+offs+2, len-needlen-offs) == 0, i); + } T_END; + } + + errno = old_errno; + + test_end(); +} + +void test_printf_format_fix() +{ + test_unchanged(); + test_ok_changes(); + /* want to test the panics too */ +} From dovecot at dovecot.org Fri Jun 27 13:22:41 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 27 Jun 2014 13:22:41 +0000 Subject: dovecot-2.2: lib: make printf_format_fix safer against shadowed ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/06f90ecbfb70 changeset: 17528:06f90ecbfb70 user: Phil Carmody date: Fri Jun 27 16:13:09 2014 +0300 description: lib: make printf_format_fix safer against shadowed %m behaviour If there's a %m followed by a %n or %m, then the %n or %m won't be seen. For %m, that's mostly harmless, but for %n it's potentially kaboom. Signed-off-by: Phil Carmody diffstat: src/lib/printf-format-fix.c | 16 +++++++++++----- 1 files changed, 11 insertions(+), 5 deletions(-) diffs (51 lines): diff -r 2c0b4244b935 -r 06f90ecbfb70 src/lib/printf-format-fix.c --- a/src/lib/printf-format-fix.c Fri Jun 27 16:12:40 2014 +0300 +++ b/src/lib/printf-format-fix.c Fri Jun 27 16:13:09 2014 +0300 @@ -11,12 +11,13 @@ unsigned int len1, len2, len3; i_assert((size_t)(p - fmt) < INT_MAX); + i_assert(p[0] == '%' && p[1] == 'm'); errstr = strerror(errno); /* we'll assume that there's only one %m in the format string. this simplifies the code and there's really no good reason to have - it multiple times. */ + it multiple times. Callers can trap this case themselves. */ len1 = p - fmt; len2 = strlen(errstr); len3 = strlen(p + 2); @@ -35,6 +36,7 @@ printf_format_fix_noalloc(const char *format, unsigned int *len_r) { const char *p; + const char *ret = format; for (p = format; *p != '\0'; ) { if (*p++ == '%') { @@ -42,16 +44,20 @@ case 'n': i_panic("%%n modifier used"); case 'm': - return fix_format_real(format, p-1, len_r); + if (ret != format) + i_panic("%%m used twice"); + ret = fix_format_real(format, p-1, len_r); + break; case '\0': - i_panic("%% modifier missing"); + i_panic("%% modifier missing in '%s'", format); } p++; } } - *len_r = p - format; - return format; + if (ret == format) + *len_r = p - format; + return ret; } const char *printf_format_fix_get_len(const char *format, unsigned int *len_r) From dovecot at dovecot.org Fri Jun 27 13:22:47 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 27 Jun 2014 13:22:47 +0000 Subject: dovecot-2.2: lib: two quite literally random little cleanups Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/60fbbf7ea75d changeset: 17529:60fbbf7ea75d user: Phil Carmody date: Fri Jun 27 16:13:37 2014 +0300 description: lib: two quite literally random little cleanups file-dotlock.c does not use randgen.h, remove the #include test-buffer.c random() has been used rather than rand() Signed-off-by: Phil Carmody diffstat: src/lib/file-dotlock.c | 1 - src/lib/test-buffer.c | 2 +- 2 files changed, 1 insertions(+), 2 deletions(-) diffs (23 lines): diff -r 06f90ecbfb70 -r 60fbbf7ea75d src/lib/file-dotlock.c --- a/src/lib/file-dotlock.c Fri Jun 27 16:13:09 2014 +0300 +++ b/src/lib/file-dotlock.c Fri Jun 27 16:13:37 2014 +0300 @@ -5,7 +5,6 @@ #include "str.h" #include "hex-binary.h" #include "hostpid.h" -#include "randgen.h" #include "eacces-error.h" #include "write-full.h" #include "safe-mkstemp.h" diff -r 06f90ecbfb70 -r 60fbbf7ea75d src/lib/test-buffer.c --- a/src/lib/test-buffer.c Fri Jun 27 16:13:09 2014 +0300 +++ b/src/lib/test-buffer.c Fri Jun 27 16:13:37 2014 +0300 @@ -18,7 +18,7 @@ buf = buffer_create_dynamic(default_pool, 1); for (i = 0; i < BUF_TEST_SIZE; i++) - testdata[i] = random(); + testdata[i] = rand(); memset(shadowbuf, 0, sizeof(shadowbuf)); srand(1); From dovecot at dovecot.org Fri Jun 27 13:22:47 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 27 Jun 2014 13:22:47 +0000 Subject: dovecot-2.2: lib: add rand helper library Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f9deece0002f changeset: 17530:f9deece0002f user: Phil Carmody date: Fri Jun 27 16:15:24 2014 +0300 description: lib: add rand helper library Initially, just wrap srand() so that we can find out what the last-used seed was. In situations where srand() is called only once (via this helper) this lets us reproduce exactly the same stream of random data again in order to reproduce rare crashes. Signed-off-by: Phil Carmody diffstat: src/lib/Makefile.am | 2 ++ src/lib/lib.h | 1 + src/lib/rand.c | 24 ++++++++++++++++++++++++ src/lib/rand.h | 19 +++++++++++++++++++ 4 files changed, 46 insertions(+), 0 deletions(-) diffs (81 lines): diff -r 60fbbf7ea75d -r f9deece0002f src/lib/Makefile.am --- a/src/lib/Makefile.am Fri Jun 27 16:13:37 2014 +0300 +++ b/src/lib/Makefile.am Fri Jun 27 16:15:24 2014 +0300 @@ -111,6 +111,7 @@ process-title.c \ priorityq.c \ randgen.c \ + rand.c \ read-full.c \ restrict-access.c \ restrict-process-size.c \ @@ -229,6 +230,7 @@ printf-format-fix.h \ process-title.h \ priorityq.h \ + rand.h \ randgen.h \ read-full.h \ restrict-access.h \ diff -r 60fbbf7ea75d -r f9deece0002f src/lib/lib.h --- a/src/lib/lib.h Fri Jun 27 16:13:37 2014 +0300 +++ b/src/lib/lib.h Fri Jun 27 16:15:24 2014 +0300 @@ -28,6 +28,7 @@ #include "data-stack.h" #include "mempool.h" #include "imem.h" +#include "rand.h" typedef struct buffer buffer_t; typedef struct buffer string_t; diff -r 60fbbf7ea75d -r f9deece0002f src/lib/rand.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/rand.c Fri Jun 27 16:15:24 2014 +0300 @@ -0,0 +1,24 @@ +/* Copyright (c) 2014 Dovecot authors, see the included COPYING file */ + +/* Wrap srand() so that we can reproduce fuzzed tests */ + +#include "lib.h" +#include + +static int seeded = 0; +static unsigned int seed; + +int rand_get_seed_count(void) +{ + return seeded; +} +unsigned int rand_get_last_seed(void) +{ + i_assert(seeded > 0); + return seed; +} +void rand_set_seed(unsigned int s) +{ + seeded++; + srand(seed = s); +} diff -r 60fbbf7ea75d -r f9deece0002f src/lib/rand.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/rand.h Fri Jun 27 16:15:24 2014 +0300 @@ -0,0 +1,19 @@ +#ifndef RAND_H +#define RAND_H + +/* Wrap srand() so that we can reproduce fuzzed tests */ + +/* If we have seeded the prng precisely once, and we remember what + * value that was with, then we can reproduce any failing test cases + * that depend on that randomness by forcing the seed value (e.g. + * in a debugger, by putting a breakpoint on rand_set_seed()). + */ + +/* Number of times we've been seeded */ +int rand_get_seed_count(void); +/* That last seed */ +unsigned int rand_get_last_seed(void); +/* Actually seed the prng (could add char* for name of function?) */ +void rand_set_seed(unsigned int s); + +#endif From dovecot at dovecot.org Fri Jun 27 13:22:47 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 27 Jun 2014 13:22:47 +0000 Subject: dovecot-2.2: lib: use new srand() wrapper in lib Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/14f505c1c6f4 changeset: 17531:14f505c1c6f4 user: Phil Carmody date: Fri Jun 27 16:16:16 2014 +0300 description: lib: use new srand() wrapper in lib Of course, multiple seeding calls make it harder to know exactly what numbers have been generated. But this is better than nothing. Signed-off-by: Phil Carmody diffstat: src/lib/lib.c | 2 +- src/lib/randgen.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diffs (33 lines): diff -r f9deece0002f -r 14f505c1c6f4 src/lib/lib.c --- a/src/lib/lib.c Fri Jun 27 16:15:24 2014 +0300 +++ b/src/lib/lib.c Fri Jun 27 16:16:16 2014 +0300 @@ -61,7 +61,7 @@ /* standard way to get rand() return different values. */ if (gettimeofday(&tv, NULL) < 0) i_fatal("gettimeofday(): %m"); - srand((unsigned int) (tv.tv_sec ^ tv.tv_usec ^ getpid())); + rand_set_seed((unsigned int) (tv.tv_sec ^ tv.tv_usec ^ getpid())); data_stack_init(); hostpid_init(); diff -r f9deece0002f -r 14f505c1c6f4 src/lib/randgen.c --- a/src/lib/randgen.c Fri Jun 27 16:15:24 2014 +0300 +++ b/src/lib/randgen.c Fri Jun 27 16:16:16 2014 +0300 @@ -53,7 +53,7 @@ } random_fill(&seed, sizeof(seed)); - srand(seed); + rand_set_seed(seed); fd_close_on_exec(urandom_fd, TRUE); } @@ -102,7 +102,7 @@ } random_fill(&seed, sizeof(seed)); - srand(seed); + rand_set_seed(seed); } void random_deinit(void) {} From dovecot at dovecot.org Fri Jun 27 13:22:47 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 27 Jun 2014 13:22:47 +0000 Subject: dovecot-2.2: lib-test: use the new srand() tracking helpers to a... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/06f29889af37 changeset: 17532:06f29889af37 user: Phil Carmody date: Fri Jun 27 16:17:07 2014 +0300 description: lib-test: use the new srand() tracking helpers to aid debugging We can only be sure we know the entirity of the stream of numbers returned by rand if rand_set_seed has been called precisely once, as after that we can't be sure when it was called a 2nd or further time. However, at least we can know that that has happened. (Likewise, any calls to srand() will disturb the flow.) Most unit test cases should be simple enough that there should be only one seeding. Signed-off-by: Phil Carmody diffstat: src/lib-test/test-common.c | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) diffs (36 lines): diff -r 14f505c1c6f4 -r 06f29889af37 src/lib-test/test-common.c --- a/src/lib-test/test-common.c Fri Jun 27 16:16:16 2014 +0300 +++ b/src/lib-test/test-common.c Fri Jun 27 16:17:07 2014 +0300 @@ -164,11 +164,24 @@ test_success = FALSE; } +static void +test_dump_rand_state(void) +{ + if (rand_get_seed_count() > 0) + printf("test: random seed #%i was %u\n", + rand_get_seed_count(), + rand_get_last_seed()); + else + printf("test: random seed unknown\n"); +} + void test_end(void) { i_assert(test_prefix != NULL); test_out("", test_success); + if (!test_success) + test_dump_rand_state(); i_free_and_null(test_prefix); test_success = FALSE; } @@ -217,6 +230,7 @@ test_error_handler(const struct failure_context *ctx, const char *format, va_list args) { + test_dump_rand_state(); default_error_handler(ctx, format, args); #ifdef DEBUG if (ctx->type == LOG_TYPE_WARNING && From dovecot at dovecot.org Fri Jun 27 13:22:47 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 27 Jun 2014 13:22:47 +0000 Subject: dovecot-2.2: lib: remove unwanted srand()s from unit tests Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9fd5c57fa49b changeset: 17533:9fd5c57fa49b user: Phil Carmody date: Fri Jun 27 16:17:50 2014 +0300 description: lib: remove unwanted srand()s from unit tests We'll get better coverage without them. Note: this change causes the following test case failure occasionally: test-istream-concat.c:88: Assert failed: size >= TEST_MAX_BUFFER_SIZE istream concat random ................................................ : FAILED test: random seed #1 was 1403027537 (The seed may vary, obviously.) Signed-off-by: Phil Carmody diffstat: src/lib/test-buffer.c | 1 - src/lib/test-istream-concat.c | 1 - 2 files changed, 0 insertions(+), 2 deletions(-) diffs (22 lines): diff -r 06f29889af37 -r 9fd5c57fa49b src/lib/test-buffer.c --- a/src/lib/test-buffer.c Fri Jun 27 16:17:07 2014 +0300 +++ b/src/lib/test-buffer.c Fri Jun 27 16:17:50 2014 +0300 @@ -21,7 +21,6 @@ testdata[i] = rand(); memset(shadowbuf, 0, sizeof(shadowbuf)); - srand(1); shadowbuf_size = 0; for (i = 0; i < BUF_TEST_COUNT; i++) { if (buf->used == BUF_TEST_SIZE) { diff -r 06f29889af37 -r 9fd5c57fa49b src/lib/test-istream-concat.c --- a/src/lib/test-istream-concat.c Fri Jun 27 16:17:07 2014 +0300 +++ b/src/lib/test-istream-concat.c Fri Jun 27 16:17:50 2014 +0300 @@ -57,7 +57,6 @@ size_t size = 0; unsigned int i, j, offset, stream_count, data_len; - srand(3); stream_count = (rand() % TEST_MAX_ISTREAM_COUNT) + 2; streams = t_new(struct istream *, stream_count + 1); for (i = 0, offset = 0; i < stream_count; i++) { From dovecot at dovecot.org Fri Jun 27 13:22:47 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 27 Jun 2014 13:22:47 +0000 Subject: dovecot-2.2: lib: rand - force reseeding with known seed from en... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fe0c69112049 changeset: 17534:fe0c69112049 user: Phil Carmody date: Fri Jun 27 16:20:25 2014 +0300 description: lib: rand - force reseeding with known seed from environment Use DOVECOT_SRAND=12345 as an environmental variable to force seeding to that number. The logic behind the logging is that the subsequent calls will almost certainly be from random_fill_weak() which expects to have been seeded from a CSPRNG - not a constant! Having this environmental variable set in a production system that expects CSPRNG seeding should be flagging diagnostics. Signed-off-by: Phil Carmody diffstat: src/lib/rand.c | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletions(-) diffs (27 lines): diff -r 9fd5c57fa49b -r fe0c69112049 src/lib/rand.c --- a/src/lib/rand.c Fri Jun 27 16:17:50 2014 +0300 +++ b/src/lib/rand.c Fri Jun 27 16:20:25 2014 +0300 @@ -7,6 +7,7 @@ static int seeded = 0; static unsigned int seed; +static char const *env_seed; int rand_get_seed_count(void) { @@ -19,6 +20,14 @@ } void rand_set_seed(unsigned int s) { + if (seeded == 0) { + env_seed = getenv("DOVECOT_SRAND"); + if (env_seed != NULL) + seed = strtoul(env_seed, NULL, 0); + } seeded++; - srand(seed = s); + if (env_seed == NULL) + seed = s; + + srand(seed); } From dovecot at dovecot.org Fri Jun 27 13:30:45 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 27 Jun 2014 13:30:45 +0000 Subject: dovecot-2.2: lib: istream-concat read() returned -2 too early. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/31efe2d04793 changeset: 17535:31efe2d04793 user: Timo Sirainen date: Fri Jun 27 16:29:18 2014 +0300 description: lib: istream-concat read() returned -2 too early. diffstat: src/lib/istream-concat.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r fe0c69112049 -r 31efe2d04793 src/lib/istream-concat.c --- a/src/lib/istream-concat.c Fri Jun 27 16:20:25 2014 +0300 +++ b/src/lib/istream-concat.c Fri Jun 27 16:29:18 2014 +0300 @@ -145,7 +145,7 @@ /* we either read something or we're at EOF */ last_stream = cstream->input[cstream->cur_idx+1] == NULL; if (ret == -1 && !last_stream) { - if (stream->pos >= stream->max_buffer_size) + if (stream->pos - stream->skip >= stream->max_buffer_size) return -2; i_stream_concat_read_next(cstream); From dovecot at dovecot.org Fri Jun 27 14:39:31 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 27 Jun 2014 14:39:31 +0000 Subject: dovecot-2.2: auth: Added assert to make sure sysconf() returns w... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1abf8621981a changeset: 17536:1abf8621981a user: Timo Sirainen date: Fri Jun 27 17:37:56 2014 +0300 description: auth: Added assert to make sure sysconf() returns what we expect. userdb nss shouldn't even be used though. So this is mainly to silence Coverity. diffstat: src/auth/userdb-nss.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diffs (18 lines): diff -r 31efe2d04793 -r 1abf8621981a src/auth/userdb-nss.c --- a/src/auth/userdb-nss.c Fri Jun 27 16:29:18 2014 +0300 +++ b/src/auth/userdb-nss.c Fri Jun 27 17:37:56 2014 +0300 @@ -104,9 +104,13 @@ { struct nss_userdb_module *module; const char *const *tmp; + long bufsize; + + bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); + i_assert(bufsize > 0); module = p_new(pool, struct nss_userdb_module, 1); - module->bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); + module->bufsize = bufsize; module->buf = p_malloc(pool, module->bufsize); module->module.blocking = TRUE; From dovecot at dovecot.org Fri Jun 27 14:41:47 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 27 Jun 2014 14:41:47 +0000 Subject: dovecot-2.2: imap-url: Fixed handling of ipath-empty syntax (bas... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3f9d15b600b1 changeset: 17537:3f9d15b600b1 user: Stephan Bosch date: Fri Jun 27 17:39:52 2014 +0300 description: imap-url: Fixed handling of ipath-empty syntax (basically empty relative URLs). This also normalizes Mailbox/ to Mailbox. Initial indication reported by Coverity. diffstat: src/lib-imap/imap-url.c | 338 +++++++++++++++++++++--------------------- src/lib-imap/test-imap-url.c | 75 ++++++++- src/lib/uri-util.c | 6 +- 3 files changed, 241 insertions(+), 178 deletions(-) diffs (truncated from 547 to 300 lines): diff -r 1abf8621981a -r 3f9d15b600b1 src/lib-imap/imap-url.c --- a/src/lib-imap/imap-url.c Fri Jun 27 17:37:56 2014 +0300 +++ b/src/lib-imap/imap-url.c Fri Jun 27 17:39:52 2014 +0300 @@ -508,7 +508,7 @@ int rel = relative; /* /;PARTIAL= */ - if (base->have_partial && rel-- <= 0) { + if (base->have_partial && --rel <= 0) { have_partial = base->have_partial; partial_offset = base->partial_offset; partial_size = base->partial_size; @@ -528,7 +528,7 @@ } } /* /;UID= */ - if (base->uid > 0 && rel-- <= 0) { + if (base->uid > 0 && --rel <= 0) { uid = base->uid; } /* /mail/box;UIDVALIDITY= */ @@ -556,196 +556,198 @@ } /* Scan for last mailbox-ref segment */ - if (uid == 0) { - p = NULL; - while (*segment != NULL) { - /* ';' must be pct-encoded; if it is not, this is - either the last mailbox-ref path segment containing - ';UIDVALIDITY=' or the subsequent iuid ';UID=' path - segment */ - if ((p = strchr(*segment, ';')) != NULL) - break; + if (segment != NULL) { + if (relative == 0 || (!have_partial && section == NULL)) { + p = NULL; + while (*segment != NULL) { + /* ';' must be pct-encoded; if it is not, this is + either the last mailbox-ref path segment containing + ';UIDVALIDITY=' or the subsequent iuid ';UID=' path + segment */ + if ((p = strchr(*segment, ';')) != NULL) + break; - if (segment > path || - (!mailbox_endslash && str_len(mailbox) > 0)) - str_append_c(mailbox, '/'); - if (**segment != '\0') { - if (!uri_data_decode(parser, *segment, NULL, &value)) - return -1; - str_append(mailbox, value); - mailbox_endslash = FALSE; - } - segment++; - } - - /* Handle ';' */ - if (p != NULL) { - /* [uidvalidity] */ - if (strncasecmp(p, ";UIDVALIDITY=", 13) == 0) { - /* append last bit of mailbox */ - if (segment > path || - (!mailbox_endslash && str_len(mailbox) > 0)) - str_append_c(mailbox, '/'); - if (*segment != p) { - if (!uri_data_decode(parser, *segment, p, &value)) + if (**segment != '\0') { + if (segment > path || + (!mailbox_endslash && str_len(mailbox) > 0)) + str_append_c(mailbox, '/'); + if (!uri_data_decode(parser, *segment, NULL, &value)) return -1; str_append(mailbox, value); + mailbox_endslash = FALSE; } + segment++; + } - /* ";UIDVALIDITY=" nz-number */ - if (strchr(p+13, ';') != NULL) { - parser->error = "Encountered stray ';' after UIDVALIDITY"; + /* Handle ';' */ + if (p != NULL) { + /* [uidvalidity] */ + if (strncasecmp(p, ";UIDVALIDITY=", 13) == 0) { + /* append last bit of mailbox */ + if (*segment != p) { + if (segment > path || + (!mailbox_endslash && str_len(mailbox) > 0)) + str_append_c(mailbox, '/'); + if (!uri_data_decode(parser, *segment, p, &value)) + return -1; + str_append(mailbox, value); + } + + /* ";UIDVALIDITY=" nz-number */ + if (strchr(p+13, ';') != NULL) { + parser->error = "Encountered stray ';' after UIDVALIDITY"; + return -1; + } + + /* nz-number */ + if (p[13] == '\0') { + parser->error = "Empty UIDVALIDITY value"; + return -1; + } + if (imap_url_parse_number(parser, p+13, &uidvalidity) <= 0) + return -1; + if (uidvalidity == 0) { + parser->error = "UIDVALIDITY cannot be zero"; + return -1; + } + segment++; + } else if (p != *segment) { + parser->error = "Encountered stray ';' in mailbox reference"; return -1; } - - /* nz-number */ - if (p[13] == '\0') { - parser->error = "Empty UIDVALIDITY value"; - return -1; - } - if (imap_url_parse_number(parser, p+13, &uidvalidity) <= 0) - return -1; - if (uidvalidity == 0) { - parser->error = "UIDVALIDITY cannot be zero"; - return -1; - } - segment++; - } else if (p != *segment) { - parser->error = "Encountered stray ';' in mailbox reference"; - return -1; - } - } - - /* iuid */ - if (*segment != NULL && strncasecmp(*segment, ";UID=", 5) == 0) { - /* ";UID=" nz-number */ - value = (*segment)+5; - if ((p = strchr(value,';')) != NULL) { - if (segment[1] != NULL ) { - /* not the last segment, so it cannot be extension like iurlauth */ - parser->error = "Encountered stray ';' in UID path segment"; - return -1; - } - urlext = p; - value = t_strdup_until(value, p); - } - /* nz-number */ - if (*value == '\0') { - parser->error = "Empty UID value"; - return -1; - } - if (imap_url_parse_number(parser, value, &uid) <= 0) - return -1; - if (uid == 0) { - parser->error = "UID cannot be zero"; - return -1; - } - segment++; - } - } - - /* [isection] [ipartial] */ - if (*segment != NULL && uid > 0 && !have_partial) { - /* [isection] */ - if (section != NULL || - strncasecmp(*segment, ";SECTION=", 9) == 0) { - /* ";SECTION=" enc-section */ - if (section == NULL) { - section = t_str_new(256); - value = (*segment) + 9; - } else { - value = *segment; } - /* enc-section can contain slashes, so we merge path segments until one - contains ';' */ - while ((p = strchr(value,';')) == NULL) { - if (!section_endslash && str_len(section) > 0) - str_append_c(section, '/'); - if (*value != '\0') { - if (!uri_data_decode(parser, value, NULL, &value)) - return -1; - str_append(section, value); - section_endslash = FALSE; - } - - segment++; - if (*segment == NULL) - break; - value = *segment; - } - - if (p != NULL) { - /* found ';' */ - if (p != value) { - /* it is not at the beginning of the path segment */ - if (segment[1] != NULL) { + /* iuid */ + if (*segment != NULL && strncasecmp(*segment, ";UID=", 5) == 0) { + /* ";UID=" nz-number */ + value = (*segment)+5; + if ((p = strchr(value,';')) != NULL) { + if (segment[1] != NULL ) { /* not the last segment, so it cannot be extension like iurlauth */ - parser->error = "Encountered stray ';' in SECTION path segment"; + parser->error = "Encountered stray ';' in UID path segment"; return -1; } urlext = p; value = t_strdup_until(value, p); + } + /* nz-number */ + if (*value == '\0') { + parser->error = "Empty UID value"; + return -1; + } + if (imap_url_parse_number(parser, value, &uid) <= 0) + return -1; + if (uid == 0) { + parser->error = "UID cannot be zero"; + return -1; + } + segment++; + } + } + + /* [isection] [ipartial] */ + if (*segment != NULL && uid > 0) { + /* [isection] */ + if (section != NULL || + strncasecmp(*segment, ";SECTION=", 9) == 0) { + /* ";SECTION=" enc-section */ + if (section == NULL) { + section = t_str_new(256); + value = (*segment) + 9; + } else { + value = *segment; + } + + /* enc-section can contain slashes, so we merge path segments until one + contains ';' */ + while ((p = strchr(value,';')) == NULL) { if (!section_endslash && str_len(section) > 0) str_append_c(section, '/'); - if (!uri_data_decode(parser, value, NULL, &value)) - return -1; - str_append(section, value); + if (*value != '\0') { + if (!uri_data_decode(parser, value, NULL, &value)) + return -1; + str_append(section, value); + section_endslash = FALSE; + } + segment++; + if (*segment == NULL) + break; + value = *segment; + } + + if (p != NULL) { + /* found ';' */ + if (p != value) { + /* it is not at the beginning of the path segment */ + if (segment[1] != NULL) { + /* not the last segment, so it cannot be extension like iurlauth */ + parser->error = "Encountered stray ';' in SECTION path segment"; + return -1; + } + urlext = p; + value = t_strdup_until(value, p); + if (!section_endslash && str_len(section) > 0) + str_append_c(section, '/'); + if (!uri_data_decode(parser, value, NULL, &value)) + return -1; + str_append(section, value); + segment++; + } + } + + if (str_len(section) == 0) { + parser->error = "Empty SECTION value"; + return -1; } } - if (str_len(section) == 0) { - parser->error = "Empty SECTION value"; - return -1; + /* [ipartial] */ + if (*segment != NULL && + strncasecmp(*segment, ";PARTIAL=", 9) == 0) { + have_partial = TRUE; + + /* ";PARTIAL=" partial-range */ + value = (*segment) + 9; From dovecot at dovecot.org Mon Jun 30 11:37:36 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 30 Jun 2014 11:37:36 +0000 Subject: dovecot-2.2: imap: Don't disconnect due to inconsistent mailbox ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d09ecf549f6a changeset: 17538:d09ecf549f6a user: Timo Sirainen date: Mon Jun 30 14:28:31 2014 +0300 description: imap: Don't disconnect due to inconsistent mailbox unless the mailbox is the selected mailbox. diffstat: src/imap/imap-commands-util.c | 6 ------ 1 files changed, 0 insertions(+), 6 deletions(-) diffs (16 lines): diff -r 3f9d15b600b1 -r d09ecf549f6a src/imap/imap-commands-util.c --- a/src/imap/imap-commands-util.c Fri Jun 27 17:39:52 2014 +0300 +++ b/src/imap/imap-commands-util.c Mon Jun 30 14:28:31 2014 +0300 @@ -173,12 +173,6 @@ void client_send_box_error(struct client_command_context *cmd, struct mailbox *box) { - if (mailbox_is_inconsistent(box)) { - /* we can't do forced CLOSE, so have to disconnect */ - client_disconnect_with_error(cmd->client, - "IMAP session state is inconsistent, please relogin."); - return; - } client_send_storage_error(cmd, mailbox_get_storage(box)); } From dovecot at dovecot.org Mon Jun 30 11:37:36 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 30 Jun 2014 11:37:36 +0000 Subject: dovecot-2.2: imap: If we disconnect client because mailbox is in... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/852bc94983ab changeset: 17539:852bc94983ab user: Timo Sirainen date: Mon Jun 30 14:29:26 2014 +0300 description: imap: If we disconnect client because mailbox is inconsistent, send the error message before BYE. diffstat: src/imap/imap-commands-util.c | 16 +++++++--------- 1 files changed, 7 insertions(+), 9 deletions(-) diffs (45 lines): diff -r d09ecf549f6a -r 852bc94983ab src/imap/imap-commands-util.c --- a/src/imap/imap-commands-util.c Mon Jun 30 14:28:31 2014 +0300 +++ b/src/imap/imap-commands-util.c Mon Jun 30 14:29:26 2014 +0300 @@ -182,17 +182,16 @@ const char *error_string; enum mail_error error; + error_string = mail_storage_get_last_error(storage, &error); + client_send_tagline(cmd, imap_get_error_string(cmd, error_string, + error)); + if (cmd->client->mailbox != NULL && mailbox_is_inconsistent(cmd->client->mailbox)) { /* we can't do forced CLOSE, so have to disconnect */ client_disconnect_with_error(cmd->client, "IMAP session state is inconsistent, please relogin."); - return; } - - error_string = mail_storage_get_last_error(storage, &error); - client_send_tagline(cmd, imap_get_error_string(cmd, error_string, - error)); } void client_send_untagged_storage_error(struct client *client, @@ -201,16 +200,15 @@ const char *error_string; enum mail_error error; + error_string = mail_storage_get_last_error(storage, &error); + client_send_line(client, t_strconcat("* NO ", error_string, NULL)); + if (client->mailbox != NULL && mailbox_is_inconsistent(client->mailbox)) { /* we can't do forced CLOSE, so have to disconnect */ client_disconnect_with_error(client, "IMAP session state is inconsistent, please relogin."); - return; } - - error_string = mail_storage_get_last_error(storage, &error); - client_send_line(client, t_strconcat("* NO ", error_string, NULL)); } bool client_parse_mail_flags(struct client_command_context *cmd, From dovecot at dovecot.org Mon Jun 30 11:37:36 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 30 Jun 2014 11:37:36 +0000 Subject: dovecot-2.2: lib-storage: Added index_storage_mailbox_delete_pre... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0eee02b75557 changeset: 17540:0eee02b75557 user: Timo Sirainen date: Mon Jun 30 14:30:43 2014 +0300 description: lib-storage: Added index_storage_mailbox_delete_pre/post(). This avoids reimplementing the whole index_storage_mailbox_delete() for storage backends that need to do more work in the middle. diffstat: src/lib-storage/index/index-storage.c | 24 +++++++++++++++++++++--- src/lib-storage/index/index-storage.h | 2 ++ 2 files changed, 23 insertions(+), 3 deletions(-) diffs (62 lines): diff -r 852bc94983ab -r 0eee02b75557 src/lib-storage/index/index-storage.c --- a/src/lib-storage/index/index-storage.c Mon Jun 30 14:29:26 2014 +0300 +++ b/src/lib-storage/index/index-storage.c Mon Jun 30 14:30:43 2014 +0300 @@ -670,11 +670,9 @@ return mailbox_transaction_commit(&t); } -int index_storage_mailbox_delete(struct mailbox *box) +int index_storage_mailbox_delete_pre(struct mailbox *box) { - struct mailbox_metadata metadata; struct mailbox_status status; - int ret_guid; if (!box->opened) { /* \noselect mailbox, try deleting only the directory */ @@ -714,6 +712,13 @@ return -1; } } + return 1; +} + +int index_storage_mailbox_delete_post(struct mailbox *box) +{ + struct mailbox_metadata metadata; + int ret_guid; ret_guid = mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata); @@ -743,6 +748,19 @@ return 0; } +int index_storage_mailbox_delete(struct mailbox *box) +{ + int ret; + + if ((ret = index_storage_mailbox_delete_pre(box)) <= 0) + return ret; + /* mails have been now successfully deleted. some mailbox formats may + at this point do some other deletion that is required for it. + the _post() deletion will close the index and delete the + directory. */ + return index_storage_mailbox_delete_post(box); +} + int index_storage_mailbox_rename(struct mailbox *src, struct mailbox *dest) { guid_128_t guid; diff -r 852bc94983ab -r 0eee02b75557 src/lib-storage/index/index-storage.h --- a/src/lib-storage/index/index-storage.h Mon Jun 30 14:29:26 2014 +0300 +++ b/src/lib-storage/index/index-storage.h Mon Jun 30 14:30:43 2014 +0300 @@ -74,6 +74,8 @@ int index_storage_mailbox_update_common(struct mailbox *box, const struct mailbox_update *update); int index_storage_mailbox_create(struct mailbox *box, bool directory); +int index_storage_mailbox_delete_pre(struct mailbox *box); +int index_storage_mailbox_delete_post(struct mailbox *box); int index_storage_mailbox_delete(struct mailbox *box); int index_storage_mailbox_delete_dir(struct mailbox *box, bool mailbox_deleted); int index_storage_mailbox_rename(struct mailbox *src, struct mailbox *dest); From dovecot at dovecot.org Mon Jun 30 11:37:37 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 30 Jun 2014 11:37:37 +0000 Subject: dovecot-2.2: lib-storage: mailbox_delete() now handled "mailbox ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2b1c5a96b416 changeset: 17541:2b1c5a96b416 user: Timo Sirainen date: Mon Jun 30 14:31:47 2014 +0300 description: lib-storage: mailbox_delete() now handled "mailbox is being deleted" explicitly. Earlier we just treated it as \NoSelect mailbox and failed later. diffstat: src/lib-storage/mail-storage.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 0eee02b75557 -r 2b1c5a96b416 src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Mon Jun 30 14:30:43 2014 +0300 +++ b/src/lib-storage/mail-storage.c Mon Jun 30 14:31:47 2014 +0300 @@ -1311,7 +1311,8 @@ box->deleting = TRUE; if (mailbox_open(box) < 0) { - if (mailbox_get_last_mail_error(box) != MAIL_ERROR_NOTFOUND) + if (mailbox_get_last_mail_error(box) != MAIL_ERROR_NOTFOUND && + !box->mailbox_deleted) return -1; /* \noselect mailbox */ } From dovecot at dovecot.org Mon Jun 30 11:37:37 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 30 Jun 2014 11:37:37 +0000 Subject: dovecot-2.2: lib-storage: When deleting mailbox, finish the expu... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0279f9d2bd81 changeset: 17542:0279f9d2bd81 user: Timo Sirainen date: Mon Jun 30 14:34:00 2014 +0300 description: lib-storage: When deleting mailbox, finish the expunges before marking mailbox deleted. This decreases the amount of time the mailbox is visible but not accessible. diffstat: src/lib-storage/index/index-storage.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (15 lines): diff -r 2b1c5a96b416 -r 0279f9d2bd81 src/lib-storage/index/index-storage.c --- a/src/lib-storage/index/index-storage.c Mon Jun 30 14:31:47 2014 +0300 +++ b/src/lib-storage/index/index-storage.c Mon Jun 30 14:34:00 2014 +0300 @@ -667,7 +667,10 @@ mailbox_transaction_rollback(&t); return -1; } - return mailbox_transaction_commit(&t); + if (mailbox_transaction_commit(&t) < 0) + return -1; + /* sync to actually perform the expunges */ + return mailbox_sync(box, 0); } int index_storage_mailbox_delete_pre(struct mailbox *box) From dovecot at dovecot.org Mon Jun 30 11:37:37 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 30 Jun 2014 11:37:37 +0000 Subject: dovecot-2.2: lib-storage: Shrink "mailbox is being deleted" time... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c8c9e3a85625 changeset: 17543:c8c9e3a85625 user: Timo Sirainen date: Mon Jun 30 14:35:32 2014 +0300 description: lib-storage: Shrink "mailbox is being deleted" timeout from 5 mins to 30 secs. Even 30s may be too much since normally a few seconds would be enough, but keep it high enough just in case. diffstat: src/lib-storage/mail-storage.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 0279f9d2bd81 -r c8c9e3a85625 src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Mon Jun 30 14:34:00 2014 +0300 +++ b/src/lib-storage/mail-storage.c Mon Jun 30 14:35:32 2014 +0300 @@ -26,7 +26,7 @@ #include #include -#define MAILBOX_DELETE_RETRY_SECS (60*5) +#define MAILBOX_DELETE_RETRY_SECS 30 extern struct mail_search_register *mail_search_register_imap; extern struct mail_search_register *mail_search_register_human; From dovecot at dovecot.org Mon Jun 30 13:42:58 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 30 Jun 2014 13:42:58 +0000 Subject: dovecot-2.2: fts-tika: Fixed crash if Tika returned 200 reply wi... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/49dfc6da1786 changeset: 17544:49dfc6da1786 user: Timo Sirainen date: Mon Jun 30 16:41:32 2014 +0300 description: fts-tika: Fixed crash if Tika returned 200 reply without payload. diffstat: src/plugins/fts/fts-parser-tika.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diffs (18 lines): diff -r c8c9e3a85625 -r 49dfc6da1786 src/plugins/fts/fts-parser-tika.c --- a/src/plugins/fts/fts-parser-tika.c Mon Jun 30 14:35:32 2014 +0300 +++ b/src/plugins/fts/fts-parser-tika.c Mon Jun 30 16:41:32 2014 +0300 @@ -84,8 +84,12 @@ switch (response->status) { case 200: /* read response */ - i_stream_ref(response->payload); - parser->payload = response->payload; + if (response->payload == NULL) + parser->payload = i_stream_create_from_data("", 0); + else { + i_stream_ref(response->payload); + parser->payload = response->payload; + } break; case 204: /* empty response */ case 422: /* Unprocessable Entity */ From dovecot at dovecot.org Mon Jun 30 14:26:27 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 30 Jun 2014 14:26:27 +0000 Subject: dovecot-2.2: fts-tika: Hiden "Unsupported Media Type" errors. Lo... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2c2b94840ff3 changeset: 17545:2c2b94840ff3 user: Timo Sirainen date: Mon Jun 30 17:25:02 2014 +0300 description: fts-tika: Hiden "Unsupported Media Type" errors. Log HTTP status code on errors. diffstat: src/plugins/fts/fts-parser-tika.c | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) diffs (27 lines): diff -r 49dfc6da1786 -r 2c2b94840ff3 src/plugins/fts/fts-parser-tika.c --- a/src/plugins/fts/fts-parser-tika.c Mon Jun 30 16:41:32 2014 +0300 +++ b/src/plugins/fts/fts-parser-tika.c Mon Jun 30 17:25:02 2014 +0300 @@ -92,18 +92,19 @@ } break; case 204: /* empty response */ + case 415: /* Unsupported Media Type */ case 422: /* Unprocessable Entity */ if (parser->user->mail_debug) { - i_debug("fts_tika: PUT %s failed: %s", + i_debug("fts_tika: PUT %s failed: %u %s", mail_user_plugin_getenv(parser->user, "fts_tika"), - response->reason); + response->status, response->reason); } parser->payload = i_stream_create_from_data("", 0); break; default: - i_error("fts_tika: PUT %s failed: %s", + i_error("fts_tika: PUT %s failed: %u %s", mail_user_plugin_getenv(parser->user, "fts_tika"), - response->reason); + response->status, response->reason); parser->failed = TRUE; break; } From dovecot at dovecot.org Mon Jun 30 21:11:46 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 30 Jun 2014 21:11:46 +0000 Subject: dovecot-2.2: lib-http: Added http_client_request_get_target() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/40e128ff3537 changeset: 17546:40e128ff3537 user: Timo Sirainen date: Tue Jul 01 00:10:21 2014 +0300 description: lib-http: Added http_client_request_get_target() This can be useful in error message logging without having to duplicate the string. diffstat: src/lib-http/http-client-request.c | 5 +++++ src/lib-http/http-client.h | 1 + 2 files changed, 6 insertions(+), 0 deletions(-) diffs (26 lines): diff -r 2c2b94840ff3 -r 40e128ff3537 src/lib-http/http-client-request.c --- a/src/lib-http/http-client-request.c Mon Jun 30 17:25:02 2014 +0300 +++ b/src/lib-http/http-client-request.c Tue Jul 01 00:10:21 2014 +0300 @@ -336,6 +336,11 @@ return 1; /* valid delay */ } +const char *http_client_request_get_target(struct http_client_request *req) +{ + return req->target; +} + enum http_request_state http_client_request_get_state(struct http_client_request *req) { diff -r 2c2b94840ff3 -r 40e128ff3537 src/lib-http/http-client.h --- a/src/lib-http/http-client.h Mon Jun 30 17:25:02 2014 +0300 +++ b/src/lib-http/http-client.h Tue Jul 01 00:10:21 2014 +0300 @@ -185,6 +185,7 @@ void http_client_request_delay(struct http_client_request *req, time_t seconds); +const char *http_client_request_get_target(struct http_client_request *req); enum http_request_state http_client_request_get_state(struct http_client_request *req); void http_client_request_submit(struct http_client_request *req);