From dovecot at dovecot.org Wed Oct 1 07:34:18 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 01 Oct 2014 07:34:18 +0000 Subject: dovecot-2.2: lib-http: client: Fixed aborting request in the mid... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/adcf35ac5432 changeset: 17857:adcf35ac5432 user: Stephan Bosch date: Wed Oct 01 10:33:39 2014 +0300 description: lib-http: client: Fixed aborting request in the middle of sending payload. If the request payload is so big that it cannot be sent all at once, the caller may at some point abort the request when it is still being sent. The bug occurred when the request finally finished sending. It erroneously advanced the state to WAITING rather than remaining ABORTED, thus 'reviving' the request unexpectedly. diffstat: src/lib-http/http-client-connection.c | 1 + src/lib-http/http-client-request.c | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diffs (40 lines): diff -r df53b5ccc2ba -r adcf35ac5432 src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Wed Oct 01 00:17:09 2014 +0300 +++ b/src/lib-http/http-client-connection.c Wed Oct 01 10:33:39 2014 +0300 @@ -299,6 +299,7 @@ if (conn->peer->no_payload_sync) req->payload_sync = FALSE; + i_assert(req->state == HTTP_REQUEST_STATE_QUEUED); array_append(&conn->request_wait_list, &req, 1); http_client_request_ref(req); diff -r df53b5ccc2ba -r adcf35ac5432 src/lib-http/http-client-request.c --- a/src/lib-http/http-client-request.c Wed Oct 01 00:17:09 2014 +0300 +++ b/src/lib-http/http-client-request.c Wed Oct 01 10:33:39 2014 +0300 @@ -453,14 +453,23 @@ { i_assert(req->conn != NULL); + /* drop payload output stream */ if (req->payload_output != NULL) { o_stream_unref(&req->payload_output); req->payload_output = NULL; } - req->state = HTTP_REQUEST_STATE_WAITING; + + /* advance state only when request didn't get aborted in the mean time */ + if (req->state != HTTP_REQUEST_STATE_ABORTED) { + i_assert(req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT); + req->state = HTTP_REQUEST_STATE_WAITING; + } + + /* release connection */ req->conn->output_locked = FALSE; - http_client_request_debug(req, "Finished sending payload"); + http_client_request_debug(req, "Finished sending%s payload", + (req->state == HTTP_REQUEST_STATE_ABORTED ? " aborted" : "")); } static int From dovecot at dovecot.org Wed Oct 1 07:34:19 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 01 Oct 2014 07:34:19 +0000 Subject: dovecot-2.2: lib-http: client: Fixed recovery after connection f... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/548cb71d63da changeset: 17858:548cb71d63da user: Stephan Bosch date: Wed Oct 01 10:33:49 2014 +0300 description: lib-http: client: Fixed recovery after connection failure. If a parallel already connected connection was active, the queue wasn't notified of the failure. Only pending connections should be considered in this case and not established ones. diffstat: src/lib-http/http-client-peer.c | 41 +++++++++++++++++++++++++++---------- src/lib-http/http-client-private.h | 5 +++- 2 files changed, 34 insertions(+), 12 deletions(-) diffs (96 lines): diff -r adcf35ac5432 -r 548cb71d63da src/lib-http/http-client-peer.c --- a/src/lib-http/http-client-peer.c Wed Oct 01 10:33:39 2014 +0300 +++ b/src/lib-http/http-client-peer.c Wed Oct 01 10:33:49 2014 +0300 @@ -529,22 +529,28 @@ { const struct http_client_settings *set = &peer->client->set; struct http_client_queue *const *queue; - unsigned int num_urgent; - - i_assert(array_count(&peer->conns) > 0); - - http_client_peer_debug(peer, "Failed to make connection"); + unsigned int pending; peer->last_failure = ioloop_timeval; - if (array_count(&peer->conns) == 1) { + /* count number of pending connections */ + pending = http_client_peer_pending_connections(peer); + i_assert(pending > 0); + + http_client_peer_debug(peer, + "Failed to make connection " + "(connections=%u, connecting=%u)", + array_count(&peer->conns), pending); + + /* manage backoff timer only when this was the only attempt */ + if (pending == 1) { if (peer->backoff_time_msecs == 0) peer->backoff_time_msecs = set->connect_backoff_time_msecs; else peer->backoff_time_msecs *= 2; } - if (array_count(&peer->conns) > 1) { + if (pending > 1) { /* if there are other connections attempting to connect, wait for them before failing the requests. remember that we had trouble with connecting so in future we don't try to create @@ -558,9 +564,6 @@ http_client_queue_connection_failure(*queue, &peer->addr, reason); } } - if (array_count(&peer->conns) == 0 && - http_client_peer_requests_pending(peer, &num_urgent) == 0) - http_client_peer_free(&peer); } void http_client_peer_connection_lost(struct http_client_peer *peer) @@ -586,7 +589,8 @@ http_client_peer_free(&peer); } -unsigned int http_client_peer_idle_connections(struct http_client_peer *peer) +unsigned int +http_client_peer_idle_connections(struct http_client_peer *peer) { struct http_client_connection *const *conn_idx; unsigned int idle = 0; @@ -600,6 +604,21 @@ return idle; } +unsigned int +http_client_peer_pending_connections(struct http_client_peer *peer) +{ + struct http_client_connection *const *conn_idx; + unsigned int pending = 0; + + /* find idle connections */ + array_foreach(&peer->conns, conn_idx) { + if (!(*conn_idx)->closing && !(*conn_idx)->connected) + pending++; + } + + return pending; +} + void http_client_peer_switch_ioloop(struct http_client_peer *peer) { if (peer->to_req_handling != NULL) { diff -r adcf35ac5432 -r 548cb71d63da src/lib-http/http-client-private.h --- a/src/lib-http/http-client-private.h Wed Oct 01 10:33:39 2014 +0300 +++ b/src/lib-http/http-client-private.h Wed Oct 01 10:33:49 2014 +0300 @@ -308,7 +308,10 @@ const char *reason); void http_client_peer_connection_lost(struct http_client_peer *peer); bool http_client_peer_is_connected(struct http_client_peer *peer); -unsigned int http_client_peer_idle_connections(struct http_client_peer *peer); +unsigned int +http_client_peer_idle_connections(struct http_client_peer *peer); +unsigned int +http_client_peer_pending_connections(struct http_client_peer *peer); void http_client_peer_switch_ioloop(struct http_client_peer *peer); struct http_client_queue * From dovecot at dovecot.org Thu Oct 2 09:32:14 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 02 Oct 2014 09:32:14 +0000 Subject: dovecot-2.2: doveadm backup: Locally expunged mails weren't alwa... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c02918434721 changeset: 17859:c02918434721 user: Timo Sirainen date: Thu Oct 02 12:31:34 2014 +0300 description: doveadm backup: Locally expunged mails weren't always added back. diffstat: src/doveadm/dsync/dsync-mailbox-import.c | 42 ++++++++++++++++++++++++++++--- 1 files changed, 37 insertions(+), 5 deletions(-) diffs (80 lines): diff -r 548cb71d63da -r c02918434721 src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Wed Oct 01 10:33:49 2014 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Thu Oct 02 12:31:34 2014 +0300 @@ -104,6 +104,7 @@ unsigned int revert_local_changes:1; unsigned int mails_have_guids:1; unsigned int mails_use_guid128:1; + unsigned int delete_mailbox:1; }; static void dsync_mailbox_save_newmails(struct dsync_mailbox_importer *importer, @@ -1376,6 +1377,22 @@ } static void +dsync_mailbox_revert_missing(struct dsync_mailbox_importer *importer, + const struct dsync_mail_change *change) +{ + i_assert(importer->revert_local_changes); + + /* mail exists on remote, but not locally. we'll need to + insert this mail back, which means deleting the whole + mailbox and resyncing. */ + imp_debug(importer, "Deleting mailbox '%s': UID=%u GUID=%s is missing locally", + mailbox_get_vname(importer->box), + change->uid, change->guid); + importer->delete_mailbox = TRUE; + importer->failed = TRUE; +} + +static void dsync_mailbox_find_common_uid(struct dsync_mailbox_importer *importer, const struct dsync_mail_change *change) { @@ -1390,8 +1407,10 @@ looking it up locally. */ return; } - if (change->guid == NULL || - !dsync_mailbox_find_common_expunged_uid(importer, change)) { + if (importer->revert_local_changes) + dsync_mailbox_revert_missing(importer, change); + else if (change->guid == NULL || + !dsync_mailbox_find_common_expunged_uid(importer, change)) { /* couldn't match it for an expunged mail. use the last message with a matching GUID as the last common UID. */ @@ -1419,7 +1438,10 @@ } return; } - dsync_mailbox_find_common_expunged_uid(importer, change); + if (importer->revert_local_changes) + dsync_mailbox_revert_missing(importer, change); + else + dsync_mailbox_find_common_expunged_uid(importer, change); } int dsync_mailbox_import_change(struct dsync_mailbox_importer *importer, @@ -2427,8 +2449,18 @@ *last_common_modseq_r = importer->local_initial_highestmodseq; *last_common_pvt_modseq_r = importer->local_initial_highestpvtmodseq; } - mailbox_get_open_status(importer->box, STATUS_MESSAGES, &status); - *last_messages_count_r = status.messages; + if (importer->delete_mailbox) { + if (mailbox_delete(importer->box) < 0) { + i_error("Couldn't delete mailbox %s: %s", + mailbox_get_vname(importer->box), + mailbox_get_last_error(importer->box, NULL)); + importer->failed = TRUE; + } + *last_messages_count_r = 0; + } else { + mailbox_get_open_status(importer->box, STATUS_MESSAGES, &status); + *last_messages_count_r = status.messages; + } ret = importer->failed ? -1 : 0; pool_unref(&importer->pool); From dovecot at dovecot.org Thu Oct 2 09:48:51 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 02 Oct 2014 09:48:51 +0000 Subject: dovecot-2.2: doveadm backup: Fix to earlier commit - don't try t... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8aea6edb29d3 changeset: 17860:8aea6edb29d3 user: Timo Sirainen date: Thu Oct 02 12:48:00 2014 +0300 description: doveadm backup: Fix to earlier commit - don't try to delete an already empty mailbox. diffstat: src/doveadm/dsync/dsync-mailbox-import.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r c02918434721 -r 8aea6edb29d3 src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Thu Oct 02 12:31:34 2014 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Thu Oct 02 12:48:00 2014 +0300 @@ -1407,7 +1407,8 @@ looking it up locally. */ return; } - if (importer->revert_local_changes) + if (importer->revert_local_changes && + importer->local_uid_next > 1) dsync_mailbox_revert_missing(importer, change); else if (change->guid == NULL || !dsync_mailbox_find_common_expunged_uid(importer, change)) { From dovecot at dovecot.org Thu Oct 2 09:57:28 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 02 Oct 2014 09:57:28 +0000 Subject: dovecot-2.2: dsync: Added more debug logging. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0b4352d6dfdb changeset: 17861:0b4352d6dfdb user: Timo Sirainen date: Thu Oct 02 12:56:30 2014 +0300 description: dsync: Added more debug logging. diffstat: src/doveadm/dsync/dsync-mailbox-import.c | 66 ++++++++++++++++++++++++------- 1 files changed, 51 insertions(+), 15 deletions(-) diffs (145 lines): diff -r 8aea6edb29d3 -r 0b4352d6dfdb src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Thu Oct 02 12:48:00 2014 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Thu Oct 02 12:56:30 2014 +0300 @@ -1278,7 +1278,13 @@ unsigned int n, i, count; uint32_t uid; - imp_debug(importer, "Last common UID=%u", importer->last_common_uid); + if (importer->debug) T_BEGIN { + string_t *expunges = t_str_new(64); + + imap_write_seq_range(expunges, &importer->maybe_expunge_uids); + imp_debug(importer, "Last common UID=%u. Delayed expunges=%s", + importer->last_common_uid, str_c(expunges)); + } T_END; importer->last_common_uid_found = TRUE; dsync_mailbox_rewind_search(importer); @@ -1299,8 +1305,14 @@ /* handle pending saves */ saves = array_get(&importer->maybe_saves, &count); for (i = 0; i < count; i++) { - if (saves[i]->uid > importer->last_common_uid) + if (saves[i]->uid > importer->last_common_uid) { + imp_debug(importer, "Delayed save UID=%u: Save", + saves[i]->uid); dsync_mailbox_save(importer, saves[i]); + } else { + imp_debug(importer, "Delayed save UID=%u: Ignore", + saves[i]->uid); + } } } @@ -1394,7 +1406,8 @@ static void dsync_mailbox_find_common_uid(struct dsync_mailbox_importer *importer, - const struct dsync_mail_change *change) + const struct dsync_mail_change *change, + const char **result_r) { int ret; @@ -1405,23 +1418,30 @@ if (change->type == DSYNC_MAIL_CHANGE_TYPE_EXPUNGE) { /* mail doesn't exist remotely either, don't bother looking it up locally. */ + *result_r = "Expunged mail not found locally"; return; } if (importer->revert_local_changes && - importer->local_uid_next > 1) + importer->local_uid_next > 1) { dsync_mailbox_revert_missing(importer, change); - else if (change->guid == NULL || + *result_r = "Reverting local change by deleting mailbox"; + } else if (change->guid == NULL || !dsync_mailbox_find_common_expunged_uid(importer, change)) { /* couldn't match it for an expunged mail. use the last message with a matching GUID as the last common UID. */ dsync_mailbox_common_uid_found(importer); + *result_r = "No more local mails found"; + } else { + *result_r = "Mail expunged locally"; } return; } if (change->guid == NULL) { /* we can't know if this UID matches */ + i_assert(change->type == DSYNC_MAIL_CHANGE_TYPE_EXPUNGE); + *result_r = "Expunged mail has no GUID, can't verify it"; return; } if (importer->cur_mail->uid == change->uid) { @@ -1429,25 +1449,36 @@ really the same mail or not */ if ((ret = dsync_mailbox_import_match_msg(importer, change)) < 0) { /* unknown */ + *result_r = "Error while verifying mail GUID"; return; } if (ret == 0) { /* mismatch - found the first non-common UID */ dsync_mailbox_common_uid_found(importer); + *result_r = "Mail GUID mismatch"; } else { importer->last_common_uid = change->uid; + *result_r = "Mail exists locally"; } return; } - if (importer->revert_local_changes) + if (importer->revert_local_changes) { dsync_mailbox_revert_missing(importer, change); - else - dsync_mailbox_find_common_expunged_uid(importer, change); + *result_r = "Reverting local change by deleting mailbox"; + } else if (dsync_mailbox_find_common_expunged_uid(importer, change)) { + *result_r = "Mail expunged locally"; + } else { + *result_r = "Mail not found locally"; + } + *result_r = t_strdup_printf("%s (next local mail UID=%u)", + *result_r, importer->cur_mail->uid); } int dsync_mailbox_import_change(struct dsync_mailbox_importer *importer, const struct dsync_mail_change *change) { + const char *result; + i_assert(!importer->new_uids_assigned); i_assert(importer->prev_uid < change->uid); @@ -1456,15 +1487,20 @@ if (importer->failed) return -1; - imp_debug(importer, "Import change GUID=%s UID=%u hdr_hash=%s", + if (!importer->last_common_uid_found) { + result = NULL; + dsync_mailbox_find_common_uid(importer, change, &result); + i_assert(result != NULL); + } else { + result = "New mail"; + } + + imp_debug(importer, "Import change GUID=%s UID=%u hdr_hash=%s result=%s", change->guid != NULL ? change->guid : "", change->uid, - change->hdr_hash != NULL ? change->hdr_hash : ""); + change->hdr_hash != NULL ? change->hdr_hash : "", result); - if (!importer->last_common_uid_found) { - dsync_mailbox_find_common_uid(importer, change); - if (importer->failed) - return -1; - } + if (importer->failed) + return -1; if (importer->last_common_uid_found) { /* a) uid <= last_common_uid for flag changes and expunges. From dovecot at dovecot.org Thu Oct 2 10:15:50 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 02 Oct 2014 10:15:50 +0000 Subject: dovecot-2.2: dsync: Improved debug logging. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c3ef6f19d518 changeset: 17862:c3ef6f19d518 user: Timo Sirainen date: Thu Oct 02 13:15:22 2014 +0300 description: dsync: Improved debug logging. diffstat: src/doveadm/dsync/dsync-mailbox-import.c | 30 +++++++++++++++++++++--------- 1 files changed, 21 insertions(+), 9 deletions(-) diffs (82 lines): diff -r 0b4352d6dfdb -r c3ef6f19d518 src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Thu Oct 02 12:56:30 2014 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Thu Oct 02 13:15:22 2014 +0300 @@ -1318,17 +1318,22 @@ static int dsync_mailbox_import_match_msg(struct dsync_mailbox_importer *importer, - const struct dsync_mail_change *change) + const struct dsync_mail_change *change, + const char **result_r) { - const char *hdr_hash; + const char *hdr_hash, *cmp_guid; if (*change->guid != '\0' && *importer->cur_guid != '\0') { /* we have GUIDs, verify them */ if (dsync_mail_change_guid_equals(importer, change, - importer->cur_guid, NULL)) + importer->cur_guid, &cmp_guid)) { + *result_r = "GUIDs match"; return 1; - else + } else { + *result_r = t_strdup_printf("GUIDs don't match (%s vs %s)", + change->guid, cmp_guid); return 0; + } } /* verify hdr_hash if it exists */ @@ -1337,20 +1342,30 @@ if (change->type == DSYNC_MAIL_CHANGE_TYPE_EXPUNGE) { /* the message was already expunged, so we don't know its header. return "unknown". */ + *result_r = "Unknown match for expunge"; return -1; } i_error("Mailbox %s: GUIDs not supported, " "sync with header hashes instead", mailbox_get_vname(importer->box)); importer->failed = TRUE; + *result_r = "Error, invalid parameters"; return -1; } if (dsync_mail_get_hdr_hash(importer->cur_mail, &hdr_hash) < 0) { dsync_mail_error(importer, importer->cur_mail, "hdr-stream"); + *result_r = "Error fetching header stream"; return -1; } - return strcmp(change->hdr_hash, hdr_hash) == 0 ? 1 : 0; + if (strcmp(change->hdr_hash, hdr_hash) == 0) { + *result_r = "Headers hashes match"; + return 1; + } else { + *result_r = t_strdup_printf("Headers hashes don't match (%s vs %s)", + change->hdr_hash, hdr_hash); + return 0; + } } static bool @@ -1447,18 +1462,15 @@ if (importer->cur_mail->uid == change->uid) { /* we have a matching local UID. check GUID to see if it's really the same mail or not */ - if ((ret = dsync_mailbox_import_match_msg(importer, change)) < 0) { + if ((ret = dsync_mailbox_import_match_msg(importer, change, result_r)) < 0) { /* unknown */ - *result_r = "Error while verifying mail GUID"; return; } if (ret == 0) { /* mismatch - found the first non-common UID */ dsync_mailbox_common_uid_found(importer); - *result_r = "Mail GUID mismatch"; } else { importer->last_common_uid = change->uid; - *result_r = "Mail exists locally"; } return; } From dovecot at dovecot.org Thu Oct 2 16:43:54 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 02 Oct 2014 16:43:54 +0000 Subject: dovecot-2.2: lib-storage: Added %{session} to mail_user_var_expa... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ddde8c6a5b70 changeset: 17863:ddde8c6a5b70 user: Timo Sirainen date: Thu Oct 02 19:43:09 2014 +0300 description: lib-storage: Added %{session} to mail_user_var_expand_table() diffstat: src/lib-storage/mail-user.c | 14 ++++++++------ 1 files changed, 8 insertions(+), 6 deletions(-) diffs (33 lines): diff -r c3ef6f19d518 -r ddde8c6a5b70 src/lib-storage/mail-user.c --- a/src/lib-storage/mail-user.c Thu Oct 02 13:15:22 2014 +0300 +++ b/src/lib-storage/mail-user.c Thu Oct 02 19:43:09 2014 +0300 @@ -207,6 +207,7 @@ { 'p', NULL, "pid" }, { 'i', NULL, "uid" }, { '\0', NULL, "gid" }, + { '\0', NULL, "session" }, { '\0', NULL, "auth_user" }, { '\0', NULL, "auth_username" }, { '\0', NULL, "auth_domain" }, @@ -235,14 +236,15 @@ tab[7].value = my_pid; tab[8].value = p_strdup(user->pool, dec2str(user->uid)); tab[9].value = p_strdup(user->pool, dec2str(user->gid)); + tab[10].value = user->session_id; if (user->auth_user == NULL) { - tab[10].value = tab[0].value; - tab[11].value = tab[1].value; - tab[12].value = tab[2].value; + tab[11].value = tab[0].value; + tab[12].value = tab[1].value; + tab[13].value = tab[2].value; } else { - tab[10].value = user->auth_user; - tab[11].value = t_strcut(user->auth_user, '@'); - tab[12].value = strchr(user->auth_user, '@'); + tab[11].value = user->auth_user; + tab[12].value = t_strcut(user->auth_user, '@'); + tab[13].value = strchr(user->auth_user, '@'); } user->var_expand_table = tab; From dovecot at dovecot.org Thu Oct 2 16:43:54 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 02 Oct 2014 16:43:54 +0000 Subject: dovecot-2.2: dsync: Debug message fix Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/01ba94a2d4c5 changeset: 17864:01ba94a2d4c5 user: Timo Sirainen date: Thu Oct 02 19:43:25 2014 +0300 description: dsync: Debug message fix diffstat: src/doveadm/dsync/dsync-mailbox-import.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r ddde8c6a5b70 -r 01ba94a2d4c5 src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Thu Oct 02 19:43:09 2014 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Thu Oct 02 19:43:25 2014 +0300 @@ -1331,7 +1331,7 @@ return 1; } else { *result_r = t_strdup_printf("GUIDs don't match (%s vs %s)", - change->guid, cmp_guid); + importer->cur_guid, cmp_guid); return 0; } } From dovecot at dovecot.org Fri Oct 3 13:04:57 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 03 Oct 2014 13:04:57 +0000 Subject: dovecot-2.2: master: If log process crashes, restart it immediat... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/026cf7ee272c changeset: 17865:026cf7ee272c user: Timo Sirainen date: Fri Oct 03 16:04:06 2014 +0300 description: master: If log process crashes, restart it immediately. The regular service_monitor_listen_start() doesn't work for it, because the log fds aren't in the listeners. diffstat: src/master/service-monitor.c | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-) diffs (21 lines): diff -r 01ba94a2d4c5 -r 026cf7ee272c src/master/service-monitor.c --- a/src/master/service-monitor.c Thu Oct 02 19:43:25 2014 +0300 +++ b/src/master/service-monitor.c Fri Oct 03 16:04:06 2014 +0300 @@ -656,8 +656,16 @@ service_monitor_start_extra_avail(service); /* if there are no longer listening processes, start listening for more */ - if (service->to_throttle == NULL) + if (service->to_throttle != NULL) { + /* throttling */ + } else if (service == service->list->log && + service->process_count == 0) { + /* log service must always be running */ + if (service_process_create(service) == NULL) + service_monitor_throttle(service); + } else { service_monitor_listen_start(service); + } } service_list_unref(service->list); } From dovecot at dovecot.org Fri Oct 3 13:32:04 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 03 Oct 2014 13:32:04 +0000 Subject: dovecot-2.2: lib-lda, lmtp: Separate internal errors from remote... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f21d82a32ca8 changeset: 17866:f21d82a32ca8 user: Timo Sirainen date: Fri Oct 03 16:31:33 2014 +0300 description: lib-lda, lmtp: Separate internal errors from remote errors. LMTP proxy shouldn't log remote errors with error level, because the proxy itself didn't have any failure. This is an API change, but I'm not aware of any plugins actually using the lmtp-client.h directly. diffstat: src/lib-lda/lmtp-client.c | 51 +++++++++++++++++++++++++++++++++++----------- src/lib-lda/lmtp-client.h | 15 +++++++++++- src/lib-lda/smtp-client.c | 8 +++--- src/lmtp/lmtp-proxy.c | 29 +++++++++++++++++++------- 4 files changed, 77 insertions(+), 26 deletions(-) diffs (277 lines): diff -r 026cf7ee272c -r f21d82a32ca8 src/lib-lda/lmtp-client.c --- a/src/lib-lda/lmtp-client.c Fri Oct 03 16:04:06 2014 +0300 +++ b/src/lib-lda/lmtp-client.c Fri Oct 03 16:31:33 2014 +0300 @@ -74,6 +74,7 @@ unsigned int rcpt_to_successes:1; unsigned int output_finished:1; unsigned int finish_called:1; + unsigned int global_remote_failure:1; }; static void lmtp_client_send_rcpts(struct lmtp_client *client); @@ -198,17 +199,22 @@ return "??"; } -void lmtp_client_fail(struct lmtp_client *client, const char *line) +static void +lmtp_client_fail_full(struct lmtp_client *client, const char *line, bool remote) { + enum lmtp_client_result result; struct lmtp_rcpt *recipients; unsigned int i, count; client->global_fail_string = p_strdup(client->pool, line); + client->global_remote_failure = remote; + result = remote ? LMTP_CLIENT_RESULT_REMOTE_ERROR : + LMTP_CLIENT_RESULT_INTERNAL_ERROR; lmtp_client_ref(client); recipients = array_get_modifiable(&client->recipients, &count); for (i = client->rcpt_next_receive_idx; i < count; i++) { - recipients[i].rcpt_to_callback(FALSE, line, + recipients[i].rcpt_to_callback(result, line, recipients[i].context); recipients[i].failed = TRUE; } @@ -216,7 +222,7 @@ for (i = client->rcpt_next_data_idx; i < count; i++) { if (!recipients[i].failed) { - recipients[i].data_callback(FALSE, line, + recipients[i].data_callback(result, line, recipients[i].context); } } @@ -227,21 +233,33 @@ } static void +lmtp_client_fail_remote(struct lmtp_client *client, const char *line) +{ + lmtp_client_fail_full(client, line, TRUE); +} + +void lmtp_client_fail(struct lmtp_client *client, const char *line) +{ + lmtp_client_fail_full(client, line, FALSE); +} + +static void lmtp_client_rcpt_next(struct lmtp_client *client, const char *line) { struct lmtp_rcpt *rcpt; - bool success; + enum lmtp_client_result result; - success = line[0] == '2'; - if (success) + result = line[0] == '2' ? LMTP_CLIENT_RESULT_OK : + LMTP_CLIENT_RESULT_REMOTE_ERROR; + if (result == LMTP_CLIENT_RESULT_OK) client->rcpt_to_successes = TRUE; rcpt = array_idx_modifiable(&client->recipients, client->rcpt_next_receive_idx); client->rcpt_next_receive_idx++; - rcpt->failed = !success; - rcpt->rcpt_to_callback(success, line, rcpt->context); + rcpt->failed = result != LMTP_CLIENT_RESULT_OK; + rcpt->rcpt_to_callback(result, line, rcpt->context); } static int lmtp_client_send_data_cmd(struct lmtp_client *client) @@ -250,7 +268,8 @@ return 0; if (client->global_fail_string != NULL || !client->rcpt_to_successes) { - lmtp_client_fail(client, client->global_fail_string); + lmtp_client_fail_full(client, client->global_fail_string, + client->global_remote_failure); return -1; } else { client->input_state++; @@ -264,6 +283,7 @@ { struct lmtp_rcpt *rcpt; unsigned int i, count; + enum lmtp_client_result result; rcpt = array_get_modifiable(&client->recipients, &count); for (i = client->rcpt_next_data_idx; i < count; i++) { @@ -274,7 +294,9 @@ client->rcpt_next_data_idx = i + 1; rcpt[i].failed = line[0] != '2'; - rcpt[i].data_callback(!rcpt[i].failed, line, rcpt[i].context); + result = rcpt[i].failed ? LMTP_CLIENT_RESULT_REMOTE_ERROR : + LMTP_CLIENT_RESULT_OK; + rcpt[i].data_callback(result, line, rcpt[i].context); if (client->protocol == LMTP_CLIENT_PROTOCOL_LMTP) break; } @@ -529,7 +551,7 @@ case LMTP_INPUT_STATE_DATA_CONTINUE: /* Start sending DATA */ if (strncmp(line, "354", 3) != 0) { - lmtp_client_fail(client, line); + lmtp_client_fail_remote(client, line); return -1; } client->input_state++; @@ -728,6 +750,7 @@ lmtp_callback_t *data_callback, void *context) { struct lmtp_rcpt *rcpt; + enum lmtp_client_result result; rcpt = array_append_space(&client->recipients); rcpt->address = p_strdup(client->pool, address); @@ -736,12 +759,16 @@ rcpt->context = context; if (client->global_fail_string != NULL) { + /* we've already failed */ client->rcpt_next_receive_idx++; i_assert(client->rcpt_next_receive_idx == array_count(&client->recipients)); + result = client->global_remote_failure ? + LMTP_CLIENT_RESULT_REMOTE_ERROR : + LMTP_CLIENT_RESULT_INTERNAL_ERROR; rcpt->failed = TRUE; - rcpt_to_callback(FALSE, client->global_fail_string, context); + rcpt_to_callback(result, client->global_fail_string, context); } else if (client->input_state == LMTP_INPUT_STATE_RCPT_TO) lmtp_client_send_rcpts(client); } diff -r 026cf7ee272c -r f21d82a32ca8 src/lib-lda/lmtp-client.h --- a/src/lib-lda/lmtp-client.h Fri Oct 03 16:04:06 2014 +0300 +++ b/src/lib-lda/lmtp-client.h Fri Oct 03 16:31:33 2014 +0300 @@ -12,6 +12,16 @@ LMTP_CLIENT_PROTOCOL_SMTP }; +enum lmtp_client_result { + /* Command succeeded */ + LMTP_CLIENT_RESULT_OK = 1, + /* Command failed because remote server returned an error */ + LMTP_CLIENT_RESULT_REMOTE_ERROR = 0, + /* Command failed because of an internal error (e.g. couldn't connect + to remote) */ + LMTP_CLIENT_RESULT_INTERNAL_ERROR = -1 +}; + struct lmtp_client_settings { const char *my_hostname; const char *mail_from; @@ -31,7 +41,8 @@ /* reply contains the reply coming from remote server, or NULL if it's a connection error. */ -typedef void lmtp_callback_t(bool success, const char *reply, void *context); +typedef void lmtp_callback_t(enum lmtp_client_result result, + const char *reply, void *context); /* called when session is finished, either because all RCPT TOs failed or because all DATA replies have been received. */ typedef void lmtp_finish_callback_t(void *context); @@ -61,7 +72,7 @@ This is useful with non-blocking istreams and tee-istreams. */ void lmtp_client_send_more(struct lmtp_client *client); /* Fail the connection with line as the reply to unfinished RCPT TO/DATA - replies. */ + replies. This will be treated as an internal failure. */ void lmtp_client_fail(struct lmtp_client *client, const char *line); /* Return the state (command reply) the client is currently waiting for. */ const char *lmtp_client_state_to_string(struct lmtp_client *client); diff -r 026cf7ee272c -r f21d82a32ca8 src/lib-lda/smtp-client.c --- a/src/lib-lda/smtp-client.c Fri Oct 03 16:04:06 2014 +0300 +++ b/src/lib-lda/smtp-client.c Fri Oct 03 16:31:33 2014 +0300 @@ -217,11 +217,11 @@ } static void -rcpt_to_callback(bool success, const char *reply, void *context) +rcpt_to_callback(enum lmtp_client_result result, const char *reply, void *context) { struct smtp_client *smtp_client = context; - if (!success) { + if (result != LMTP_CLIENT_RESULT_OK) { if (reply[0] != '5') smtp_client->tempfail = TRUE; smtp_client_error(smtp_client, t_strdup_printf( @@ -231,11 +231,11 @@ } static void -data_callback(bool success, const char *reply, void *context) +data_callback(enum lmtp_client_result result, const char *reply, void *context) { struct smtp_client *smtp_client = context; - if (!success) { + if (result != LMTP_CLIENT_RESULT_OK) { if (reply[0] != '5') smtp_client->tempfail = TRUE; smtp_client_error(smtp_client, t_strdup_printf( diff -r 026cf7ee272c -r f21d82a32ca8 src/lmtp/lmtp-proxy.c --- a/src/lmtp/lmtp-proxy.c Fri Oct 03 16:04:06 2014 +0300 +++ b/src/lmtp/lmtp-proxy.c Fri Oct 03 16:31:33 2014 +0300 @@ -220,7 +220,8 @@ } static void -lmtp_proxy_conn_rcpt_to(bool success, const char *reply, void *context) +lmtp_proxy_conn_rcpt_to(enum lmtp_client_result result, + const char *reply, void *context) { struct lmtp_proxy_recipient *rcpt = context; struct lmtp_proxy_connection *conn = rcpt->conn; @@ -228,11 +229,12 @@ i_assert(rcpt->reply == NULL); rcpt->reply = p_strdup(conn->proxy->pool, reply); - rcpt->rcpt_to_failed = !success; + rcpt->rcpt_to_failed = result != LMTP_CLIENT_RESULT_OK; } static void -lmtp_proxy_conn_data(bool success, const char *reply, void *context) +lmtp_proxy_conn_data(enum lmtp_client_result result, + const char *reply, void *context) { struct lmtp_proxy_recipient *rcpt = context; struct lmtp_proxy_connection *conn = rcpt->conn; @@ -247,14 +249,25 @@ rcpt->reply = p_strdup(conn->proxy->pool, reply); rcpt->data_reply_received = TRUE; - if (!success) { + switch (result) { + case LMTP_CLIENT_RESULT_OK: + 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); + break; + case LMTP_CLIENT_RESULT_REMOTE_ERROR: + /* the problem isn't with the proxy, it's with the remote side. + so the remote side will log an error, while for us this is + just an info event */ + i_info("%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); + break; + case LMTP_CLIENT_RESULT_INTERNAL_ERROR: 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); + break; } lmtp_proxy_try_finish(conn->proxy); From dovecot at dovecot.org Fri Oct 3 13:58:10 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 03 Oct 2014 13:58:10 +0000 Subject: dovecot-2.2: fs-posix: Added prefix parameter that is prefixed t... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/554b021d6a3f changeset: 17867:554b021d6a3f user: Timo Sirainen date: Fri Oct 03 16:57:39 2014 +0300 description: fs-posix: Added prefix parameter that is prefixed to all paths. diffstat: src/lib-fs/fs-posix.c | 109 +++++++++++++++++++++++++++++-------------------- 1 files changed, 64 insertions(+), 45 deletions(-) diffs (truncated from 357 to 300 lines): diff -r f21d82a32ca8 -r 554b021d6a3f src/lib-fs/fs-posix.c --- a/src/lib-fs/fs-posix.c Fri Oct 03 16:31:33 2014 +0300 +++ b/src/lib-fs/fs-posix.c Fri Oct 03 16:57:39 2014 +0300 @@ -31,14 +31,14 @@ struct posix_fs { struct fs fs; - char *temp_file_prefix, *root_path; + char *temp_file_prefix, *root_path, *path_prefix; enum fs_posix_lock_method lock_method; mode_t mode, dir_mode; }; struct posix_fs_file { struct fs_file file; - char *temp_path; + char *temp_path, *full_path; int fd; enum fs_open_mode open_mode; enum fs_open_flags open_flags; @@ -95,7 +95,14 @@ fs->lock_method = FS_POSIX_LOCK_METHOD_FLOCK; else if (strcmp(arg, "lock=dotlock") == 0) fs->lock_method = FS_POSIX_LOCK_METHOD_DOTLOCK; - else if (strncmp(arg, "mode=", 5) == 0) { + else if (strncmp(arg, "prefix=", 7) == 0) { + unsigned int len = strlen(arg + 7); + i_free(fs->path_prefix); + if (len > 0 && arg[7+len-1] != '/') + fs->path_prefix = i_strconcat(arg + 7, "/", NULL); + else + fs->path_prefix = i_strdup(arg + 7); + } else if (strncmp(arg, "mode=", 5) == 0) { fs->mode = strtoul(arg+5, NULL, 8) & 0666; if (fs->mode == 0) { fs_set_error(_fs, "Invalid mode: %s", arg+5); @@ -119,6 +126,7 @@ i_free(fs->temp_file_prefix); i_free(fs->root_path); + i_free(fs->path_prefix); i_free(fs); } @@ -183,8 +191,8 @@ i_assert(file->temp_path == NULL); - if ((slash = strrchr(file->file.path, '/')) != NULL) - str_append_n(str, file->file.path, slash - file->file.path + 1); + if ((slash = strrchr(file->full_path, '/')) != NULL) + str_append_n(str, file->full_path, slash - file->full_path + 1); str_append(str, fs->temp_file_prefix); fd = safe_mkstemp_hostpid(str, fs->mode, (uid_t)-1, (gid_t)-1); @@ -206,7 +214,7 @@ static int fs_posix_open(struct posix_fs_file *file) { struct posix_fs *fs = (struct posix_fs *)file->file.fs; - const char *path = file->file.path; + const char *path = file->full_path; i_assert(file->fd == -1); @@ -238,6 +246,7 @@ fs_posix_file_init(struct fs *_fs, const char *path, enum fs_open_mode mode, enum fs_open_flags flags) { + struct posix_fs *fs = (struct posix_fs *)_fs; struct posix_fs_file *file; guid_128_t guid; @@ -250,6 +259,8 @@ file->file.path = i_strdup_printf("%s/%s", path, guid_128_to_string(guid)); } + file->full_path = fs->path_prefix == NULL ? i_strdup(file->file.path) : + i_strconcat(fs->path_prefix, file->file.path, NULL); file->open_mode = mode; file->open_flags = flags; file->fd = -1; @@ -263,7 +274,7 @@ if (file->fd != -1 && file->file.output == NULL) { if (close(file->fd) < 0) { fs_set_critical(file->file.fs, "close(%s) failed: %m", - file->file.path); + file->full_path); } file->fd = -1; } @@ -293,6 +304,7 @@ } i_free(file->temp_path); + i_free(file->full_path); i_free(file->file.path); i_free(file); } @@ -309,7 +321,7 @@ /* HAVE_POSIX_FADVISE alone isn't enough for CentOS 4.9 */ #if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED) if (posix_fadvise(file->fd, 0, length, POSIX_FADV_WILLNEED) < 0) { - i_error("posix_fadvise(%s) failed: %m", _file->path); + i_error("posix_fadvise(%s) failed: %m", file->full_path); return TRUE; } #endif @@ -330,14 +342,14 @@ file->seek_to_beginning = FALSE; if (lseek(file->fd, 0, SEEK_SET) < 0) { fs_set_critical(_file->fs, "lseek(%s, 0) failed: %m", - _file->path); + file->full_path); return -1; } } ret = read(file->fd, buf, size); if (ret < 0) - fs_set_error(_file->fs, "read(%s) failed: %m", _file->path); + fs_set_error(_file->fs, "read(%s) failed: %m", file->full_path); fs_posix_file_close(_file); return ret; } @@ -354,7 +366,7 @@ /* the stream could live even after the fs_file */ input = i_stream_create_fd_autoclose(&file->fd, max_buffer_size); } - i_stream_set_name(input, _file->path); + i_stream_set_name(input, file->full_path); return input; } @@ -365,7 +377,7 @@ if ((file->open_flags & FS_OPEN_FLAG_FSYNC) != 0) { if (fdatasync(file->fd) < 0) { fs_set_error(file->file.fs, "fdatasync(%s) failed: %m", - file->file.path); + file->full_path); return -1; } } @@ -373,7 +385,7 @@ if (close(file->fd) < 0) { file->fd = -1; fs_set_error(file->file.fs, "close(%s) failed: %m", - file->file.path); + file->full_path); return -1; } file->fd = -1; @@ -381,9 +393,9 @@ switch (file->open_mode) { case FS_OPEN_MODE_CREATE_UNIQUE_128: case FS_OPEN_MODE_CREATE: - if ((ret = link(file->temp_path, file->file.path)) < 0) { + if ((ret = link(file->temp_path, file->full_path)) < 0) { fs_set_error(file->file.fs, "link(%s, %s) failed: %m", - file->temp_path, file->file.path); + file->temp_path, file->full_path); } if (unlink(file->temp_path) < 0) { fs_set_error(file->file.fs, "unlink(%s) failed: %m", @@ -393,9 +405,9 @@ return -1; break; case FS_OPEN_MODE_REPLACE: - if (rename(file->temp_path, file->file.path) < 0) { + if (rename(file->temp_path, file->full_path) < 0) { fs_set_error(file->file.fs, "rename(%s, %s) failed: %m", - file->temp_path, file->file.path); + file->temp_path, file->full_path); return -1; } break; @@ -423,7 +435,7 @@ if (file->open_mode != FS_OPEN_MODE_APPEND) { if (write_full(file->fd, data, size) < 0) { fs_set_error(_file->fs, "write(%s) failed: %m", - _file->path); + file->full_path); return -1; } return fs_posix_write_finish(file); @@ -432,13 +444,13 @@ /* atomic append - it should either succeed or fail */ ret = write(file->fd, data, size); if (ret < 0) { - fs_set_error(_file->fs, "write(%s) failed: %m", _file->path); + fs_set_error(_file->fs, "write(%s) failed: %m", file->full_path); return -1; } if ((size_t)ret != size) { fs_set_error(_file->fs, "write(%s) returned %"PRIuSIZE_T"/%"PRIuSIZE_T, - _file->path, (size_t)ret, size); + file->full_path, (size_t)ret, size); errno = ENOSPC; return -1; } @@ -462,7 +474,7 @@ _file->output = o_stream_create_fd_file(file->fd, (uoff_t)-1, FALSE); } - o_stream_set_name(_file->output, _file->path); + o_stream_set_name(_file->output, file->full_path); } static int fs_posix_write_stream_finish(struct fs_file *_file, bool success) @@ -518,20 +530,20 @@ case FS_POSIX_LOCK_METHOD_FLOCK: #ifndef HAVE_FLOCK fs_set_error(_file->fs, "flock() not supported by OS " - "(for file %s)", _file->path); + "(for file %s)", file->full_path); #else if (secs == 0) { - ret = file_try_lock(file->fd, _file->path, F_WRLCK, + ret = file_try_lock(file->fd, file->full_path, F_WRLCK, FILE_LOCK_METHOD_FLOCK, &fs_lock.file_lock); } else { - ret = file_wait_lock(file->fd, _file->path, F_WRLCK, + ret = file_wait_lock(file->fd, file->full_path, F_WRLCK, FILE_LOCK_METHOD_FLOCK, secs, &fs_lock.file_lock); } if (ret < 0) { fs_set_error(_file->fs, "flock(%s) failed: %m", - _file->path); + file->full_path); } #endif break; @@ -541,14 +553,14 @@ dotlock_set.use_excl_lock = TRUE; dotlock_set.timeout = secs; - ret = file_dotlock_create(&dotlock_set, _file->path, + ret = file_dotlock_create(&dotlock_set, file->full_path, secs == 0 ? 0 : DOTLOCK_CREATE_FLAG_NONBLOCK, &fs_lock.dotlock); if (ret < 0) { fs_set_error(_file->fs, "file_dotlock_create(%s) failed: %m", - _file->path); + file->full_path); } break; } @@ -574,12 +586,13 @@ static int fs_posix_exists(struct fs_file *_file) { + struct posix_fs_file *file = (struct posix_fs_file *)_file; struct stat st; - if (stat(_file->path, &st) < 0) { + if (stat(file->full_path, &st) < 0) { if (errno != ENOENT) { fs_set_error(_file->fs, "stat(%s) failed: %m", - _file->path); + file->full_path); return -1; } return 0; @@ -589,8 +602,9 @@ static int fs_posix_stat(struct fs_file *_file, struct stat *st_r) { - if (stat(_file->path, st_r) < 0) { - fs_set_error(_file->fs, "stat(%s) failed: %m", _file->path); + struct posix_fs_file *file = (struct posix_fs_file *)_file; + if (stat(file->full_path, st_r) < 0) { + fs_set_error(_file->fs, "stat(%s) failed: %m", file->full_path); return -1; } return 0; @@ -621,20 +635,22 @@ static int fs_posix_rename(struct fs_file *_src, struct fs_file *_dest) { struct posix_fs *fs = (struct posix_fs *)_src->fs; + struct posix_fs_file *src = (struct posix_fs_file *)_src; + struct posix_fs_file *dest = (struct posix_fs_file *)_dest; unsigned int try_count = 0; int ret; - ret = rename(_src->path, _dest->path); + ret = rename(src->full_path, dest->full_path); while (ret < 0 && errno == ENOENT && try_count <= MAX_MKDIR_RETRY_COUNT) { - if (fs_posix_mkdir_parents(fs, _dest->path) < 0) + if (fs_posix_mkdir_parents(fs, dest->full_path) < 0) return -1; - ret = rename(_src->path, _dest->path); + ret = rename(src->full_path, dest->full_path); try_count++; } if (ret < 0) { From dovecot at dovecot.org Fri Oct 3 14:12:27 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 03 Oct 2014 14:12:27 +0000 Subject: dovecot-2.2: imap: GETMETADATA was returning mailbox name as UTF... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5446d1877c7e changeset: 17868:5446d1877c7e user: Timo Sirainen date: Fri Oct 03 17:11:58 2014 +0300 description: imap: GETMETADATA was returning mailbox name as UTF-8 instead of mUTF-7 diffstat: src/imap/cmd-getmetadata.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diffs (26 lines): diff -r 554b021d6a3f -r 5446d1877c7e src/imap/cmd-getmetadata.c --- a/src/imap/cmd-getmetadata.c Fri Oct 03 16:57:39 2014 +0300 +++ b/src/imap/cmd-getmetadata.c Fri Oct 03 17:11:58 2014 +0300 @@ -5,6 +5,7 @@ #include "istream.h" #include "ostream.h" #include "mailbox-list-iter.h" +#include "imap-utf7.h" #include "imap-quote.h" #include "imap-metadata.h" @@ -105,9 +106,13 @@ str = t_str_new(64); if (!ctx->first_entry_sent) { + string_t *mailbox_mutf7 = t_str_new(64); + ctx->first_entry_sent = TRUE; str_append(str, "* METADATA "); - imap_append_astring(str, mailbox_get_vname(ctx->box)); + if (imap_utf8_to_utf7(mailbox_get_vname(ctx->box), mailbox_mutf7) < 0) + i_unreached(); + imap_append_astring(str, str_c(mailbox_mutf7)); str_append(str, " ("); /* nothing can be sent until untagged METADATA is finished */ From dovecot at dovecot.org Fri Oct 3 14:36:41 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 03 Oct 2014 14:36:41 +0000 Subject: dovecot-2.2: example-config: Added ssl_options setting. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7c77918587bc changeset: 17869:7c77918587bc user: Timo Sirainen date: Fri Oct 03 17:36:11 2014 +0300 description: example-config: Added ssl_options setting. diffstat: doc/example-config/conf.d/10-ssl.conf | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 5446d1877c7e -r 7c77918587bc doc/example-config/conf.d/10-ssl.conf --- a/doc/example-config/conf.d/10-ssl.conf Fri Oct 03 17:11:58 2014 +0300 +++ b/doc/example-config/conf.d/10-ssl.conf Fri Oct 03 17:36:11 2014 +0300 @@ -56,3 +56,7 @@ # SSL crypto device to use, for valid values run "openssl engine" #ssl_crypto_device = + +# SSL extra options. Currently supported options are: +# no_compression - Disable compression. +#ssl_options = From dovecot at dovecot.org Fri Oct 3 19:40:32 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 03 Oct 2014 19:40:32 +0000 Subject: dovecot-2.2: Released v2.2.14.rc1. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/34e52cbeb837 changeset: 17870:34e52cbeb837 user: Timo Sirainen date: Fri Oct 03 18:18:41 2014 +0300 description: Released v2.2.14.rc1. diffstat: NEWS | 43 +++++++++++++++++++++++++++++++++++++++++++ configure.ac | 4 ++-- 2 files changed, 45 insertions(+), 2 deletions(-) diffs (64 lines): diff -r 7c77918587bc -r 34e52cbeb837 NEWS --- a/NEWS Fri Oct 03 17:36:11 2014 +0300 +++ b/NEWS Fri Oct 03 18:18:41 2014 +0300 @@ -1,3 +1,46 @@ +v2.2.14 2014-10-xx Timo Sirainen + + * lmtp: Delivered-To: header no longer contains <> around the email + address. Other MDAs don't have it either. + * "Out of disk space" errors are now treated as temporary errors + (not the same as "Out of disk quota"). + * replication plugin: Use replication only for users who have a + non-empty mail_replica setting. + + + lmtp proxy: Log a line about each mail delivery. + + Added login_source_ips setting. This can be used to set the source IP + address round-robin from a pool of IPs (in case you run out of TCP + ports). + + Rawlog settings can use tcp:: as the path. + + virtual plugin: Don't keep more than virtual_max_open_mailboxes + (default 64) number of backend mailboxes open. + + SSL/TLS compression can be disabled with ssl_options=no_compression + + acl: Global ACL file now supports "quotes" around patterns. + + Added last-login plugin to set user's last-login timestamp on login. + + LDAP auth: Allow passdb credentials lookup also with auth_bind=yes + - IMAP: MODSEQ was sent in FETCH reply even if CONDSTORE/QRESYNC wasn't + enabled. This broke at least old Outlooks. + - passdb static treated missing password field the same as an empty + password field. + - mdbox: Fixed potential infinite looping when scanning a broken + mdbox file. + - imap-login, pop3-login: Fixed potential crashes when client + disconnected unexpectedly. + - imap proxy: The connection was hanging in some usage patterns. This + mainly affected older Outlooks. + - lmtp proxy: The proxy sometimes delivered empty mails in error + situations or potentially delivered truncated mails. + - fts-lucene: If whitespace_chars was set, we may have ended up + indexing some garbage words, growing the index size unnecessarily. + - -c and -i parameters for dovecot/doveadm commands were ignored if + the config socket was readable. + - quota: Quota recalculation didn't include INBOX in some setups. + - Mail headers were sometimes added to dovecot.index.cache in wrong + order. The main problem this caused was with dsync+imapc incremental + syncing when the second sync thought the local mailbox had changed. + - doveadm backup didn't notice if emails were missing from the middle + of the destination mailbox. Now it deletes and resyncs the mailbox. + v2.2.13 2014-05-11 Timo Sirainen * Fixed a DoS attack against imap/pop3-login processes. If SSL/TLS diff -r 7c77918587bc -r 34e52cbeb837 configure.ac --- a/configure.ac Fri Oct 03 17:36:11 2014 +0300 +++ b/configure.ac Fri Oct 03 18:18:41 2014 +0300 @@ -2,8 +2,8 @@ # Be sure to update ABI version also if anything changes that might require # recompiling plugins. Most importantly that means if any structs are changed. -AC_INIT([Dovecot],[2.2.13],[dovecot at dovecot.org]) -AC_DEFINE_UNQUOTED([DOVECOT_ABI_VERSION], "2.2.ABIv13.2($PACKAGE_VERSION)", [Dovecot ABI version]) +AC_INIT([Dovecot],[2.2.14.rc1],[dovecot at dovecot.org]) +AC_DEFINE_UNQUOTED([DOVECOT_ABI_VERSION], "2.2.ABIv14($PACKAGE_VERSION)", [Dovecot ABI version]) AC_CONFIG_SRCDIR([src]) From dovecot at dovecot.org Fri Oct 3 19:40:32 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 03 Oct 2014 19:40:32 +0000 Subject: dovecot-2.2: Added tag 2.2.14.rc1 for changeset 34e52cbeb837 Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d1c95ddc5936 changeset: 17871:d1c95ddc5936 user: Timo Sirainen date: Fri Oct 03 18:18:41 2014 +0300 description: Added tag 2.2.14.rc1 for changeset 34e52cbeb837 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 34e52cbeb837 -r d1c95ddc5936 .hgtags --- a/.hgtags Fri Oct 03 18:18:41 2014 +0300 +++ b/.hgtags Fri Oct 03 18:18:41 2014 +0300 @@ -118,3 +118,4 @@ 8e4433702920216747e874d2914518de6748d05f 2.2.12 791ec610422cd2852cf51bd1842e90aa04d3ed20 2.2.13.rc1 c55c660d6e9dd0b433768c906c1462cf6e8d71d5 2.2.13 +34e52cbeb83725178c0c0a282ffa5ef1c161e3cb 2.2.14.rc1 From dovecot at dovecot.org Fri Oct 3 19:40:33 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 03 Oct 2014 19:40:33 +0000 Subject: dovecot-2.2: Added signature for changeset 34e52cbeb837 Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a7b885c94295 changeset: 17872:a7b885c94295 user: Timo Sirainen date: Fri Oct 03 18:18:44 2014 +0300 description: Added signature for changeset 34e52cbeb837 diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r d1c95ddc5936 -r a7b885c94295 .hgsigs --- a/.hgsigs Fri Oct 03 18:18:41 2014 +0300 +++ b/.hgsigs Fri Oct 03 18:18:44 2014 +0300 @@ -81,3 +81,4 @@ 8e4433702920216747e874d2914518de6748d05f 0 iEYEABECAAYFAlL9OsoACgkQyUhSUUBVisnz6ACgmR2KgErDS5jB8SvPB2u7yaRN6SIAnRwxqa0LGPBM52Fdw2e8vDVFxSWU 791ec610422cd2852cf51bd1842e90aa04d3ed20 0 iEUEABECAAYFAlNrnasACgkQyUhSUUBVismrBQCUD5Q/tPiX+KtsoWM3aUOyooARWgCfcfUrhO5jUSBEXZ9F61wVynvtxf0= c55c660d6e9dd0b433768c906c1462cf6e8d71d5 0 iEYEABECAAYFAlNv0HUACgkQyUhSUUBVisllBwCePV2jKcugiF0QYnIFLGJytMsW22kAn2bGBQ5hD/LrpTml5h9aCchkpSL3 +34e52cbeb83725178c0c0a282ffa5ef1c161e3cb 0 iEYEABECAAYFAlQuvlIACgkQyUhSUUBVislFdwCfTD1ctLwAmkwWzuIugFdnLBo7wYoAoJbAtUIRsFyyxdgvslqT9aJ6Mg0A From dovecot at dovecot.org Fri Oct 3 19:40:33 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 03 Oct 2014 19:40:33 +0000 Subject: dovecot-2.2: lib-lda: smtp client may have crashed if remote ret... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/bc0629daf4d4 changeset: 17873:bc0629daf4d4 user: Timo Sirainen date: Fri Oct 03 22:39:53 2014 +0300 description: lib-lda: smtp client may have crashed if remote returned a permanent error. diffstat: src/lib-lda/smtp-client.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (16 lines): diff -r a7b885c94295 -r bc0629daf4d4 src/lib-lda/smtp-client.c --- a/src/lib-lda/smtp-client.c Fri Oct 03 18:18:44 2014 +0300 +++ b/src/lib-lda/smtp-client.c Fri Oct 03 22:39:53 2014 +0300 @@ -317,8 +317,11 @@ i_assert(smtp_client->error != NULL); *error_r = t_strdup(smtp_client->error); return -1; - } else + } else { + i_assert(smtp_client->error != NULL); + *error_r = t_strdup(smtp_client->error); return 0; + } } int smtp_client_deinit(struct smtp_client *client, const char **error_r) From dovecot at dovecot.org Fri Oct 3 21:15:33 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 03 Oct 2014 21:15:33 +0000 Subject: dovecot-2.2: Make static analyzer happier Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/dfef14b27eea changeset: 17874:dfef14b27eea user: Timo Sirainen date: Fri Oct 03 22:44:31 2014 +0300 description: Make static analyzer happier diffstat: src/auth/passdb-static.c | 1 + src/doveadm/doveadm-dict.c | 1 + src/plugins/virtual/virtual-config.c | 3 +++ 3 files changed, 5 insertions(+), 0 deletions(-) diffs (42 lines): diff -r bc0629daf4d4 -r dfef14b27eea src/auth/passdb-static.c --- a/src/auth/passdb-static.c Fri Oct 03 22:39:53 2014 +0300 +++ b/src/auth/passdb-static.c Fri Oct 03 22:44:31 2014 +0300 @@ -33,6 +33,7 @@ } else { auth_request_log_info(request, AUTH_SUBSYS_DB, "No password returned (and no nopassword)"); + *password_r = NULL; return PASSDB_RESULT_PASSWORD_MISMATCH; } return PASSDB_RESULT_OK; diff -r bc0629daf4d4 -r dfef14b27eea src/doveadm/doveadm-dict.c --- a/src/doveadm/doveadm-dict.c Fri Oct 03 22:39:53 2014 +0300 +++ b/src/doveadm/doveadm-dict.c Fri Oct 03 22:44:31 2014 +0300 @@ -25,6 +25,7 @@ while ((c = getopt(*argc, *argv, getopt_args)) > 0) { switch (c) { case 'R': + i_assert(recurse != NULL); *recurse = TRUE; break; case 'u': diff -r bc0629daf4d4 -r dfef14b27eea src/plugins/virtual/virtual-config.c --- a/src/plugins/virtual/virtual-config.c Fri Oct 03 22:39:53 2014 +0300 +++ b/src/plugins/virtual/virtual-config.c Fri Oct 03 22:44:31 2014 +0300 @@ -77,6 +77,8 @@ struct mail_search_args *search_args; unsigned int i, count; + *error_r = NULL; + if (ctx->rule_idx == array_count(&ctx->mbox->backend_boxes)) { i_assert(str_len(ctx->rule) == 0); return 0; @@ -87,6 +89,7 @@ search_args = virtual_search_args_parse(ctx->rule, error_r); str_truncate(ctx->rule, 0); if (search_args == NULL) { + i_assert(*error_r != NULL); *error_r = t_strconcat("Previous search rule is invalid: ", *error_r, NULL); return -1; From dovecot at dovecot.org Fri Oct 3 21:30:13 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 03 Oct 2014 21:30:13 +0000 Subject: dovecot-2.2: fs-posix: Compile fix for systems without flock() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/dd25099bd633 changeset: 17875:dd25099bd633 user: Timo Sirainen date: Sat Oct 04 00:29:30 2014 +0300 description: fs-posix: Compile fix for systems without flock() diffstat: src/lib-fs/fs-posix.c | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diffs (13 lines): diff -r dfef14b27eea -r dd25099bd633 src/lib-fs/fs-posix.c --- a/src/lib-fs/fs-posix.c Fri Oct 03 22:44:31 2014 +0300 +++ b/src/lib-fs/fs-posix.c Sat Oct 04 00:29:30 2014 +0300 @@ -515,9 +515,7 @@ static int fs_posix_lock(struct fs_file *_file, unsigned int secs, struct fs_lock **lock_r) { -#ifdef HAVE_FLOCK struct posix_fs_file *file = (struct posix_fs_file *)_file; -#endif struct posix_fs *fs = (struct posix_fs *)_file->fs; struct dotlock_settings dotlock_set; struct posix_fs_lock fs_lock, *ret_lock; From dovecot at dovecot.org Sat Oct 4 14:33:30 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 04 Oct 2014 14:33:30 +0000 Subject: dovecot-2.2: lib-http: client: Fixed problem occuring when a nes... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ecb0ba0ce02f changeset: 17876:ecb0ba0ce02f user: Stephan Bosch date: Sat Oct 04 17:30:54 2014 +0300 description: lib-http: client: Fixed problem occuring when a nested ioloop was run inside a request callback using the same client. If requests in the nested ioloop would use the same connection as the one that called the callback, the requests would (in the best scenario) all be doomed to time out. diffstat: src/lib-http/http-client-connection.c | 17 +++++++++++++++-- src/lib-http/http-client-private.h | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diffs (68 lines): diff -r dd25099bd633 -r ecb0ba0ce02f src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Sat Oct 04 00:29:30 2014 +0300 +++ b/src/lib-http/http-client-connection.c Sat Oct 04 17:30:54 2014 +0300 @@ -53,13 +53,22 @@ { unsigned int pending_count = array_count(&conn->request_wait_list); - if (conn->pending_request != NULL) + if (conn->in_req_callback || conn->pending_request != NULL) pending_count++; return pending_count; } bool http_client_connection_is_ready(struct http_client_connection *conn) { + if (conn->in_req_callback) { + /* this can happen when a nested ioloop is created inside request + callback. we currently don't reuse connections that are occupied + this way, but theoretically we could, although that would add + quite a bit of complexity. + */ + return FALSE; + } + return (conn->connected && !conn->output_locked && !conn->close_indicated && !conn->tunneling && http_client_connection_count_pending(conn) < @@ -184,6 +193,7 @@ if (conn->connected && array_is_created(&conn->request_wait_list) && array_count(&conn->request_wait_list) == 0 && + !conn->in_req_callback && conn->incoming_payload == NULL && conn->client->set.max_idle_time_msecs > 0) { @@ -437,6 +447,7 @@ struct istream *payload; bool retrying; + i_assert(!conn->in_req_callback); i_assert(conn->incoming_payload == NULL); i_assert(conn->pending_request == NULL); @@ -459,10 +470,12 @@ if (conn->to_requests != NULL) timeout_remove(&conn->to_requests); } - + + conn->in_req_callback = TRUE; http_client_connection_ref(conn); retrying = !http_client_request_callback(req, response); http_client_connection_unref(&conn); + conn->in_req_callback = FALSE; if (conn == NULL) { /* the callback managed to get this connection destroyed */ if (!retrying) diff -r dd25099bd633 -r ecb0ba0ce02f src/lib-http/http-client-private.h --- a/src/lib-http/http-client-private.h Sat Oct 04 00:29:30 2014 +0300 +++ b/src/lib-http/http-client-private.h Sat Oct 04 17:30:54 2014 +0300 @@ -142,6 +142,7 @@ unsigned int output_locked:1; /* output is locked; no pipelining */ unsigned int payload_continue:1; /* received 100-continue for current request */ + unsigned int in_req_callback:1; /* performin request callback (busy) */ }; struct http_client_peer { From dovecot at dovecot.org Sat Oct 4 14:33:30 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 04 Oct 2014 14:33:30 +0000 Subject: dovecot-2.2: lib: ioloop: Fixed absolute timeout removal. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9ce4d8d394cc changeset: 17877:9ce4d8d394cc user: Stephan Bosch date: Sat Oct 04 17:31:14 2014 +0300 description: lib: ioloop: Fixed absolute timeout removal. Absolute timeouts fire only once, so the timeout should be removed from the priority queue once it fires. diffstat: src/lib/ioloop.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diffs (33 lines): diff -r ecb0ba0ce02f -r 9ce4d8d394cc src/lib/ioloop.c --- a/src/lib/ioloop.c Sat Oct 04 17:30:54 2014 +0300 +++ b/src/lib/ioloop.c Sat Oct 04 17:31:14 2014 +0300 @@ -266,7 +266,8 @@ struct timeout *timeout = *_timeout; *_timeout = NULL; - priorityq_remove(timeout->ioloop->timeouts, &timeout->item); + if (timeout->item.idx != UINT_MAX) + priorityq_remove(timeout->ioloop->timeouts, &timeout->item); timeout_free(timeout); } @@ -295,6 +296,7 @@ void timeout_reset(struct timeout *timeout) { + i_assert(!timeout->one_shot); timeout_reset_timeval(timeout, NULL); } @@ -434,7 +436,10 @@ if (timeout_get_wait_time(timeout, &tv, &tv_call) > 0) break; - if (!timeout->one_shot) { + if (timeout->one_shot) { + /* remove timeout from queue */ + priorityq_remove(timeout->ioloop->timeouts, &timeout->item); + } else { /* update timeout's next_run and reposition it in the queue */ timeout_reset_timeval(timeout, &tv_call); } From dovecot at dovecot.org Sat Oct 4 14:33:31 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 04 Oct 2014 14:33:31 +0000 Subject: dovecot-2.2: lib: Fixed io_loop_move_timeout() to retain the nex... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/312dd5c349f5 changeset: 17878:312dd5c349f5 user: Stephan Bosch date: Sat Oct 04 17:31:38 2014 +0300 description: lib: Fixed io_loop_move_timeout() to retain the next_run time, so that the timeout is not implicitly reset. This problem became with timeout_add_absolute(), since resetting an absolute timeout causes it to fire immediately (msecs == 0). diffstat: src/lib/ioloop.c | 18 ++++++++++++++++-- 1 files changed, 16 insertions(+), 2 deletions(-) diffs (35 lines): diff -r 9ce4d8d394cc -r 312dd5c349f5 src/lib/ioloop.c --- a/src/lib/ioloop.c Sat Oct 04 17:31:14 2014 +0300 +++ b/src/lib/ioloop.c Sat Oct 04 17:31:38 2014 +0300 @@ -254,6 +254,21 @@ return timeout; } +static struct timeout * +timeout_copy(const struct timeout *old_to) +{ + struct timeout *new_to; + + new_to = timeout_add_common + (old_to->source_linenum, old_to->callback, old_to->context); + new_to->one_shot = old_to->one_shot; + new_to->msecs = old_to->msecs; + new_to->next_run = old_to->next_run; + priorityq_add(new_to->ioloop->timeouts, &new_to->item); + + return new_to; +} + static void timeout_free(struct timeout *timeout) { if (timeout->ctx != NULL) @@ -829,8 +844,7 @@ if (old_to->ioloop == current_ioloop) return old_to; - new_to = timeout_add(old_to->msecs, old_to->source_linenum, - old_to->callback, old_to->context); + new_to = timeout_copy(old_to); timeout_remove(_timeout); return new_to; } From dovecot at dovecot.org Sat Oct 4 14:33:31 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 04 Oct 2014 14:33:31 +0000 Subject: dovecot-2.2: lib-http: client queue: Start using new timeval_cmp... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/94ba0150905b changeset: 17879:94ba0150905b user: Stephan Bosch date: Sat Oct 04 17:31:38 2014 +0300 description: lib-http: client queue: Start using new timeval_cmp_margin function for delay handling. diffstat: src/lib-http/http-client-queue.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diffs (32 lines): diff -r 312dd5c349f5 -r 94ba0150905b src/lib-http/http-client-queue.c --- a/src/lib-http/http-client-queue.c Sat Oct 04 17:31:38 2014 +0300 +++ b/src/lib-http/http-client-queue.c Sat Oct 04 17:31:38 2014 +0300 @@ -16,6 +16,8 @@ #include "http-client-private.h" +#define TIMEOUT_CMP_MARGIN_USECS 2000 + /* * Logging */ @@ -412,7 +414,8 @@ finished = 0; reqs = array_get(&queue->delayed_request_queue, &count); for (i = 0; i < count; i++) { - if (timeval_cmp(&reqs[i]->release_time, &ioloop_timeval) > 0) { + if (timeval_cmp_margin(&reqs[i]->release_time, + &ioloop_timeval, TIMEOUT_CMP_MARGIN_USECS) > 0) { break; } @@ -465,7 +468,8 @@ if (req->release_time.tv_sec > 0) { io_loop_time_refresh(); - if (timeval_cmp(&req->release_time, &ioloop_timeval) > 0) { + if (timeval_cmp_margin(&req->release_time, + &ioloop_timeval, TIMEOUT_CMP_MARGIN_USECS) > 0) { (void)array_bsearch_insert_pos(&queue->delayed_request_queue, &req, http_client_queue_delayed_cmp, &insert_idx); array_insert(&queue->delayed_request_queue, insert_idx, &req, 1); From dovecot at dovecot.org Sat Oct 4 14:33:36 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 04 Oct 2014 14:33:36 +0000 Subject: dovecot-2.2: lib-http: client: Added support for delaying reques... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c6431fb17158 changeset: 17880:c6431fb17158 user: Stephan Bosch date: Sat Oct 04 17:31:38 2014 +0300 description: lib-http: client: Added support for delaying requests in milliseconds. diffstat: src/lib-http/http-client-request.c | 8 ++++++++ src/lib-http/http-client.h | 2 ++ 2 files changed, 10 insertions(+), 0 deletions(-) diffs (37 lines): diff -r 94ba0150905b -r c6431fb17158 src/lib-http/http-client-request.c --- a/src/lib-http/http-client-request.c Sat Oct 04 17:31:38 2014 +0300 +++ b/src/lib-http/http-client-request.c Sat Oct 04 17:31:38 2014 +0300 @@ -5,6 +5,7 @@ #include "str.h" #include "hash.h" #include "array.h" +#include "time-util.h" #include "istream.h" #include "ostream.h" #include "dns-lookup.h" @@ -319,6 +320,13 @@ req->release_time.tv_sec += seconds; } +void http_client_request_delay_msecs(struct http_client_request *req, + unsigned int msecs) +{ + req->release_time = ioloop_timeval; + timeval_add_msecs(&req->release_time, msecs); +} + int http_client_request_delay_from_response(struct http_client_request *req, const struct http_response *response) { diff -r 94ba0150905b -r c6431fb17158 src/lib-http/http-client.h --- a/src/lib-http/http-client.h Sat Oct 04 17:31:38 2014 +0300 +++ b/src/lib-http/http-client.h Sat Oct 04 17:31:38 2014 +0300 @@ -198,6 +198,8 @@ time_t time); void http_client_request_delay(struct http_client_request *req, time_t seconds); +void http_client_request_delay_msecs(struct http_client_request *req, + unsigned int msecs); const char *http_client_request_get_method(struct http_client_request *req); const char *http_client_request_get_target(struct http_client_request *req); From dovecot at dovecot.org Sat Oct 4 14:33:36 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 04 Oct 2014 14:33:36 +0000 Subject: dovecot-2.2: lib-http: client: Added support for absolute reques... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4f175c27bea5 changeset: 17881:4f175c27bea5 user: Stephan Bosch date: Sat Oct 04 17:32:48 2014 +0300 description: lib-http: client: Added support for absolute request timeout. Requests cannot survive beyond this deadline. diffstat: src/lib-http/http-client-connection.c | 13 +- src/lib-http/http-client-host.c | 7 +- src/lib-http/http-client-private.h | 15 +- src/lib-http/http-client-queue.c | 380 +++++++++++++++++++++++++++------ src/lib-http/http-client-request.c | 62 +++++- src/lib-http/http-client.c | 2 + src/lib-http/http-client.h | 11 + 7 files changed, 404 insertions(+), 86 deletions(-) diffs (truncated from 862 to 300 lines): diff -r c6431fb17158 -r 4f175c27bea5 src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Sat Oct 04 17:31:38 2014 +0300 +++ b/src/lib-http/http-client-connection.c Sat Oct 04 17:32:48 2014 +0300 @@ -423,9 +423,8 @@ net_set_nonblock(conn->conn.fd_in, TRUE); conn->incoming_payload = NULL; - + conn->pending_request = NULL; http_client_request_finish(&req); - conn->pending_request = NULL; /* room for new requests */ if (http_client_connection_is_ready(conn)) @@ -438,6 +437,9 @@ necessary. */ conn->to_input = timeout_add_short(0, http_client_payload_destroyed_timeout, conn); + + i_assert(req != NULL); + http_client_request_unref(&req); } static bool @@ -451,6 +453,7 @@ i_assert(conn->incoming_payload == NULL); i_assert(conn->pending_request == NULL); + http_client_request_ref(req); req->state = HTTP_REQUEST_STATE_GOT_RESPONSE; if (response->payload != NULL) { @@ -480,6 +483,7 @@ /* the callback managed to get this connection destroyed */ if (!retrying) http_client_request_finish(&req); + http_client_request_unref(&req); return FALSE; } @@ -493,6 +497,7 @@ http_client_connection_input, &conn->conn); } + http_client_request_unref(&req); return TRUE; } @@ -501,13 +506,17 @@ payload = response->payload; response->payload = NULL; conn->pending_request = req; + + /* request is dereferenced in payload destroy callback */ i_stream_unref(&payload); + if (conn->to_input != NULL) { /* already finished reading the payload */ http_client_payload_finished(conn); } } else { http_client_request_finish(&req); + http_client_request_unref(&req); } if (conn->incoming_payload == NULL) { diff -r c6431fb17158 -r 4f175c27bea5 src/lib-http/http-client-host.c --- a/src/lib-http/http-client-host.c Sat Oct 04 17:31:38 2014 +0300 +++ b/src/lib-http/http-client-host.c Sat Oct 04 17:32:48 2014 +0300 @@ -82,11 +82,12 @@ /* make connections to requested ports */ array_foreach_modifiable(&host->queues, queue_idx) { struct http_client_queue *queue = *queue_idx; - unsigned int count = array_count(&queue->request_queue); + unsigned int reqs_pending = + http_client_queue_requests_pending(queue, NULL); queue->ips_connect_idx = queue->ips_connect_start_idx = 0; - if (count > 0) + if (reqs_pending > 0) http_client_queue_connection_setup(queue); - requests += count; + requests += reqs_pending; } if (requests == 0 && host->client->ioloop != NULL) diff -r c6431fb17158 -r 4f175c27bea5 src/lib-http/http-client-private.h --- a/src/lib-http/http-client-private.h Sat Oct 04 17:31:38 2014 +0300 +++ b/src/lib-http/http-client-private.h Sat Oct 04 17:32:48 2014 +0300 @@ -75,6 +75,8 @@ struct timeval submit_time; struct timeval sent_time; struct timeval response_time; + struct timeval timeout_time; + unsigned int timeout_msecs; unsigned int attempts; unsigned int redirects; @@ -194,10 +196,17 @@ this can be more than one when soft connect timeouts are enabled */ ARRAY_TYPE(http_client_peer) pending_peers; + /* all requests associated to this queue + (ordered by earliest timeout first) */ + ARRAY_TYPE(http_client_request) requests; + + /* delayed requests waiting to be released after delay */ + ARRAY_TYPE(http_client_request) delayed_requests; + /* requests pending in queue to be picked up by connections */ - ARRAY_TYPE(http_client_request) request_queue, delayed_request_queue; + ARRAY_TYPE(http_client_request) queued_requests, queued_urgent_requests; - struct timeout *to_connect, *to_delayed; + struct timeout *to_connect, *to_request, *to_delayed; }; struct http_client_host { @@ -332,7 +341,7 @@ const struct http_client_peer_addr *addr, bool no_urgent); unsigned int http_client_queue_requests_pending(struct http_client_queue *queue, - unsigned int *num_urgent_r); + unsigned int *num_urgent_r) ATTR_NULL(2); void http_client_queue_connection_success(struct http_client_queue *queue, const struct http_client_peer_addr *addr); diff -r c6431fb17158 -r 4f175c27bea5 src/lib-http/http-client-queue.c --- a/src/lib-http/http-client-queue.c Sat Oct 04 17:31:38 2014 +0300 +++ b/src/lib-http/http-client-queue.c Sat Oct 04 17:32:48 2014 +0300 @@ -18,6 +18,14 @@ #define TIMEOUT_CMP_MARGIN_USECS 2000 +static void +http_client_queue_set_delay_timer(struct http_client_queue *queue, + struct timeval time); +static void +http_client_queue_set_request_timer(struct http_client_queue *queue, + const struct timeval *time); + + /* * Logging */ @@ -42,13 +50,9 @@ } /* - * Queue + * Queue object */ -static void -http_client_queue_set_delay_timer(struct http_client_queue *queue, - struct timeval time); - static struct http_client_queue * http_client_queue_find(struct http_client_host *host, const struct http_client_peer_addr *addr) @@ -99,8 +103,10 @@ queue->addr.https_name = queue->https_name; queue->name = name; queue->ips_connect_idx = 0; - i_array_init(&queue->request_queue, 16); - i_array_init(&queue->delayed_request_queue, 4); + i_array_init(&queue->requests, 16); + i_array_init(&queue->queued_requests, 16); + i_array_init(&queue->queued_urgent_requests, 16); + i_array_init(&queue->delayed_requests, 4); array_append(&host->queues, &queue, 1); } @@ -114,8 +120,10 @@ i_free(queue->https_name); if (array_is_created(&queue->pending_peers)) array_free(&queue->pending_peers); - array_free(&queue->request_queue); - array_free(&queue->delayed_request_queue); + array_free(&queue->requests); + array_free(&queue->queued_requests); + array_free(&queue->queued_urgent_requests); + array_free(&queue->delayed_requests); if (queue->to_connect != NULL) timeout_remove(&queue->to_connect); if (queue->to_delayed != NULL) @@ -124,6 +132,10 @@ i_free(queue); } +/* + * Error handling + */ + void http_client_queue_fail(struct http_client_queue *queue, unsigned int status, const char *error) { @@ -131,7 +143,7 @@ struct http_client_request **req_idx; /* abort all pending requests */ - req_arr = &queue->request_queue; + req_arr = &queue->requests; t_array_init(&treqs, array_count(req_arr)); array_copy(&treqs.arr, 0, &req_arr->arr, 0, array_count(req_arr)); array_foreach_modifiable(&treqs, req_idx) { @@ -139,43 +151,15 @@ } array_clear(req_arr); - /* abort all delayed requests */ - req_arr = &queue->delayed_request_queue; - array_clear(&treqs); - array_copy(&treqs.arr, 0, &req_arr->arr, 0, array_count(req_arr)); - array_foreach_modifiable(&treqs, req_idx) { - http_client_request_error(*req_idx, status, error); - } - array_clear(req_arr); + /* all queues must be empty now */ + i_assert(array_count(&queue->delayed_requests) == 0); + i_assert(array_count(&queue->queued_requests) == 0); + i_assert(array_count(&queue->queued_urgent_requests) == 0); } -void -http_client_queue_drop_request(struct http_client_queue *queue, - struct http_client_request *req) -{ - ARRAY_TYPE(http_client_request) *req_arr; - struct http_client_request **req_idx; - - /* remove from main queue */ - req_arr = &queue->request_queue; - array_foreach_modifiable(req_arr, req_idx) { - if (*req_idx == req) { - array_delete(req_arr, array_foreach_idx(req_arr, req_idx), 1); - break; - } - } - - /* remove from delay queue */ - if (req->release_time.tv_sec > 0) { - req_arr = &queue->delayed_request_queue; - array_foreach_modifiable(req_arr, req_idx) { - if (*req_idx == req) { - array_delete(req_arr, array_foreach_idx(req_arr, req_idx), 1); - break; - } - } - } -} +/* + * Connection management + */ static bool http_client_queue_is_last_connect_ip(struct http_client_queue *queue) @@ -234,7 +218,9 @@ struct http_client_host *host = queue->host; struct http_client_peer *peer = NULL; const struct http_client_peer_addr *addr = &queue->addr; - unsigned int num_requests = array_count(&queue->request_queue); + unsigned int num_requests = + array_count(&queue->queued_requests) + + array_count(&queue->queued_urgent_requests); if (num_requests == 0) return; @@ -248,6 +234,7 @@ (addr->https_name == NULL ? "" : t_strdup_printf(" (SSL=%s)", addr->https_name)), num_requests); + /* create/get peer */ peer = http_client_peer_get(queue->client, addr); http_client_peer_link_queue(peer, queue); @@ -285,7 +272,7 @@ /* start soft connect time-out (but only if we have another IP left) */ msecs = host->client->set.soft_connect_timeout_msecs; if (!http_client_queue_is_last_connect_ip(queue) && msecs > 0 && - queue->to_connect == NULL) { + queue->to_connect == NULL) { queue->to_connect = timeout_add(msecs, http_client_queue_soft_connect_timeout, queue); } @@ -344,7 +331,7 @@ t_strdup_printf(" (SSL=%s)", addr->https_name)), reason, (array_is_created(&queue->pending_peers) ? array_count(&queue->pending_peers): 0), - array_count(&queue->request_queue)); + array_count(&queue->requests)); if (array_is_created(&queue->pending_peers) && array_count(&queue->pending_peers) > 0) { struct http_client_peer *const *peer_idx; @@ -391,18 +378,217 @@ return TRUE; } +/* + * Main request queue + */ From dovecot at dovecot.org Sat Oct 4 14:33:37 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 04 Oct 2014 14:33:37 +0000 Subject: dovecot-2.2: lib-http: Fixed detecting disconnection when ioloop... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/77c4b78a4fa2 changeset: 17882:77c4b78a4fa2 user: Stephan Bosch date: Sat Oct 04 17:32:48 2014 +0300 description: lib-http: Fixed detecting disconnection when ioloop is running only intermittently. This fix only applies to ioloops created and run by lib-http itself. diffstat: src/lib-http/http-client-connection.c | 60 +++++++++++++++++++++++++--------- src/lib-http/http-client-private.h | 1 + src/lib-http/http-client-request.c | 30 ++++++++++------- 3 files changed, 62 insertions(+), 29 deletions(-) diffs (138 lines): diff -r 4f175c27bea5 -r 77c4b78a4fa2 src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Sat Oct 04 17:32:48 2014 +0300 +++ b/src/lib-http/http-client-connection.c Sat Oct 04 17:32:48 2014 +0300 @@ -58,23 +58,6 @@ return pending_count; } -bool http_client_connection_is_ready(struct http_client_connection *conn) -{ - if (conn->in_req_callback) { - /* this can happen when a nested ioloop is created inside request - callback. we currently don't reuse connections that are occupied - this way, but theoretically we could, although that would add - quite a bit of complexity. - */ - return FALSE; - } - - return (conn->connected && !conn->output_locked && - !conn->close_indicated && !conn->tunneling && - http_client_connection_count_pending(conn) < - conn->client->set.max_pipelined_requests); -} - bool http_client_connection_is_idle(struct http_client_connection *conn) { return (conn->to_idle != NULL); @@ -174,6 +157,48 @@ http_client_connection_unref(_conn); } +bool http_client_connection_is_ready(struct http_client_connection *conn) +{ + int ret; + + if (conn->in_req_callback) { + /* this can happen when a nested ioloop is created inside request + callback. we currently don't reuse connections that are occupied + this way, but theoretically we could, although that would add + quite a bit of complexity. + */ + return FALSE; + } + + if (!conn->connected || conn->output_locked || + conn->close_indicated || conn->tunneling || + http_client_connection_count_pending(conn) >= + conn->client->set.max_pipelined_requests) + return FALSE; + + if (conn->last_ioloop != NULL && conn->last_ioloop != current_ioloop) { + conn->last_ioloop = current_ioloop; + /* Active ioloop is different from what we saw earlier; + we may have missed a disconnection event on this connection. + Verify status by reading from connection. */ + if ((ret=i_stream_read(conn->conn.input)) < 0) { + int stream_errno = conn->conn.input->stream_errno; + + i_assert(ret != -2); + i_assert(conn->conn.input->stream_errno != 0 || conn->conn.input->eof); + http_client_connection_abort_temp_error(&conn, + HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, + t_strdup_printf("Connection lost: read(%s) failed: %s", + i_stream_get_name(conn->conn.input), + stream_errno != 0 ? + i_stream_get_error(conn->conn.input) : + "EOF")); + return FALSE; + } + } + return TRUE; +} + static void http_client_connection_idle_timeout(struct http_client_connection *conn) { @@ -802,6 +827,7 @@ { /* connected */ conn->connected = TRUE; + conn->last_ioloop = current_ioloop; if (conn->to_connect != NULL && (conn->ssl_iostream == NULL || ssl_iostream_is_handshaked(conn->ssl_iostream))) diff -r 4f175c27bea5 -r 77c4b78a4fa2 src/lib-http/http-client-private.h --- a/src/lib-http/http-client-private.h Sat Oct 04 17:32:48 2014 +0300 +++ b/src/lib-http/http-client-private.h Sat Oct 04 17:32:48 2014 +0300 @@ -131,6 +131,7 @@ struct http_client_request *pending_request; struct istream *incoming_payload; struct io *io_req_payload; + struct ioloop *last_ioloop; /* requests that have been sent, waiting for response */ ARRAY_TYPE(http_client_request) request_wait_list; diff -r 4f175c27bea5 -r 77c4b78a4fa2 src/lib-http/http-client-request.c --- a/src/lib-http/http-client-request.c Sat Oct 04 17:32:48 2014 +0300 +++ b/src/lib-http/http-client-request.c Sat Oct 04 17:32:48 2014 +0300 @@ -792,21 +792,27 @@ o_stream_get_name(output), o_stream_get_error(output)); ret = -1; - } + } else { + http_client_request_debug(req, "Sent header"); - http_client_request_debug(req, "Sent header"); - - if (ret >= 0 && req->payload_output != NULL) { - if (!req->payload_sync) { - if (http_client_request_send_more(req, error_r) < 0) - ret = -1; + if (req->payload_output != NULL) { + if (!req->payload_sync) { + if (http_client_request_send_more(req, error_r) < 0) + ret = -1; + } else { + http_client_request_debug(req, "Waiting for 100-continue"); + conn->output_locked = TRUE; + } } else { - http_client_request_debug(req, "Waiting for 100-continue"); - conn->output_locked = TRUE; + req->state = HTTP_REQUEST_STATE_WAITING; + conn->output_locked = FALSE; } - } else { - req->state = HTTP_REQUEST_STATE_WAITING; - conn->output_locked = FALSE; + if (ret >= 0 && o_stream_flush(output) < 0) { + *error_r = t_strdup_printf("flush(%s) failed: %s", + o_stream_get_name(output), + o_stream_get_error(output)); + ret = -1; + } } o_stream_uncork(output); return ret; From dovecot at dovecot.org Sat Oct 4 14:48:32 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 04 Oct 2014 14:48:32 +0000 Subject: dovecot-2.2: lib: Added support for connecting UDP sockets. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/95ac50948e39 changeset: 17883:95ac50948e39 user: Stephan Bosch date: Sat Oct 04 17:48:03 2014 +0300 description: lib: Added support for connecting UDP sockets. diffstat: src/lib/net.c | 17 ++++++++++++----- src/lib/net.h | 5 ++++- 2 files changed, 16 insertions(+), 6 deletions(-) diffs (74 lines): diff -r 77c4b78a4fa2 -r 95ac50948e39 src/lib/net.c --- a/src/lib/net.c Sat Oct 04 17:32:48 2014 +0300 +++ b/src/lib/net.c Sat Oct 04 17:48:03 2014 +0300 @@ -182,7 +182,7 @@ #endif static int net_connect_ip_full(const struct ip_addr *ip, unsigned int port, - const struct ip_addr *my_ip, bool blocking) + const struct ip_addr *my_ip, int sock_type, bool blocking) { union sockaddr_union so; int fd, ret, opt = 1; @@ -195,7 +195,7 @@ /* create the socket */ memset(&so, 0, sizeof(so)); so.sin.sin_family = ip->family; - fd = socket(ip->family, SOCK_STREAM, 0); + fd = socket(ip->family, sock_type, 0); if (fd == -1) { i_error("socket() failed: %m"); @@ -204,7 +204,8 @@ /* set socket options */ (void)setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); - (void)setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt)); + if (sock_type == SOCK_STREAM) + (void)setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt)); if (!blocking) net_set_nonblock(fd, TRUE); @@ -242,13 +243,19 @@ int net_connect_ip(const struct ip_addr *ip, unsigned int port, const struct ip_addr *my_ip) { - return net_connect_ip_full(ip, port, my_ip, FALSE); + return net_connect_ip_full(ip, port, my_ip, SOCK_STREAM, FALSE); } int net_connect_ip_blocking(const struct ip_addr *ip, unsigned int port, const struct ip_addr *my_ip) { - return net_connect_ip_full(ip, port, my_ip, TRUE); + return net_connect_ip_full(ip, port, my_ip, SOCK_STREAM, TRUE); +} + +int net_connect_udp(const struct ip_addr *ip, unsigned int port, + const struct ip_addr *my_ip) +{ + return net_connect_ip_full(ip, port, my_ip, SOCK_DGRAM, FALSE); } int net_try_bind(const struct ip_addr *ip) diff -r 77c4b78a4fa2 -r 95ac50948e39 src/lib/net.h --- a/src/lib/net.h Sat Oct 04 17:32:48 2014 +0300 +++ b/src/lib/net.h Sat Oct 04 17:48:03 2014 +0300 @@ -67,13 +67,16 @@ int net_ip_cmp(const struct ip_addr *ip1, const struct ip_addr *ip2); unsigned int net_ip_hash(const struct ip_addr *ip); -/* Connect to socket with ip address. The socket and connect() is +/* Connect to TCP socket with ip address. The socket and connect() is non-blocking. */ int net_connect_ip(const struct ip_addr *ip, unsigned int port, const struct ip_addr *my_ip) ATTR_NULL(3); /* Like net_connect_ip(), but do a blocking connect(). */ int net_connect_ip_blocking(const struct ip_addr *ip, unsigned int port, const struct ip_addr *my_ip) ATTR_NULL(3); +/* Like net_connect_ip(), but open a UDP socket. */ +int net_connect_udp(const struct ip_addr *ip, unsigned int port, + const struct ip_addr *my_ip); /* Returns 0 if we can bind() as given IP, -1 if not. */ int net_try_bind(const struct ip_addr *ip); /* Connect to named UNIX socket */ From dovecot at dovecot.org Sun Oct 5 10:24:34 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 05 Oct 2014 10:24:34 +0000 Subject: dovecot-2.2: doveadm sync/backup: Updated usage string Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4d07c32012ff changeset: 17884:4d07c32012ff user: Timo Sirainen date: Sun Oct 05 13:24:02 2014 +0300 description: doveadm sync/backup: Updated usage string diffstat: src/doveadm/doveadm-dsync.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (17 lines): diff -r 95ac50948e39 -r 4d07c32012ff src/doveadm/doveadm-dsync.c --- a/src/doveadm/doveadm-dsync.c Sat Oct 04 17:48:03 2014 +0300 +++ b/src/doveadm/doveadm-dsync.c Sun Oct 05 13:24:02 2014 +0300 @@ -1101,11 +1101,11 @@ struct doveadm_mail_cmd cmd_dsync_mirror = { cmd_dsync_alloc, "sync", - "[-1dfR] [-l ] [-r ] [-m ] [-n | -N] [-x ] [-s ] " + "[-1fPRU] [-l ] [-r ] [-m ] [-g ] [-n | -N] [-x ] [-s ] -d|" }; struct doveadm_mail_cmd cmd_dsync_backup = { cmd_dsync_backup_alloc, "backup", - "[-dfR] [-l ] [-r ] [-m ] [-n | -N] [-x ] [-s ] " + "[-fPRU] [-l ] [-r ] [-m ] [-g ] [-n | -N] [-x ] [-s ] -d|" }; struct doveadm_mail_cmd cmd_dsync_server = { cmd_dsync_server_alloc, "dsync-server", &doveadm_mail_cmd_hide From dovecot at dovecot.org Sun Oct 5 17:57:10 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 05 Oct 2014 17:57:10 +0000 Subject: dovecot-2.2: dsync: Fixed linking with some systems. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/768073f6fccf changeset: 17885:768073f6fccf user: Timo Sirainen date: Sun Oct 05 20:56:39 2014 +0300 description: dsync: Fixed linking with some systems. diffstat: src/doveadm/dsync/Makefile.am | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 4d07c32012ff -r 768073f6fccf src/doveadm/dsync/Makefile.am --- a/src/doveadm/dsync/Makefile.am Sun Oct 05 13:24:02 2014 +0300 +++ b/src/doveadm/dsync/Makefile.am Sun Oct 05 20:56:39 2014 +0300 @@ -34,7 +34,7 @@ dsync-transaction-log-scan.c libdovecot_dsync_la_SOURCES = -libdovecot_dsync_la_LIBADD = libdsync.la ../../lib-storage/libdovecot-storage.la +libdovecot_dsync_la_LIBADD = libdsync.la ../../lib-storage/libdovecot-storage.la ../../lib-dovecot/libdovecot.la libdovecot_dsync_la_DEPENDENCIES = libdsync.la libdovecot_dsync_la_LDFLAGS = -export-dynamic From dovecot at dovecot.org Mon Oct 6 09:22:25 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 06 Oct 2014 09:22:25 +0000 Subject: dovecot-2.2: doveadm backup: When deleting a mailbox, log a warn... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d7ac3056ed7c changeset: 17886:d7ac3056ed7c user: Timo Sirainen date: Mon Oct 06 12:21:24 2014 +0300 description: doveadm backup: When deleting a mailbox, log a warning, not just a debug message. Because we're also returning temporary failure in any case, so there needs to be some kind of a warning/error logged. diffstat: src/doveadm/dsync/dsync-mailbox-import.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 768073f6fccf -r d7ac3056ed7c src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Sun Oct 05 20:56:39 2014 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Mon Oct 06 12:21:24 2014 +0300 @@ -1412,7 +1412,7 @@ /* mail exists on remote, but not locally. we'll need to insert this mail back, which means deleting the whole mailbox and resyncing. */ - imp_debug(importer, "Deleting mailbox '%s': UID=%u GUID=%s is missing locally", + i_warning("Deleting mailbox '%s': UID=%u GUID=%s is missing locally", mailbox_get_vname(importer->box), change->uid, change->guid); importer->delete_mailbox = TRUE; From dovecot at dovecot.org Mon Oct 6 09:22:25 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 06 Oct 2014 09:22:25 +0000 Subject: dovecot-2.2: doveadm backup: Local mailbox was deleted also when... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/124a7fc23706 changeset: 17887:124a7fc23706 user: Timo Sirainen date: Mon Oct 06 12:21:52 2014 +0300 description: doveadm backup: Local mailbox was deleted also when there were just new messages. diffstat: src/doveadm/dsync/dsync-mailbox-import.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r d7ac3056ed7c -r 124a7fc23706 src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Mon Oct 06 12:21:24 2014 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Mon Oct 06 12:21:52 2014 +0300 @@ -1437,7 +1437,7 @@ return; } if (importer->revert_local_changes && - importer->local_uid_next > 1) { + importer->local_uid_next > change->uid) { dsync_mailbox_revert_missing(importer, change); *result_r = "Reverting local change by deleting mailbox"; } else if (change->guid == NULL || From dovecot at dovecot.org Mon Oct 6 10:15:42 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 06 Oct 2014 10:15:42 +0000 Subject: dovecot-2.2: doveadm backup: Don't unnecessarily delete mailbox ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/68e5eaecc8b4 changeset: 17888:68e5eaecc8b4 user: Timo Sirainen date: Mon Oct 06 13:15:10 2014 +0300 description: doveadm backup: Don't unnecessarily delete mailbox when handling expunges diffstat: src/doveadm/dsync/dsync-mailbox-import.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 124a7fc23706 -r 68e5eaecc8b4 src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Mon Oct 06 12:21:52 2014 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Mon Oct 06 13:15:10 2014 +0300 @@ -1474,7 +1474,8 @@ } return; } - if (importer->revert_local_changes) { + if (importer->revert_local_changes && + change->type != DSYNC_MAIL_CHANGE_TYPE_EXPUNGE) { dsync_mailbox_revert_missing(importer, change); *result_r = "Reverting local change by deleting mailbox"; } else if (dsync_mailbox_find_common_expunged_uid(importer, change)) { From dovecot at dovecot.org Mon Oct 6 10:16:08 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 06 Oct 2014 10:16:08 +0000 Subject: dovecot-2.2: dsync: Fixed potential crash when deleting mailbox. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d2fbe6b6c53e changeset: 17889:d2fbe6b6c53e user: Timo Sirainen date: Mon Oct 06 13:13:04 2014 +0300 description: dsync: Fixed potential crash when deleting mailbox. diffstat: src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 68e5eaecc8b4 -r d2fbe6b6c53e src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c --- a/src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c Mon Oct 06 13:15:10 2014 +0300 +++ b/src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c Mon Oct 06 13:13:04 2014 +0300 @@ -127,7 +127,7 @@ i_debug("brain %c: Change during sync: " "Mailbox GUID %s deletion conflict: %s", brain->master_brain ? 'M' : 'S', - mailbox_get_vname(box), errstr); + guid_128_to_string(change->mailbox_guid), errstr); } brain->changes_during_sync = TRUE; return ret; From dovecot at dovecot.org Mon Oct 6 10:17:31 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 06 Oct 2014 10:17:31 +0000 Subject: dovecot-2.2: dsync: Debug logging improvements and comment clari... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/bf086c6f6e4a changeset: 17890:bf086c6f6e4a user: Timo Sirainen date: Mon Oct 06 13:17:00 2014 +0300 description: dsync: Debug logging improvements and comment clarifications. diffstat: src/doveadm/dsync/dsync-mailbox-import.c | 43 +++++++++++++++++++------------ 1 files changed, 26 insertions(+), 17 deletions(-) diffs (95 lines): diff -r d2fbe6b6c53e -r bf086c6f6e4a src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Mon Oct 06 13:13:04 2014 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Mon Oct 06 13:17:00 2014 +0300 @@ -1370,12 +1370,14 @@ static bool dsync_mailbox_find_common_expunged_uid(struct dsync_mailbox_importer *importer, - const struct dsync_mail_change *change) + const struct dsync_mail_change *change, + const char **result_r) { const struct dsync_mail_change *local_change; if (*change->guid == '\0') { /* remote doesn't support GUIDs, can't verify expunge */ + *result_r = "GUIDs not supported, can't verify expunge"; return FALSE; } @@ -1385,20 +1387,27 @@ GUID string to 128bit GUID first. */ local_change = hash_table_lookup(importer->local_changes, POINTER_CAST(change->uid)); - if (local_change == NULL || local_change->guid == NULL) + if (local_change == NULL || local_change->guid == NULL) { + *result_r = "Expunged local mail's GUID not found"; return FALSE; + } i_assert(local_change->type == DSYNC_MAIL_CHANGE_TYPE_EXPUNGE); if (dsync_mail_change_guid_equals(importer, local_change, - change->guid, NULL)) + change->guid, NULL)) { importer->last_common_uid = change->uid; - else if (change->type != DSYNC_MAIL_CHANGE_TYPE_EXPUNGE) + *result_r = "Expunged local mail's GUID matches remote"; + } else if (change->type != DSYNC_MAIL_CHANGE_TYPE_EXPUNGE) { dsync_mailbox_common_uid_found(importer); - else { + *result_r = "Expunged local mail's GUID doesn't match remote GUID"; + } else { /* GUID mismatch for two expunged mails. dsync can't update GUIDs for already expunged messages, so we can't immediately determine that the rest of the messages are a mismatch. so for now we'll just skip over this pair. */ + *result_r = "Expunged mails' GUIDs don't match - delaying decision"; + /* NOTE: the return value here doesn't matter, because the only + caller that checks for it never reaches this code path */ } return TRUE; } @@ -1436,20 +1445,22 @@ *result_r = "Expunged mail not found locally"; return; } - if (importer->revert_local_changes && - importer->local_uid_next > change->uid) { + i_assert(change->guid != NULL); + if (importer->local_uid_next <= change->uid) { + dsync_mailbox_common_uid_found(importer); + *result_r = "Mail's UID is above local UIDNEXT"; + } else if (importer->revert_local_changes) { dsync_mailbox_revert_missing(importer, change); *result_r = "Reverting local change by deleting mailbox"; - } else if (change->guid == NULL || - !dsync_mailbox_find_common_expunged_uid(importer, change)) { - /* couldn't match it for an expunged mail. use the last - message with a matching GUID as the last common + } else if (!dsync_mailbox_find_common_expunged_uid(importer, change, result_r)) { + /* it's unknown if this mail existed locally and was + expunged. since we don't want to lose any mails, + assume that we need to preserve the mail. use the + last message with a matching GUID as the last common UID. */ dsync_mailbox_common_uid_found(importer); - *result_r = "No more local mails found"; - } else { - *result_r = "Mail expunged locally"; } + *result_r = t_strdup_printf("%s - No more local mails found", *result_r); return; } @@ -1478,10 +1489,8 @@ change->type != DSYNC_MAIL_CHANGE_TYPE_EXPUNGE) { dsync_mailbox_revert_missing(importer, change); *result_r = "Reverting local change by deleting mailbox"; - } else if (dsync_mailbox_find_common_expunged_uid(importer, change)) { - *result_r = "Mail expunged locally"; } else { - *result_r = "Mail not found locally"; + (void)dsync_mailbox_find_common_expunged_uid(importer, change, result_r); } *result_r = t_strdup_printf("%s (next local mail UID=%u)", *result_r, importer->cur_mail->uid); From dovecot at dovecot.org Mon Oct 6 13:42:59 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 06 Oct 2014 13:42:59 +0000 Subject: dovecot-2.2: man: Reworked dsync.1 and renamed it to doveadm-syn... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b57fe99a69c0 changeset: 17891:b57fe99a69c0 user: Pascal Volk date: Sun Oct 05 20:18:20 2014 +0000 description: man: Reworked dsync.1 and renamed it to doveadm-sync.1. diffstat: .hgignore | 4 +- doc/man/Makefile.am | 10 +- doc/man/doveadm-backup.1 | 1 + doc/man/doveadm-sync.1.in | 361 ++++++++++++++++++++++++++++++++++++++++++++++ doc/man/dsync.1 | 1 + doc/man/dsync.1.in | 302 -------------------------------------- 6 files changed, 371 insertions(+), 308 deletions(-) diffs (truncated from 742 to 300 lines): diff -r bf086c6f6e4a -r b57fe99a69c0 .hgignore --- a/.hgignore Mon Oct 06 13:17:00 2014 +0300 +++ b/.hgignore Sun Oct 05 20:18:20 2014 +0000 @@ -105,5 +105,5 @@ syntax: regexp src/.*/test-[^\.]*$ -doc/man/doveadm-(acl|altmove|auth|batch|deduplicate|director|dump|exec|expunge|fetch|flags|fts|import|instance|index|force-resync|help|kick|log|mailbox|mount|move|penalty|purge|pw|quota|search|user|who)\.1$ -doc/man/(doveadm|doveconf|dovecot-lda|dovecot|dsync)\.1$ +doc/man/doveadm-(acl|altmove|auth|batch|deduplicate|director|dump|exec|expunge|fetch|flags|fts|import|instance|index|force-resync|help|kick|log|mailbox|mount|move|penalty|purge|pw|quota|search|sync|user|who)\.1$ +doc/man/(doveadm|doveconf|dovecot-lda|dovecot)\.1$ diff -r bf086c6f6e4a -r b57fe99a69c0 doc/man/Makefile.am --- a/doc/man/Makefile.am Mon Oct 06 13:17:00 2014 +0300 +++ b/doc/man/Makefile.am Sun Oct 05 20:18:20 2014 +0000 @@ -4,10 +4,12 @@ dist_man1_MANS = \ deliver.1 \ + doveadm-backup.1 \ doveadm-config.1 \ doveadm-copy.1 \ doveadm-reload.1 \ - doveadm-stop.1 + doveadm-stop.1 \ + dsync.1 dist_man7_MANS = \ doveadm-search-query.7 @@ -41,12 +43,12 @@ doveadm-pw.1 \ doveadm-quota.1 \ doveadm-search.1 \ + doveadm-sync.1 \ doveadm-user.1 \ doveadm-who.1 \ doveconf.1 \ dovecot.1 \ - dovecot-lda.1 \ - dsync.1 + dovecot-lda.1 man_includefiles = \ $(srcdir)/global-options-formatter.inc \ @@ -85,12 +87,12 @@ doveadm-pw.1.in \ doveadm-quota.1.in \ doveadm-search.1.in \ + doveadm-sync.1.in \ doveadm-user.1.in \ doveadm-who.1.in \ doveconf.1.in \ dovecot.1.in \ dovecot-lda.1.in \ - dsync.1.in \ sed.sh \ $(man_includefiles) diff -r bf086c6f6e4a -r b57fe99a69c0 doc/man/doveadm-backup.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/man/doveadm-backup.1 Sun Oct 05 20:18:20 2014 +0000 @@ -0,0 +1,1 @@ +.so man1/doveadm-sync.1 \ No newline at end of file diff -r bf086c6f6e4a -r b57fe99a69c0 doc/man/doveadm-sync.1.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/man/doveadm-sync.1.in Sun Oct 05 20:18:20 2014 +0000 @@ -0,0 +1,361 @@ +.\" Copyright (c) 2014 Dovecot authors, see the included COPYING file +.TH DOVEADM\-SYNC 1 "2014-10-05" "Dovecot v2.2" "Dovecot" +.SH NAME +doveadm\-sync \- Dovecot\(aqs two\-way mailbox synchronization utility +.br +doveadm\-backup \- Dovecot\(aqs one\-way mailbox synchronization utility +.\"------------------------------------------------------------------------ +.SH SYNOPSIS +.BR "doveadm sync" " [" \-Dv ] +[\fB\-u\fP \fIuser\fP|\fB\-A\fP] +[\fB\-S\fP \fIsocket_path\fP] +.RB [ \-1fPRU ] +[\fB\-l\fP \fIsecs\fP] +[\fB\-r\fP \fIrawlog_path\fP] +[\fB\-m\fP \fImailbox\fP] +[\fB\-g\fP \fImailbox_guid\fP] +[\fB\-n\fP \fInamespace\fP|\fB\-N\fP] +[\fB\-x\fP \fIexclude\fP] +[\fB\-s\fP \fIstate\fP] +\fB\-d\fP|\fIdestination\fP +.\"------------------------------------- +.PP +.BR "doveadm backup" " [" \-Dv ] +[\fB\-u\fP \fIuser\fP|\fB\-A\fP] +[\fB\-S\fP \fIsocket_path\fP] +.RB [ \-fPRU ] +[\fB\-l\fP \fIsecs\fP] +[\fB\-r\fP \fIrawlog_path\fP] +[\fB\-m\fP \fImailbox\fP] +[\fB\-g\fP \fImailbox_guid\fP] +[\fB\-n\fP \fInamespace\fP|\fB\-N\fP] +[\fB\-x\fP \fIexclude\fP] +[\fB\-s\fP \fIstate\fP] +\fB\-d\fP|\fIdestination\fP +.\"------------------------------------------------------------------------ +.SH DESCRIPTION +dsync is Dovecot\(aqs mailbox synchronization utility. +It can be used for several different use cases: Two\-way synchronization of +mailboxes, creating backups of mails, and convert mailboxes from/to +different mailbox formats. +All of these can be used within the same server or between different +servers (via +.BR ssh (1) +or tcp connections). +Remote mailboxes can be accessed also via IMAP protocol, which allows using +dsync for mailbox migration purposes. +.PP +You can run dsync in one of three modes: +.RS \(bu 4 +.\"------------------------------------- +.IP \(bu +.B doveadm backup +performs one\-way synchronization. +If there are any changes in the destination they will be deleted, so the +destination will look exactly like the source. +.\"------------------------------------- +.IP \(bu +.B doveadm sync +performs two\-way synchronization. +It merges all changes without losing anything. +Both the mailboxes will end up looking identical after the synchronization +is finished. +.\"------------------------------------- +.IP \(bu +.B doveadm sync \-1 +performs one\-way synchronization, but it merges the changes in destination +without deleting anything. +This doesn\(aqt currently work perfectly, so its use should be limited. +Its main purpose is that during mailbox migration you can run +.B doveadm backup +multiple times, then switch mails to be delivered to the new mailbox and +run +.B doveadm sync \-1 +once more to transfer any last new mails from the old mailbox. +.\"------------------------------------- +.RE +.PP +There are also three different synchronization algorithms: +.RS \(bu 4 +.\"------------------------------------- +.IP \(bu +Full synchronization (\-f parameter) scans through all the messages in all +the mailboxes. +This guarantees that everything will be synchronized, but it\(aqs +unnecessarily slow for incremental synchronization. +.\"------------------------------------- +.IP \(bu +Fast synchronization (default) first attempts to find mailboxes that have +changed, and synchronize only those. +This is done by checking the mailboxes\(aq metadata (NEXTUID and +HIGHESTMODSEQ). +Usually this works fine, especially with one\-way synchronization, but if +both sides do exactly the same number of changes, the metadata may end up +containing the same values even if the changes were different. +.\"------------------------------------- +.IP \(bu +Stateful synchronization (\-s parameter) is the most efficient way to +synchronize mailboxes. +It relies on having the earlier dsync run\(aqs state saved somewhere and +being passed to the next dsync run. +Based on this state dsync can send only the changes that happened after the +previous dsync run. +As long as the state or the mailboxes aren\(aqt corrupted this algorithm +should work perfectly. +The replicator process uses this internally to perform most of the +synchronization. +.\"------------------------------------- +.RE +.PP +The syncing is done as perfectly as possible: an IMAP or a POP3 client +shouldn\(aqt be able to notice any differences between the two mailboxes. +Two\-way syncing means that it\(aqs safe to do any kind of modifications in +both sides, and dsync will merge the changes without losing any changes +done on either side. +This is possible because dsync can access Dovecot\(aqs index logs that keep +track of changes. +It\(aqs of course possible to have conflicts during merging, these are +resolved in a safe way. +See the +.I dsync design +document for more information. +.PP +dsync uses the same configuration files as the rest of Dovecot (via +.BR doveconf (1) +binary). +The entire configuration can be changed by giving \-c parameter to another +configuration file, or using \-o parameter to override specific settings. +When executing a remote dsync program it works the same way: +it uses its own local configuration. +.PP +dsync can be run completely standalone. +It doesn\(aqt require any Dovecot server processes to be running, except +when using \-u parameter to do a +.I userdb +lookup from auth process. +.PP +dsync can sync either one or multiple users using the \-u or \-A +parameters. +For continuous replication you can use the Dovecot replicator process, +which automatically runs dsync whenever messages have changed. +.\"------------------------------------------------------------------------ + at INCLUDE:global-options@ +.\" --- command specific options --- "/. +.PP +Command specific +.IR options : +.TP +.B \-1 +Do one\-way synchronization instead of two\-way synchronization. +.\"------------------------------------- + at INCLUDE:option-A@ +.\"------------------------------------- +.TP +.B \-N +Synchronize all the available namespaces. +By default only namespaces that don\(aqt have explicit location setting +are synchronized. +.\"------------------------------------- +.TP +.B \-P +Run a +.BR doveadm\-purge (1) +for the destination (remote) storage after synchronization. +.\"------------------------------------- + at INCLUDE:option-S-socket@ +.\"------------------------------------- +.TP +.B \-U +This is used internally by replicator to have dsync notify it when the +synchronization is finished. +.\"------------------------------------- +.TP +.B \-d +Use the default destination, which is looked up from the +.I mail_replica userdb +extra field. +.\"------------------------------------- +.TP +.BI \-g \ mailbox_guid +Same as \-m, but find the mailbox to be synchronized by its GUID instead +of by name. +.\"------------------------------------- +.TP +.BI \-l \ secs +Lock the dsync for this user. +Wait for maximum +.I secs +before giving up. +This parameter should be used to avoid broken synchronization if it\(aqs +possible that dsync is being run concurrently for the same user. +.\"------------------------------------- +.TP +.BI \-n \ namespace +Synchronize only the specified namespace. +This parameter can be used multiple times. +.\"------------------------------------- +.TP +.BI \-r \ rawlog_path +Running dsync remotely, write the remote input/output traffic to the +specified log file. +.\"------------------------------------- +.TP +.BI \-s \ previous_state +Use stateful synchronization. +If the previous state is unknown, use an empty string. +The new state is always printed to standard output. +.\"------------------------------------- + at INCLUDE:option-u-user@ +.\"------------------------------------- +.TP +.BI \-x \ mailbox_mask +Exclude the specified mailbox name/mask. +The mask may contain \(dq\fB?\fP\(dq and \(dq\fB*\fP\(dq wildcards. +This parameter can be used multiple times. +.\"------------------------------------------------------------------------ +.SH ARGUMENTS +.TP +.I destination +This argument specifies the synchronized destination. +It can be one of: +.RS +.TP +location +Same as +.I mail_location +setting, e.g. maildir:\(ti/Maildir +.TP +.BI remote: login at host +Uses +.I dsync_remote_cmd +setting to connect to the remote host (usually via ssh) +.TP +.I remoteprefix:login at host From dovecot at dovecot.org Mon Oct 6 13:42:59 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 06 Oct 2014 13:42:59 +0000 Subject: dovecot-2.2: man: Forgot to update doveadm.1 in previous commit ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cee8255aca62 changeset: 17892:cee8255aca62 user: Pascal Volk date: Sun Oct 05 23:25:48 2014 +0000 description: man: Forgot to update doveadm.1 in previous commit (fec91a386bb0). diffstat: doc/man/doveadm.1.in | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletions(-) diffs (34 lines): diff -r b57fe99a69c0 -r cee8255aca62 doc/man/doveadm.1.in --- a/doc/man/doveadm.1.in Sun Oct 05 20:18:20 2014 +0000 +++ b/doc/man/doveadm.1.in Sun Oct 05 23:25:48 2014 +0000 @@ -107,6 +107,11 @@ Move matching mails to the alternative storage. .\"------------------------------------- .TP +.B doveadm backup +.BR doveadm\-backup (1), +Dovecot\(aqs one\-way mailbox synchronization utility. +.\"------------------------------------- +.TP .B doveadm batch .BR doveadm\-batch (1), Execute multiple commands for multiple users. @@ -182,6 +187,11 @@ Initialize/recalculate or show current quota usage. .\"------------------------------------- .TP +.B doveadm sync +.BR doveadm\-sync (1), +Dovecot\(aqs two\-way mailbox synchronization utility. +.\"------------------------------------- +.TP .B doveadm search .BR doveadm\-search (1), Show a list of mailbox GUIDs and message UIDs matching given search query. @@ -222,5 +232,4 @@ .BR doveadm\-help (1), .BR doveconf (1), .BR dovecot (1), -.BR dsync (1), .BR doveadm\-search\-query (7) \ No newline at end of file From dovecot at dovecot.org Mon Oct 6 13:42:59 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 06 Oct 2014 13:42:59 +0000 Subject: dovecot-2.2: man: Added doveadm-replicator.1. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/da3edfc529bb changeset: 17893:da3edfc529bb user: Pascal Volk date: Sun Oct 05 23:36:10 2014 +0000 description: man: Added doveadm-replicator.1. diffstat: .hgignore | 2 +- doc/man/Makefile.am | 2 + doc/man/doveadm-replicator.1.in | 123 ++++++++++++++++++++++++++++++++++++++++ doc/man/doveadm.1.in | 5 + 4 files changed, 131 insertions(+), 1 deletions(-) diffs (172 lines): diff -r cee8255aca62 -r da3edfc529bb .hgignore --- a/.hgignore Sun Oct 05 23:25:48 2014 +0000 +++ b/.hgignore Sun Oct 05 23:36:10 2014 +0000 @@ -105,5 +105,5 @@ syntax: regexp src/.*/test-[^\.]*$ -doc/man/doveadm-(acl|altmove|auth|batch|deduplicate|director|dump|exec|expunge|fetch|flags|fts|import|instance|index|force-resync|help|kick|log|mailbox|mount|move|penalty|purge|pw|quota|search|sync|user|who)\.1$ +doc/man/doveadm-(acl|altmove|auth|batch|deduplicate|director|dump|exec|expunge|fetch|flags|fts|import|instance|index|force-resync|help|kick|log|mailbox|mount|move|penalty|purge|pw|quota|replicator|search|sync|user|who)\.1$ doc/man/(doveadm|doveconf|dovecot-lda|dovecot)\.1$ diff -r cee8255aca62 -r da3edfc529bb doc/man/Makefile.am --- a/doc/man/Makefile.am Sun Oct 05 23:25:48 2014 +0000 +++ b/doc/man/Makefile.am Sun Oct 05 23:36:10 2014 +0000 @@ -42,6 +42,7 @@ doveadm-purge.1 \ doveadm-pw.1 \ doveadm-quota.1 \ + doveadm-replicator.1 \ doveadm-search.1 \ doveadm-sync.1 \ doveadm-user.1 \ @@ -86,6 +87,7 @@ doveadm-purge.1.in \ doveadm-pw.1.in \ doveadm-quota.1.in \ + doveadm-replicator.1.in \ doveadm-search.1.in \ doveadm-sync.1.in \ doveadm-user.1.in \ diff -r cee8255aca62 -r da3edfc529bb doc/man/doveadm-replicator.1.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/man/doveadm-replicator.1.in Sun Oct 05 23:36:10 2014 +0000 @@ -0,0 +1,123 @@ +.\" Copyright (c) 2014 Dovecot authors, see the included COPYING file +.TH DOVEADM\-REPLICATOR 1 "2014-10-05" "Dovecot v2.2" "Dovecot" +.SH NAME +doveadm\-replicator \- Manage users\(aq mail replicaton +.\"------------------------------------------------------------------------ +.SH SYNOPSIS +.BR doveadm " [" \-Dv ] +[\fB\-f\fP \fIformatter\fP] +.BI replicator \ command +.RI [ OPTIONS ]\ [ ARGUMENTS ] +.\"------------------------------------------------------------------------ +.SH DESCRIPTION +The +doveadm replicator +.I COMMANDS +can be used to manage the automated replication of users\(aq mail. +.\"------------------------------------------------------------------------ + at INCLUDE:global-options-formatter@ +.\" --- command specific options --- "/. +.PP +This command uses by default the output formatter +.B flow +(without the +.IR key = +prefix). +.PP +Command specific +.IR options : +.TP +.BI \-a \ replicator_socket_path +This option is used to specify an absolute path to an alternative UNIX +domain socket. +.sp +By default +.BR doveadm (1) +will use the socket +.IR @rundir@/replicator\-doveadm . +The socket may be located in another directory, when the default +.I base_dir +setting was overridden in +.IR @pkgsysconfdir@/dovecot.conf . +.\"------------------------------------------------------------------------ +.SH ARGUMENTS +.TP +.I user_mask +Specifies for which users the command should be executed. +In most cases you would like to use patterns which contains wildcards, +e.g. \(rs*@example.net for all users of the example.net domain, or simply +\(rs* for all users. +.sp +When the SQL userdb module is used make sure that the +.I iterate_query +setting in +.I @pkgsysconfdir@/dovecot\-sql.conf.ext +matches your database layout. +When using the LDAP userdb module, make sure that the +.IR iterate_attrs " and " iterate_filter +settings in +.I @pkgsysconfdir@/dovecot\-ldap.conf.ext +match your LDAP schema. +Otherwise +.BR doveadm (1) +will be unable to iterate over all users. +.\"------------------------------------------------------------------------ +.SH COMMANDS +.SS replicator add +.B doveadm replicator add +[\fB\-a\fP \fIreplicator_socket_path\fP] +.I user_mask +.PP +Add the specified user(s) to the replicator. +If the +.I user_mask +contains \(dq?\(dq or \(dq*\(dq wildcards, the list of usernames is looked +up from the +.IR userdb . +.\"------------------------------------- +.SS replicator dsync\-status +.B doveadm replicator dsync\-status +[\fB\-a\fP \fIreplicator_socket_path\fP] +.PP +Show the status for the currently running dsync processes. +.\"------------------------------------- +.SS replicator remove +.B doveadm replicator remove +[\fB\-a\fP \fIreplicator_socket_path\fP] +.I username +.PP +Remove the specified user from replicator. +.\"------------------------------------- +.SS replicator replicate +.B doveadm replicator replicate +[\fB\-a\fP \fIreplicator_socket_path\fP] +.RB [ \-f ] +[\fB\-p\fP \fIpriority\fP] +.I user_mask +.PP +Start replication for the specified users now. +If the \-f parameter is given, full replication is done for the user. +You can also specify the priority, which can be either +.B high " or " low. +If the user mask contains \(dq?\(dq or \(dq*\(dq wildcards, the list of +usernames is looked up from the users that currently exist in replicator +(not from the +.IR userdb ). +.\"------------------------------------- +.SS replicator status +.B doveadm replicator status +[\fB\-a\fP \fIreplicator_socket_path\fP] +.I user_mask +.PP +Show the replication status for users. +.\"------------------------------------------------------------------------ + at INCLUDE:reporting-bugs@ +.\"------------------------------------------------------------------------ +.SH SEE ALSO +.BR doveadm (1), +.BR doveadm\-sync (1), +.\"------------------------------------- +.PP +Additional resources: +.IP "Replication with dsync" +http://wiki2.dovecot.org/Replication \ No newline at end of file diff -r cee8255aca62 -r da3edfc529bb doc/man/doveadm.1.in --- a/doc/man/doveadm.1.in Sun Oct 05 23:25:48 2014 +0000 +++ b/doc/man/doveadm.1.in Sun Oct 05 23:36:10 2014 +0000 @@ -187,6 +187,11 @@ Initialize/recalculate or show current quota usage. .\"------------------------------------- .TP +.B doveadm replicator +.BR doveadm\-replicator (1), +Manage users\(aq mail replicaton. +.\"------------------------------------- +.TP .B doveadm sync .BR doveadm\-sync (1), Dovecot\(aqs two\-way mailbox synchronization utility. From dovecot at dovecot.org Mon Oct 6 17:16:40 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 06 Oct 2014 17:16:40 +0000 Subject: dovecot-2.2: log_timestamp setting supports now %{usecs} Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e0f37f309685 changeset: 17894:e0f37f309685 user: Timo Sirainen date: Mon Oct 06 20:16:07 2014 +0300 description: log_timestamp setting supports now %{usecs} This is mainly useful for debugging. diffstat: src/lib/failures.c | 38 +++++++++++++++++++++++++++++--------- src/lib/failures.h | 1 + src/log/log-connection.c | 24 +++++++++++++++--------- 3 files changed, 45 insertions(+), 18 deletions(-) diffs (187 lines): diff -r da3edfc529bb -r e0f37f309685 src/lib/failures.c --- a/src/lib/failures.c Sun Oct 05 23:36:10 2014 +0000 +++ b/src/lib/failures.c Mon Oct 06 20:16:07 2014 +0300 @@ -45,7 +45,8 @@ static int log_fd = STDERR_FILENO, log_info_fd = STDERR_FILENO, log_debug_fd = STDERR_FILENO; -static char *log_prefix = NULL, *log_stamp_format = NULL; +static char *log_prefix = NULL; +static char *log_stamp_format = NULL, *log_stamp_format_suffix = NULL; static bool failure_ignore_errors = FALSE, log_prefix_sent = FALSE; static bool coredump_on_error = FALSE; @@ -54,12 +55,17 @@ const char *format, va_list args); /* kludgy .. we want to trust log_stamp_format with -Wformat-nonliteral */ -static const char *get_log_stamp_format(const char *unused) +static const char * +get_log_stamp_format(const char *format_arg, unsigned int timestamp_usecs) ATTR_FORMAT_ARG(1); -static const char *get_log_stamp_format(const char *unused ATTR_UNUSED) +static const char *get_log_stamp_format(const char *format_arg ATTR_UNUSED, + unsigned int timestamp_usecs) { - return log_stamp_format; + if (log_stamp_format_suffix == NULL) + return log_stamp_format; + return t_strdup_printf("%s%06u%s", log_stamp_format, + timestamp_usecs, log_stamp_format_suffix); } void failure_exit(int status) @@ -73,16 +79,19 @@ { const struct tm *tm = ctx->timestamp; char buf[256]; - time_t now; + struct timeval now; if (log_stamp_format != NULL) { if (tm == NULL) { - now = time(NULL); - tm = localtime(&now); + if (gettimeofday(&now, NULL) < 0) + i_panic("gettimeofday() failed: %m"); + tm = localtime(&now.tv_sec); + } else { + now.tv_usec = ctx->timestamp_usecs; } if (strftime(buf, sizeof(buf), - get_log_stamp_format("unused"), tm) > 0) + get_log_stamp_format("unused", now.tv_usec), tm) > 0) str_append(str, buf); } if (log_prefix != NULL) @@ -702,8 +711,18 @@ void i_set_failure_timestamp_format(const char *fmt) { + const char *p; + i_free(log_stamp_format); - log_stamp_format = i_strdup(fmt); + i_free_and_null(log_stamp_format_suffix); + + p = strstr(fmt, "%{usecs}"); + if (p == NULL) + log_stamp_format = i_strdup(fmt); + else T_BEGIN { + log_stamp_format = i_strdup_until(fmt, p); + log_stamp_format_suffix = i_strdup(p + 8); + } T_END; } void i_set_failure_send_ip(const struct ip_addr *ip) @@ -746,4 +765,5 @@ i_free_and_null(log_prefix); i_free_and_null(log_stamp_format); + i_free_and_null(log_stamp_format_suffix); } diff -r da3edfc529bb -r e0f37f309685 src/lib/failures.h --- a/src/lib/failures.h Sun Oct 05 23:36:10 2014 +0000 +++ b/src/lib/failures.h Mon Oct 06 20:16:07 2014 +0300 @@ -36,6 +36,7 @@ enum log_type type; int exit_status; /* for LOG_TYPE_FATAL */ const struct tm *timestamp; /* NULL = use time() + localtime() */ + unsigned int timestamp_usecs; }; #define DEFAULT_FAILURE_STAMP_FORMAT "%b %d %H:%M:%S " diff -r da3edfc529bb -r e0f37f309685 src/log/log-connection.c --- a/src/log/log-connection.c Sun Oct 05 23:36:10 2014 +0000 +++ b/src/log/log-connection.c Mon Oct 06 20:16:07 2014 +0300 @@ -81,7 +81,8 @@ static void client_log_ctx(struct log_connection *log, - const struct failure_context *ctx, time_t log_time, + const struct failure_context *ctx, + const struct timeval *log_time, const char *prefix, const char *text) { struct log_error err; @@ -98,7 +99,7 @@ case LOG_TYPE_PANIC: memset(&err, 0, sizeof(err)); err.type = ctx->type; - err.timestamp = log_time; + err.timestamp = log_time->tv_sec; err.prefix = prefix; err.text = text; log_error_buffer_add(log->errorbuf, &err); @@ -111,7 +112,8 @@ static void client_log_fatal(struct log_connection *log, struct log_client *client, - const char *line, time_t log_time, const struct tm *tm) + const char *line, const struct timeval *log_time, + const struct tm *tm) { struct failure_context failure_ctx; const char *prefix = log->default_prefix; @@ -119,6 +121,7 @@ memset(&failure_ctx, 0, sizeof(failure_ctx)); failure_ctx.type = LOG_TYPE_FATAL; failure_ctx.timestamp = tm; + failure_ctx.timestamp_usecs = log_time->tv_usec; if (client != NULL) { if (client->prefix != NULL) @@ -133,7 +136,8 @@ } static void -log_parse_master_line(const char *line, time_t log_time, const struct tm *tm) +log_parse_master_line(const char *line, const struct timeval *log_time, + const struct tm *tm) { struct log_connection *const *logs, *log; struct log_client *client; @@ -186,7 +190,7 @@ static void log_it(struct log_connection *log, const char *line, - time_t log_time, const struct tm *tm) + const struct timeval *log_time, const struct tm *tm) { struct failure_line failure; struct failure_context failure_ctx; @@ -223,6 +227,7 @@ memset(&failure_ctx, 0, sizeof(failure_ctx)); failure_ctx.type = failure.log_type; failure_ctx.timestamp = tm; + failure_ctx.timestamp_usecs = log_time->tv_usec; prefix = client != NULL && client->prefix != NULL ? client->prefix : log->default_prefix; @@ -279,7 +284,7 @@ { const char *line; ssize_t ret; - time_t now; + struct timeval now; struct tm tm; if (!log->handshaked) { @@ -291,11 +296,12 @@ while ((ret = i_stream_read(log->input)) > 0 || ret == -2) { /* get new timestamps for every read() */ - now = time(NULL); - tm = *localtime(&now); + if (gettimeofday(&now, NULL) < 0) + i_panic("gettimeofday() failed: %m"); + tm = *localtime(&now.tv_sec); while ((line = i_stream_next_line(log->input)) != NULL) - log_it(log, line, now, &tm); + log_it(log, line, &now, &tm); } if (log->input->eof) From dovecot at dovecot.org Mon Oct 6 17:17:52 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 06 Oct 2014 17:17:52 +0000 Subject: dovecot-2.2: Minor code cleanup to previous change. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1b66c30fd421 changeset: 17895:1b66c30fd421 user: Timo Sirainen date: Mon Oct 06 20:17:19 2014 +0300 description: Minor code cleanup to previous change. No need to have a data stack frame here. diffstat: src/lib/failures.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (16 lines): diff -r e0f37f309685 -r 1b66c30fd421 src/lib/failures.c --- a/src/lib/failures.c Mon Oct 06 20:16:07 2014 +0300 +++ b/src/lib/failures.c Mon Oct 06 20:17:19 2014 +0300 @@ -719,10 +719,10 @@ p = strstr(fmt, "%{usecs}"); if (p == NULL) log_stamp_format = i_strdup(fmt); - else T_BEGIN { + else { log_stamp_format = i_strdup_until(fmt, p); log_stamp_format_suffix = i_strdup(p + 8); - } T_END; + } } void i_set_failure_send_ip(const struct ip_addr *ip) From dovecot at dovecot.org Mon Oct 6 18:16:26 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 06 Oct 2014 18:16:26 +0000 Subject: dovecot-2.2: sdbox: Fixed race condition when two processes mkdi... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3e9fda96a205 changeset: 17896:3e9fda96a205 user: Timo Sirainen date: Mon Oct 06 21:15:31 2014 +0300 description: sdbox: Fixed race condition when two processes mkdir() the same directory diffstat: src/lib-storage/index/dbox-single/sdbox-file.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 1b66c30fd421 -r 3e9fda96a205 src/lib-storage/index/dbox-single/sdbox-file.c --- a/src/lib-storage/index/dbox-single/sdbox-file.c Mon Oct 06 20:17:19 2014 +0300 +++ b/src/lib-storage/index/dbox-single/sdbox-file.c Mon Oct 06 21:15:31 2014 +0300 @@ -255,7 +255,8 @@ dir = t_strdup_until(path, p); if (mkdir_parents_chgrp(dir, perm->dir_create_mode, perm->file_create_gid, - perm->file_create_gid_origin) < 0) { + perm->file_create_gid_origin) < 0 && + errno != EEXIST) { mail_storage_set_critical(box->storage, "mkdir_parents(%s) failed: %m", dir); return -1; From dovecot at dovecot.org Mon Oct 6 19:12:35 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 06 Oct 2014 19:12:35 +0000 Subject: dovecot-2.2: lib-dict: Fixed race condition in mkdir()ing dict f... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/721089f22ae4 changeset: 17897:721089f22ae4 user: Timo Sirainen date: Mon Oct 06 22:12:01 2014 +0300 description: lib-dict: Fixed race condition in mkdir()ing dict file's parent directory. diffstat: src/lib-dict/dict-file.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 3e9fda96a205 -r 721089f22ae4 src/lib-dict/dict-file.c --- a/src/lib-dict/dict-file.c Mon Oct 06 21:15:31 2014 +0300 +++ b/src/lib-dict/dict-file.c Mon Oct 06 22:12:01 2014 +0300 @@ -445,7 +445,7 @@ mode = st.st_mode; } - if (mkdir_parents(path, mode) < 0) { + if (mkdir_parents(path, mode) < 0 && errno != EEXIST) { i_error("mkdir_parents(%s) failed: %m", path); return -1; } From dovecot at dovecot.org Mon Oct 6 21:05:49 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 06 Oct 2014 21:05:49 +0000 Subject: dovecot-2.2: man: Fixed broken syntax in doveadm-sync.1. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f5e4566f1e03 changeset: 17898:f5e4566f1e03 user: Pascal Volk date: Mon Oct 06 20:50:34 2014 +0000 description: man: Fixed broken syntax in doveadm-sync.1. diffstat: doc/man/doveadm-sync.1.in | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 721089f22ae4 -r f5e4566f1e03 doc/man/doveadm-sync.1.in --- a/doc/man/doveadm-sync.1.in Mon Oct 06 22:12:01 2014 +0300 +++ b/doc/man/doveadm-sync.1.in Mon Oct 06 20:50:34 2014 +0000 @@ -46,7 +46,7 @@ dsync for mailbox migration purposes. .PP You can run dsync in one of three modes: -.RS \(bu 4 +.RS .\"------------------------------------- .IP \(bu .B doveadm backup @@ -76,7 +76,7 @@ .RE .PP There are also three different synchronization algorithms: -.RS \(bu 4 +.RS .\"------------------------------------- .IP \(bu Full synchronization (\-f parameter) scans through all the messages in all From dovecot at dovecot.org Mon Oct 6 23:33:37 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 06 Oct 2014 23:33:37 +0000 Subject: dovecot-2.2: lib-index: Don't keep cache file locked for as long... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d6e08d98a170 changeset: 17899:d6e08d98a170 user: Timo Sirainen date: Tue Oct 07 02:33:03 2014 +0300 description: lib-index: Don't keep cache file locked for as long while syncing index. The earlier code was required for updating the cache offsets, but this code no longer exists. Now we just need to update the record counts in the header, which can be done quickly at the end of the sync. diffstat: src/lib-index/mail-cache-private.h | 2 - src/lib-index/mail-cache-sync-update.c | 74 +++++++++------------------------ src/lib-index/mail-cache-transaction.c | 15 ------ 3 files changed, 20 insertions(+), 71 deletions(-) diffs (144 lines): diff -r f5e4566f1e03 -r d6e08d98a170 src/lib-index/mail-cache-private.h --- a/src/lib-index/mail-cache-private.h Mon Oct 06 20:50:34 2014 +0000 +++ b/src/lib-index/mail-cache-private.h Tue Oct 07 02:33:03 2014 +0300 @@ -256,8 +256,6 @@ void mail_cache_file_close(struct mail_cache *cache); int mail_cache_reopen(struct mail_cache *cache); -void mail_cache_delete(struct mail_cache *cache); - /* Notify the decision handling code that field was looked up for seq. This should be called even for fields that aren't currently in cache file */ void mail_cache_decision_state_update(struct mail_cache_view *view, diff -r f5e4566f1e03 -r d6e08d98a170 src/lib-index/mail-cache-sync-update.c --- a/src/lib-index/mail-cache-sync-update.c Mon Oct 06 20:50:34 2014 +0000 +++ b/src/lib-index/mail-cache-sync-update.c Tue Oct 07 02:33:03 2014 +0300 @@ -5,21 +5,9 @@ #include "mail-index-sync-private.h" struct mail_cache_sync_context { - unsigned int locked:1; - unsigned int lock_failed:1; + unsigned expunge_count; }; -static void mail_cache_handler_deinit(struct mail_index_sync_map_ctx *sync_ctx, - struct mail_cache_sync_context *ctx) -{ - if (ctx == NULL) - return; - - if (ctx->locked) - (void)mail_cache_unlock(sync_ctx->view->index->cache); - i_free(ctx); -} - static struct mail_cache_sync_context *mail_cache_handler_init(void **context) { struct mail_cache_sync_context *ctx; @@ -33,48 +21,35 @@ return ctx; } -static int mail_cache_handler_lock(struct mail_cache_sync_context *ctx, - struct mail_cache *cache) +static void mail_cache_handler_deinit(struct mail_index_sync_map_ctx *sync_ctx, + struct mail_cache_sync_context *ctx) { - int ret; + struct mail_cache *cache = sync_ctx->view->index->cache; - if (ctx->locked) - return MAIL_CACHE_IS_UNUSABLE(cache) ? 0 : 1; - if (ctx->lock_failed) - return 0; + if (ctx == NULL) + return; - if (!ctx->locked) { - if ((ret = mail_cache_lock(cache, TRUE)) <= 0) { - ctx->lock_failed = TRUE; - return ret; - } - ctx->locked = TRUE; + if (mail_cache_lock(cache, TRUE) > 0) { + /* update the record counts in the cache file's header. these + are used to figure out when a cache file should be + recreated and the old data dropped. */ + cache->hdr_copy.deleted_record_count += ctx->expunge_count; + if (cache->hdr_copy.record_count >= ctx->expunge_count) + cache->hdr_copy.record_count -= ctx->expunge_count; + else + cache->hdr_copy.record_count = 0; + cache->hdr_modified = TRUE; + (void)mail_cache_unlock(cache); } - return 1; -} - -static bool get_cache_file_seq(struct mail_index_view *view, - uint32_t *cache_file_seq_r) -{ - const struct mail_index_ext *ext; - - ext = mail_index_view_get_ext(view, view->index->cache->ext_id); - if (ext == NULL) - return FALSE; - - *cache_file_seq_r = ext->reset_id; - return TRUE; + i_free(ctx); } int mail_cache_expunge_handler(struct mail_index_sync_map_ctx *sync_ctx, uint32_t seq ATTR_UNUSED, const void *data, - void **sync_context, void *context) + void **sync_context, void *context ATTR_UNUSED) { - struct mail_cache *cache = context; struct mail_cache_sync_context *ctx = *sync_context; const uint32_t *cache_offset = data; - uint32_t cache_file_seq; - int ret; if (data == NULL) { mail_cache_handler_deinit(sync_ctx, ctx); @@ -86,15 +61,6 @@ return 0; ctx = mail_cache_handler_init(sync_context); - ret = mail_cache_handler_lock(ctx, cache); - if (ret <= 0) - return ret; - - if (!get_cache_file_seq(sync_ctx->view, &cache_file_seq)) - return 0; - - if (!MAIL_CACHE_IS_UNUSABLE(cache) && - cache_file_seq == cache->hdr->file_seq) - mail_cache_delete(cache); + ctx->expunge_count++; return 0; } diff -r f5e4566f1e03 -r d6e08d98a170 src/lib-index/mail-cache-transaction.c --- a/src/lib-index/mail-cache-transaction.c Mon Oct 06 20:50:34 2014 +0000 +++ b/src/lib-index/mail-cache-transaction.c Tue Oct 07 02:33:03 2014 +0300 @@ -800,18 +800,3 @@ return mail_cache_field_exists(ctx->view, seq, field_idx) == 0; } - -void mail_cache_delete(struct mail_cache *cache) -{ - i_assert(cache->locked); - - /* we'll only update the deleted record count in the header. we can't - really do any actual deleting as other processes might still be - using the data. also it's actually useful as old index views are - still able to ask cached data for messages that have already been - expunged. */ - cache->hdr_copy.deleted_record_count++; - if (cache->hdr_copy.record_count > 0) - cache->hdr_copy.record_count--; - cache->hdr_modified = TRUE; -} From dovecot at dovecot.org Mon Oct 6 23:36:31 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 06 Oct 2014 23:36:31 +0000 Subject: dovecot-2.2: lib-index: Fixed cache file creation race condition. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6aeb2a7e5303 changeset: 17900:6aeb2a7e5303 user: Timo Sirainen date: Tue Oct 07 02:35:41 2014 +0300 description: lib-index: Fixed cache file creation race condition. If two processes are creating the index files at the same time, don't have one of them delete the dovecot.index.cache that the other one just created. This means we never should be calling mail_cache_create(), so it was removed entirely. diffstat: src/lib-index/mail-cache.c | 12 ------------ src/lib-index/mail-cache.h | 1 - src/lib-index/mail-index.c | 8 ++------ 3 files changed, 2 insertions(+), 19 deletions(-) diffs (65 lines): diff -r d6e08d98a170 -r 6aeb2a7e5303 src/lib-index/mail-cache.c --- a/src/lib-index/mail-cache.c Tue Oct 07 02:33:03 2014 +0300 +++ b/src/lib-index/mail-cache.c Tue Oct 07 02:35:41 2014 +0300 @@ -546,18 +546,6 @@ return cache; } -struct mail_cache *mail_cache_create(struct mail_index *index) -{ - struct mail_cache *cache; - - cache = mail_cache_alloc(index); - if (!MAIL_INDEX_IS_IN_MEMORY(index)) { - if (unlink(cache->filepath) < 0 && errno != ENOENT) - mail_cache_set_syscall_error(cache, "unlink()"); - } - return cache; -} - void mail_cache_free(struct mail_cache **_cache) { struct mail_cache *cache = *_cache; diff -r d6e08d98a170 -r 6aeb2a7e5303 src/lib-index/mail-cache.h --- a/src/lib-index/mail-cache.h Tue Oct 07 02:33:03 2014 +0300 +++ b/src/lib-index/mail-cache.h Tue Oct 07 02:35:41 2014 +0300 @@ -43,7 +43,6 @@ }; struct mail_cache *mail_cache_open_or_create(struct mail_index *index); -struct mail_cache *mail_cache_create(struct mail_index *index); void mail_cache_free(struct mail_cache **cache); /* Register fields. fields[].idx is updated to contain field index. diff -r d6e08d98a170 -r 6aeb2a7e5303 src/lib-index/mail-index.c --- a/src/lib-index/mail-index.c Tue Oct 07 02:33:03 2014 +0300 +++ b/src/lib-index/mail-index.c Tue Oct 07 02:35:41 2014 +0300 @@ -474,7 +474,6 @@ enum mail_index_open_flags flags) { int ret; - bool created = FALSE; ret = mail_transaction_log_open(index->log); if (ret == 0) { @@ -501,7 +500,6 @@ index->map->hdr.indexid = index->indexid; } index->initial_create = FALSE; - created = TRUE; } if (ret >= 0) { ret = index->map != NULL ? 1 : mail_index_try_open(index); @@ -525,10 +523,8 @@ return -1; } - if (index->cache == NULL) { - index->cache = created ? mail_cache_create(index) : - mail_cache_open_or_create(index); - } + if (index->cache == NULL) + index->cache = mail_cache_open_or_create(index); return 1; } From dovecot at dovecot.org Mon Oct 6 23:55:07 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 06 Oct 2014 23:55:07 +0000 Subject: dovecot-2.2: lib-index: Code cleanup - avoid code duplication. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a10eea380073 changeset: 17901:a10eea380073 user: Timo Sirainen date: Tue Oct 07 02:54:35 2014 +0300 description: lib-index: Code cleanup - avoid code duplication. diffstat: src/lib-index/mail-cache.c | 91 ++++++++++++++++++++------------------------- 1 files changed, 41 insertions(+), 50 deletions(-) diffs (128 lines): diff -r 6aeb2a7e5303 -r a10eea380073 src/lib-index/mail-cache.c --- a/src/lib-index/mail-cache.c Tue Oct 07 02:35:41 2014 +0300 +++ b/src/lib-index/mail-cache.c Tue Oct 07 02:54:35 2014 +0300 @@ -95,6 +95,34 @@ cache->st_dev = st.st_dev; } +static int mail_cache_try_open(struct mail_cache *cache) +{ + const void *data; + + cache->opened = TRUE; + + if (MAIL_INDEX_IS_IN_MEMORY(cache->index)) + return 0; + + cache->fd = nfs_safe_open(cache->filepath, + cache->index->readonly ? O_RDONLY : O_RDWR); + if (cache->fd == -1) { + if (errno == ENOENT) { + cache->need_compress_file_seq = 0; + return 0; + } + + mail_cache_set_syscall_error(cache, "open()"); + return -1; + } + + mail_cache_init_file_cache(cache); + + if (mail_cache_map(cache, 0, 0, &data) < 0) + return -1; + return 1; +} + static bool mail_cache_need_reopen(struct mail_cache *cache) { struct stat st; @@ -143,34 +171,14 @@ return FALSE; } -int mail_cache_reopen(struct mail_cache *cache) +static int mail_cache_reopen_now(struct mail_cache *cache) { struct mail_index_view *view; const struct mail_index_ext *ext; - const void *data; - - i_assert(!cache->locked); - - if (!mail_cache_need_reopen(cache)) { - /* reopening does no good */ - return 0; - } mail_cache_file_close(cache); - cache->fd = nfs_safe_open(cache->filepath, - cache->index->readonly ? O_RDONLY : O_RDWR); - if (cache->fd == -1) { - if (errno == ENOENT) - cache->need_compress_file_seq = 0; - else - mail_cache_set_syscall_error(cache, "open()"); - return -1; - } - - mail_cache_init_file_cache(cache); - - if (mail_cache_map(cache, 0, 0, &data) < 0) + if (mail_cache_try_open(cache) <= 0) return -1; if (mail_cache_header_fields_read(cache) < 0) @@ -193,6 +201,17 @@ return 1; } +int mail_cache_reopen(struct mail_cache *cache) +{ + i_assert(!cache->locked); + + if (!mail_cache_need_reopen(cache)) { + /* reopening does no good */ + return 0; + } + return mail_cache_reopen_now(cache); +} + static void mail_cache_update_need_compress(struct mail_cache *cache) { const struct mail_cache_header *hdr = cache->hdr; @@ -460,34 +479,6 @@ cache->mmap_base, FALSE); } -static int mail_cache_try_open(struct mail_cache *cache) -{ - const void *data; - - cache->opened = TRUE; - - if (MAIL_INDEX_IS_IN_MEMORY(cache->index)) - return 0; - - cache->fd = nfs_safe_open(cache->filepath, - cache->index->readonly ? O_RDONLY : O_RDWR); - if (cache->fd == -1) { - if (errno == ENOENT) { - cache->need_compress_file_seq = 0; - return 0; - } - - mail_cache_set_syscall_error(cache, "open()"); - return -1; - } - - mail_cache_init_file_cache(cache); - - if (mail_cache_map(cache, 0, 0, &data) < 0) - return -1; - return 1; -} - int mail_cache_open_and_verify(struct mail_cache *cache) { int ret; From dovecot at dovecot.org Tue Oct 7 15:47:52 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 07 Oct 2014 15:47:52 +0000 Subject: dovecot-2.2: lib-index: mail_cache_lock() partial rewrite. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8c84b69e7f69 changeset: 17902:8c84b69e7f69 user: Timo Sirainen date: Tue Oct 07 18:47:09 2014 +0300 description: lib-index: mail_cache_lock() partial rewrite. require_same_reset_id is no longer needed, if it ever was. If we're locking the cache file, we always want the latest one. The logic of locking in general was somewhat confusing and it probably didn't always successfully lock when it should have, because the reset_id happened to match an old file. diffstat: src/lib-index/mail-cache-fields.c | 2 +- src/lib-index/mail-cache-private.h | 2 +- src/lib-index/mail-cache-sync-update.c | 2 +- src/lib-index/mail-cache-transaction.c | 2 +- src/lib-index/mail-cache.c | 127 +++++++++++++++----------------- 5 files changed, 63 insertions(+), 72 deletions(-) diffs (219 lines): diff -r a10eea380073 -r 8c84b69e7f69 src/lib-index/mail-cache-fields.c --- a/src/lib-index/mail-cache-fields.c Tue Oct 07 02:54:35 2014 +0300 +++ b/src/lib-index/mail-cache-fields.c Tue Oct 07 18:47:09 2014 +0300 @@ -531,7 +531,7 @@ return ret; } - if (mail_cache_lock(cache, FALSE) <= 0) + if (mail_cache_lock(cache) <= 0) return -1; T_BEGIN { diff -r a10eea380073 -r 8c84b69e7f69 src/lib-index/mail-cache-private.h --- a/src/lib-index/mail-cache-private.h Tue Oct 07 02:54:35 2014 +0300 +++ b/src/lib-index/mail-cache-private.h Tue Oct 07 18:47:09 2014 +0300 @@ -212,7 +212,7 @@ /* Explicitly lock the cache file. Returns -1 if error / timed out, 1 if ok, 0 if cache is broken/doesn't exist */ -int mail_cache_lock(struct mail_cache *cache, bool require_same_reset_id); +int mail_cache_lock(struct mail_cache *cache); int mail_cache_try_lock(struct mail_cache *cache); /* Returns -1 if cache is / just got corrupted, 0 if ok. */ int mail_cache_unlock(struct mail_cache *cache); diff -r a10eea380073 -r 8c84b69e7f69 src/lib-index/mail-cache-sync-update.c --- a/src/lib-index/mail-cache-sync-update.c Tue Oct 07 02:54:35 2014 +0300 +++ b/src/lib-index/mail-cache-sync-update.c Tue Oct 07 18:47:09 2014 +0300 @@ -29,7 +29,7 @@ if (ctx == NULL) return; - if (mail_cache_lock(cache, TRUE) > 0) { + if (mail_cache_lock(cache) > 0) { /* update the record counts in the cache file's header. these are used to figure out when a cache file should be recreated and the old data dropped. */ diff -r a10eea380073 -r 8c84b69e7f69 src/lib-index/mail-cache-transaction.c --- a/src/lib-index/mail-cache-transaction.c Tue Oct 07 02:54:35 2014 +0300 +++ b/src/lib-index/mail-cache-transaction.c Tue Oct 07 18:47:09 2014 +0300 @@ -251,7 +251,7 @@ mail_cache_transaction_open_if_needed(ctx); - if ((ret = mail_cache_lock(cache, FALSE)) <= 0) { + if ((ret = mail_cache_lock(cache)) <= 0) { if (ret < 0) return -1; diff -r a10eea380073 -r 8c84b69e7f69 src/lib-index/mail-cache.c --- a/src/lib-index/mail-cache.c Tue Oct 07 02:54:35 2014 +0300 +++ b/src/lib-index/mail-cache.c Tue Oct 07 18:47:09 2014 +0300 @@ -81,15 +81,15 @@ { struct stat st; - if (cache->file_cache == NULL) - return; + if (cache->file_cache != NULL) + file_cache_set_fd(cache->file_cache, cache->fd); - file_cache_set_fd(cache->file_cache, cache->fd); - - if (fstat(cache->fd, &st) == 0) - (void)file_cache_set_size(cache->file_cache, st.st_size); - else if (!ESTALE_FSTAT(errno)) + if (fstat(cache->fd, &st) == 0) { + if (cache->file_cache != NULL) + (void)file_cache_set_size(cache->file_cache, st.st_size); + } else if (!ESTALE_FSTAT(errno)) { mail_cache_set_syscall_error(cache, "fstat()"); + } cache->st_ino = st.st_ino; cache->st_dev = st.st_dev; @@ -614,14 +614,13 @@ } static int -mail_cache_lock_full(struct mail_cache *cache, bool require_same_reset_id, - bool nonblock) +mail_cache_lock_full(struct mail_cache *cache, bool nonblock) { const struct mail_index_ext *ext; const void *data; struct mail_index_view *iview; uint32_t reset_id; - int i, ret; + int i; i_assert(!cache->locked); @@ -633,77 +632,69 @@ cache->index->readonly) return 0; - iview = mail_index_view_open(cache->index); - ext = mail_index_view_get_ext(iview, cache->ext_id); - reset_id = ext == NULL ? 0 : ext->reset_id; - mail_index_view_close(&iview); - - if (ext == NULL && require_same_reset_id) { - /* cache not used */ - return 0; + for (;;) { + if (mail_cache_lock_file(cache, nonblock) <= 0) + return -1; + i_assert(!MAIL_CACHE_IS_UNUSABLE(cache)); + if (!mail_cache_need_reopen(cache)) { + /* locked the latest file */ + break; + } + if (mail_cache_reopen_now(cache) <= 0) { + i_assert(cache->file_lock == NULL); + return -1; + } + i_assert(cache->file_lock == NULL); + /* okay, so it was just compressed. try again. */ } - for (i = 0; i < 3; i++) { - if (cache->hdr->file_seq != reset_id && - (require_same_reset_id || i == 0)) { - /* we want the latest cache file */ - if (reset_id < cache->hdr->file_seq) { - /* either we're still waiting for index to - catch up with a cache compression, or - that catching up is never going to happen */ - ret = 0; - break; - } - ret = mail_cache_reopen(cache); - if (ret < 0 || (ret == 0 && require_same_reset_id)) - break; + /* now verify that the index reset_id matches the cache's file_seq */ + for (i = 0; ; i++) { + iview = mail_index_view_open(cache->index); + ext = mail_index_view_get_ext(iview, cache->ext_id); + reset_id = ext == NULL ? 0 : ext->reset_id; + mail_index_view_close(&iview); + + if (cache->hdr->file_seq == reset_id) + break; + /* mismatch. try refreshing index once. if that doesn't help, + we can't use the cache. */ + if (i > 0) { + mail_cache_unlock_file(cache); + return 0; } - - if ((ret = mail_cache_lock_file(cache, nonblock)) <= 0) { - ret = -1; - break; - } - cache->locked = TRUE; - - if (cache->hdr->file_seq == reset_id || - !require_same_reset_id) { - /* got it */ - break; - } - - /* okay, so it was just compressed. try again. */ - (void)mail_cache_unlock(cache); - ret = 0; - } - - if (ret > 0) { - /* make sure our header is up to date */ - if (cache->file_cache != NULL) { - file_cache_invalidate(cache->file_cache, 0, - sizeof(struct mail_cache_header)); - } - if (cache->read_buf != NULL) - buffer_set_used_size(cache->read_buf, 0); - if (mail_cache_map(cache, 0, 0, &data) > 0) - cache->hdr_copy = *cache->hdr; - else { - (void)mail_cache_unlock(cache); - ret = -1; + if (mail_index_refresh(cache->index) < 0) { + mail_cache_unlock_file(cache); + return -1; } } - i_assert((ret <= 0 && !cache->locked) || (ret > 0 && cache->locked)); - return ret; + /* successfully locked - make sure our header is up to date */ + cache->locked = TRUE; + cache->hdr_modified = FALSE; + + if (cache->file_cache != NULL) { + file_cache_invalidate(cache->file_cache, 0, + sizeof(struct mail_cache_header)); + } + if (cache->read_buf != NULL) + buffer_set_used_size(cache->read_buf, 0); + if (mail_cache_map(cache, 0, 0, &data) <= 0) { + (void)mail_cache_unlock(cache); + return -1; + } + cache->hdr_copy = *cache->hdr; + return 1; } -int mail_cache_lock(struct mail_cache *cache, bool require_same_reset_id) +int mail_cache_lock(struct mail_cache *cache) { - return mail_cache_lock_full(cache, require_same_reset_id, FALSE); + return mail_cache_lock_full(cache, FALSE); } int mail_cache_try_lock(struct mail_cache *cache) { - return mail_cache_lock_full(cache, FALSE, TRUE); + return mail_cache_lock_full(cache, TRUE); } int mail_cache_unlock(struct mail_cache *cache) From dovecot at dovecot.org Tue Oct 7 15:58:44 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 07 Oct 2014 15:58:44 +0000 Subject: dovecot-2.2: lib-index: Try to minimize race conditions while co... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/bd55bdba0e75 changeset: 17903:bd55bdba0e75 user: Timo Sirainen date: Tue Oct 07 18:58:01 2014 +0300 description: lib-index: Try to minimize race conditions while compressing cache. There are some unavoidable race conditions, but try to keep their time window as small as possible. diffstat: src/lib-index/mail-cache-compress.c | 20 +++++++++++++------- 1 files changed, 13 insertions(+), 7 deletions(-) diffs (60 lines): diff -r 8c84b69e7f69 -r bd55bdba0e75 src/lib-index/mail-cache-compress.c --- a/src/lib-index/mail-cache-compress.c Tue Oct 07 18:47:09 2014 +0300 +++ b/src/lib-index/mail-cache-compress.c Tue Oct 07 18:58:01 2014 +0300 @@ -93,17 +93,23 @@ buffer_append_zero(ctx->buffer, 4 - (field->size & 3)); } -static uint32_t -get_next_file_seq(struct mail_cache *cache, struct mail_index_view *view) +static uint32_t get_next_file_seq(struct mail_cache *cache) { const struct mail_index_ext *ext; + struct mail_index_view *view; uint32_t file_seq; + /* make sure we look up the latest reset_id */ + if (mail_index_refresh(cache->index) < 0) + return -1; + + view = mail_index_view_open(cache->index); ext = mail_index_view_get_ext(view, cache->ext_id); file_seq = ext != NULL ? ext->reset_id + 1 : (uint32_t)ioloop_time; if (cache->hdr != NULL && file_seq <= cache->hdr->file_seq) file_seq = cache->hdr->file_seq + 1; + mail_index_view_close(&view); return file_seq != 0 ? file_seq : 1; } @@ -166,6 +172,10 @@ unsigned int i, used_fields_count, orig_fields_count, record_count; time_t max_drop_time; + /* get the latest info on fields */ + if (mail_cache_header_fields_read(cache) < 0) + return -1; + view = mail_index_transaction_get_view(trans); cache_view = mail_cache_view_open(cache, view); output = o_stream_create_fd_file(fd, 0, FALSE); @@ -175,7 +185,7 @@ hdr.minor_version = MAIL_CACHE_MINOR_VERSION; hdr.compat_sizeof_uoff_t = sizeof(uoff_t); hdr.indexid = cache->index->indexid; - hdr.file_seq = get_next_file_seq(cache, view); + hdr.file_seq = get_next_file_seq(cache); o_stream_nsend(output, &hdr, sizeof(hdr)); memset(&ctx, 0, sizeof(ctx)); @@ -353,10 +363,6 @@ unsigned int i, count; int fd, ret; - /* get the latest info on fields */ - if (mail_cache_header_fields_read(cache) < 0) - return -1; - old_mask = umask(cache->index->mode ^ 0666); fd = file_dotlock_open(&cache->dotlock_settings, cache->filepath, DOTLOCK_CREATE_FLAG_NONBLOCK, &dotlock); From dovecot at dovecot.org Tue Oct 7 16:07:50 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 07 Oct 2014 16:07:50 +0000 Subject: dovecot-2.2: lib-index: Added path parameter to mail_index_creat... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0a34975b2dcc changeset: 17904:0a34975b2dcc user: Timo Sirainen date: Tue Oct 07 19:04:36 2014 +0300 description: lib-index: Added path parameter to mail_index_create_tmp_file() This allows using it for creating any kind of a new index file with proper file permissions. Some of the old code should probably be changed to use this. Maybe even move this function to public mail-index.h diffstat: src/lib-index/mail-index-private.h | 3 ++- src/lib-index/mail-index-write.c | 2 +- src/lib-index/mail-index.c | 5 +++-- 3 files changed, 6 insertions(+), 4 deletions(-) diffs (47 lines): diff -r bd55bdba0e75 -r 0a34975b2dcc src/lib-index/mail-index-private.h --- a/src/lib-index/mail-index-private.h Tue Oct 07 18:58:01 2014 +0300 +++ b/src/lib-index/mail-index-private.h Tue Oct 07 19:04:36 2014 +0300 @@ -259,7 +259,8 @@ void mail_index_unregister_sync_lost_handler(struct mail_index *index, mail_index_sync_lost_handler_t *cb); -int mail_index_create_tmp_file(struct mail_index *index, const char **path_r); +int mail_index_create_tmp_file(struct mail_index *index, + const char *path_prefix, const char **path_r); int mail_index_try_open_only(struct mail_index *index); void mail_index_close_file(struct mail_index *index); diff -r bd55bdba0e75 -r 0a34975b2dcc src/lib-index/mail-index-write.c --- a/src/lib-index/mail-index-write.c Tue Oct 07 18:58:01 2014 +0300 +++ b/src/lib-index/mail-index-write.c Tue Oct 07 19:04:36 2014 +0300 @@ -68,7 +68,7 @@ i_assert(!MAIL_INDEX_IS_IN_MEMORY(index)); i_assert(map->hdr.indexid == index->indexid); - fd = mail_index_create_tmp_file(index, &path); + fd = mail_index_create_tmp_file(index, index->filepath, &path); if (fd == -1) return -1; diff -r bd55bdba0e75 -r 0a34975b2dcc src/lib-index/mail-index.c --- a/src/lib-index/mail-index.c Tue Oct 07 18:58:01 2014 +0300 +++ b/src/lib-index/mail-index.c Tue Oct 07 19:04:36 2014 +0300 @@ -438,7 +438,8 @@ return ret; } -int mail_index_create_tmp_file(struct mail_index *index, const char **path_r) +int mail_index_create_tmp_file(struct mail_index *index, + const char *path_prefix, const char **path_r) { mode_t old_mask; const char *path; @@ -446,7 +447,7 @@ i_assert(!MAIL_INDEX_IS_IN_MEMORY(index)); - path = *path_r = t_strconcat(index->filepath, ".tmp", NULL); + path = *path_r = t_strconcat(path_prefix, ".tmp", NULL); old_mask = umask(0); fd = open(path, O_RDWR|O_CREAT|O_EXCL, index->mode); umask(old_mask); From dovecot at dovecot.org Tue Oct 7 16:07:50 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 07 Oct 2014 16:07:50 +0000 Subject: dovecot-2.2: lib-index: Delay unlocking cache compression until ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/51f5680d4108 changeset: 17905:51f5680d4108 user: Timo Sirainen date: Tue Oct 07 19:07:16 2014 +0300 description: lib-index: Delay unlocking cache compression until changes to transaction log are committed. This should fix race condition with two processes compressing the file at the same time with same file_seq and becoming confused. diffstat: src/lib-index/mail-cache-compress.c | 228 ++++++++++++++++++++------------ src/lib-index/mail-cache-transaction.c | 5 +- src/lib-index/mail-cache.h | 11 +- src/lib-index/mail-index-sync.c | 13 +- src/lib-storage/index/index-rebuild.c | 10 +- 5 files changed, 170 insertions(+), 97 deletions(-) diffs (truncated from 436 to 300 lines): diff -r 0a34975b2dcc -r 51f5680d4108 src/lib-index/mail-cache-compress.c --- a/src/lib-index/mail-cache-compress.c Tue Oct 07 19:04:36 2014 +0300 +++ b/src/lib-index/mail-cache-compress.c Tue Oct 07 19:07:16 2014 +0300 @@ -10,6 +10,7 @@ #include "file-set-size.h" #include "mail-cache-private.h" +#include #include struct mail_cache_copy_context { @@ -23,6 +24,10 @@ bool new_msg; }; +struct mail_cache_compress_lock { + struct dotlock *dotlock; +}; + static void mail_cache_merge_bitmask(struct mail_cache_copy_context *ctx, const struct mail_cache_iterate_field *field) @@ -315,104 +320,27 @@ return 0; } -static int mail_cache_compress_has_file_changed(struct mail_cache *cache) +static int +mail_cache_compress_write(struct mail_cache *cache, + struct mail_index_transaction *trans, + int fd, const char *temp_path, bool *unlock) { - struct mail_cache_header hdr; - unsigned int i; - int fd, ret; - - for (i = 0;; i++) { - fd = nfs_safe_open(cache->filepath, O_RDONLY); - if (fd == -1) { - if (errno == ENOENT) - return 0; - - mail_cache_set_syscall_error(cache, "open()"); - return -1; - } - - ret = read_full(fd, &hdr, sizeof(hdr)); - i_close_fd(&fd); - - if (ret >= 0) { - if (ret == 0) - return 0; - if (cache->need_compress_file_seq == 0) { - /* previously it didn't exist */ - return 1; - } - return hdr.file_seq != cache->need_compress_file_seq; - } else if (errno != ESTALE || i >= NFS_ESTALE_RETRY_COUNT) { - mail_cache_set_syscall_error(cache, "read()"); - return -1; - } - } -} - -static int mail_cache_compress_locked(struct mail_cache *cache, - struct mail_index_transaction *trans, - bool *unlock) -{ - struct dotlock *dotlock; struct stat st; - mode_t old_mask; uint32_t file_seq, old_offset; ARRAY_TYPE(uint32_t) ext_offsets; const uint32_t *offsets; - const void *data; unsigned int i, count; - int fd, ret; - old_mask = umask(cache->index->mode ^ 0666); - fd = file_dotlock_open(&cache->dotlock_settings, cache->filepath, - DOTLOCK_CREATE_FLAG_NONBLOCK, &dotlock); - umask(old_mask); - - if (fd == -1) { - if (errno != EAGAIN) - mail_cache_set_syscall_error(cache, "file_dotlock_open()"); + if (mail_cache_copy(cache, trans, fd, &file_seq, &ext_offsets) < 0) return -1; - } - - if ((ret = mail_cache_compress_has_file_changed(cache)) != 0) { - if (ret < 0) - return -1; - - /* was just compressed, forget this */ - cache->need_compress_file_seq = 0; - file_dotlock_delete(&dotlock); - - if (*unlock) { - (void)mail_cache_unlock(cache); - *unlock = FALSE; - } - - return mail_cache_reopen(cache); - } - - mail_index_fchown(cache->index, fd, - file_dotlock_get_lock_path(dotlock)); - - if (mail_cache_copy(cache, trans, fd, &file_seq, &ext_offsets) < 0) { - /* the fields may have been updated in memory already. - reverse those changes by re-reading them from file. */ - if (mail_cache_header_fields_read(cache) < 0) - return -1; - file_dotlock_delete(&dotlock); - return -1; - } if (fstat(fd, &st) < 0) { mail_cache_set_syscall_error(cache, "fstat()"); - file_dotlock_delete(&dotlock); + array_free(&ext_offsets); return -1; } - - if (file_dotlock_replace(&dotlock, - DOTLOCK_REPLACE_FLAG_DONT_CLOSE_FD) < 0) { - mail_cache_set_syscall_error(cache, - "file_dotlock_replace()"); - i_close_fd(&fd); + if (rename(temp_path, cache->filepath) < 0) { + mail_cache_set_syscall_error(cache, "rename()"); array_free(&ext_offsets); return -1; } @@ -439,7 +367,101 @@ cache->st_ino = st.st_ino; cache->st_dev = st.st_dev; cache->field_header_write_pending = FALSE; + return 0; +} +static int mail_cache_compress_has_file_changed(struct mail_cache *cache) +{ + struct mail_cache_header hdr; + unsigned int i; + int fd, ret; + + for (i = 0;; i++) { + fd = nfs_safe_open(cache->filepath, O_RDONLY); + if (fd == -1) { + if (errno == ENOENT) + return 0; + + mail_cache_set_syscall_error(cache, "open()"); + return -1; + } + + ret = read_full(fd, &hdr, sizeof(hdr)); + i_close_fd(&fd); + + if (ret >= 0) { + if (ret == 0) + return 0; + if (cache->need_compress_file_seq == 0) { + /* previously it didn't exist or it + was unusable and was just unlinked */ + return 1; + } + return hdr.file_seq != cache->need_compress_file_seq; + } else if (errno != ESTALE || i >= NFS_ESTALE_RETRY_COUNT) { + mail_cache_set_syscall_error(cache, "read()"); + return -1; + } + } +} + +static int mail_cache_compress_dotlock(struct mail_cache *cache, + struct dotlock **dotlock_r) +{ + if (file_dotlock_create(&cache->dotlock_settings, cache->filepath, + DOTLOCK_CREATE_FLAG_NONBLOCK, dotlock_r) <= 0) { + if (errno != EAGAIN) + mail_cache_set_syscall_error(cache, "file_dotlock_open()"); + return -1; + } + return 0; +} + +static int mail_cache_compress_locked(struct mail_cache *cache, + struct mail_index_transaction *trans, + bool *unlock, struct dotlock **dotlock_r) +{ + const char *temp_path; + const void *data; + int fd, ret; + + /* There are two possible locking situations here: + a) Cache is locked against any modifications. + b) Cache doesn't exist or is unusable. There's no lock. + Because the cache lock itself is unreliable, we'll be using a + separate dotlock to guard against two processes compressing the + cache at the same time. */ + + if (mail_cache_compress_dotlock(cache, dotlock_r) < 0) + return -1; + /* we've locked the cache compression now. if somebody else had just + recreated the cache, reopen the cache and return success. */ + if ((ret = mail_cache_compress_has_file_changed(cache)) != 0) { + if (ret < 0) + return -1; + + /* was just compressed, forget this */ + cache->need_compress_file_seq = 0; + file_dotlock_delete(dotlock_r); + + if (*unlock) { + (void)mail_cache_unlock(cache); + *unlock = FALSE; + } + + return mail_cache_reopen(cache) < 0 ? -1 : 0; + } + + /* we want to recreate the cache. write it first to a temporary file */ + fd = mail_index_create_tmp_file(cache->index, cache->filepath, &temp_path); + if (fd == -1) + return -1; + if (mail_cache_compress_write(cache, trans, fd, temp_path, unlock) < 0) { + i_close_fd(&fd); + if (unlink(temp_path) < 0) + i_error("unlink(%s) failed: %m", temp_path); + return -1; + } if (cache->file_cache != NULL) file_cache_set_fd(cache->file_cache, cache->fd); @@ -453,15 +475,21 @@ } int mail_cache_compress(struct mail_cache *cache, - struct mail_index_transaction *trans) + struct mail_index_transaction *trans, + struct mail_cache_compress_lock **lock_r) { + struct dotlock *dotlock = NULL; bool unlock = FALSE; int ret; i_assert(!cache->compressing); - if (MAIL_INDEX_IS_IN_MEMORY(cache->index) || cache->index->readonly) + *lock_r = NULL; + + if (MAIL_INDEX_IS_IN_MEMORY(cache->index) || cache->index->readonly) { + *lock_r = i_new(struct mail_cache_compress_lock, 1); return 0; + } /* compression isn't very efficient with small read()s */ if (cache->map_with_read) { @@ -483,9 +511,10 @@ } else { switch (mail_cache_try_lock(cache)) { case -1: + /* already locked or some other error */ return -1; case 0: - /* couldn't lock, either it's broken or doesn't exist. + /* cache is broken or doesn't exist. just start creating it. */ break; default: @@ -494,15 +523,36 @@ } } cache->compressing = TRUE; - ret = mail_cache_compress_locked(cache, trans, &unlock); + ret = mail_cache_compress_locked(cache, trans, &unlock, &dotlock); cache->compressing = FALSE; if (unlock) { if (mail_cache_unlock(cache) < 0) ret = -1; } + if (ret < 0) { + if (dotlock != NULL) + file_dotlock_delete(&dotlock); + /* the fields may have been updated in memory already. + reverse those changes by re-reading them from file. */ + (void)mail_cache_header_fields_read(cache); + } else { + *lock_r = i_new(struct mail_cache_compress_lock, 1); + (*lock_r)->dotlock = dotlock; + } return ret; } +void mail_cache_compress_unlock(struct mail_cache_compress_lock **_lock) +{ + struct mail_cache_compress_lock *lock = *_lock; From dovecot at dovecot.org Tue Oct 7 16:49:20 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 07 Oct 2014 16:49:20 +0000 Subject: dovecot-2.2: lib-fs: struct fs_file's write_pending is a flag Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/66842b55d2de changeset: 17906:66842b55d2de user: Phil Carmody date: Tue Oct 07 19:48:34 2014 +0300 description: lib-fs: struct fs_file's write_pending is a flag Signed-off-by: Phil Carmody diffstat: src/lib-fs/fs-api-private.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 51f5680d4108 -r 66842b55d2de src/lib-fs/fs-api-private.h --- a/src/lib-fs/fs-api-private.h Tue Oct 07 19:07:16 2014 +0300 +++ b/src/lib-fs/fs-api-private.h Tue Oct 07 19:48:34 2014 +0300 @@ -94,7 +94,7 @@ struct istream *copy_input; struct ostream *copy_output; - unsigned int write_pending; + unsigned int write_pending:1; unsigned int metadata_changed:1; }; From dovecot at dovecot.org Tue Oct 7 17:28:45 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 07 Oct 2014 17:28:45 +0000 Subject: dovecot-2.2: lib-index: Fixed assert-crash in some cache locking... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/51233ae4af26 changeset: 17907:51233ae4af26 user: Timo Sirainen date: Tue Oct 07 20:13:36 2014 +0300 description: lib-index: Fixed assert-crash in some cache locking race conditions. If mail_index_map() is being called, we can't refresh the index or it'll crash. It wouldn't help anyway, since the index was just refreshed. diffstat: src/lib-index/mail-cache.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 66842b55d2de -r 51233ae4af26 src/lib-index/mail-cache.c --- a/src/lib-index/mail-cache.c Tue Oct 07 19:48:34 2014 +0300 +++ b/src/lib-index/mail-cache.c Tue Oct 07 20:13:36 2014 +0300 @@ -659,7 +659,7 @@ break; /* mismatch. try refreshing index once. if that doesn't help, we can't use the cache. */ - if (i > 0) { + if (i > 0 || cache->index->mapping) { mail_cache_unlock_file(cache); return 0; } From dovecot at dovecot.org Tue Oct 7 17:28:45 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 07 Oct 2014 17:28:45 +0000 Subject: dovecot-2.2: lib-mail: Added asserts Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/64e59ebcfe25 changeset: 17908:64e59ebcfe25 user: Timo Sirainen date: Tue Oct 07 20:28:06 2014 +0300 description: lib-mail: Added asserts diffstat: src/lib-mail/message-parser.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (20 lines): diff -r 51233ae4af26 -r 64e59ebcfe25 src/lib-mail/message-parser.c --- a/src/lib-mail/message-parser.c Tue Oct 07 20:13:36 2014 +0300 +++ b/src/lib-mail/message-parser.c Tue Oct 07 20:28:06 2014 +0300 @@ -984,6 +984,8 @@ { struct message_parser_ctx *ctx; + i_assert(parts != NULL); + ctx = message_parser_init_int(input, hdr_flags, flags); ctx->parts = ctx->part = parts; ctx->parse_next_block = preparsed_parse_next_header_init; @@ -1003,6 +1005,7 @@ message_parse_header_deinit(&ctx->hdr_parser_ctx); i_stream_unref(&ctx->input); pool_unref(&ctx->parser_pool); + i_assert(ret < 0 || *parts_r != NULL); return ret; } From dovecot at dovecot.org Tue Oct 7 17:29:50 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 07 Oct 2014 17:29:50 +0000 Subject: dovecot-2.2: lib-storage: Fixed assert-crash when BODYSTRUCTURE ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2b84c33d5d11 changeset: 17909:2b84c33d5d11 user: Timo Sirainen date: Tue Oct 07 20:29:16 2014 +0300 description: lib-storage: Fixed assert-crash when BODYSTRUCTURE parsing fails due to broken mail size. diffstat: src/lib-storage/index/index-mail.c | 26 +++++++++++++++----------- 1 files changed, 15 insertions(+), 11 deletions(-) diffs (36 lines): diff -r 64e59ebcfe25 -r 2b84c33d5d11 src/lib-storage/index/index-mail.c --- a/src/lib-storage/index/index-mail.c Tue Oct 07 20:28:06 2014 +0300 +++ b/src/lib-storage/index/index-mail.c Tue Oct 07 20:29:16 2014 +0300 @@ -847,17 +847,21 @@ i_stream_ref(parser_input); ret = message_parser_deinit(&mail->data.parser_ctx, &mail->data.parts) < 0 ? 0 : 1; - if (parser_input->stream_errno == 0 || - parser_input->stream_errno == EPIPE) { - /* EPIPE = input already closed. allow the caller to - decide if that is an error or not. (for example we - could be coming here from IMAP APPEND when IMAP - client has closed the connection too early. we - don't want to log an error in that case.) */ - i_assert(!success || - (i_stream_read(parser_input) == -1 && - !i_stream_have_bytes_left(parser_input))); - } else { + if (success && (parser_input->stream_errno == 0 || + parser_input->stream_errno == EPIPE)) { + /* do one final read, which verifies that the message + size is correct. */ + if (i_stream_read(parser_input) != -1 || + i_stream_have_bytes_left(parser_input)) + i_unreached(); + } + /* EPIPE = input already closed. allow the caller to + decide if that is an error or not. (for example we + could be coming here from IMAP APPEND when IMAP + client has closed the connection too early. we + don't want to log an error in that case.) */ + if (parser_input->stream_errno != 0 && + parser_input->stream_errno != EPIPE) { index_mail_stream_log_failure_for(mail, parser_input); ret = -1; } From dovecot at dovecot.org Tue Oct 7 18:36:30 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 07 Oct 2014 18:36:30 +0000 Subject: dovecot-2.2: lib-storage: Fixed some race condition crashes with... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/96f79038038f changeset: 17910:96f79038038f user: Timo Sirainen date: Tue Oct 07 21:35:44 2014 +0300 description: lib-storage: Fixed some race condition crashes with LAYOUT=index diffstat: src/lib-storage/list/mailbox-list-index-backend.c | 90 +++++++++++++++------- src/lib-storage/list/mailbox-list-index.c | 13 ++- src/lib-storage/list/mailbox-list-index.h | 4 + 3 files changed, 76 insertions(+), 31 deletions(-) diffs (193 lines): diff -r 2b84c33d5d11 -r 96f79038038f src/lib-storage/list/mailbox-list-index-backend.c --- a/src/lib-storage/list/mailbox-list-index-backend.c Tue Oct 07 20:29:16 2014 +0300 +++ b/src/lib-storage/list/mailbox-list-index-backend.c Tue Oct 07 21:35:44 2014 +0300 @@ -66,8 +66,8 @@ } static int -index_list_get_node(struct index_mailbox_list *list, const char *name, - struct mailbox_list_index_node **node_r) +index_list_get_refreshed_node(struct index_mailbox_list *list, const char *name, + struct mailbox_list_index_node **node_r) { struct mailbox_list_index_node *node; @@ -81,6 +81,33 @@ return 1; } +static int +index_list_get_refreshed_node_seq(struct index_mailbox_list *list, + struct mail_index_view *view, + const char *name, + struct mailbox_list_index_node **node_r, + uint32_t *seq_r) +{ + unsigned int i; + int ret; + + *node_r = NULL; + *seq_r = 0; + + for (i = 0; i < 2; i++) { + if ((ret = index_list_get_refreshed_node(list, name, node_r)) <= 0) + return ret; + if (mail_index_lookup_seq(view, (*node_r)->uid, seq_r)) + return 1; + /* mailbox was just expunged. refreshing should notice it. */ + if (mailbox_list_index_refresh_force(&list->list) < 0) + return -1; + } + i_panic("mailbox list index: refreshing doesn't lose expunged uid=%u", + (*node_r)->uid); + return -1; +} + static const char * index_get_guid_path(struct mailbox_list *_list, const char *root_dir, const guid_128_t mailbox_guid) @@ -124,22 +151,35 @@ if (!mailbox_list_set_get_root_path(&_list->set, type, &root_dir)) return 0; - if ((ret = index_list_get_node(list, name, &node)) <= 0) { - if (ret == 0) { - mailbox_list_set_error(_list, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + if (ilist->sync_ctx != NULL) { + /* we could get here during sync from + index_list_mailbox_create_selectable() */ + view = ilist->sync_ctx->view; + node = mailbox_list_index_lookup(&list->list, name); + if (node == NULL) { + seq = 0; + ret = 0; + } else if (mail_index_lookup_seq(view, node->uid, &seq)) { + ret = 1; + } else { + i_panic("mailbox list index: lost uid=%u", node->uid); } - return -1; + } else { + view = mail_index_view_open(ilist->index); + ret = index_list_get_refreshed_node_seq(list, view, name, &node, &seq); + if (ret < 0) { + mail_index_view_close(&view); + return -1; + } } - /* we could get here during sync from - index_list_mailbox_create_selectable() */ - view = ilist->sync_ctx == NULL ? mail_index_view_open(ilist->index) : - ilist->sync_ctx->view; - if (!mail_index_lookup_seq(view, node->uid, &seq)) - i_panic("mailbox list index: lost uid=%u", node->uid); - if (!mailbox_list_index_status(_list, view, seq, 0, - &status, mailbox_guid) || - guid_128_is_empty(mailbox_guid)) { + i_assert(ret == 0 || seq != 0); + if (ret == 0) { + mailbox_list_set_error(_list, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + ret = -1; + } else if (!mailbox_list_index_status(_list, view, seq, 0, + &status, mailbox_guid) || + guid_128_is_empty(mailbox_guid)) { mailbox_list_set_error(_list, MAIL_ERROR_NOTFOUND, T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); ret = -1; @@ -188,7 +228,7 @@ *existence_r = MAILBOX_EXISTENCE_NONE; - if ((ret = index_list_get_node(list, name, &node)) < 0) + if ((ret = index_list_get_refreshed_node(list, name, &node)) < 0) return -1; if (ret == 0) return 0; @@ -435,16 +475,12 @@ const void *data; bool expunged; uint32_t seq; - int ret; if (mailbox_list_index_sync_begin(&list->list, &sync_ctx) < 0) return -1; - if ((ret = index_list_get_node(list, name, &node)) < 0) { - (void)mailbox_list_index_sync_end(&sync_ctx, FALSE); - return -1; - } - if (ret == 0) { + node = mailbox_list_index_lookup(&list->list, name); + if (node == NULL) { (void)mailbox_list_index_sync_end(&sync_ctx, FALSE); mailbox_list_set_error(&list->list, MAIL_ERROR_NOTFOUND, T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); @@ -552,7 +588,6 @@ const void *data; bool created, expunged; uint32_t oldseq, newseq; - int ret; if (_oldlist != _newlist) { mailbox_list_set_error(_oldlist, MAIL_ERROR_NOTPOSSIBLE, @@ -563,11 +598,8 @@ if (mailbox_list_index_sync_begin(&list->list, &sync_ctx) < 0) return -1; - if ((ret = index_list_get_node(list, oldname, &oldnode)) < 0) { - (void)mailbox_list_index_sync_end(&sync_ctx, FALSE); - return -1; - } - if (ret == 0) { + oldnode = mailbox_list_index_lookup(&list->list, oldname); + if (oldnode == NULL) { (void)mailbox_list_index_sync_end(&sync_ctx, FALSE); mailbox_list_set_error(&list->list, MAIL_ERROR_NOTFOUND, T_MAIL_ERR_MAILBOX_NOT_FOUND(oldname)); diff -r 2b84c33d5d11 -r 96f79038038f src/lib-storage/list/mailbox-list-index.c --- a/src/lib-storage/list/mailbox-list-index.c Tue Oct 07 20:29:16 2014 +0300 +++ b/src/lib-storage/list/mailbox-list-index.c Tue Oct 07 21:35:44 2014 +0300 @@ -362,8 +362,6 @@ int mailbox_list_index_refresh(struct mailbox_list *list) { struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list); - struct mail_index_view *view; - int ret; if (ilist->syncing) return 0; @@ -376,6 +374,17 @@ return 0; } + return mailbox_list_index_refresh_force(list); +} + +int mailbox_list_index_refresh_force(struct mailbox_list *list) +{ + struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list); + struct mail_index_view *view; + int ret; + + i_assert(!ilist->syncing); + ilist->last_refresh_timeval = ioloop_timeval; if (mailbox_list_index_index_open(list) < 0) return -1; diff -r 2b84c33d5d11 -r 96f79038038f src/lib-storage/list/mailbox-list-index.h --- a/src/lib-storage/list/mailbox-list-index.h Tue Oct 07 20:29:16 2014 +0300 +++ b/src/lib-storage/list/mailbox-list-index.h Tue Oct 07 21:35:44 2014 +0300 @@ -142,7 +142,11 @@ int mailbox_list_index_index_open(struct mailbox_list *list); bool mailbox_list_index_need_refresh(struct mailbox_list_index *ilist, struct mail_index_view *view); +/* Refresh the index, but only if it hasn't been refreshed "recently" + (= within this same ioloop run) */ int mailbox_list_index_refresh(struct mailbox_list *list); +/* Refresh the index regardless of when the last refresh was done. */ +int mailbox_list_index_refresh_force(struct mailbox_list *list); void mailbox_list_index_refresh_later(struct mailbox_list *list); struct mailbox_list_index_node * From pigeonhole at rename-it.nl Tue Oct 7 21:13:02 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 07 Oct 2014 23:13:02 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve-tool: Simplified seekable stre... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/54c54979eb5b changeset: 1917:54c54979eb5b user: Stephan Bosch date: Tue Oct 07 23:12:20 2014 +0200 description: lib-sieve-tool: Simplified seekable stream callback for raw mail. No longer needed to create the temp directory. diffstat: src/lib-sieve-tool/mail-raw.c | 15 --------------- 1 files changed, 0 insertions(+), 15 deletions(-) diffs (38 lines): diff -r ce0657ede24e -r 54c54979eb5b src/lib-sieve-tool/mail-raw.c --- a/src/lib-sieve-tool/mail-raw.c Fri Sep 12 12:17:38 2014 +0200 +++ b/src/lib-sieve-tool/mail-raw.c Tue Oct 07 23:12:20 2014 +0200 @@ -9,7 +9,6 @@ #include "str-sanitize.h" #include "strescape.h" #include "safe-mkstemp.h" -#include "mkdir-parents.h" #include "abspath.h" #include "message-address.h" #include "mbox-from.h" @@ -58,26 +57,12 @@ (const char **path_r, void *context) { struct mail_user *ruser = (struct mail_user *)context; - const char *dir, *p; string_t *path; int fd; path = t_str_new(128); mail_user_set_get_temp_prefix(path, ruser->set); fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1); - if (fd == -1 && errno == ENOENT) { - dir = str_c(path); - p = strrchr(dir, '/'); - if (p != NULL) { - dir = t_strdup_until(dir, p); - if ( mkdir_parents(dir, 0600) < 0 ) { - i_error("mkdir_parents(%s) failed: %m", dir); - return -1; - } - fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1); - } - } - if (fd == -1) { i_error("safe_mkstemp(%s) failed: %m", str_c(path)); return -1; From dovecot at dovecot.org Tue Oct 7 22:26:31 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 07 Oct 2014 22:26:31 +0000 Subject: dovecot-2.2: man: Added doveadm-proxy.1. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/71b010a63bae changeset: 17911:71b010a63bae user: Pascal Volk date: Tue Oct 07 22:24:21 2014 +0000 description: man: Added doveadm-proxy.1. diffstat: .hgignore | 2 +- doc/man/Makefile.am | 2 + doc/man/doveadm-proxy.1.in | 86 ++++++++++++++++++++++++++++++++++++++++++++++ doc/man/doveadm.1.in | 7 +++- 4 files changed, 95 insertions(+), 2 deletions(-) diffs (142 lines): diff -r 96f79038038f -r 71b010a63bae .hgignore --- a/.hgignore Tue Oct 07 21:35:44 2014 +0300 +++ b/.hgignore Tue Oct 07 22:24:21 2014 +0000 @@ -105,5 +105,5 @@ syntax: regexp src/.*/test-[^\.]*$ -doc/man/doveadm-(acl|altmove|auth|batch|deduplicate|director|dump|exec|expunge|fetch|flags|fts|import|instance|index|force-resync|help|kick|log|mailbox|mount|move|penalty|purge|pw|quota|replicator|search|sync|user|who)\.1$ +doc/man/doveadm-(acl|altmove|auth|batch|deduplicate|director|dump|exec|expunge|fetch|flags|fts|import|instance|index|force-resync|help|kick|log|mailbox|mount|move|penalty|proxy|purge|pw|quota|replicator|search|sync|user|who)\.1$ doc/man/(doveadm|doveconf|dovecot-lda|dovecot)\.1$ diff -r 96f79038038f -r 71b010a63bae doc/man/Makefile.am --- a/doc/man/Makefile.am Tue Oct 07 21:35:44 2014 +0300 +++ b/doc/man/Makefile.am Tue Oct 07 22:24:21 2014 +0000 @@ -39,6 +39,7 @@ doveadm-mount.1 \ doveadm-move.1 \ doveadm-penalty.1 \ + doveadm-proxy.1 \ doveadm-purge.1 \ doveadm-pw.1 \ doveadm-quota.1 \ @@ -84,6 +85,7 @@ doveadm-mount.1.in \ doveadm-move.1.in \ doveadm-penalty.1.in \ + doveadm-proxy.1.in \ doveadm-purge.1.in \ doveadm-pw.1.in \ doveadm-quota.1.in \ diff -r 96f79038038f -r 71b010a63bae doc/man/doveadm-proxy.1.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/man/doveadm-proxy.1.in Tue Oct 07 22:24:21 2014 +0000 @@ -0,0 +1,86 @@ +.\" Copyright (c) 2014 Dovecot authors, see the included COPYING file +.TH DOVEADM\-PROXY 1 "2014-10-07" "Dovecot v2.2" "Dovecot" +.SH NAME +doveadm\-proxy \- Handle Dovecot proxy connections +.\"------------------------------------------------------------------------ +.SH SYNOPSIS +.BR doveadm " [" \-Dv ] +[\fB\-f\fP \fIformatter\fP] +.BI proxy \ command +.RI [ OPTIONS ]\ [ ARGUMENTS ] +.\"------------------------------------------------------------------------ +.SH DESCRIPTION +The +.B doveadm proxy +.I commands +are used to list or kick active Dovecot proxy connections. +.\"------------------------------------------------------------------------ + at INCLUDE:global-options-formatter@ +.\" --- command specific options --- "/. +.PP +This command uses by default the +.B table +output formatter. +.PP +Command specific +.IR options : +.\"------------------------------------- +.TP +.BI \-a \ ipc_socket_path +This option is used to specify an alternative socket. +The option\(aqs argument is either an absolute path to a local UNIX domain +socket, or a hostname and port +.RI ( hostname : port ), +in order to connect a remote host via a TCP socket. +.sp +By default +.BR doveadm (1) +will use the socket +.IR @rundir@/ipc . +The socket may be located in another directory, when the default +.I base_dir +setting was overridden in +.IR @pkgsysconfdir@/dovecot.conf . +.\"------------------------------------------------------------------------ +.SH ARGUMENTS +.TP +.I user +Is a +.IR user \(aqs +login name. +Depending on the configuration, a login name may be for example +.BR jane " or " john at example.com . +It\(aqs also possible to use +.RB \(dq * \(dq +and +.RB \(dq ? \(dq +wildcards (e.g. *@example.org). +.\"------------------------------------------------------------------------ +.SH COMMANDS +.SS proxy kick +.B doveadm proxy kick +[\fB\-a\fP \fIipc_socket_path\fP] +.I user +.PP +Kick all the connections being proxied for the given +.IR user . +.\"------------------------------------- +.SS proxy list +.B doveadm proxy list +[\fB\-a\fP \fIipc_socket_path\fP] +.PP +List all the users currently being proxied. +.\"------------------------------------------------------------------------ +.SH EXAMPLE +List all currently active proxy connections: +.PP +.nf +.B doveadm proxy list +username proto src ip dest ip port +jane at example.net imap 192.168.0.100 192.168.0.5 143 +.fi +.\"------------------------------------------------------------------------ + at INCLUDE:reporting-bugs@ +.\"------------------------------------------------------------------------ +.SH SEE ALSO +.BR doveadm (1) \ No newline at end of file diff -r 96f79038038f -r 71b010a63bae doc/man/doveadm.1.in --- a/doc/man/doveadm.1.in Tue Oct 07 21:35:44 2014 +0300 +++ b/doc/man/doveadm.1.in Tue Oct 07 22:24:21 2014 +0000 @@ -1,5 +1,5 @@ .\" Copyright (c) 2010-2014 Dovecot authors, see the included COPYING file -.TH DOVEADM 1 "2014-09-24" "Dovecot v2.2" "Dovecot" +.TH DOVEADM 1 "2014-10-07" "Dovecot v2.2" "Dovecot" .SH NAME doveadm \- Dovecot\(aqs administration utility .\"------------------------------------------------------------------------ @@ -74,6 +74,11 @@ Show current penalties. .\"------------------------------------- .TP +.B doveadm proxy +.BR doveadm\-proxy (1), +Handle Dovecot proxy connections. +.\"------------------------------------- +.TP .B doveadm who .BR doveadm\-who (1); Show who is logged in to the Dovecot server. From pigeonhole at rename-it.nl Tue Oct 7 22:32:39 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Wed, 08 Oct 2014 00:32:39 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: Addressed race condition writ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/fe7ce895158b changeset: 1918:fe7ce895158b user: Stephan Bosch date: Wed Oct 08 00:32:28 2014 +0200 description: lib-sieve: Addressed race condition writing to user error log file. diffstat: src/lib-sieve/sieve-error.c | 18 +++++++++++++----- 1 files changed, 13 insertions(+), 5 deletions(-) diffs (31 lines): diff -r 54c54979eb5b -r fe7ce895158b src/lib-sieve/sieve-error.c --- a/src/lib-sieve/sieve-error.c Tue Oct 07 23:12:20 2014 +0200 +++ b/src/lib-sieve/sieve-error.c Wed Oct 08 00:32:28 2014 +0200 @@ -1032,14 +1032,22 @@ /* Rotate logfile */ rotated = t_strconcat(ehandler->logfile, ".0", NULL); - if ( rename(ehandler->logfile, rotated) < 0 ) { - sieve_sys_error(svinst, - "failed to rotate logfile: rename(%s, %s) failed: %m", - ehandler->logfile, rotated); + if ( rename(ehandler->logfile, rotated) < 0 && errno != ENOENT ) { + if ( errno == EACCES ) { + sieve_sys_error(svinst, + "failed to rotate logfile: %s", + eacces_error_get_creating("rename", + t_strconcat(ehandler->logfile, ", ", rotated, NULL))); + } else { + sieve_sys_error(svinst, + "failed to rotate logfile: rename(%s, %s) failed: %m", + ehandler->logfile, rotated); + } } /* Open clean logfile (overwrites existing if rename() failed earlier) */ - fd = open(ehandler->logfile, O_CREAT | O_WRONLY | O_TRUNC, 0600); + fd = open(ehandler->logfile, + O_CREAT | O_APPEND | O_WRONLY | O_TRUNC, 0600); if (fd == -1) { if ( errno == EACCES ) { sieve_sys_error(svinst, From dovecot at dovecot.org Wed Oct 8 08:34:38 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 08 Oct 2014 08:34:38 +0000 Subject: dovecot-2.2: lib-storage: Fixed earlier LAYOUT=index change to r... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6252183ada83 changeset: 17912:6252183ada83 user: Timo Sirainen date: Wed Oct 08 11:33:50 2014 +0300 description: lib-storage: Fixed earlier LAYOUT=index change to refresh index before opening a view to it. Fixes an assert-crash. diffstat: src/lib-storage/list/mailbox-list-index-backend.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 71b010a63bae -r 6252183ada83 src/lib-storage/list/mailbox-list-index-backend.c --- a/src/lib-storage/list/mailbox-list-index-backend.c Tue Oct 07 22:24:21 2014 +0000 +++ b/src/lib-storage/list/mailbox-list-index-backend.c Wed Oct 08 11:33:50 2014 +0300 @@ -165,6 +165,8 @@ i_panic("mailbox list index: lost uid=%u", node->uid); } } else { + if (mailbox_list_index_refresh(&list->list) < 0) + return -1; view = mail_index_view_open(ilist->index); ret = index_list_get_refreshed_node_seq(list, view, name, &node, &seq); if (ret < 0) { From dovecot at dovecot.org Wed Oct 8 08:34:39 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 08 Oct 2014 08:34:39 +0000 Subject: dovecot-2.2: lib-storage: LAYOUT=index small code cleanup Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/57aa5f0f9b91 changeset: 17913:57aa5f0f9b91 user: Timo Sirainen date: Wed Oct 08 11:34:05 2014 +0300 description: lib-storage: LAYOUT=index small code cleanup diffstat: src/lib-storage/list/mailbox-list-index-backend.c | 29 +++++----------------- 1 files changed, 7 insertions(+), 22 deletions(-) diffs (62 lines): diff -r 6252183ada83 -r 57aa5f0f9b91 src/lib-storage/list/mailbox-list-index-backend.c --- a/src/lib-storage/list/mailbox-list-index-backend.c Wed Oct 08 11:33:50 2014 +0300 +++ b/src/lib-storage/list/mailbox-list-index-backend.c Wed Oct 08 11:34:05 2014 +0300 @@ -66,22 +66,6 @@ } static int -index_list_get_refreshed_node(struct index_mailbox_list *list, const char *name, - struct mailbox_list_index_node **node_r) -{ - struct mailbox_list_index_node *node; - - if (mailbox_list_index_refresh(&list->list) < 0) - return -1; - - node = mailbox_list_index_lookup(&list->list, name); - if (node == NULL) - return 0; - *node_r = node; - return 1; -} - -static int index_list_get_refreshed_node_seq(struct index_mailbox_list *list, struct mail_index_view *view, const char *name, @@ -89,14 +73,14 @@ uint32_t *seq_r) { unsigned int i; - int ret; *node_r = NULL; *seq_r = 0; for (i = 0; i < 2; i++) { - if ((ret = index_list_get_refreshed_node(list, name, node_r)) <= 0) - return ret; + *node_r = mailbox_list_index_lookup(&list->list, name); + if (*node_r == NULL) + return 0; if (mail_index_lookup_seq(view, (*node_r)->uid, seq_r)) return 1; /* mailbox was just expunged. refreshing should notice it. */ @@ -226,13 +210,14 @@ enum mailbox_existence *existence_r) { struct mailbox_list_index_node *node; - int ret; *existence_r = MAILBOX_EXISTENCE_NONE; - if ((ret = index_list_get_refreshed_node(list, name, &node)) < 0) + if (mailbox_list_index_refresh(&list->list) < 0) return -1; - if (ret == 0) + + node = mailbox_list_index_lookup(&list->list, name); + if (node == NULL) return 0; if ((node->flags & (MAILBOX_LIST_INDEX_FLAG_NONEXISTENT | From dovecot at dovecot.org Wed Oct 8 13:29:14 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 08 Oct 2014 13:29:14 +0000 Subject: dovecot-2.2: lib: Compiling fix for FreeBSD Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f0015ab0efb1 changeset: 17914:f0015ab0efb1 user: Timo Sirainen date: Wed Oct 08 16:28:40 2014 +0300 description: lib: Compiling fix for FreeBSD Patch by Eero H?nninen diffstat: src/lib/net.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-) diffs (24 lines): diff -r 57aa5f0f9b91 -r f0015ab0efb1 src/lib/net.c --- a/src/lib/net.c Wed Oct 08 11:34:05 2014 +0300 +++ b/src/lib/net.c Wed Oct 08 16:28:40 2014 +0300 @@ -155,15 +155,17 @@ #ifdef __FreeBSD__ static int net_connect_ip_full_freebsd(const struct ip_addr *ip, unsigned int port, - const struct ip_addr *my_ip, bool blocking); + const struct ip_addr *my_ip, int sock_type, + bool blocking); static int net_connect_ip_full(const struct ip_addr *ip, unsigned int port, - const struct ip_addr *my_ip, bool blocking) + const struct ip_addr *my_ip, int sock_type, + bool blocking) { int fd, try; for (try = 0;;) { - fd = net_connect_ip_full_freebsd(ip, port, my_ip, blocking); + fd = net_connect_ip_full_freebsd(ip, port, my_ip, sock_type, blocking); if (fd != -1 || ++try == 5 || (errno != EADDRINUSE && errno != EACCES)) break; From dovecot at dovecot.org Wed Oct 8 19:11:11 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 08 Oct 2014 19:11:11 +0000 Subject: dovecot-2.2: lda, lmtp: Use mail_deliver_context.tempfail_error ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/10d11d9c0c98 changeset: 17915:10d11d9c0c98 user: Timo Sirainen date: Wed Oct 08 22:10:34 2014 +0300 description: lda, lmtp: Use mail_deliver_context.tempfail_error first if it exists (instead of storage error). diffstat: src/lda/main.c | 6 +++--- src/lmtp/commands.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diffs (43 lines): diff -r f0015ab0efb1 -r 10d11d9c0c98 src/lda/main.c --- a/src/lda/main.c Wed Oct 08 16:28:40 2014 +0300 +++ b/src/lda/main.c Wed Oct 08 22:10:34 2014 +0300 @@ -435,11 +435,11 @@ lda_set_dest_addr(&ctx, user, destaddr_source); if (mail_deliver(&ctx, &storage) < 0) { - if (storage != NULL) { - errstr = mail_storage_get_last_error(storage, &error); - } else if (ctx.tempfail_error != NULL) { + if (ctx.tempfail_error != NULL) { errstr = ctx.tempfail_error; error = MAIL_ERROR_TEMP; + } else if (storage != NULL) { + errstr = mail_storage_get_last_error(storage, &error); } else { /* This shouldn't happen */ i_error("BUG: Saving failed to unknown storage"); diff -r f0015ab0efb1 -r 10d11d9c0c98 src/lmtp/commands.c --- a/src/lmtp/commands.c Wed Oct 08 16:28:40 2014 +0300 +++ b/src/lmtp/commands.c Wed Oct 08 22:10:34 2014 +0300 @@ -694,6 +694,10 @@ client_send_line(client, "250 2.0.0 <%s> %s Saved", rcpt->address, client->state.session_id); ret = 0; + } else if (dctx.tempfail_error != NULL) { + client_send_line(client, "451 4.2.0 <%s> %s", + rcpt->address, dctx.tempfail_error); + ret = -1; } else if (storage != NULL) { error = mail_storage_get_last_error(storage, &mail_error); if (mail_error == MAIL_ERROR_NOQUOTA) { @@ -706,10 +710,6 @@ rcpt->address, error); } ret = -1; - } else if (dctx.tempfail_error != NULL) { - client_send_line(client, "451 4.2.0 <%s> %s", - rcpt->address, dctx.tempfail_error); - ret = -1; } else { /* This shouldn't happen */ i_error("BUG: Saving failed to unknown storage"); From dovecot at dovecot.org Thu Oct 9 09:02:59 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 09:02:59 +0000 Subject: dovecot-2.2: lib-lda: Added smtp_client_abort() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/90fbf199ebda changeset: 17916:90fbf199ebda user: Timo Sirainen date: Thu Oct 09 12:02:21 2014 +0300 description: lib-lda: Added smtp_client_abort() diffstat: src/lib-lda/smtp-client.c | 20 ++++++++++++++++++-- src/lib-lda/smtp-client.h | 1 + 2 files changed, 19 insertions(+), 2 deletions(-) diffs (48 lines): diff -r 10d11d9c0c98 -r 90fbf199ebda src/lib-lda/smtp-client.c --- a/src/lib-lda/smtp-client.c Wed Oct 08 22:10:34 2014 +0300 +++ b/src/lib-lda/smtp-client.c Thu Oct 09 12:02:21 2014 +0300 @@ -324,6 +324,23 @@ } } +void smtp_client_abort(struct smtp_client **_client) +{ + struct smtp_client *client = *_client; + + *_client = NULL; + + o_stream_ignore_last_errors(client->output); + if (!client->use_smtp) { + if (client->pid != (pid_t)-1) + (void)kill(client->pid, SIGTERM); + (void)smtp_client_deinit_sendmail(client); + } else { + o_stream_destroy(&client->output); + pool_unref(&client->pool); + } +} + int smtp_client_deinit(struct smtp_client *client, const char **error_r) { int ret; @@ -339,8 +356,7 @@ /* the mail has been written to a file. now actually send it. */ ret = smtp_client_send_flush(client, error_r); - o_stream_destroy(&client->output); - pool_unref(&client->pool); + smtp_client_abort(&client); return ret; } diff -r 10d11d9c0c98 -r 90fbf199ebda src/lib-lda/smtp-client.h --- a/src/lib-lda/smtp-client.h Wed Oct 08 22:10:34 2014 +0300 +++ b/src/lib-lda/smtp-client.h Thu Oct 09 12:02:21 2014 +0300 @@ -8,6 +8,7 @@ /* Get an output stream where the message can be written to. The recipients must already be added before calling this. */ struct ostream *smtp_client_send(struct smtp_client *client); +void smtp_client_abort(struct smtp_client **client); /* Returns 1 on success, 0 on permanent failure (e.g. invalid destination), -1 on temporary failure. */ int smtp_client_deinit(struct smtp_client *client, const char **error_r); From dovecot at dovecot.org Thu Oct 9 13:42:04 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 13:42:04 +0000 Subject: dovecot-2.2: lib-storage: Fixed header parsing when there were m... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0e1a3c909a13 changeset: 17917:0e1a3c909a13 user: Timo Sirainen date: Thu Oct 09 16:41:23 2014 +0300 description: lib-storage: Fixed header parsing when there were multiple same header names. For example if a mail had: Name1: a Name1: b Name2: c If the Name1: was initially added to cache and Name2: not, but later on both were attempted to be added to cache, the Name2: lookup would have been added with "b" instead of "c" value. diffstat: src/lib-storage/index/index-mail-headers.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diffs (26 lines): diff -r 90fbf199ebda -r 0e1a3c909a13 src/lib-storage/index/index-mail-headers.c --- a/src/lib-storage/index/index-mail-headers.c Thu Oct 09 12:02:21 2014 +0300 +++ b/src/lib-storage/index/index-mail-headers.c Thu Oct 09 16:41:23 2014 +0300 @@ -71,6 +71,7 @@ if (match_idx < match_count) { /* save index to first header line */ + i_assert(match_idx == lines[i].field_idx); j = i + 1; array_idx_set(&mail->header_match_lines, match_idx, &j); match_idx++; @@ -78,8 +79,12 @@ if (!mail_cache_field_can_add(_mail->transaction->cache_trans, _mail->seq, lines[i].field_idx)) { - /* header is already cached */ - j = i + 1; + /* header is already cached. skip over all the + header lines. */ + for (j = i+1; j < count; j++) { + if (lines[j].field_idx != lines[i].field_idx) + break; + } continue; } From dovecot at dovecot.org Thu Oct 9 13:42:38 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 13:42:38 +0000 Subject: dovecot-2.2: lib-storage: If uncached header unfolding fails, pa... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/43f17a91c6e5 changeset: 17918:43f17a91c6e5 user: Timo Sirainen date: Thu Oct 09 16:42:01 2014 +0300 description: lib-storage: If uncached header unfolding fails, panic instead of returning error. This really shouldn't be happening. This also makes it clear that return value -1 means some kind of I/O error instead of corruption. diffstat: src/lib-storage/index/index-mail-headers.c | 29 ++++++++++++++++++++--------- 1 files changed, 20 insertions(+), 9 deletions(-) diffs (77 lines): diff -r 0e1a3c909a13 -r 43f17a91c6e5 src/lib-storage/index/index-mail-headers.c --- a/src/lib-storage/index/index-mail-headers.c Thu Oct 09 16:41:23 2014 +0300 +++ b/src/lib-storage/index/index-mail-headers.c Thu Oct 09 16:42:01 2014 +0300 @@ -773,9 +773,10 @@ bool decode_to_utf8, const char *const **value_r) { struct index_mail *mail = (struct index_mail *)_mail; - int ret, i; + bool retry = TRUE; + int ret; - for (i = 0; i < 2; i++) { + for (;; retry = FALSE) { if (index_mail_get_raw_headers(mail, field, value_r) < 0) return -1; if (!decode_to_utf8 || **value_r == NULL) @@ -785,16 +786,20 @@ ret = index_mail_headers_decode(mail, value_r, UINT_MAX); } T_END; - if (ret < 0) { + if (ret < 0 && retry) { mail_cache_set_corrupted(_mail->box->cache, "Broken header %s for mail UID %u", field, _mail->uid); - /* retry by parsing the full header */ } else { break; } } - return ret; + if (ret < 0) { + i_panic("BUG: Broken header %s for mail UID %u " + "wasn't fixed by re-parsing the header", + field, _mail->uid); + } + return 1; } int index_mail_get_first_header(struct mail *_mail, const char *field, @@ -802,9 +807,10 @@ { struct index_mail *mail = (struct index_mail *)_mail; const char *const *list; - int ret, i; + bool retry = TRUE; + int ret; - for (i = 0; i < 2; i++) { + for (;; retry = FALSE) { if (index_mail_get_raw_headers(mail, field, &list) < 0) return -1; if (!decode_to_utf8 || list[0] == NULL) { @@ -816,7 +822,7 @@ ret = index_mail_headers_decode(mail, &list, 1); } T_END; - if (ret < 0) { + if (ret < 0 && retry) { mail_cache_set_corrupted(_mail->box->cache, "Broken header %s for mail UID %u", field, _mail->uid); @@ -825,8 +831,13 @@ break; } } + if (ret < 0) { + i_panic("BUG: Broken header %s for mail UID %u " + "wasn't fixed by re-parsing the header", + field, _mail->uid); + } *value_r = list[0]; - return ret < 0 ? -1 : (list[0] != NULL ? 1 : 0); + return list[0] != NULL ? 1 : 0; } static void From dovecot at dovecot.org Thu Oct 9 13:52:05 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 13:52:05 +0000 Subject: dovecot-2.2: lib-storage: Small comment update Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0221a504683c changeset: 17919:0221a504683c user: Timo Sirainen date: Thu Oct 09 16:51:22 2014 +0300 description: lib-storage: Small comment update diffstat: src/lib-storage/mail-storage.h | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (15 lines): diff -r 43f17a91c6e5 -r 0221a504683c src/lib-storage/mail-storage.h --- a/src/lib-storage/mail-storage.h Thu Oct 09 16:42:01 2014 +0300 +++ b/src/lib-storage/mail-storage.h Thu Oct 09 16:51:22 2014 +0300 @@ -725,8 +725,9 @@ ARRAY_TYPE(seq_range) *removed_uids, ARRAY_TYPE(seq_range) *added_uids); -/* Build mail_keywords from NULL-terminated keywords list. - Returns 0 if successful, -1 if there are invalid keywords (error is set). */ +/* Build mail_keywords from NULL-terminated keywords list. Any duplicate + keywords are removed. Returns 0 if successful, -1 if there are invalid + keywords (error is set). */ int mailbox_keywords_create(struct mailbox *box, const char *const keywords[], struct mail_keywords **keywords_r); /* Like mailbox_keywords_create(), except ignore invalid keywords. */ From dovecot at dovecot.org Thu Oct 9 15:15:23 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 15:15:23 +0000 Subject: dovecot-2.2: lib: Added file_lock_find() to find which process h... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d162eabd72cc changeset: 17920:d162eabd72cc user: Timo Sirainen date: Thu Oct 09 18:12:14 2014 +0300 description: lib: Added file_lock_find() to find which process has a file locked. diffstat: src/lib/file-lock.c | 4 ++-- src/lib/file-lock.h | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diffs (27 lines): diff -r 0221a504683c -r d162eabd72cc src/lib/file-lock.c --- a/src/lib/file-lock.c Thu Oct 09 16:51:22 2014 +0300 +++ b/src/lib/file-lock.c Thu Oct 09 18:12:14 2014 +0300 @@ -131,8 +131,8 @@ #endif } -static const char * -file_lock_find(int lock_fd, enum file_lock_method lock_method, int lock_type) +const char *file_lock_find(int lock_fd, enum file_lock_method lock_method, + int lock_type) { const char *ret; diff -r 0221a504683c -r d162eabd72cc src/lib/file-lock.h --- a/src/lib/file-lock.h Thu Oct 09 16:51:22 2014 +0300 +++ b/src/lib/file-lock.h Thu Oct 09 18:12:14 2014 +0300 @@ -50,4 +50,9 @@ /* Free the lock without unlocking it (because you're closing the fd anyway). */ void file_lock_free(struct file_lock **lock); +/* Returns human-readable string containing the process that has the file + currently locked. Returns "" if unknown, otherwise " (string)". */ +const char *file_lock_find(int lock_fd, enum file_lock_method lock_method, + int lock_type); + #endif From dovecot at dovecot.org Thu Oct 9 15:15:35 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 15:15:35 +0000 Subject: dovecot-2.2: lib: o_stream_send_istream() should return -1 if th... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5e53b6d55f63 changeset: 17921:5e53b6d55f63 user: Timo Sirainen date: Thu Oct 09 18:12:46 2014 +0300 description: lib: o_stream_send_istream() should return -1 if there was an error reading input stream. diffstat: src/lib/ostream.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r d162eabd72cc -r 5e53b6d55f63 src/lib/ostream.c --- a/src/lib/ostream.c Thu Oct 09 18:12:14 2014 +0300 +++ b/src/lib/ostream.c Thu Oct 09 18:12:46 2014 +0300 @@ -369,6 +369,8 @@ (void)i_stream_read_data(instream, &data, &iov.iov_len, 0); if (iov.iov_len == 0) { /* all sent */ + if (instream->stream_errno != 0) + return -1; break; } From dovecot at dovecot.org Thu Oct 9 15:15:35 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 15:15:35 +0000 Subject: dovecot-2.2: lib: o_stream_send_istream() shouldn't ignore EINTR... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/00115d4930d4 changeset: 17922:00115d4930d4 user: Timo Sirainen date: Thu Oct 09 18:14:43 2014 +0300 description: lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams. Also added extra asserts to make sure that either we return an error or we write everything from input stream to output stream. This should make it safe to write to files using just: if (o_stream_send_istream(ostream, istream) < 0) { // failed } else { // everything in istream was written to ostream } diffstat: src/lib/ostream-file.c | 46 +++++++++++++++++++++++++++++++++++++--------- 1 files changed, 37 insertions(+), 9 deletions(-) diffs (90 lines): diff -r 5e53b6d55f63 -r 00115d4930d4 src/lib/ostream-file.c --- a/src/lib/ostream-file.c Thu Oct 09 18:12:46 2014 +0300 +++ b/src/lib/ostream-file.c Thu Oct 09 18:14:43 2014 +0300 @@ -173,10 +173,13 @@ const struct const_iovec *iov, int iov_size) { ssize_t ret, ret2; - size_t size, sent; + size_t size, sent, total_size; bool partial; int i; + for (i = 0, total_size = 0; i < iov_size; i++) + total_size += iov[i].iov_len; + o_stream_socket_cork(fstream); if (iov_size == 1) { i_assert(iov->iov_len > 0); @@ -234,8 +237,15 @@ } if (ret < 0) { - if (errno == EAGAIN || errno == EINTR) + if (fstream->file) { + if (errno == EINTR) { + /* automatically retry */ + return o_stream_writev(fstream, iov, iov_size); + } + } else if (errno == EAGAIN || errno == EINTR) { + /* try again later */ return 0; + } fstream->ostream.ostream.stream_errno = errno; stream_closed(fstream); return -1; @@ -278,10 +288,14 @@ } } } - if (ret2 <= 0) - return ret2; - ret += ret2; + i_assert(ret2 != 0); + if (ret2 < 0) + ret = ret2; + else + ret += ret2; } + i_assert(ret < 0 || !fstream->file || + (size_t)ret == total_size); return ret; } @@ -713,9 +727,18 @@ ret = safe_sendfile(foutstream->fd, in_fd, &offset, MAX_SSIZE_T(send_size)); if (ret <= 0) { - if (ret == 0 || errno == EINTR || errno == EAGAIN) { - ret = 0; + if (ret == 0) break; + if (foutstream->file) { + if (errno == EINTR) { + /* automatically retry */ + continue; + } + } else { + if (errno == EINTR || errno == EAGAIN) { + ret = 0; + break; + } } outstream->ostream.stream_errno = errno; @@ -735,8 +758,13 @@ i_stream_seek(instream, v_offset); if (ret == 0) { - /* we should be at EOF, verify it by reading instream */ - (void)i_stream_read(instream); + /* we should be at EOF. if not, write more. */ + i_assert(!foutstream->file || + instream->v_offset - start_offset == in_size); + if (i_stream_read(instream) > 0) { + if (io_stream_sendfile(outstream, instream, in_fd) < 0) + return -1; + } } return ret < 0 ? -1 : (off_t)(instream->v_offset - start_offset); } From dovecot at dovecot.org Thu Oct 9 15:19:47 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 15:19:47 +0000 Subject: dovecot-2.2: lib-index: Moved MAIL_TRANSACTION_LOG_LOCK_WARN_SEC... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/568f817804b3 changeset: 17923:568f817804b3 user: Timo Sirainen date: Thu Oct 09 18:17:26 2014 +0300 description: lib-index: Moved MAIL_TRANSACTION_LOG_LOCK_WARN_SECS as part of public API. diffstat: src/lib-index/mail-index.h | 4 ++++ src/lib-index/mail-transaction-log-private.h | 1 - 2 files changed, 4 insertions(+), 1 deletions(-) diffs (25 lines): diff -r 00115d4930d4 -r 568f817804b3 src/lib-index/mail-index.h --- a/src/lib-index/mail-index.h Thu Oct 09 18:14:43 2014 +0300 +++ b/src/lib-index/mail-index.h Thu Oct 09 18:17:26 2014 +0300 @@ -12,6 +12,10 @@ #define MAIL_INDEX_HEADER_MIN_SIZE 120 +/* Log a warning when transaction log has been locked for this many seconds. + This lock is held also between mail_index_sync_begin()..commit(). */ +#define MAIL_TRANSACTION_LOG_LOCK_WARN_SECS 30 + enum mail_index_open_flags { /* Create index if it doesn't exist */ MAIL_INDEX_OPEN_FLAG_CREATE = 0x01, diff -r 00115d4930d4 -r 568f817804b3 src/lib-index/mail-transaction-log-private.h --- a/src/lib-index/mail-transaction-log-private.h Thu Oct 09 18:14:43 2014 +0300 +++ b/src/lib-index/mail-transaction-log-private.h Thu Oct 09 18:17:26 2014 +0300 @@ -10,7 +10,6 @@ mails. */ #define MAIL_TRANSACTION_LOG_LOCK_TIMEOUT (3*60) #define MAIL_TRANSACTION_LOG_LOCK_CHANGE_TIMEOUT (3*60) -#define MAIL_TRANSACTION_LOG_LOCK_WARN_SECS 30 /* Rotate when log is older than ROTATE_TIME and larger than MIN_SIZE */ #define MAIL_TRANSACTION_LOG_ROTATE_MIN_SIZE (1024*32) From dovecot at dovecot.org Thu Oct 9 15:19:47 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 15:19:47 +0000 Subject: dovecot-2.2: maildir: Use MAIL_TRANSACTION_LOG_LOCK_WARN_SECS as... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1c3dcade6f02 changeset: 17924:1c3dcade6f02 user: Timo Sirainen date: Thu Oct 09 18:19:11 2014 +0300 description: maildir: Use MAIL_TRANSACTION_LOG_LOCK_WARN_SECS as threshold for logging a "long sync" warning. This is because the index syncing keeps the log locked, and other processes trying to lock the log will start logging warnings as well. diffstat: src/lib-storage/index/maildir/maildir-sync.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 568f817804b3 -r 1c3dcade6f02 src/lib-storage/index/maildir/maildir-sync.h --- a/src/lib-storage/index/maildir/maildir-sync.h Thu Oct 09 18:17:26 2014 +0300 +++ b/src/lib-storage/index/maildir/maildir-sync.h Thu Oct 09 18:19:11 2014 +0300 @@ -12,7 +12,7 @@ to see if we need to touch the uidlist lock. */ #define MAILDIR_SLOW_CHECK_COUNT 10000 /* If syncing takes longer than this, log a warning. */ -#define MAILDIR_SYNC_TIME_WARN_SECS 60 +#define MAILDIR_SYNC_TIME_WARN_SECS MAIL_TRANSACTION_LOG_LOCK_WARN_SECS struct maildir_mailbox; struct maildir_sync_context; From dovecot at dovecot.org Thu Oct 9 15:21:31 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 15:21:31 +0000 Subject: dovecot-2.2: lib-index: If locking transaction log times out, sh... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ec1fd3dc0a74 changeset: 17925:ec1fd3dc0a74 user: Timo Sirainen date: Thu Oct 09 18:20:56 2014 +0300 description: lib-index: If locking transaction log times out, show the PID which has it locked. diffstat: src/lib-index/mail-transaction-log-file.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (15 lines): diff -r 1c3dcade6f02 -r ec1fd3dc0a74 src/lib-index/mail-transaction-log-file.c --- a/src/lib-index/mail-transaction-log-file.c Thu Oct 09 18:19:11 2014 +0300 +++ b/src/lib-index/mail-transaction-log-file.c Thu Oct 09 18:20:56 2014 +0300 @@ -387,8 +387,9 @@ mail_index_set_error(file->log->index, "Timeout (%us) while waiting for lock for " - "transaction log file %s", - lock_timeout_secs, file->filepath); + "transaction log file %s%s", + lock_timeout_secs, file->filepath, + file_lock_find(file->fd, file->log->index->lock_method, F_WRLCK)); file->log->index->index_lock_timeout = TRUE; return -1; } From dovecot at dovecot.org Thu Oct 9 15:24:23 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 15:24:23 +0000 Subject: dovecot-2.2: lib-index: Replaced some automatic transaction log ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/623a9f46c747 changeset: 17926:623a9f46c747 user: Timo Sirainen date: Thu Oct 09 18:23:41 2014 +0300 description: lib-index: Replaced some automatic transaction log unlocks with asserts. Some earlier Dovecot versions were read-locking transaction logs and this was useful there. But now we only do exclusive locking for the log head, so it's an error not to explicitly unlock the files. diffstat: src/lib-index/mail-transaction-log-file.c | 2 +- src/lib-index/mail-transaction-log.c | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diffs (41 lines): diff -r ec1fd3dc0a74 -r 623a9f46c747 src/lib-index/mail-transaction-log-file.c --- a/src/lib-index/mail-transaction-log-file.c Thu Oct 09 18:20:56 2014 +0300 +++ b/src/lib-index/mail-transaction-log-file.c Thu Oct 09 18:23:41 2014 +0300 @@ -101,7 +101,7 @@ *_file = NULL; - mail_transaction_log_file_unlock(file); + i_assert(!file->locked); for (p = &file->log->files; *p != NULL; p = &(*p)->next) { if (*p == file) { diff -r ec1fd3dc0a74 -r 623a9f46c747 src/lib-index/mail-transaction-log.c --- a/src/lib-index/mail-transaction-log.c Thu Oct 09 18:20:56 2014 +0300 +++ b/src/lib-index/mail-transaction-log.c Thu Oct 09 18:23:41 2014 +0300 @@ -210,10 +210,9 @@ mail_transaction_log_file_free(&file); } - /* if we still have locked files with refcount=0, unlock them */ + /* sanity check: we shouldn't have locked refcount=0 files */ for (; file != NULL; file = file->next) { - if (file->locked && file->refcount == 0) - mail_transaction_log_file_unlock(file); + i_assert(!file->locked || file->refcount > 0); } i_assert(log->head == NULL || log->files != NULL); } @@ -267,8 +266,11 @@ if (--log->head->refcount == 0) mail_transaction_logs_clean(log); - else + else { + /* the newly created log file is already locked */ + i_assert(file->locked); mail_transaction_log_file_unlock(log->head); + } mail_transaction_log_set_head(log, file); return 0; } From dovecot at dovecot.org Thu Oct 9 15:26:46 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 15:26:46 +0000 Subject: dovecot-2.2: lib-index: Include reason string in warnings about ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fce66ec2ac1c changeset: 17927:fce66ec2ac1c user: Timo Sirainen date: Thu Oct 09 18:26:05 2014 +0300 description: lib-index: Include reason string in warnings about keeping transaction log locked for too long. diffstat: src/lib-index/mail-index-fsck.c | 2 +- src/lib-index/mail-index-sync.c | 11 ++++++----- src/lib-index/mail-transaction-log-append.c | 2 +- src/lib-index/mail-transaction-log-file.c | 9 +++++---- src/lib-index/mail-transaction-log-private.h | 3 ++- src/lib-index/mail-transaction-log.c | 14 +++++++++----- src/lib-index/mail-transaction-log.h | 3 ++- src/lib-index/test-mail-transaction-log-append.c | 3 ++- 8 files changed, 28 insertions(+), 19 deletions(-) diffs (193 lines): diff -r 623a9f46c747 -r fce66ec2ac1c src/lib-index/mail-index-fsck.c --- a/src/lib-index/mail-index-fsck.c Thu Oct 09 18:23:41 2014 +0300 +++ b/src/lib-index/mail-index-fsck.c Thu Oct 09 18:26:05 2014 +0300 @@ -457,7 +457,7 @@ mail_index_write(index, FALSE); if (!orig_locked) - mail_transaction_log_sync_unlock(index->log); + mail_transaction_log_sync_unlock(index->log, "fsck"); return 0; } diff -r 623a9f46c747 -r fce66ec2ac1c src/lib-index/mail-index-sync.c --- a/src/lib-index/mail-index-sync.c Thu Oct 09 18:23:41 2014 +0300 +++ b/src/lib-index/mail-index-sync.c Thu Oct 09 18:26:05 2014 +0300 @@ -348,14 +348,14 @@ if ((ret = mail_index_map(index, MAIL_INDEX_SYNC_HANDLER_HEAD)) <= 0) { if (ret == 0) { if (locked) - mail_transaction_log_sync_unlock(index->log); + mail_transaction_log_sync_unlock(index->log, "sync init failure"); return -1; } /* let's try again */ if (mail_index_map(index, MAIL_INDEX_SYNC_HANDLER_HEAD) <= 0) { if (locked) - mail_transaction_log_sync_unlock(index->log); + mail_transaction_log_sync_unlock(index->log, "sync init failure"); return -1; } } @@ -363,7 +363,7 @@ if (!mail_index_need_sync(index, flags, log_file_seq, log_file_offset) && !index->index_deleted) { if (locked) - mail_transaction_log_sync_unlock(index->log); + mail_transaction_log_sync_unlock(index->log, "syncing determined unnecessary"); return 0; } @@ -379,7 +379,7 @@ (flags & MAIL_INDEX_SYNC_FLAG_DELETING_INDEX) == 0) { /* index is already deleted. we can't sync. */ if (locked) - mail_transaction_log_sync_unlock(index->log); + mail_transaction_log_sync_unlock(index->log, "syncing detected deleted index"); return -1; } @@ -725,7 +725,8 @@ *_ctx = NULL; ctx->index->syncing = FALSE; - mail_transaction_log_sync_unlock(ctx->index->log); + mail_transaction_log_sync_unlock(ctx->index->log, + "Mailbox was synchronized"); mail_index_view_close(&ctx->view); mail_index_transaction_rollback(&ctx->sync_trans); diff -r 623a9f46c747 -r fce66ec2ac1c src/lib-index/mail-transaction-log-append.c --- a/src/lib-index/mail-transaction-log-append.c Thu Oct 09 18:23:41 2014 +0300 +++ b/src/lib-index/mail-transaction-log-append.c Thu Oct 09 18:26:05 2014 +0300 @@ -247,7 +247,7 @@ ret = mail_transaction_log_append_locked(ctx); if (!index->log_sync_locked) - mail_transaction_log_file_unlock(index->log->head); + mail_transaction_log_file_unlock(index->log->head, "appending"); buffer_free(&ctx->output); i_free(ctx); diff -r 623a9f46c747 -r fce66ec2ac1c src/lib-index/mail-transaction-log-file.c --- a/src/lib-index/mail-transaction-log-file.c Thu Oct 09 18:23:41 2014 +0300 +++ b/src/lib-index/mail-transaction-log-file.c Thu Oct 09 18:26:05 2014 +0300 @@ -394,7 +394,8 @@ return -1; } -void mail_transaction_log_file_unlock(struct mail_transaction_log_file *file) +void mail_transaction_log_file_unlock(struct mail_transaction_log_file *file, + const char *lock_reason) { unsigned int lock_time; @@ -408,9 +409,9 @@ return; lock_time = time(NULL) - file->lock_created; - if (lock_time >= MAIL_TRANSACTION_LOG_LOCK_TIMEOUT) { - i_warning("Transaction log file %s was locked for %u seconds", - file->filepath, lock_time); + if (lock_time >= MAIL_TRANSACTION_LOG_LOCK_TIMEOUT && lock_reason != NULL) { + i_warning("Transaction log file %s was locked for %u seconds (%s)", + file->filepath, lock_time, lock_reason); } if (file->log->index->lock_method == FILE_LOCK_METHOD_DOTLOCK) { diff -r 623a9f46c747 -r fce66ec2ac1c src/lib-index/mail-transaction-log-private.h --- a/src/lib-index/mail-transaction-log-private.h Thu Oct 09 18:23:41 2014 +0300 +++ b/src/lib-index/mail-transaction-log-private.h Thu Oct 09 18:26:05 2014 +0300 @@ -137,7 +137,8 @@ bool mail_transaction_log_want_rotate(struct mail_transaction_log *log); int mail_transaction_log_rotate(struct mail_transaction_log *log, bool reset); int mail_transaction_log_lock_head(struct mail_transaction_log *log); -void mail_transaction_log_file_unlock(struct mail_transaction_log_file *file); +void mail_transaction_log_file_unlock(struct mail_transaction_log_file *file, + const char *lock_reason); void mail_transaction_update_modseq(const struct mail_transaction_header *hdr, const void *data, uint64_t *cur_modseq); diff -r 623a9f46c747 -r fce66ec2ac1c src/lib-index/mail-transaction-log.c --- a/src/lib-index/mail-transaction-log.c Thu Oct 09 18:23:41 2014 +0300 +++ b/src/lib-index/mail-transaction-log.c Thu Oct 09 18:26:05 2014 +0300 @@ -269,7 +269,9 @@ else { /* the newly created log file is already locked */ i_assert(file->locked); - mail_transaction_log_file_unlock(log->head); + mail_transaction_log_file_unlock(log->head, + !log->index->log_sync_locked ? "rotating" : + "rotating while syncing"); } mail_transaction_log_set_head(log, file); return 0; @@ -448,6 +450,7 @@ file->refcount++; ret = mail_transaction_log_refresh(log, TRUE); if (--file->refcount == 0) { + mail_transaction_log_file_unlock(file, "trying to lock head"); mail_transaction_logs_clean(log); file = NULL; } @@ -460,7 +463,7 @@ } if (file != NULL) - mail_transaction_log_file_unlock(file); + mail_transaction_log_file_unlock(file, "trying to lock head"); if (ret < 0) break; @@ -487,7 +490,7 @@ /* update sync_offset */ if (mail_transaction_log_file_map(log->head, log->head->sync_offset, (uoff_t)-1) <= 0) { - mail_transaction_log_file_unlock(log->head); + mail_transaction_log_file_unlock(log->head, "trying to lock syncing"); return -1; } @@ -497,12 +500,13 @@ return 0; } -void mail_transaction_log_sync_unlock(struct mail_transaction_log *log) +void mail_transaction_log_sync_unlock(struct mail_transaction_log *log, + const char *log_reason) { i_assert(log->index->log_sync_locked); log->index->log_sync_locked = FALSE; - mail_transaction_log_file_unlock(log->head); + mail_transaction_log_file_unlock(log->head, log_reason); } void mail_transaction_log_get_head(struct mail_transaction_log *log, diff -r 623a9f46c747 -r fce66ec2ac1c src/lib-index/mail-transaction-log.h --- a/src/lib-index/mail-transaction-log.h Thu Oct 09 18:23:41 2014 +0300 +++ b/src/lib-index/mail-transaction-log.h Thu Oct 09 18:26:05 2014 +0300 @@ -279,7 +279,8 @@ written to while it's locked. Returns end offset. */ int mail_transaction_log_sync_lock(struct mail_transaction_log *log, uint32_t *file_seq_r, uoff_t *file_offset_r); -void mail_transaction_log_sync_unlock(struct mail_transaction_log *log); +void mail_transaction_log_sync_unlock(struct mail_transaction_log *log, + const char *lock_reason); /* Returns the current head. Works only when log is locked. */ void mail_transaction_log_get_head(struct mail_transaction_log *log, uint32_t *file_seq_r, uoff_t *file_offset_r); diff -r 623a9f46c747 -r fce66ec2ac1c src/lib-index/test-mail-transaction-log-append.c --- a/src/lib-index/test-mail-transaction-log-append.c Thu Oct 09 18:23:41 2014 +0300 +++ b/src/lib-index/test-mail-transaction-log-append.c Thu Oct 09 18:26:05 2014 +0300 @@ -22,7 +22,8 @@ return log_lock_failure ? -1 : 0; } -void mail_transaction_log_file_unlock(struct mail_transaction_log_file *file ATTR_UNUSED) {} +void mail_transaction_log_file_unlock(struct mail_transaction_log_file *file ATTR_UNUSED, + const char *lock_reason ATTR_UNUSED) {} void mail_transaction_update_modseq(const struct mail_transaction_header *hdr, const void *data ATTR_UNUSED, From dovecot at dovecot.org Thu Oct 9 15:27:53 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 15:27:53 +0000 Subject: dovecot-2.2: lib-index: Added mail_index_sync_no_warning() to pr... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/193c82411d73 changeset: 17928:193c82411d73 user: Timo Sirainen date: Thu Oct 09 18:27:14 2014 +0300 description: lib-index: Added mail_index_sync_no_warning() to prevent "long transaction lock" warnings. Use it with Maildir to prevent double-warning. diffstat: src/lib-index/mail-index-sync.c | 9 ++++++++- src/lib-index/mail-index.h | 4 ++++ src/lib-storage/index/maildir/maildir-sync-index.c | 1 + 3 files changed, 13 insertions(+), 1 deletions(-) diffs (58 lines): diff -r fce66ec2ac1c -r 193c82411d73 src/lib-index/mail-index-sync.c --- a/src/lib-index/mail-index-sync.c Thu Oct 09 18:26:05 2014 +0300 +++ b/src/lib-index/mail-index-sync.c Thu Oct 09 18:27:14 2014 +0300 @@ -24,6 +24,8 @@ ARRAY(struct mail_index_sync_list) sync_list; uint32_t next_uid; uint32_t last_tail_seq, last_tail_offset; + + unsigned int no_warning:1; }; static void mail_index_sync_add_expunge(struct mail_index_sync_ctx *ctx) @@ -716,6 +718,11 @@ sync_list->idx = 0; } +void mail_index_sync_no_warning(struct mail_index_sync_ctx *ctx) +{ + ctx->no_warning = TRUE; +} + static void mail_index_sync_end(struct mail_index_sync_ctx **_ctx) { struct mail_index_sync_ctx *ctx = *_ctx; @@ -726,7 +733,7 @@ ctx->index->syncing = FALSE; mail_transaction_log_sync_unlock(ctx->index->log, - "Mailbox was synchronized"); + ctx->no_warning ? NULL : "Mailbox was synchronized"); mail_index_view_close(&ctx->view); mail_index_transaction_rollback(&ctx->sync_trans); diff -r fce66ec2ac1c -r 193c82411d73 src/lib-index/mail-index.h --- a/src/lib-index/mail-index.h Thu Oct 09 18:26:05 2014 +0300 +++ b/src/lib-index/mail-index.h Thu Oct 09 18:27:14 2014 +0300 @@ -377,6 +377,10 @@ /* Update result when refreshing index at the end of sync. */ void mail_index_sync_set_commit_result(struct mail_index_sync_ctx *ctx, struct mail_index_transaction_commit_result *result); +/* Don't log a warning even if syncing took over + MAIL_TRANSACTION_LOG_LOCK_WARN_SECS seconds. Usually this is called because + the caller itself already logged a warning about it. */ +void mail_index_sync_no_warning(struct mail_index_sync_ctx *ctx); /* Commit synchronization by writing all changes to mail index file. */ int mail_index_sync_commit(struct mail_index_sync_ctx **ctx); /* Rollback synchronization - none of the changes listed by sync_next() are diff -r fce66ec2ac1c -r 193c82411d73 src/lib-storage/index/maildir/maildir-sync-index.c --- a/src/lib-storage/index/maildir/maildir-sync-index.c Thu Oct 09 18:26:05 2014 +0300 +++ b/src/lib-storage/index/maildir/maildir-sync-index.c Thu Oct 09 18:27:14 2014 +0300 @@ -316,6 +316,7 @@ mailbox_get_path(&ctx->mbox->box), time_diff, ctx->new_msgs_count, ctx->flag_change_count, ctx->expunge_count); + mail_index_sync_no_warning(ctx->sync_ctx); } if (ret < 0) From dovecot at dovecot.org Thu Oct 9 15:41:41 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 15:41:41 +0000 Subject: dovecot-2.2: lib: Fixed assert-crash in o_stream_send_istream() ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c36cfd735d60 changeset: 17929:c36cfd735d60 user: Timo Sirainen date: Thu Oct 09 18:40:54 2014 +0300 description: lib: Fixed assert-crash in o_stream_send_istream() if input stream was the one that failed. diffstat: src/lib/ostream.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) diffs (19 lines): diff -r 193c82411d73 -r c36cfd735d60 src/lib/ostream.c --- a/src/lib/ostream.c Thu Oct 09 18:27:14 2014 +0300 +++ b/src/lib/ostream.c Thu Oct 09 18:40:54 2014 +0300 @@ -329,9 +329,12 @@ o_stream_clear_error(outstream); ret = _outstream->send_istream(_outstream, instream); if (unlikely(ret < 0)) { - i_assert(outstream->stream_errno != 0); - outstream->last_failed_errno = outstream->stream_errno; - errno = outstream->stream_errno; + if (outstream->stream_errno != 0) { + outstream->last_failed_errno = outstream->stream_errno; + errno = outstream->stream_errno; + } else { + i_assert(instream->stream_errno != 0); + } } return ret; } From dovecot at dovecot.org Thu Oct 9 15:41:41 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 15:41:41 +0000 Subject: dovecot-2.2: lib: Updated comment to o_stream_send_istream() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/af382aaad0e8 changeset: 17930:af382aaad0e8 user: Timo Sirainen date: Thu Oct 09 18:41:06 2014 +0300 description: lib: Updated comment to o_stream_send_istream() diffstat: src/lib/ostream.h | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (16 lines): diff -r c36cfd735d60 -r af382aaad0e8 src/lib/ostream.h --- a/src/lib/ostream.h Thu Oct 09 18:40:54 2014 +0300 +++ b/src/lib/ostream.h Thu Oct 09 18:41:06 2014 +0300 @@ -127,9 +127,9 @@ When creating wrapper streams, they copy this behavior from the parent stream. */ void o_stream_set_no_error_handling(struct ostream *stream, bool set); -/* Send data from input stream. Returns number of bytes sent, or -1 if error. - Note that this function may block if either instream or outstream is - blocking. +/* Send data from input stream. Returns number of bytes sent, or -1 if error + in either outstream or instream. Note that this function may block if either + instream or outstream is blocking. Also note that this function may not add anything to the output buffer, so if you want the flush callback to be called when more data can be written, From dovecot at dovecot.org Thu Oct 9 17:47:04 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 17:47:04 +0000 Subject: dovecot-2.2: lib-index: Removed dovecot.index locking related co... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/71c00e501179 changeset: 17931:71c00e501179 user: Timo Sirainen date: Thu Oct 09 20:46:31 2014 +0300 description: lib-index: Removed dovecot.index locking related code, which is no longer used. diffstat: src/lib-index/mail-index-private.h | 5 ----- src/lib-index/mail-index.c | 12 ------------ 2 files changed, 0 insertions(+), 17 deletions(-) diffs (59 lines): diff -r af382aaad0e8 -r 71c00e501179 src/lib-index/mail-index-private.h --- a/src/lib-index/mail-index-private.h Thu Oct 09 18:41:06 2014 +0300 +++ b/src/lib-index/mail-index-private.h Thu Oct 09 20:46:31 2014 +0300 @@ -202,14 +202,9 @@ /* syncing will update this if non-NULL */ struct mail_index_transaction_commit_result *sync_commit_result; - int lock_type; - unsigned int lock_id_counter; enum file_lock_method lock_method; unsigned int max_lock_timeout_secs; - struct file_lock *file_lock; - struct dotlock *dotlock; - pool_t keywords_pool; ARRAY_TYPE(keywords) keywords; HASH_TABLE(char *, void *) keywords_hash; /* name -> unsigned int idx */ diff -r af382aaad0e8 -r 71c00e501179 src/lib-index/mail-index.c --- a/src/lib-index/mail-index.c Thu Oct 09 18:41:06 2014 +0300 +++ b/src/lib-index/mail-index.c Thu Oct 09 20:46:31 2014 +0300 @@ -566,9 +566,6 @@ i_strdup("(in-memory index)") : i_strconcat(index->dir, "/", index->prefix, NULL); - index->lock_type = F_UNLCK; - index->lock_id_counter = 2; - index->readonly = FALSE; index->nodiskspace = FALSE; index->index_lock_timeout = FALSE; @@ -611,17 +608,11 @@ void mail_index_close_file(struct mail_index *index) { - if (index->file_lock != NULL) - file_lock_free(&index->file_lock); - if (index->fd != -1) { if (close(index->fd) < 0) mail_index_set_syscall_error(index, "close()"); index->fd = -1; } - - index->lock_id_counter += 2; - index->lock_type = F_UNLCK; } static void mail_index_close_nonopened(struct mail_index *index) @@ -794,9 +785,6 @@ mail_transaction_log_move_to_memory(index->log); } - if (index->file_lock != NULL) - file_lock_free(&index->file_lock); - if (index->fd != -1) { if (close(index->fd) < 0) mail_index_set_syscall_error(index, "close()"); From dovecot at dovecot.org Thu Oct 9 18:21:25 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 18:21:25 +0000 Subject: dovecot-2.2: man: doveadm-acl.1: Corrected description of defaul... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fa0726178312 changeset: 17932:fa0726178312 user: Pascal Volk date: Thu Oct 09 18:19:03 2014 +0000 description: man: doveadm-acl.1: Corrected description of default output formatter. diffstat: doc/man/doveadm-acl.1.in | 7 ++----- 1 files changed, 2 insertions(+), 5 deletions(-) diffs (22 lines): diff -r 71c00e501179 -r fa0726178312 doc/man/doveadm-acl.1.in --- a/doc/man/doveadm-acl.1.in Thu Oct 09 20:46:31 2014 +0300 +++ b/doc/man/doveadm-acl.1.in Thu Oct 09 18:19:03 2014 +0000 @@ -1,5 +1,5 @@ .\" Copyright (c) 2014 Dovecot authors, see the included COPYING file -.TH DOVEADM\-ACL 1 "2014-09-24" "Dovecot v2.2" "Dovecot" +.TH DOVEADM\-ACL 1 "2014-10-09" "Dovecot v2.2" "Dovecot" .SH NAME doveadm\-acl \- Manage Access Control List (ACL) .\"------------------------------------------------------------------------ @@ -19,10 +19,7 @@ .\" --- command specific options --- "/. .PP This command uses by default the output formatter -.B flow -(without the -.IR key = -prefix). +.BR table . .PP Command specific .IR options : From dovecot at dovecot.org Thu Oct 9 18:23:20 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 18:23:20 +0000 Subject: dovecot-2.2: mbox: Removed obsolete code that also wasn't compil... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8c1a2f5b0a67 changeset: 17933:8c1a2f5b0a67 user: Timo Sirainen date: Thu Oct 09 21:22:45 2014 +0300 description: mbox: Removed obsolete code that also wasn't compiling because of previous commit. diffstat: src/lib-storage/index/mbox/mbox-lock.c | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-) diffs (15 lines): diff -r fa0726178312 -r 8c1a2f5b0a67 src/lib-storage/index/mbox/mbox-lock.c --- a/src/lib-storage/index/mbox/mbox-lock.c Thu Oct 09 18:19:03 2014 +0000 +++ b/src/lib-storage/index/mbox/mbox-lock.c Thu Oct 09 21:22:45 2014 +0300 @@ -798,11 +798,6 @@ i_assert(lock_type == F_RDLCK || lock_type == F_WRLCK); i_assert(lock_type == F_RDLCK || mbox->mbox_lock_type != F_RDLCK); - /* mbox must be locked before index (the NULL check is for - MAILBOX_FLAG_KEEP_LOCKED) */ - i_assert(mbox->box.index == NULL || - mbox->box.index->lock_type != F_WRLCK); - if (mbox->mbox_lock_type == F_UNLCK) { ret = mbox_update_locking(mbox, lock_type, &fcntl_locked); if (ret <= 0) From dovecot at dovecot.org Thu Oct 9 18:23:42 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 18:23:42 +0000 Subject: dovecot-2.2: lib-lda: Compiler warning fix Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/86b1860c8deb changeset: 17934:86b1860c8deb user: Timo Sirainen date: Thu Oct 09 21:23:08 2014 +0300 description: lib-lda: Compiler warning fix diffstat: src/lib-lda/smtp-client.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 8c1a2f5b0a67 -r 86b1860c8deb src/lib-lda/smtp-client.c --- a/src/lib-lda/smtp-client.c Thu Oct 09 21:22:45 2014 +0300 +++ b/src/lib-lda/smtp-client.c Thu Oct 09 21:23:08 2014 +0300 @@ -17,6 +17,7 @@ #include #include #include +#include #define DEFAULT_SUBMISSION_PORT 25 From dovecot at dovecot.org Thu Oct 9 21:47:02 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Oct 2014 21:47:02 +0000 Subject: dovecot-2.2: lib-http: client: Fixed assert crash occurring when... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6c341dcec32a changeset: 17935:6c341dcec32a user: Stephan Bosch date: Fri Oct 10 00:46:15 2014 +0300 description: lib-http: client: Fixed assert crash occurring when DNS lookup fails immediately during request submission. In that situation, the request was not dropped from the queue immediately, triggering the assert crash. diffstat: src/lib-http/http-client-request.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (22 lines): diff -r 86b1860c8deb -r 6c341dcec32a src/lib-http/http-client-request.c --- a/src/lib-http/http-client-request.c Thu Oct 09 21:23:08 2014 +0300 +++ b/src/lib-http/http-client-request.c Fri Oct 10 00:46:15 2014 +0300 @@ -900,6 +900,9 @@ if (req->state >= HTTP_REQUEST_STATE_FINISHED) return; + if (req->queue != NULL) + http_client_queue_drop_request(req->queue, req); + if (!req->submitted) { /* we're still in http_client_request_submit(). delay reporting the error, so the caller doesn't have to handle @@ -910,8 +913,6 @@ http_client_host_delay_request_error(req->host, req); } else { http_client_request_send_error(req, status, error); - if (req->queue != NULL) - http_client_queue_drop_request(req->queue, req); http_client_request_unref(&req); } } From dovecot at dovecot.org Fri Oct 10 15:12:30 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Oct 2014 15:12:30 +0000 Subject: dovecot-2.2: maildir: Don't limit uidlist line lengths to 4096 b... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4a401e9853ee changeset: 17936:4a401e9853ee user: Timo Sirainen date: Fri Oct 10 18:11:58 2014 +0300 description: maildir: Don't limit uidlist line lengths to 4096 bytes. Although this always indicates corruption, the current code doesn't handle that very nicely. One fix would be to just ignore such long lines, but this is easier to implement.. diffstat: src/lib-storage/index/maildir/maildir-uidlist.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 6c341dcec32a -r 4a401e9853ee src/lib-storage/index/maildir/maildir-uidlist.c --- a/src/lib-storage/index/maildir/maildir-uidlist.c Fri Oct 10 00:46:15 2014 +0300 +++ b/src/lib-storage/index/maildir/maildir-uidlist.c Fri Oct 10 18:11:58 2014 +0300 @@ -758,7 +758,7 @@ st.st_size/8)); } - input = i_stream_create_fd(fd, 4096, FALSE); + input = i_stream_create_fd(fd, (size_t)-1, FALSE); i_stream_seek(input, last_read_offset); orig_uid_validity = uidlist->uid_validity; From dovecot at dovecot.org Fri Oct 10 21:00:37 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Oct 2014 21:00:37 +0000 Subject: dovecot-2.2: auth: If userdb iteration client disconnects early,... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/99dc3e3a3f75 changeset: 17937:99dc3e3a3f75 user: Timo Sirainen date: Fri Oct 10 23:59:52 2014 +0300 description: auth: If userdb iteration client disconnects early, make sure we don't get stuck. diffstat: src/auth/userdb-blocking.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diffs (24 lines): diff -r 4a401e9853ee -r 99dc3e3a3f75 src/auth/userdb-blocking.c --- a/src/auth/userdb-blocking.c Fri Oct 10 18:11:58 2014 +0300 +++ b/src/auth/userdb-blocking.c Fri Oct 10 23:59:52 2014 +0300 @@ -66,9 +66,11 @@ struct blocking_userdb_iterate_context *ctx = context; if (strncmp(reply, "*\t", 2) == 0) { + if (ctx->destroyed) + return TRUE; ctx->next = FALSE; ctx->ctx.callback(reply + 2, ctx->ctx.context); - return ctx->next; + return ctx->next || ctx->destroyed; } if (strcmp(reply, "OK") != 0) @@ -120,5 +122,7 @@ /* iter_callback() may still be called */ ctx->destroyed = TRUE; + + auth_worker_server_resume_input(ctx->conn); return ret; } From dovecot at dovecot.org Fri Oct 10 21:44:19 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Oct 2014 21:44:19 +0000 Subject: dovecot-2.2: lib-dns: The dns_lookup() call caused a crash upon ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d15da5f1731e changeset: 17938:d15da5f1731e user: Stephan Bosch date: Sat Oct 11 00:43:38 2014 +0300 description: lib-dns: The dns_lookup() call caused a crash upon a connect error, because dns_client_disconnect() can indirectly call itself recursively. Solved by dropping the list of lookups from the client object before the lookups are destroyed. diffstat: src/lib-dns/dns-lookup.c | 26 +++++++++++++++----------- 1 files changed, 15 insertions(+), 11 deletions(-) diffs (52 lines): diff -r 99dc3e3a3f75 -r d15da5f1731e src/lib-dns/dns-lookup.c --- a/src/lib-dns/dns-lookup.c Fri Oct 10 23:59:52 2014 +0300 +++ b/src/lib-dns/dns-lookup.c Sat Oct 11 00:43:38 2014 +0300 @@ -56,18 +56,9 @@ static void dns_client_disconnect(struct dns_client *client, const char *error) { - struct dns_lookup *lookup; + struct dns_lookup *lookup, *next; struct dns_lookup_result result; - memset(&result, 0, sizeof(result)); - result.ret = EAI_FAIL; - result.error = error; - - while (client->head != NULL) { - lookup = client->head; - lookup->callback(&result, lookup->context); - dns_lookup_free(&lookup); - } if (client->to_idle != NULL) timeout_remove(&client->to_idle); if (client->io != NULL) @@ -79,6 +70,19 @@ i_error("close(%s) failed: %m", client->path); client->fd = -1; } + + memset(&result, 0, sizeof(result)); + result.ret = EAI_FAIL; + result.error = error; + + lookup = client->head; + client->head = NULL; + while (lookup != NULL) { + next = lookup->next; + lookup->callback(&result, lookup->context); + dns_lookup_free(&lookup); + lookup = next; + } } static int dns_lookup_input_line(struct dns_lookup *lookup, const char *line) @@ -242,7 +246,7 @@ i_free(lookup->ips); if (client->deinit_client_at_free) dns_client_deinit(&client); - else if (client->head == NULL) { + else if (client->head == NULL && client->fd != -1) { client->to_idle = timeout_add(client->idle_timeout_msecs, dns_client_idle_timeout, client); } From dovecot at dovecot.org Fri Oct 10 21:45:33 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Oct 2014 21:45:33 +0000 Subject: dovecot-2.2: auth: Userdb iteration optimization. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a36fe1250606 changeset: 17939:a36fe1250606 user: Timo Sirainen date: Sat Oct 11 00:01:09 2014 +0300 description: auth: Userdb iteration optimization. Don't keep re-creating the timeout after iterating each user. diffstat: src/auth/auth-worker-server.c | 13 ++++++++++--- 1 files changed, 10 insertions(+), 3 deletions(-) diffs (51 lines): diff -r d15da5f1731e -r a36fe1250606 src/auth/auth-worker-server.c --- a/src/auth/auth-worker-server.c Sat Oct 11 00:43:38 2014 +0300 +++ b/src/auth/auth-worker-server.c Sat Oct 11 00:01:09 2014 +0300 @@ -46,6 +46,7 @@ unsigned int received_error:1; unsigned int restart:1; unsigned int shutdown:1; + unsigned int timeout_pending_resume:1; }; static ARRAY(struct auth_worker_connection *) connections = ARRAY_INIT; @@ -278,6 +279,7 @@ timeout_reset(conn->to); } else { conn->request = NULL; + conn->timeout_pending_resume = FALSE; timeout_remove(&conn->to); conn->to = timeout_add(AUTH_WORKER_MAX_IDLE_SECS * 1000, auth_worker_idle_timeout, conn); @@ -285,6 +287,7 @@ } if (!request->callback(line, request->context) && conn->io != NULL) { + conn->timeout_pending_resume = FALSE; timeout_remove(&conn->to); io_remove(&conn->io); return FALSE; @@ -411,6 +414,7 @@ static void worker_input_resume(struct auth_worker_connection *conn) { + conn->timeout_pending_resume = FALSE; timeout_remove(&conn->to); conn->to = timeout_add(AUTH_WORKER_LOOKUP_TIMEOUT_SECS * 1000, auth_worker_call_timeout, conn); @@ -456,9 +460,12 @@ { if (conn->io == NULL) conn->io = io_add(conn->fd, IO_READ, worker_input, conn); - if (conn->to != NULL) - timeout_remove(&conn->to); - conn->to = timeout_add_short(0, worker_input_resume, conn); + if (!conn->timeout_pending_resume) { + conn->timeout_pending_resume = TRUE; + if (conn->to != NULL) + timeout_remove(&conn->to); + conn->to = timeout_add_short(0, worker_input_resume, conn); + } } void auth_worker_server_init(void) From dovecot at dovecot.org Fri Oct 10 21:45:41 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Oct 2014 21:45:41 +0000 Subject: dovecot-2.2: auth: Make sure userdb iteration is destroyed if wo... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c4e587d1e8ac changeset: 17940:c4e587d1e8ac user: Timo Sirainen date: Sat Oct 11 00:02:00 2014 +0300 description: auth: Make sure userdb iteration is destroyed if worker connection disconnects. diffstat: src/auth/auth-master-connection.c | 13 +++++++++++++ src/auth/auth-master-connection.h | 2 +- 2 files changed, 14 insertions(+), 1 deletions(-) diffs (56 lines): diff -r a36fe1250606 -r c4e587d1e8ac src/auth/auth-master-connection.c --- a/src/auth/auth-master-connection.c Sat Oct 11 00:01:09 2014 +0300 +++ b/src/auth/auth-master-connection.c Sat Oct 11 00:02:00 2014 +0300 @@ -435,6 +435,9 @@ static void master_input_list_finish(struct master_list_iter_ctx *ctx) { + i_assert(ctx->conn->iter_ctx == ctx); + + ctx->conn->iter_ctx = NULL; ctx->conn->io = io_add(ctx->conn->fd, IO_READ, master_input, ctx->conn); if (ctx->iter != NULL) @@ -532,6 +535,13 @@ } list++; + if (conn->iter_ctx != NULL) { + i_error("Auth client is already iterating users"); + str = t_strdup_printf("DONE\t%u\tfail\n", id); + o_stream_nsend_str(conn->output, str); + return TRUE; + } + if (conn->userdb_restricted_uid != 0) { i_error("Auth client doesn't have permissions to list users: %s", auth_restricted_reason(conn)); @@ -587,6 +597,7 @@ o_stream_set_flush_callback(conn->output, master_output_list, ctx); ctx->iter = userdb_blocking_iter_init(auth_request, master_input_list_callback, ctx); + conn->iter_ctx = ctx; return TRUE; } @@ -766,6 +777,8 @@ DLLIST_REMOVE(&auth_master_connections, conn); + if (conn->iter_ctx != NULL) + master_input_list_finish(conn->iter_ctx); if (conn->input != NULL) i_stream_close(conn->input); if (conn->output != NULL) diff -r a36fe1250606 -r c4e587d1e8ac src/auth/auth-master-connection.h --- a/src/auth/auth-master-connection.h Sat Oct 11 00:01:09 2014 +0300 +++ b/src/auth/auth-master-connection.h Sat Oct 11 00:02:00 2014 +0300 @@ -15,7 +15,7 @@ struct ostream *output; struct io *io; - struct auth_request_list *requests; + struct master_list_iter_ctx *iter_ctx; /* If non-zero, allow only USER lookups whose returned uid matches this uid. Don't allow LIST/PASS lookups. */ uid_t userdb_restricted_uid; From pigeonhole at rename-it.nl Fri Oct 10 22:42:57 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 11 Oct 2014 00:42:57 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: Omitted handling errors from ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/7f079d92a674 changeset: 1919:7f079d92a674 user: Stephan Bosch date: Sat Oct 11 00:42:39 2014 +0200 description: lib-sieve: Omitted handling errors from mail_get_headers() in message header stringlist. Mail storage errors now trigger a runtime error. diffstat: src/lib-sieve/sieve-message.c | 29 +++++++++++++++++------------ 1 files changed, 17 insertions(+), 12 deletions(-) diffs (47 lines): diff -r fe7ce895158b -r 7f079d92a674 src/lib-sieve/sieve-message.c --- a/src/lib-sieve/sieve-message.c Wed Oct 08 00:32:28 2014 +0200 +++ b/src/lib-sieve/sieve-message.c Sat Oct 11 00:42:39 2014 +0200 @@ -22,6 +22,7 @@ #include "sieve-extensions.h" #include "sieve-runtime.h" #include "sieve-runtime-trace.h" +#include "sieve-interpreter.h" #include "sieve-address.h" #include "sieve-message.h" @@ -536,19 +537,23 @@ /* Fetch all matching headers from the e-mail */ if ( strlist->mime_decode ) { - if ( mail_get_headers_utf8(mail, str_c(hdr_item), &strlist->headers) < 0 || - ( strlist->headers != NULL && strlist->headers[0] == NULL ) ) { - /* Try next item when this fails somehow */ - strlist->headers = NULL; - continue; - } + ret = mail_get_headers_utf8(mail, str_c(hdr_item), &strlist->headers); } else { - if ( mail_get_headers(mail, str_c(hdr_item), &strlist->headers) < 0 || - ( strlist->headers != NULL && strlist->headers[0] == NULL ) ) { - /* Try next item when this fails somehow */ - strlist->headers = NULL; - continue; - } + ret = mail_get_headers(mail, str_c(hdr_item), &strlist->headers); + } + + if (ret < 0) { + sieve_runtime_critical(renv, NULL, + "failed to read header field", + "failed to read header field `%s': %s", + str_c(hdr_item), mailbox_get_last_error(mail->box, NULL)); + _strlist->exec_status = SIEVE_EXEC_FAILURE; + return -1; + } + + if ( strlist->headers == NULL || strlist->headers[0] == NULL ) { + /* Try next item when no headers found */ + strlist->headers = NULL; } } From pigeonhole at rename-it.nl Fri Oct 10 22:44:52 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 11 Oct 2014 00:44:52 +0200 Subject: dovecot-2.2-pigeonhole: Removed useless mail-storage includes. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/9fce6189be6c changeset: 1920:9fce6189be6c user: Stephan Bosch date: Sat Oct 11 00:44:27 2014 +0200 description: Removed useless mail-storage includes. diffstat: src/lib-sieve/cmd-redirect.c | 1 + src/lib-sieve/plugins/body/ext-body-common.c | 1 + src/lib-sieve/plugins/duplicate/tst-duplicate.c | 1 + src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c | 1 + src/lib-sieve/plugins/notify/ext-notify-common.c | 1 + src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c | 1 + src/lib-sieve/plugins/vacation/cmd-vacation.c | 1 + src/lib-sieve/sieve-actions.h | 3 ++- src/lib-sieve/sieve-interpreter.c | 1 - src/lib-sieve/sieve-interpreter.h | 1 - src/lib-sieve/storage/file/sieve-file-storage.h | 1 - src/lib-sieve/tst-exists.c | 1 + src/lib-sieve/tst-size.c | 1 + src/testsuite/cmd-test-message.c | 1 + src/testsuite/testsuite-mailstore.h | 1 - src/testsuite/testsuite-smtp.c | 2 ++ 16 files changed, 14 insertions(+), 5 deletions(-) diffs (179 lines): diff -r 7f079d92a674 -r 9fce6189be6c src/lib-sieve/cmd-redirect.c --- a/src/lib-sieve/cmd-redirect.c Sat Oct 11 00:42:39 2014 +0200 +++ b/src/lib-sieve/cmd-redirect.c Sat Oct 11 00:44:27 2014 +0200 @@ -7,6 +7,7 @@ #include "istream.h" #include "istream-header-filter.h" #include "ostream.h" +#include "mail-storage.h" #include "rfc2822.h" diff -r 7f079d92a674 -r 9fce6189be6c src/lib-sieve/plugins/body/ext-body-common.c --- a/src/lib-sieve/plugins/body/ext-body-common.c Sat Oct 11 00:42:39 2014 +0200 +++ b/src/lib-sieve/plugins/body/ext-body-common.c Sat Oct 11 00:44:27 2014 +0200 @@ -11,6 +11,7 @@ #include "message-date.h" #include "message-parser.h" #include "message-decoder.h" +#include "mail-storage.h" #include "sieve-common.h" #include "sieve-stringlist.h" diff -r 7f079d92a674 -r 9fce6189be6c src/lib-sieve/plugins/duplicate/tst-duplicate.c --- a/src/lib-sieve/plugins/duplicate/tst-duplicate.c Sat Oct 11 00:42:39 2014 +0200 +++ b/src/lib-sieve/plugins/duplicate/tst-duplicate.c Sat Oct 11 00:44:27 2014 +0200 @@ -2,6 +2,7 @@ */ #include "lib.h" +#include "mail-storage.h" #include "sieve-common.h" #include "sieve-code.h" diff -r 7f079d92a674 -r 9fce6189be6c src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c --- a/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c Sat Oct 11 00:42:39 2014 +0200 +++ b/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c Sat Oct 11 00:44:27 2014 +0200 @@ -4,6 +4,7 @@ #include "lib.h" #include "str.h" #include "str-sanitize.h" +#include "mail-storage.h" #include "sieve-common.h" #include "sieve-commands.h" diff -r 7f079d92a674 -r 9fce6189be6c src/lib-sieve/plugins/notify/ext-notify-common.c --- a/src/lib-sieve/plugins/notify/ext-notify-common.c Sat Oct 11 00:42:39 2014 +0200 +++ b/src/lib-sieve/plugins/notify/ext-notify-common.c Sat Oct 11 00:44:27 2014 +0200 @@ -7,6 +7,7 @@ #include "rfc822-parser.h" #include "message-parser.h" #include "message-decoder.h" +#include "mail-storage.h" #include "sieve-common.h" #include "sieve-code.h" diff -r 7f079d92a674 -r 9fce6189be6c src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c --- a/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c Sat Oct 11 00:42:39 2014 +0200 +++ b/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c Sat Oct 11 00:44:27 2014 +0200 @@ -3,6 +3,7 @@ #include "lib.h" #include "strfuncs.h" +#include "mail-storage.h" #include "sieve-common.h" #include "sieve-settings.h" diff -r 7f079d92a674 -r 9fce6189be6c src/lib-sieve/plugins/vacation/cmd-vacation.c --- a/src/lib-sieve/plugins/vacation/cmd-vacation.c Sat Oct 11 00:42:39 2014 +0200 +++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c Sat Oct 11 00:44:27 2014 +0200 @@ -11,6 +11,7 @@ #include "message-address.h" #include "message-date.h" #include "ioloop.h" +#include "mail-storage.h" #include "rfc2822.h" diff -r 7f079d92a674 -r 9fce6189be6c src/lib-sieve/sieve-actions.h --- a/src/lib-sieve/sieve-actions.h Sat Oct 11 00:42:39 2014 +0200 +++ b/src/lib-sieve/sieve-actions.h Sat Oct 11 00:44:27 2014 +0200 @@ -5,7 +5,8 @@ #define __SIEVE_ACTIONS_H #include "lib.h" -#include "mail-storage.h" +#include "mail-types.h" +#include "mail-error.h" #include "sieve-common.h" #include "sieve-objects.h" diff -r 7f079d92a674 -r 9fce6189be6c src/lib-sieve/sieve-interpreter.c --- a/src/lib-sieve/sieve-interpreter.c Sat Oct 11 00:42:39 2014 +0200 +++ b/src/lib-sieve/sieve-interpreter.c Sat Oct 11 00:44:27 2014 +0200 @@ -6,7 +6,6 @@ #include "mempool.h" #include "array.h" #include "hash.h" -#include "mail-storage.h" #include "sieve-common.h" #include "sieve-script.h" diff -r 7f079d92a674 -r 9fce6189be6c src/lib-sieve/sieve-interpreter.h --- a/src/lib-sieve/sieve-interpreter.h Sat Oct 11 00:42:39 2014 +0200 +++ b/src/lib-sieve/sieve-interpreter.h Sat Oct 11 00:44:27 2014 +0200 @@ -7,7 +7,6 @@ #include "lib.h" #include "array.h" #include "buffer.h" -#include "mail-storage.h" #include "sieve-common.h" #include "sieve-runtime.h" diff -r 7f079d92a674 -r 9fce6189be6c src/lib-sieve/storage/file/sieve-file-storage.h --- a/src/lib-sieve/storage/file/sieve-file-storage.h Sat Oct 11 00:42:39 2014 +0200 +++ b/src/lib-sieve/storage/file/sieve-file-storage.h Sat Oct 11 00:44:27 2014 +0200 @@ -5,7 +5,6 @@ #define __SIEVE_FILE_STORAGE_H #include "lib.h" -#include "mail-storage.h" #include "mail-user.h" #include "sieve.h" diff -r 7f079d92a674 -r 9fce6189be6c src/lib-sieve/tst-exists.c --- a/src/lib-sieve/tst-exists.c Sat Oct 11 00:42:39 2014 +0200 +++ b/src/lib-sieve/tst-exists.c Sat Oct 11 00:44:27 2014 +0200 @@ -3,6 +3,7 @@ #include "lib.h" #include "str-sanitize.h" +#include "mail-storage.h" #include "sieve-common.h" #include "sieve-commands.h" diff -r 7f079d92a674 -r 9fce6189be6c src/lib-sieve/tst-size.c --- a/src/lib-sieve/tst-size.c Sat Oct 11 00:42:39 2014 +0200 +++ b/src/lib-sieve/tst-size.c Sat Oct 11 00:44:27 2014 +0200 @@ -2,6 +2,7 @@ */ #include "lib.h" +#include "mail-storage.h" #include "sieve-common.h" #include "sieve-code.h" diff -r 7f079d92a674 -r 9fce6189be6c src/testsuite/cmd-test-message.c --- a/src/testsuite/cmd-test-message.c Sat Oct 11 00:42:39 2014 +0200 +++ b/src/testsuite/cmd-test-message.c Sat Oct 11 00:44:27 2014 +0200 @@ -3,6 +3,7 @@ #include "lib.h" #include "istream.h" +#include "mail-storage.h" #include "sieve-common.h" #include "sieve-commands.h" diff -r 7f079d92a674 -r 9fce6189be6c src/testsuite/testsuite-mailstore.h --- a/src/testsuite/testsuite-mailstore.h Sat Oct 11 00:42:39 2014 +0200 +++ b/src/testsuite/testsuite-mailstore.h Sat Oct 11 00:44:27 2014 +0200 @@ -5,7 +5,6 @@ #define __TESTSUITE_MAILSTORE_H #include "lib.h" -#include "mail-storage.h" #include "sieve-common.h" diff -r 7f079d92a674 -r 9fce6189be6c src/testsuite/testsuite-smtp.c --- a/src/testsuite/testsuite-smtp.c Sat Oct 11 00:42:39 2014 +0200 +++ b/src/testsuite/testsuite-smtp.c Sat Oct 11 00:44:27 2014 +0200 @@ -14,6 +14,8 @@ #include "testsuite-common.h" #include "testsuite-smtp.h" +#include +#include #include #include From pigeonhole at rename-it.nl Fri Oct 10 23:33:22 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 11 Oct 2014 01:33:22 +0200 Subject: dovecot-2.2-pigeonhole: LDA Sieve plugin: Fixed handling of temp... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/8c4c5dfe718d changeset: 1921:8c4c5dfe718d user: Stephan Bosch date: Sat Oct 11 01:33:15 2014 +0200 description: LDA Sieve plugin: Fixed handling of temporary SMTP errors. These caused a BUG error to be reported during delivery. Solved by signalling the occurrence of storage errors as a separate execution status flag, rather than querying the last storage itself for errors, which won't work. diffstat: src/lib-sieve/sieve-actions.c | 15 ++++++++++++--- src/lib-sieve/sieve-result.c | 2 +- src/lib-sieve/sieve-types.h | 10 ++++++---- src/plugins/lda-sieve/lda-sieve-plugin.c | 3 ++- 4 files changed, 21 insertions(+), 9 deletions(-) diffs (99 lines): diff -r 9fce6189be6c -r 8c4c5dfe718d src/lib-sieve/sieve-actions.c --- a/src/lib-sieve/sieve-actions.c Sat Oct 11 00:44:27 2014 +0200 +++ b/src/lib-sieve/sieve-actions.c Sat Oct 11 01:33:15 2014 +0200 @@ -409,7 +409,8 @@ * to NULL. This implementation will then skip actually storing the message. */ if ( senv->user != NULL ) { - if ( !act_store_mailbox_open(aenv, ctx->mailbox, &box, &error_code, &error) ) { + if ( !act_store_mailbox_open + (aenv, ctx->mailbox, &box, &error_code, &error) ) { open_failed = TRUE; } } else { @@ -697,6 +698,8 @@ /* Note the fact that the message was stored at least once */ if ( status ) aenv->exec_status->message_saved = TRUE; + else + aenv->exec_status->store_failed = TRUE; /* Log our status */ act_store_log_status(trans, aenv, FALSE, status); @@ -722,6 +725,13 @@ struct act_store_transaction *trans = (struct act_store_transaction *) tr_context; + i_assert( trans->box != NULL ); + + if (!success) { + aenv->exec_status->last_storage = mailbox_get_storage(trans->box); + aenv->exec_status->store_failed = TRUE; + } + /* Log status */ act_store_log_status(trans, aenv, TRUE, success); @@ -734,8 +744,7 @@ mailbox_transaction_rollback(&trans->mail_trans); /* Close the mailbox */ - if ( trans->box != NULL ) - mailbox_free(&trans->box); + mailbox_free(&trans->box); } /* diff -r 9fce6189be6c -r 8c4c5dfe718d src/lib-sieve/sieve-result.c --- a/src/lib-sieve/sieve-result.c Sat Oct 11 00:44:27 2014 +0200 +++ b/src/lib-sieve/sieve-result.c Sat Oct 11 01:33:15 2014 +0200 @@ -1143,7 +1143,6 @@ act->def->execute != NULL ) { status = act->def->execute (act, &result->action_env, rac->tr_context); - rac->success = ( status == SIEVE_EXEC_OK ); } /* Execute post-execute event of side effects */ @@ -1156,6 +1155,7 @@ rsef = rsef->next; } + rac->success = ( status == SIEVE_EXEC_OK ); rac = rac->next; } diff -r 9fce6189be6c -r 8c4c5dfe718d src/lib-sieve/sieve-types.h --- a/src/lib-sieve/sieve-types.h Sat Oct 11 00:44:27 2014 +0200 +++ b/src/lib-sieve/sieve-types.h Sat Oct 11 01:33:15 2014 +0200 @@ -227,11 +227,13 @@ */ struct sieve_exec_status { - bool message_saved; - bool message_forwarded; - bool tried_default_save; - bool keep_original; struct mail_storage *last_storage; + + unsigned int message_saved:1; + unsigned int message_forwarded:1; + unsigned int tried_default_save:1; + unsigned int keep_original:1; + unsigned int store_failed:1; }; /* diff -r 9fce6189be6c -r 8c4c5dfe718d src/plugins/lda-sieve/lda-sieve-plugin.c --- a/src/plugins/lda-sieve/lda-sieve-plugin.c Sat Oct 11 00:44:27 2014 +0200 +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c Sat Oct 11 01:33:15 2014 +0200 @@ -381,7 +381,8 @@ error_func = user_error_func = sieve_sys_error; - if ( estatus != NULL && estatus->last_storage != NULL ) { + if ( estatus != NULL && estatus->last_storage != NULL && + estatus->store_failed) { mail_storage_get_last_error(estatus->last_storage, &mail_error); /* Don't bother administrator too much with benign errors */ From dovecot at dovecot.org Sun Oct 12 16:00:11 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 12 Oct 2014 16:00:11 +0000 Subject: dovecot-2.2: lib-http: client: Fixed segfault caused by earlier ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/871a5b807ad0 changeset: 17941:871a5b807ad0 user: Stephan Bosch date: Sun Oct 12 08:58:40 2014 -0700 description: lib-http: client: Fixed segfault caused by earlier change. diffstat: src/lib-http/http-client-connection.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (19 lines): diff -r c4e587d1e8ac -r 871a5b807ad0 src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Sat Oct 11 00:02:00 2014 +0300 +++ b/src/lib-http/http-client-connection.c Sun Oct 12 08:58:40 2014 -0700 @@ -503,7 +503,6 @@ http_client_connection_ref(conn); retrying = !http_client_request_callback(req, response); http_client_connection_unref(&conn); - conn->in_req_callback = FALSE; if (conn == NULL) { /* the callback managed to get this connection destroyed */ if (!retrying) @@ -511,6 +510,7 @@ http_client_request_unref(&req); return FALSE; } + conn->in_req_callback = FALSE; if (retrying) { /* retrying, don't destroy the request */ From dovecot at dovecot.org Sun Oct 12 16:00:12 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 12 Oct 2014 16:00:12 +0000 Subject: dovecot-2.2: lib-http: client: With the recent addition of a con... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b254b7dc717f changeset: 17942:b254b7dc717f user: Stephan Bosch date: Sun Oct 12 08:58:40 2014 -0700 description: lib-http: client: With the recent addition of a connection attempt limit, connection failures weren't always handled correctly. diffstat: src/lib-http/http-client-queue.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (16 lines): diff -r 871a5b807ad0 -r b254b7dc717f src/lib-http/http-client-queue.c --- a/src/lib-http/http-client-queue.c Sun Oct 12 08:58:40 2014 -0700 +++ b/src/lib-http/http-client-queue.c Sun Oct 12 08:58:40 2014 -0700 @@ -172,9 +172,9 @@ i_assert(queue->ips_connect_start_idx < host->ips_count); /* if a maximum connect attempts > 1 is set, enforce it directly */ - if (set->max_connect_attempts > 1) { - return queue->connect_attempts >= set->max_connect_attempts; - } + if (set->max_connect_attempts > 1 && + queue->connect_attempts >= set->max_connect_attempts) + return TRUE; /* otherwise, we'll always go through all the IPs. we don't necessarily start connecting from the first IP, so we'll need to treat the IPs as From dovecot at dovecot.org Sun Oct 12 16:00:18 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 12 Oct 2014 16:00:18 +0000 Subject: dovecot-2.2: lib-http: client: Moved delayed failed requests fro... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0086d1e38c7a changeset: 17943:0086d1e38c7a user: Stephan Bosch date: Sun Oct 12 08:58:40 2014 -0700 description: lib-http: client: Moved delayed failed requests from host to client object. diffstat: src/lib-http/http-client-host.c | 59 --------------------------------- src/lib-http/http-client-private.h | 16 +++++--- src/lib-http/http-client-request.c | 4 +- src/lib-http/http-client.c | 67 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 68 deletions(-) diffs (254 lines): diff -r b254b7dc717f -r 0086d1e38c7a src/lib-http/http-client-host.c --- a/src/lib-http/http-client-host.c Sun Oct 12 08:58:40 2014 -0700 +++ b/src/lib-http/http-client-host.c Sun Oct 12 08:58:40 2014 -0700 @@ -150,7 +150,6 @@ host->client = client; host->name = i_strdup(hostname); i_array_init(&host->queues, 4); - i_array_init(&host->delayed_failing_requests, 1); hostname = host->name; hash_table_insert(client->hosts, hostname, host); @@ -206,7 +205,6 @@ { struct http_client_host *host = *_host; struct http_client_queue *const *queue_idx; - struct http_client_request *req, *const *req_idx; const char *hostname = host->name; http_client_host_debug(host, "Host destroy"); @@ -223,64 +221,11 @@ } array_free(&host->queues); - while (array_count(&host->delayed_failing_requests) > 0) { - req_idx = array_idx(&host->delayed_failing_requests, 0); - req = *req_idx; - - i_assert(req->refcount == 1); - http_client_request_error_delayed(&req); - } - array_free(&host->delayed_failing_requests); - - if (host->to_failing_requests != NULL) - timeout_remove(&host->to_failing_requests); - i_free(host->ips); i_free(host->name); i_free(host); } -static void -http_client_host_handle_request_errors(struct http_client_host *host) -{ - timeout_remove(&host->to_failing_requests); - - while (array_count(&host->delayed_failing_requests) > 0) { - struct http_client_request *const *req_idx = - array_idx(&host->delayed_failing_requests, 0); - struct http_client_request *req = *req_idx; - - i_assert(req->refcount == 1); - http_client_request_error_delayed(&req); - } - array_clear(&host->delayed_failing_requests); -} - -void http_client_host_delay_request_error(struct http_client_host *host, - struct http_client_request *req) -{ - if (host->to_failing_requests == NULL) { - host->to_failing_requests = timeout_add_short(0, - http_client_host_handle_request_errors, host); - } - array_append(&host->delayed_failing_requests, &req, 1); -} - -void http_client_host_remove_request_error(struct http_client_host *host, - struct http_client_request *req) -{ - struct http_client_request *const *reqs; - unsigned int i, count; - - reqs = array_get(&host->delayed_failing_requests, &count); - for (i = 0; i < count; i++) { - if (reqs[i] == req) { - array_delete(&host->delayed_failing_requests, i, 1); - return; - } - } -} - void http_client_host_switch_ioloop(struct http_client_host *host) { struct http_client_queue *const *queue_idx; @@ -289,8 +234,4 @@ dns_lookup_switch_ioloop(host->dns_lookup); array_foreach(&host->queues, queue_idx) http_client_queue_switch_ioloop(*queue_idx); - if (host->to_failing_requests != NULL) { - host->to_failing_requests = - io_loop_move_timeout(&host->to_failing_requests); - } } diff -r b254b7dc717f -r 0086d1e38c7a src/lib-http/http-client-private.h --- a/src/lib-http/http-client-private.h Sun Oct 12 08:58:40 2014 -0700 +++ b/src/lib-http/http-client-private.h Sun Oct 12 08:58:40 2014 -0700 @@ -220,10 +220,6 @@ unsigned int ips_count; struct ip_addr *ips; - /* list of requests in this host that are waiting for ioloop */ - ARRAY(struct http_client_request *) delayed_failing_requests; - struct timeout *to_failing_requests; - /* requests are managed on a per-port basis */ ARRAY_TYPE(http_client_queue) queues; @@ -239,6 +235,10 @@ struct ioloop *ioloop; struct ssl_iostream_context *ssl_ctx; + /* list of failed requests that are waiting for ioloop */ + ARRAY(struct http_client_request *) delayed_failing_requests; + struct timeout *to_failing_requests; + struct connection_list *conn_list; HASH_TABLE_TYPE(http_client_host) hosts; @@ -357,11 +357,13 @@ void http_client_host_free(struct http_client_host **_host); void http_client_host_submit_request(struct http_client_host *host, struct http_client_request *req); -void http_client_host_delay_request_error(struct http_client_host *host, +void http_client_host_switch_ioloop(struct http_client_host *host); + +void http_client_delay_request_error(struct http_client *client, struct http_client_request *req); -void http_client_host_remove_request_error(struct http_client_host *host, +void http_client_remove_request_error(struct http_client *client, struct http_client_request *req); -void http_client_host_switch_ioloop(struct http_client_host *host); + static inline const char * http_client_peer_addr2str(const struct http_client_peer_addr *addr) diff -r b254b7dc717f -r 0086d1e38c7a src/lib-http/http-client-request.c --- a/src/lib-http/http-client-request.c Sun Oct 12 08:58:40 2014 -0700 +++ b/src/lib-http/http-client-request.c Sun Oct 12 08:58:40 2014 -0700 @@ -177,7 +177,7 @@ io_loop_stop(client->ioloop); if (req->delayed_error != NULL) - http_client_host_remove_request_error(req->host, req); + http_client_remove_request_error(req->client, req); if (req->payload_input != NULL) i_stream_unref(&req->payload_input); if (req->payload_output != NULL) @@ -910,7 +910,7 @@ i_assert(req->delayed_error == NULL); req->delayed_error = p_strdup(req->pool, error); req->delayed_error_status = status; - http_client_host_delay_request_error(req->host, req); + http_client_delay_request_error(req->client, req); } else { http_client_request_send_error(req, status, error); http_client_request_unref(&req); diff -r b254b7dc717f -r 0086d1e38c7a src/lib-http/http-client.c --- a/src/lib-http/http-client.c Sun Oct 12 08:58:40 2014 -0700 +++ b/src/lib-http/http-client.c Sun Oct 12 08:58:40 2014 -0700 @@ -137,6 +137,8 @@ client->set.max_auto_retry_delay = set->max_auto_retry_delay; client->set.debug = set->debug; + i_array_init(&client->delayed_failing_requests, 1); + client->conn_list = http_client_connection_list_init(); hash_table_create(&client->hosts, default_pool, 0, str_hash, strcmp); @@ -149,9 +151,23 @@ void http_client_deinit(struct http_client **_client) { struct http_client *client = *_client; + struct http_client_request *req, *const *req_idx; struct http_client_host *host; struct http_client_peer *peer; + /* drop delayed failing requests */ + while (array_count(&client->delayed_failing_requests) > 0) { + req_idx = array_idx(&client->delayed_failing_requests, 0); + req = *req_idx; + + i_assert(req->refcount == 1); + http_client_request_error_delayed(&req); + } + array_free(&client->delayed_failing_requests); + + if (client->to_failing_requests != NULL) + timeout_remove(&client->to_failing_requests); + /* free peers */ while (client->peers_list != NULL) { peer = client->peers_list; @@ -198,6 +214,12 @@ /* move dns lookups and delayed requests */ for (host = client->hosts_list; host != NULL; host = host->next) http_client_host_switch_ioloop(host); + + /* move timeouts */ + if (client->to_failing_requests != NULL) { + client->to_failing_requests = + io_loop_move_timeout(&client->to_failing_requests); + } } void http_client_wait(struct http_client *client) @@ -266,3 +288,48 @@ } return 0; } + +/* + * Delayed request errors + */ + +static void +http_client_handle_request_errors(struct http_client *client) +{ + timeout_remove(&client->to_failing_requests); + + while (array_count(&client->delayed_failing_requests) > 0) { + struct http_client_request *const *req_idx = + array_idx(&client->delayed_failing_requests, 0); + struct http_client_request *req = *req_idx; + + i_assert(req->refcount == 1); + http_client_request_error_delayed(&req); + } + array_clear(&client->delayed_failing_requests); +} + +void http_client_delay_request_error(struct http_client *client, + struct http_client_request *req) +{ + if (client->to_failing_requests == NULL) { + client->to_failing_requests = timeout_add_short(0, + http_client_handle_request_errors, client); + } + array_append(&client->delayed_failing_requests, &req, 1); +} + +void http_client_remove_request_error(struct http_client *client, + struct http_client_request *req) +{ + struct http_client_request *const *reqs; + unsigned int i, count; + + reqs = array_get(&client->delayed_failing_requests, &count); + for (i = 0; i < count; i++) { + if (reqs[i] == req) { + array_delete(&client->delayed_failing_requests, i, 1); + return; + } + } +} From dovecot at dovecot.org Mon Oct 13 13:55:57 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Oct 2014 13:55:57 +0000 Subject: dovecot-2.2: Compile fix for systems without dlopen() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ca6f330781e6 changeset: 17944:ca6f330781e6 user: Timo Sirainen date: Mon Oct 13 06:55:15 2014 -0700 description: Compile fix for systems without dlopen() diffstat: src/lib/module-dir.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diffs (16 lines): diff -r 0086d1e38c7a -r ca6f330781e6 src/lib/module-dir.c --- a/src/lib/module-dir.c Sun Oct 12 08:58:40 2014 -0700 +++ b/src/lib/module-dir.c Mon Oct 13 06:55:15 2014 -0700 @@ -580,6 +580,12 @@ { } +struct module *module_dir_find(struct module *modules ATTR_UNUSED, + const char *name ATTR_UNUSED) +{ + return NULL; +} + void *module_get_symbol(struct module *module ATTR_UNUSED, const char *symbol ATTR_UNUSED) { From dovecot at dovecot.org Mon Oct 13 15:51:27 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Oct 2014 15:51:27 +0000 Subject: dovecot-2.2: lib-index: Automatically grow header size on header... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/931ab6f3357b changeset: 17945:931ab6f3357b user: Timo Sirainen date: Mon Oct 13 08:50:44 2014 -0700 description: lib-index: Automatically grow header size on header updates. This fixes assert-crashes when it didn't happen. For example an old Maildir index could have had a header size 24. Dovecot crashed then when trying to update it, because the new header size is 36 and there wasn't an explicit mail_index_ext_resize_hdr() call. diffstat: src/lib-index/mail-index-transaction-export.c | 24 ++++++++++++++++++++++++ 1 files changed, 24 insertions(+), 0 deletions(-) diffs (41 lines): diff -r ca6f330781e6 -r 931ab6f3357b src/lib-index/mail-index-transaction-export.c --- a/src/lib-index/mail-index-transaction-export.c Mon Oct 13 06:55:15 2014 -0700 +++ b/src/lib-index/mail-index-transaction-export.c Mon Oct 13 08:50:44 2014 -0700 @@ -81,6 +81,18 @@ return buf; } +static unsigned int +ext_hdr_update_get_size(const struct mail_index_transaction_ext_hdr_update *hu) +{ + unsigned int i; + + for (i = hu->alloc_size; i > 0; i--) { + if (hu->mask[i-1] != 0) + return i; + } + return 0; +} + static void log_append_ext_intro(struct mail_index_export_context *ctx, uint32_t ext_id, uint32_t reset_id, unsigned int *hdr_size_r) @@ -139,6 +151,18 @@ intro->name_size = 0; } intro->flags = MAIL_TRANSACTION_EXT_INTRO_FLAG_NO_SHRINK; + + /* handle increasing header size automatically */ + if (array_is_created(&t->ext_hdr_updates) && + ext_id < array_count(&t->ext_hdr_updates)) { + const struct mail_index_transaction_ext_hdr_update *hu; + unsigned int hdr_update_size; + + hu = array_idx(&t->ext_hdr_updates, ext_id); + hdr_update_size = ext_hdr_update_get_size(hu); + if (intro->hdr_size < hdr_update_size) + intro->hdr_size = hdr_update_size; + } } if (reset_id != 0) { /* we're going to reset this extension in this transaction */ From dovecot at dovecot.org Mon Oct 13 16:14:36 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Oct 2014 16:14:36 +0000 Subject: dovecot-2.2: auth: Fix to earlier commit: Don't try to resume al... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e54bd2e1a767 changeset: 17946:e54bd2e1a767 user: Timo Sirainen date: Mon Oct 13 09:13:53 2014 -0700 description: auth: Fix to earlier commit: Don't try to resume already finished user iteration. diffstat: src/auth/auth-worker-server.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r 931ab6f3357b -r e54bd2e1a767 src/auth/auth-worker-server.c --- a/src/auth/auth-worker-server.c Mon Oct 13 08:50:44 2014 -0700 +++ b/src/auth/auth-worker-server.c Mon Oct 13 09:13:53 2014 -0700 @@ -458,6 +458,11 @@ void auth_worker_server_resume_input(struct auth_worker_connection *conn) { + if (conn->request == NULL) { + /* request was just finished, don't try to resume it */ + return; + } + if (conn->io == NULL) conn->io = io_add(conn->fd, IO_READ, worker_input, conn); if (!conn->timeout_pending_resume) { From pigeonhole at rename-it.nl Tue Oct 14 01:22:36 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 14 Oct 2014 03:22:36 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: mailbox extension: The `:crea... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/a0a5f61eea69 changeset: 1922:a0a5f61eea69 user: Stephan Bosch date: Tue Oct 14 03:22:23 2014 +0200 description: lib-sieve: mailbox extension: The `:create' tag erroneously subscribed an existing folder. It should only subscribe it when it is newly created. diffstat: src/lib-sieve/plugins/mailbox/tag-mailbox-create.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 8c4c5dfe718d -r a0a5f61eea69 src/lib-sieve/plugins/mailbox/tag-mailbox-create.c --- a/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c Sat Oct 11 01:33:15 2014 +0200 +++ b/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c Tue Oct 14 03:22:23 2014 +0200 @@ -131,6 +131,7 @@ /* Check whether creation has a chance of working */ switch ( trans->error_code ) { case MAIL_ERROR_NONE: + return SIEVE_EXEC_OK; case MAIL_ERROR_NOTFOUND: break; case MAIL_ERROR_TEMP: From dovecot at dovecot.org Tue Oct 14 16:23:23 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Oct 2014 16:23:23 +0000 Subject: dovecot-2.2: lib: i_stream_read_next_line() now sets a better er... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a2c5aabc49a9 changeset: 17947:a2c5aabc49a9 user: Timo Sirainen date: Tue Oct 14 09:22:40 2014 -0700 description: lib: i_stream_read_next_line() now sets a better error message if line is too long. diffstat: src/lib/istream.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (14 lines): diff -r e54bd2e1a767 -r a2c5aabc49a9 src/lib/istream.c --- a/src/lib/istream.c Mon Oct 13 09:13:53 2014 -0700 +++ b/src/lib/istream.c Tue Oct 14 09:22:40 2014 -0700 @@ -425,6 +425,10 @@ switch (i_stream_read(stream)) { case -2: + io_stream_set_error(&stream->real_stream->iostream, + "Line is too long (over %"PRIuSIZE_T + " bytes at offset %"PRIuUOFF_T")", + i_stream_get_data_size(stream), stream->v_offset); stream->stream_errno = errno = ENOBUFS; stream->eof = TRUE; return NULL; From dovecot at dovecot.org Tue Oct 14 16:37:00 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Oct 2014 16:37:00 +0000 Subject: dovecot-2.2: Compiler warning fix Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c8fd499023ef changeset: 17948:c8fd499023ef user: Timo Sirainen date: Tue Oct 14 09:36:15 2014 -0700 description: Compiler warning fix diffstat: src/lib-http/http-client.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r a2c5aabc49a9 -r c8fd499023ef src/lib-http/http-client.h --- a/src/lib-http/http-client.h Tue Oct 14 09:22:40 2014 -0700 +++ b/src/lib-http/http-client.h Tue Oct 14 09:36:15 2014 -0700 @@ -5,6 +5,7 @@ #include "http-response.h" +struct timeval; struct http_response; struct http_client; From dovecot at dovecot.org Tue Oct 14 16:40:32 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Oct 2014 16:40:32 +0000 Subject: dovecot-2.2: lib-storage: Added X-REAL-UID search parameter. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/98b5ccc539b5 changeset: 17949:98b5ccc539b5 user: Timo Sirainen date: Tue Oct 14 09:39:50 2014 -0700 description: lib-storage: Added X-REAL-UID search parameter. diffstat: src/lib-storage/index/index-search.c | 8 ++++++++ src/lib-storage/mail-search-register-imap.c | 22 +++++++++++++++++++++- src/lib-storage/mail-search.c | 3 +++ src/lib-storage/mail-search.h | 3 ++- 4 files changed, 34 insertions(+), 2 deletions(-) diffs (97 lines): diff -r c8fd499023ef -r 98b5ccc539b5 src/lib-storage/index/index-search.c --- a/src/lib-storage/index/index-search.c Tue Oct 14 09:36:15 2014 -0700 +++ b/src/lib-storage/index/index-search.c Tue Oct 14 09:39:50 2014 -0700 @@ -357,6 +357,13 @@ if (mail_get_special(ctx->cur_mail, MAIL_FETCH_GUID, &str) < 0) return -1; return strcmp(str, arg->value.str) == 0; + case SEARCH_REAL_UID: { + struct mail *real_mail; + + if (mail_get_backend_mail(ctx->cur_mail, &real_mail) < 0) + return -1; + return seq_range_exists(&arg->value.seqset, real_mail->uid); + } default: return -1; } @@ -1347,6 +1354,7 @@ case SEARCH_MAILBOX: case SEARCH_MAILBOX_GUID: case SEARCH_MAILBOX_GLOB: + case SEARCH_REAL_UID: return TRUE; } return FALSE; diff -r c8fd499023ef -r 98b5ccc539b5 src/lib-storage/mail-search-register-imap.c --- a/src/lib-storage/mail-search-register-imap.c Tue Oct 14 09:36:15 2014 -0700 +++ b/src/lib-storage/mail-search-register-imap.c Tue Oct 14 09:39:50 2014 -0700 @@ -501,6 +501,25 @@ return sarg; } +static struct mail_search_arg * +imap_search_x_real_uid(struct mail_search_build_context *ctx) +{ + struct mail_search_arg *sarg; + + /* */ + sarg = mail_search_build_str(ctx, SEARCH_REAL_UID); + if (sarg == NULL) + return NULL; + + p_array_init(&sarg->value.seqset, ctx->pool, 16); + if (imap_seq_set_parse(sarg->value.str, + &sarg->value.seqset) < 0) { + ctx->_error = "Invalid X-REAL-UID messageset"; + return NULL; + } + return sarg; +} + static const struct mail_search_register_arg imap_register_args[] = { /* argument set operations */ { "NOT", imap_search_not }, @@ -572,7 +591,8 @@ /* Other Dovecot extensions: */ { "INTHREAD", imap_search_inthread }, { "X-GUID", imap_search_x_guid }, - { "X-MAILBOX", imap_search_x_mailbox } + { "X-MAILBOX", imap_search_x_mailbox }, + { "X-REAL-UID", imap_search_x_real_uid } }; static struct mail_search_register *mail_search_register_init_imap(void) diff -r c8fd499023ef -r 98b5ccc539b5 src/lib-storage/mail-search.c --- a/src/lib-storage/mail-search.c Tue Oct 14 09:36:15 2014 -0700 +++ b/src/lib-storage/mail-search.c Tue Oct 14 09:39:50 2014 -0700 @@ -283,6 +283,7 @@ break; case SEARCH_SEQSET: case SEARCH_UIDSET: + case SEARCH_REAL_UID: p_array_init(&new_arg->value.seqset, pool, array_count(&arg->value.seqset)); array_append_array(&new_arg->value.seqset, &arg->value.seqset); @@ -759,6 +760,8 @@ return FALSE; case SEARCH_UIDSET: return array_cmp(&arg1->value.seqset, &arg2->value.seqset); + case SEARCH_REAL_UID: + return array_cmp(&arg1->value.seqset, &arg2->value.seqset); case SEARCH_FLAGS: return arg1->value.flags == arg2->value.flags; diff -r c8fd499023ef -r 98b5ccc539b5 src/lib-storage/mail-search.h --- a/src/lib-storage/mail-search.h Tue Oct 14 09:36:15 2014 -0700 +++ b/src/lib-storage/mail-search.h Tue Oct 14 09:39:50 2014 -0700 @@ -42,7 +42,8 @@ SEARCH_GUID, SEARCH_MAILBOX, SEARCH_MAILBOX_GUID, - SEARCH_MAILBOX_GLOB + SEARCH_MAILBOX_GLOB, + SEARCH_REAL_UID }; enum mail_search_date_type { From dovecot at dovecot.org Tue Oct 14 16:54:31 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Oct 2014 16:54:31 +0000 Subject: dovecot-2.2: Released v2.2.14. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6dad1f6e8930 changeset: 17950:6dad1f6e8930 user: Timo Sirainen date: Tue Oct 14 19:49:55 2014 +0300 description: Released v2.2.14. diffstat: NEWS | 7 ++++++- configure.ac | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diffs (35 lines): diff -r 98b5ccc539b5 -r 6dad1f6e8930 NEWS --- a/NEWS Tue Oct 14 09:39:50 2014 -0700 +++ b/NEWS Tue Oct 14 19:49:55 2014 +0300 @@ -1,4 +1,4 @@ -v2.2.14 2014-10-xx Timo Sirainen +v2.2.14 2014-10-14 Timo Sirainen * lmtp: Delivered-To: header no longer contains <> around the email address. Other MDAs don't have it either. @@ -38,8 +38,13 @@ - Mail headers were sometimes added to dovecot.index.cache in wrong order. The main problem this caused was with dsync+imapc incremental syncing when the second sync thought the local mailbox had changed. + - Fixed several race conditions with dovecot.index.cache handling that + may have caused unnecessary "cache is corrupted" errors. - doveadm backup didn't notice if emails were missing from the middle of the destination mailbox. Now it deletes and resyncs the mailbox. + - auth: If auth client listed userdb and disconnected before finishing, + the auth worker process got stuck (and eventually all workers could + get used up and requests would start failing). v2.2.13 2014-05-11 Timo Sirainen diff -r 98b5ccc539b5 -r 6dad1f6e8930 configure.ac --- a/configure.ac Tue Oct 14 09:39:50 2014 -0700 +++ b/configure.ac Tue Oct 14 19:49:55 2014 +0300 @@ -2,7 +2,7 @@ # Be sure to update ABI version also if anything changes that might require # recompiling plugins. Most importantly that means if any structs are changed. -AC_INIT([Dovecot],[2.2.14.rc1],[dovecot at dovecot.org]) +AC_INIT([Dovecot],[2.2.14],[dovecot at dovecot.org]) AC_DEFINE_UNQUOTED([DOVECOT_ABI_VERSION], "2.2.ABIv14($PACKAGE_VERSION)", [Dovecot ABI version]) AC_CONFIG_SRCDIR([src]) From dovecot at dovecot.org Tue Oct 14 16:54:31 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Oct 2014 16:54:31 +0000 Subject: dovecot-2.2: Added tag 2.2.14 for changeset 6dad1f6e8930 Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7caa4657a147 changeset: 17951:7caa4657a147 user: Timo Sirainen date: Tue Oct 14 19:49:55 2014 +0300 description: Added tag 2.2.14 for changeset 6dad1f6e8930 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 6dad1f6e8930 -r 7caa4657a147 .hgtags --- a/.hgtags Tue Oct 14 19:49:55 2014 +0300 +++ b/.hgtags Tue Oct 14 19:49:55 2014 +0300 @@ -119,3 +119,4 @@ 791ec610422cd2852cf51bd1842e90aa04d3ed20 2.2.13.rc1 c55c660d6e9dd0b433768c906c1462cf6e8d71d5 2.2.13 34e52cbeb83725178c0c0a282ffa5ef1c161e3cb 2.2.14.rc1 +6dad1f6e8930940f3c763cf3f27aaa7a9c979520 2.2.14 From dovecot at dovecot.org Tue Oct 14 16:54:36 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Oct 2014 16:54:36 +0000 Subject: dovecot-2.2: Added signature for changeset 6dad1f6e8930 Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b37e57304344 changeset: 17952:b37e57304344 user: Timo Sirainen date: Tue Oct 14 19:49:58 2014 +0300 description: Added signature for changeset 6dad1f6e8930 diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 7caa4657a147 -r b37e57304344 .hgsigs --- a/.hgsigs Tue Oct 14 19:49:55 2014 +0300 +++ b/.hgsigs Tue Oct 14 19:49:58 2014 +0300 @@ -82,3 +82,4 @@ 791ec610422cd2852cf51bd1842e90aa04d3ed20 0 iEUEABECAAYFAlNrnasACgkQyUhSUUBVismrBQCUD5Q/tPiX+KtsoWM3aUOyooARWgCfcfUrhO5jUSBEXZ9F61wVynvtxf0= c55c660d6e9dd0b433768c906c1462cf6e8d71d5 0 iEYEABECAAYFAlNv0HUACgkQyUhSUUBVisllBwCePV2jKcugiF0QYnIFLGJytMsW22kAn2bGBQ5hD/LrpTml5h9aCchkpSL3 34e52cbeb83725178c0c0a282ffa5ef1c161e3cb 0 iEYEABECAAYFAlQuvlIACgkQyUhSUUBVislFdwCfTD1ctLwAmkwWzuIugFdnLBo7wYoAoJbAtUIRsFyyxdgvslqT9aJ6Mg0A +6dad1f6e8930940f3c763cf3f27aaa7a9c979520 0 iEYEABECAAYFAlQ9VDQACgkQyUhSUUBVisk1fgCfdmFGZA/0DGz9vQFDeBTFK/JLhAEAnA966b+cMBaRegwj/v0Zta7c62lS From dovecot at dovecot.org Tue Oct 14 17:16:54 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Oct 2014 17:16:54 +0000 Subject: dovecot-2.2: auth: Check for empty username after doing all the ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4dc3f6103c48 changeset: 17953:4dc3f6103c48 user: Timo Sirainen date: Tue Oct 14 10:16:03 2014 -0700 description: auth: Check for empty username after doing all the username changes. diffstat: src/auth/auth-request.c | 16 +++++----------- 1 files changed, 5 insertions(+), 11 deletions(-) diffs (40 lines): diff -r b37e57304344 -r 4dc3f6103c48 src/auth/auth-request.c --- a/src/auth/auth-request.c Tue Oct 14 19:49:58 2014 +0300 +++ b/src/auth/auth-request.c Tue Oct 14 10:16:03 2014 -0700 @@ -1190,6 +1190,11 @@ request->user = old_username; } + if (user[0] == '\0') { + /* Some PAM plugins go nuts with empty usernames */ + *error_r = "Empty username"; + return FALSE; + } return user; } @@ -1206,11 +1211,6 @@ /* it does, set it. */ login_username = t_strdup_until(username, p); - if (*login_username == '\0') { - *error_r = "Empty login username"; - return FALSE; - } - /* username is the master user */ username = p + 1; } @@ -1228,12 +1228,6 @@ username = request->user; } - if (*username == '\0') { - /* Some PAM plugins go nuts with empty usernames */ - *error_r = "Empty username"; - return FALSE; - } - request->user = auth_request_fix_username(request, username, error_r); if (request->user == NULL) return FALSE; From dovecot at dovecot.org Tue Oct 14 17:18:11 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Oct 2014 17:18:11 +0000 Subject: dovecot-2.2: auth: Minor fix to previous commit. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/544945b6c3a5 changeset: 17954:544945b6c3a5 user: Timo Sirainen date: Tue Oct 14 10:17:26 2014 -0700 description: auth: Minor fix to previous commit. diffstat: src/auth/auth-request.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 4dc3f6103c48 -r 544945b6c3a5 src/auth/auth-request.c --- a/src/auth/auth-request.c Tue Oct 14 10:16:03 2014 -0700 +++ b/src/auth/auth-request.c Tue Oct 14 10:17:26 2014 -0700 @@ -1193,7 +1193,7 @@ if (user[0] == '\0') { /* Some PAM plugins go nuts with empty usernames */ *error_r = "Empty username"; - return FALSE; + return NULL; } return user; } From dovecot at dovecot.org Tue Oct 14 19:14:58 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Oct 2014 19:14:58 +0000 Subject: dovecot-2.2: Compiling fix for some systems. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/93a3335ec0d5 changeset: 17955:93a3335ec0d5 user: Timo Sirainen date: Tue Oct 14 12:14:14 2014 -0700 description: Compiling fix for some systems. diffstat: src/lib-storage/list/mailbox-list-index.h | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 544945b6c3a5 -r 93a3335ec0d5 src/lib-storage/list/mailbox-list-index.h --- a/src/lib-storage/list/mailbox-list-index.h Tue Oct 14 10:17:26 2014 -0700 +++ b/src/lib-storage/list/mailbox-list-index.h Tue Oct 14 12:14:14 2014 -0700 @@ -27,6 +27,8 @@ #include "mail-storage.h" #include "mailbox-list-private.h" +#include + #define MAILBOX_LIST_INDEX_HIERARHCY_SEP '~' #define MAILBOX_LIST_INDEX_PREFIX "dovecot.list.index" From dovecot at dovecot.org Tue Oct 14 19:18:26 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Oct 2014 19:18:26 +0000 Subject: dovecot-2.2: lib-ssl-iostream: Allow commas also in ssl_protocol... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9ce9e00cc997 changeset: 17956:9ce9e00cc997 user: Timo Sirainen date: Tue Oct 14 12:17:36 2014 -0700 description: lib-ssl-iostream: Allow commas also in ssl_protocols setting. diffstat: src/lib-ssl-iostream/iostream-openssl-common.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 93a3335ec0d5 -r 9ce9e00cc997 src/lib-ssl-iostream/iostream-openssl-common.c --- a/src/lib-ssl-iostream/iostream-openssl-common.c Tue Oct 14 12:14:14 2014 -0700 +++ b/src/lib-ssl-iostream/iostream-openssl-common.c Tue Oct 14 12:17:36 2014 -0700 @@ -20,7 +20,7 @@ int proto, op = 0, include = 0, exclude = 0; bool neg; - tmp = t_strsplit_spaces(protocols, " "); + tmp = t_strsplit_spaces(protocols, ", "); for (; *tmp != NULL; tmp++) { const char *name = *tmp; From pigeonhole at rename-it.nl Tue Oct 14 22:24:11 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Wed, 15 Oct 2014 00:24:11 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: Implemented sieve_redirect_en... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/aaf7f0f48b99 changeset: 1923:aaf7f0f48b99 user: Stephan Bosch date: Wed Oct 15 00:23:55 2014 +0200 description: lib-sieve: Implemented sieve_redirect_envelope_from setting, which allows configuring the envelope sender of redirected messages. Can either be set to the envelope sender, recipient, or orignal recipient of the processed message or it can be set explicitly to a static address. diffstat: INSTALL | 18 +++++ src/lib-sieve/cmd-redirect.c | 33 +++++++++ src/lib-sieve/sieve-common.h | 11 ++- src/lib-sieve/sieve-settings.c | 101 +++++++++++++++++++++++++++++- src/lib-sieve/sieve-settings.h | 9 ++- src/lib-sieve/sieve.c | 26 +------ src/testsuite/cmd-test-config.c | 41 +++++++----- tests/execute/smtp.svtest | 134 +++++++++++++++++++++++++++++++++++++++- 8 files changed, 327 insertions(+), 46 deletions(-) diffs (truncated from 553 to 300 lines): diff -r a0a5f61eea69 -r aaf7f0f48b99 INSTALL --- a/INSTALL Tue Oct 14 03:22:23 2014 +0200 +++ b/INSTALL Wed Oct 15 00:23:55 2014 +0200 @@ -208,6 +208,24 @@ part is left of the separator and the :detail part is right. This setting is also used by Dovecot's LMTP service. + sieve_redirect_envelope_from = sender + Specifies what envelope sender address is used for redirected messages. + Normally, the Sieve "redirect" command copies the sender address for the + redirected message from the processed message. So, the redirected message + appears to originate from the original sender. The following values are + supported for this setting: + + "sender" - The sender address is used (default) + "recipient" - The final recipient address is used + "orig_recipient" - The original recipient is used + "" - Redirected messages are always sent from user at domain. + The angle brackets are mandatory. The null "<>" address + is also supported. + + When the envelope sender of the processed message is the null address "<>", + the envelope sender of the redirected message is also always "<>", + irrespective of what is configured for this setting. + For example: plugin { diff -r a0a5f61eea69 -r aaf7f0f48b99 src/lib-sieve/cmd-redirect.c --- a/src/lib-sieve/cmd-redirect.c Tue Oct 14 03:22:23 2014 +0200 +++ b/src/lib-sieve/cmd-redirect.c Wed Oct 15 00:23:55 2014 +0200 @@ -4,6 +4,7 @@ #include "lib.h" #include "ioloop.h" #include "str-sanitize.h" +#include "strfuncs.h" #include "istream.h" #include "istream-header-filter.h" #include "ostream.h" @@ -316,6 +317,8 @@ const struct sieve_script_env *senv = aenv->scriptenv; const char *sender = sieve_message_get_sender(msgctx); const char *recipient = sieve_message_get_final_recipient(msgctx); + enum sieve_redirect_envelope_from env_from = + aenv->svinst->redirect_from; struct istream *input; struct ostream *output; const char *error; @@ -332,6 +335,36 @@ if (mail_get_stream(mail, NULL, NULL, &input) < 0) return SIEVE_EXEC_TEMP_FAILURE; + /* Determine which sender to use + + From RFC 5228, Section 4.2: + + The envelope sender address on the outgoing message is chosen by the + sieve implementation. It MAY be copied from the message being + processed. However, if the message being processed has an empty + envelope sender address the outgoing message MUST also have an empty + envelope sender address. This last requirement is imposed to prevent + loops in the case where a message is redirected to an invalid address + when then returns a delivery status notification that also ends up + being redirected to the same invalid address. + */ + if ( sender != NULL && + env_from != SIEVE_REDIRECT_ENVELOPE_FROM_SENDER ) { + switch ( env_from ) { + case SIEVE_REDIRECT_ENVELOPE_FROM_RECIPIENT: + sender = sieve_message_get_final_recipient(msgctx); + break; + case SIEVE_REDIRECT_ENVELOPE_FROM_ORIG_RECIPIENT: + sender = sieve_message_get_orig_recipient(msgctx); + break; + case SIEVE_REDIRECT_ENVELOPE_FROM_EXPLICIT: + sender = aenv->svinst->redirect_from_explicit; + break; + default: + i_unreached(); + } + } + /* Open SMTP transport */ sctx = sieve_smtp_start_single(senv, ctx->to_address, sender, &output); diff -r a0a5f61eea69 -r aaf7f0f48b99 src/lib-sieve/sieve-common.h --- a/src/lib-sieve/sieve-common.h Tue Oct 14 03:22:23 2014 +0200 +++ b/src/lib-sieve/sieve-common.h Wed Oct 15 00:23:55 2014 +0200 @@ -22,6 +22,13 @@ #define SIEVE_MAX_NUMBER ((sieve_number_t) -1) +enum sieve_redirect_envelope_from { + SIEVE_REDIRECT_ENVELOPE_FROM_SENDER, + SIEVE_REDIRECT_ENVELOPE_FROM_RECIPIENT, + SIEVE_REDIRECT_ENVELOPE_FROM_ORIG_RECIPIENT, + SIEVE_REDIRECT_ENVELOPE_FROM_EXPLICIT +}; + /* * Forward declarations */ @@ -194,10 +201,12 @@ enum sieve_env_location env_location; enum sieve_delivery_phase delivery_phase; - /* Limits */ + /* Settings */ size_t max_script_size; unsigned int max_actions; unsigned int max_redirects; + enum sieve_redirect_envelope_from redirect_from; + const char *redirect_from_explicit; }; #endif /* __SIEVE_COMMON_H */ diff -r a0a5f61eea69 -r aaf7f0f48b99 src/lib-sieve/sieve-settings.c --- a/src/lib-sieve/sieve-settings.c Tue Oct 14 03:22:23 2014 +0200 +++ b/src/lib-sieve/sieve-settings.c Wed Oct 15 00:23:55 2014 +0200 @@ -4,12 +4,40 @@ #include "lib.h" #include "sieve-common.h" +#include "sieve-limits.h" #include "sieve-error.h" #include "sieve-settings.h" #include #include +// FIXME: add to dovecot +static const char *t_str_trim(const char *str) +{ + const char *p, *pend, *begin; + + p = str; + pend = str + strlen(str); + if (p == pend) + return ""; + + while (p < pend && (*p == ' ' || *p == '\t')) + p++; + begin = p; + + p = pend - 1; + while (p > begin && (*p == ' ' || *p == '\t')) + p--; + + if (p <= begin) + return ""; + return t_strdup_until(begin, p+1); +} + +/* + * Access to settings + */ + static bool sieve_setting_parse_uint (struct sieve_instance *svinst, const char *setting, const char *str_value, char **endptr, unsigned long long int *value_r) @@ -157,8 +185,11 @@ const char *str_value; str_value = sieve_setting_get(svinst, setting); + if ( str_value == NULL ) + return FALSE; - if ( str_value == NULL || *str_value == '\0' ) + str_value = t_str_trim(str_value); + if ( *str_value == '\0' ) return FALSE; if ( strcasecmp(str_value, "yes" ) == 0) { @@ -185,8 +216,11 @@ char *endp; str_value = sieve_setting_get(svinst, setting); + if ( str_value == NULL ) + return FALSE; - if ( str_value == NULL || *str_value == '\0' ) + str_value = t_str_trim(str_value); + if ( *str_value == '\0' ) return FALSE; if ( !sieve_setting_parse_uint(svinst, setting, str_value, &endp, &value) ) @@ -225,3 +259,66 @@ return TRUE; } +/* + * Main Sieve engine settings + */ + +void sieve_settings_load +(struct sieve_instance *svinst) +{ + unsigned long long int uint_setting; + size_t size_setting; + const char *str_setting; + + svinst->max_script_size = SIEVE_DEFAULT_MAX_SCRIPT_SIZE; + if ( sieve_setting_get_size_value + (svinst, "sieve_max_script_size", &size_setting) ) { + svinst->max_script_size = size_setting; + } + + svinst->max_actions = SIEVE_DEFAULT_MAX_ACTIONS; + if ( sieve_setting_get_uint_value + (svinst, "sieve_max_actions", &uint_setting) ) { + svinst->max_actions = (unsigned int) uint_setting; + } + + svinst->max_redirects = SIEVE_DEFAULT_MAX_REDIRECTS; + if ( sieve_setting_get_uint_value + (svinst, "sieve_max_redirects", &uint_setting) ) { + svinst->max_redirects = (unsigned int) uint_setting; + } + + svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_SENDER; + svinst->redirect_from_explicit = NULL; + if ( (str_setting=sieve_setting_get + (svinst, "sieve_redirect_envelope_from")) != NULL ) { + size_t set_len; + + str_setting = t_str_trim(str_setting); + str_setting = t_str_lcase(str_setting); + set_len = strlen(str_setting); + if ( set_len > 0 ) { + if ( strcmp(str_setting, "sender") == 0 ) { + svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_SENDER; + } else if ( strcmp(str_setting, "recipient") == 0 ) { + svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_RECIPIENT; + } else if ( strcmp(str_setting, "orig_recipient") == 0 ) { + svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_ORIG_RECIPIENT; + } else if ( str_setting[0] == '<' && str_setting[set_len-1] == '>') { + svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_EXPLICIT; + + str_setting = t_str_trim(t_strndup(str_setting+1, set_len-2)); + if ( *str_setting != '\0' ) { + svinst->redirect_from_explicit = + p_strdup(svinst->pool, str_setting); + } + } else { + sieve_sys_warning(svinst, + "Invalid value `%s' for sieve_redirect_envelope_from setting", + str_setting); + } + } + } +} + + diff -r a0a5f61eea69 -r aaf7f0f48b99 src/lib-sieve/sieve-settings.h --- a/src/lib-sieve/sieve-settings.h Tue Oct 14 03:22:23 2014 +0200 +++ b/src/lib-sieve/sieve-settings.h Wed Oct 15 00:23:55 2014 +0200 @@ -7,7 +7,7 @@ #include "sieve-common.h" /* - * Settings + * Access to settings */ static inline const char *sieve_setting_get @@ -38,6 +38,13 @@ sieve_number_t *value_r); /* + * Main Sieve engine settings + */ + +void sieve_settings_load + (struct sieve_instance *svinst); + +/* * Home directory */ diff -r a0a5f61eea69 -r aaf7f0f48b99 src/lib-sieve/sieve.c --- a/src/lib-sieve/sieve.c Tue Oct 14 03:22:23 2014 +0200 +++ b/src/lib-sieve/sieve.c Wed Oct 15 00:23:55 2014 +0200 @@ -8,7 +8,6 @@ #include "eacces-error.h" #include "home-expand.h" -#include "sieve-limits.h" #include "sieve-settings.h" #include "sieve-extensions.h" #include "sieve-plugins.h" @@ -47,9 +46,7 @@ const struct sieve_callbacks *callbacks, void *context, bool debug) { struct sieve_instance *svinst; - unsigned long long int uint_setting; - size_t size_setting; - const char *domain; + const char *domain; pool_t pool; From dovecot at dovecot.org Tue Oct 14 23:58:03 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Oct 2014 23:58:03 +0000 Subject: dovecot-2.2: imap-zlib: Removed check for disallowing COMPRESS t... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e3b9cd19c33d changeset: 17957:e3b9cd19c33d user: Timo Sirainen date: Tue Oct 14 16:57:13 2014 -0700 description: imap-zlib: Removed check for disallowing COMPRESS to be used with TLS compression. Clients shouldn't be doing this in any case, and this check doesn't work properly with proxies. We could solve the check properly for Dovecot proxies by having them send the TLS compression state to backends, but it would still leave non-Dovecot proxies broken. Although we could just not advertise COMPRESS=DEFLATE extension if TLS compression is enabled and non-Dovecot proxies at least wouldn't cause failures. Still, overall seems like a lot of work for such a small and probably unnecessary extra check. diffstat: src/plugins/imap-zlib/imap-zlib-plugin.c | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-) diffs (15 lines): diff -r 9ce9e00cc997 -r e3b9cd19c33d src/plugins/imap-zlib/imap-zlib-plugin.c --- a/src/plugins/imap-zlib/imap-zlib-plugin.c Tue Oct 14 12:17:36 2014 -0700 +++ b/src/plugins/imap-zlib/imap-zlib-plugin.c Tue Oct 14 16:57:13 2014 -0700 @@ -87,11 +87,6 @@ t_str_ucase(zclient->handler->name))); return TRUE; } - if (client->tls_compression) { - client_send_tagline(cmd, - "NO [COMPRESSIONACTIVE] TLS compression already enabled."); - return TRUE; - } handler = compression_lookup_handler(t_str_lcase(mechanism)); if (handler == NULL || handler->create_istream == NULL) { From dovecot at dovecot.org Wed Oct 15 14:37:49 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Oct 2014 14:37:49 +0000 Subject: dovecot-2.2: doveconf: Allow settings plugins to print comments ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e9a05136fff2 changeset: 17958:e9a05136fff2 user: Timo Sirainen date: Wed Oct 15 07:37:05 2014 -0700 description: doveconf: Allow settings plugins to print comments to the output header. If plugin contains _doveconf_comment string, it's written as part of the doveconf output. The idea mainly being that the major plugins (such as Pigeonhole) could print their version number there to avoid having to ask for it separately. diffstat: src/config/doveconf.c | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-) diffs (35 lines): diff -r e3b9cd19c33d -r e9a05136fff2 src/config/doveconf.c --- a/src/config/doveconf.c Tue Oct 14 16:57:13 2014 -0700 +++ b/src/config/doveconf.c Wed Oct 15 07:37:05 2014 -0700 @@ -707,6 +707,7 @@ bool config_path_specified, expand_vars = FALSE, hide_key = FALSE; bool parse_full_config = FALSE, simple_output = FALSE; bool dump_defaults = FALSE, host_verify = FALSE; + bool print_plugin_comment = FALSE; if (getenv("USE_SYSEXITS") != NULL) { /* we're coming from (e.g.) LDA */ @@ -787,11 +788,23 @@ /* print the config file path before parsing it, so in case of errors it's still shown */ printf("# "DOVECOT_VERSION_FULL": %s\n", config_path); + print_plugin_comment = TRUE; fflush(stdout); } master_service_init_finish(master_service); config_parse_load_modules(); + if (print_plugin_comment) { + struct module *m; + + for (m = modules; m != NULL; m = m->next) { + const char **str = module_get_symbol_quiet(m, + t_strdup_printf("%s_doveconf_comment", m->name)); + if (str != NULL) + printf("# %s\n", *str); + } + } + if ((ret = config_parse_file(dump_defaults ? NULL : config_path, expand_vars, parse_full_config ? NULL : wanted_modules, From dovecot at dovecot.org Thu Oct 16 14:26:11 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 16 Oct 2014 14:26:11 +0000 Subject: dovecot-2.2: doveconf: Changed _doveconf_comment symbol suffix t... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/470ec616ba74 changeset: 17959:470ec616ba74 user: Timo Sirainen date: Thu Oct 16 07:25:17 2014 -0700 description: doveconf: Changed _doveconf_comment symbol suffix to _doveconf_banner That describes its behavior better. diffstat: src/config/doveconf.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diffs (34 lines): diff -r e9a05136fff2 -r 470ec616ba74 src/config/doveconf.c --- a/src/config/doveconf.c Wed Oct 15 07:37:05 2014 -0700 +++ b/src/config/doveconf.c Thu Oct 16 07:25:17 2014 -0700 @@ -707,7 +707,7 @@ bool config_path_specified, expand_vars = FALSE, hide_key = FALSE; bool parse_full_config = FALSE, simple_output = FALSE; bool dump_defaults = FALSE, host_verify = FALSE; - bool print_plugin_comment = FALSE; + bool print_plugin_banner = FALSE; if (getenv("USE_SYSEXITS") != NULL) { /* we're coming from (e.g.) LDA */ @@ -788,18 +788,18 @@ /* print the config file path before parsing it, so in case of errors it's still shown */ printf("# "DOVECOT_VERSION_FULL": %s\n", config_path); - print_plugin_comment = TRUE; + print_plugin_banner = TRUE; fflush(stdout); } master_service_init_finish(master_service); config_parse_load_modules(); - if (print_plugin_comment) { + if (print_plugin_banner) { struct module *m; for (m = modules; m != NULL; m = m->next) { const char **str = module_get_symbol_quiet(m, - t_strdup_printf("%s_doveconf_comment", m->name)); + t_strdup_printf("%s_doveconf_banner", m->name)); if (str != NULL) printf("# %s\n", *str); } From dovecot at dovecot.org Thu Oct 16 15:19:52 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 16 Oct 2014 15:19:52 +0000 Subject: dovecot-2.2: lib-storage: LAYOUT=index doesn't reserve '~' as in... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/30b84781a363 changeset: 17960:30b84781a363 user: Timo Sirainen date: Thu Oct 16 08:19:03 2014 -0700 description: lib-storage: LAYOUT=index doesn't reserve '~' as internal separator anymore. The index doesn't reserve any character as hierarchy separator, so the internal separator can change at any time. Use the namespace's configured hierarchy separator as the internal separator to avoid reserving any characters. If namespace separator isn't configured, fallback to the original '~' so this change shouldn't break anything. diffstat: src/lib-storage/list/mailbox-list-index-backend.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (16 lines): diff -r 470ec616ba74 -r 30b84781a363 src/lib-storage/list/mailbox-list-index-backend.c --- a/src/lib-storage/list/mailbox-list-index-backend.c Thu Oct 16 07:25:17 2014 -0700 +++ b/src/lib-storage/list/mailbox-list-index-backend.c Thu Oct 16 08:19:03 2014 -0700 @@ -60,9 +60,10 @@ pool_unref(&list->list.pool); } -static char index_list_get_hierarchy_sep(struct mailbox_list *list ATTR_UNUSED) +static char index_list_get_hierarchy_sep(struct mailbox_list *list) { - return MAILBOX_LIST_INDEX_HIERARHCY_SEP; + return *list->ns->set->separator != '\0' ? *list->ns->set->separator : + MAILBOX_LIST_INDEX_HIERARHCY_SEP; } static int From dovecot at dovecot.org Fri Oct 17 17:00:14 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 17 Oct 2014 17:00:14 +0000 Subject: dovecot-2.2: lib-lda: duplicate_flush() now unlocks the duplicat... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f1deba7bc3e3 changeset: 17961:f1deba7bc3e3 user: Timo Sirainen date: Fri Oct 17 09:59:21 2014 -0700 description: lib-lda: duplicate_flush() now unlocks the duplicate database even if nothing had changed. diffstat: src/lib-lda/duplicate.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diffs (27 lines): diff -r 30b84781a363 -r f1deba7bc3e3 src/lib-lda/duplicate.c --- a/src/lib-lda/duplicate.c Thu Oct 16 08:19:03 2014 -0700 +++ b/src/lib-lda/duplicate.c Fri Oct 17 09:59:21 2014 -0700 @@ -292,8 +292,13 @@ struct hash_iterate_context *iter; struct duplicate *d; - if (file == NULL || !file->changed || file->new_fd == -1) + if (file == NULL) return; + if (!file->changed || file->new_fd == -1) { + /* unlock the duplicate database */ + duplicate_file_free(&ctx->file); + return; + } memset(&hdr, 0, sizeof(hdr)); hdr.version = DUPLICATE_VERSION; @@ -358,7 +363,7 @@ *_ctx = NULL; if (ctx->file != NULL) { duplicate_flush(ctx); - duplicate_file_free(&ctx->file); + i_assert(ctx->file == NULL); } i_free(ctx->path); i_free(ctx); From dovecot at dovecot.org Fri Oct 17 17:03:39 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 17 Oct 2014 17:03:39 +0000 Subject: dovecot-2.2: lib-lda: And fixed the earlier commit. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6142d6b2ae98 changeset: 17962:6142d6b2ae98 user: Timo Sirainen date: Fri Oct 17 10:02:54 2014 -0700 description: lib-lda: And fixed the earlier commit. diffstat: src/lib-lda/duplicate.c | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-) diffs (22 lines): diff -r f1deba7bc3e3 -r 6142d6b2ae98 src/lib-lda/duplicate.c --- a/src/lib-lda/duplicate.c Fri Oct 17 09:59:21 2014 -0700 +++ b/src/lib-lda/duplicate.c Fri Oct 17 10:02:54 2014 -0700 @@ -323,16 +323,14 @@ if (o_stream_nfinish(output) < 0) { i_error("write(%s) failed: %m", file->path); o_stream_unref(&output); - file_dotlock_delete(&file->dotlock); - file->new_fd = -1; + duplicate_file_free(&ctx->file); return; } o_stream_unref(&output); - file->changed = FALSE; if (file_dotlock_replace(&file->dotlock, 0) < 0) i_error("file_dotlock_replace(%s) failed: %m", file->path); - file->new_fd = -1; + duplicate_file_free(&ctx->file); } struct duplicate_context *duplicate_init(struct mail_user *user) From pigeonhole at rename-it.nl Fri Oct 17 18:50:14 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 17 Oct 2014 20:50:14 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: Restructured result execution... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/a856f89b54ca changeset: 1924:a856f89b54ca user: Stephan Bosch date: Fri Oct 17 20:49:57 2014 +0200 description: lib-sieve: Restructured result execution, so that all actions which involve mail storage are always committed before all others. diffstat: src/lib-sieve/sieve-actions.c | 4 +- src/lib-sieve/sieve-actions.h | 3 +- src/lib-sieve/sieve-result.c | 338 ++++++++++++++++++++++++++--------------- 3 files changed, 221 insertions(+), 124 deletions(-) diffs (truncated from 425 to 300 lines): diff -r aaf7f0f48b99 -r a856f89b54ca src/lib-sieve/sieve-actions.c --- a/src/lib-sieve/sieve-actions.c Wed Oct 15 00:23:55 2014 +0200 +++ b/src/lib-sieve/sieve-actions.c Fri Oct 17 20:49:57 2014 +0200 @@ -207,7 +207,9 @@ const struct sieve_action_def act_store = { .name = "store", - .flags = SIEVE_ACTFLAG_TRIES_DELIVER, + .flags = + SIEVE_ACTFLAG_TRIES_DELIVER | + SIEVE_ACTFLAG_MAIL_STORAGE, .equals = act_store_equals, .check_duplicate = act_store_check_duplicate, .print = act_store_print, diff -r aaf7f0f48b99 -r a856f89b54ca src/lib-sieve/sieve-actions.h --- a/src/lib-sieve/sieve-actions.h Wed Oct 15 00:23:55 2014 +0200 +++ b/src/lib-sieve/sieve-actions.h Fri Oct 17 20:49:57 2014 +0200 @@ -36,7 +36,8 @@ enum sieve_action_flags { SIEVE_ACTFLAG_TRIES_DELIVER = (1 << 0), - SIEVE_ACTFLAG_SENDS_RESPONSE = (1 << 1) + SIEVE_ACTFLAG_SENDS_RESPONSE = (1 << 1), + SIEVE_ACTFLAG_MAIL_STORAGE = (1 << 2) }; /* diff -r aaf7f0f48b99 -r a856f89b54ca src/lib-sieve/sieve-result.c --- a/src/lib-sieve/sieve-result.c Wed Oct 15 00:23:55 2014 +0200 +++ b/src/lib-sieve/sieve-result.c Fri Oct 17 20:49:57 2014 +0200 @@ -1067,32 +1067,13 @@ return result->executed; } -int sieve_result_execute -(struct sieve_result *result, bool *keep) +static int sieve_result_transaction_start +(struct sieve_result *result, struct sieve_result_action *first, + struct sieve_result_action **last_r) { - bool implicit_keep = TRUE, executed = result->executed; - int status = SIEVE_EXEC_OK, commit_status, result_status; - struct sieve_result_action *rac, *first_action; - struct sieve_result_action *last_attempted; - int ret; + struct sieve_result_action *rac = first; + int status = SIEVE_EXEC_OK; - if ( keep != NULL ) *keep = FALSE; - - /* Prepare environment */ - - _sieve_result_prepare_execution(result); - - /* Make notice of this attempt */ - - first_action = ( result->last_attempted_action == NULL ? - result->first_action : result->last_attempted_action->next ); - result->last_attempted_action = result->last_action; - - /* - * Transaction start - */ - - rac = first_action; while ( status == SIEVE_EXEC_OK && rac != NULL ) { struct sieve_action *act = &rac->action; @@ -1111,12 +1092,16 @@ rac = rac->next; } - /* - * Transaction execute - */ + *last_r = rac; + return status; +} - last_attempted = rac; - rac = first_action; +static int sieve_result_transaction_execute +(struct sieve_result *result, struct sieve_result_action *first) +{ + struct sieve_result_action *rac = first; + int status = SIEVE_EXEC_OK; + while ( status == SIEVE_EXEC_OK && rac != NULL ) { struct sieve_action *act = &rac->action; struct sieve_result_side_effect *rsef; @@ -1159,118 +1144,158 @@ rac = rac->next; } - /* - * Transaction commit/rollback - */ + return status; +} - commit_status = status; - rac = first_action; - while ( rac != NULL && rac != last_attempted ) { - struct sieve_action *act = &rac->action; - struct sieve_result_side_effect *rsef; - struct sieve_side_effect *sef; +static int sieve_result_action_commit +(struct sieve_result *result, struct sieve_result_action *rac, + bool *impl_keep) +{ + struct sieve_action *act = &rac->action; + struct sieve_result_side_effect *rsef; + int cstatus = SIEVE_EXEC_OK; - if ( status == SIEVE_EXEC_OK ) { - bool impl_keep = TRUE; - int cstatus = SIEVE_EXEC_OK; + if ( act->def->commit != NULL ) { + cstatus = act->def->commit + (act, &result->action_env, rac->tr_context, impl_keep); + if ( cstatus == SIEVE_EXEC_OK ) { + act->executed = TRUE; + result->executed = TRUE; + } + } - if ( rac->keep && keep != NULL ) *keep = TRUE; + if ( cstatus == SIEVE_EXEC_OK ) { + /* Execute post_commit event of side effects */ + rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL; + while ( rsef != NULL ) { + struct sieve_side_effect *sef = &rsef->seffect; + if ( sef->def->post_commit != NULL ) + sef->def->post_commit + (sef, act, &result->action_env, rac->tr_context, impl_keep); + rsef = rsef->next; + } + } - /* Skip non-actions (inactive keep) and executed ones */ - if ( act->def == NULL || act->executed ) { - rac = rac->next; - continue; - } + return cstatus; +} - if ( act->def->commit != NULL ) { - cstatus = act->def->commit - (act, &result->action_env, rac->tr_context, &impl_keep); - if ( cstatus == SIEVE_EXEC_OK ) { - act->executed = TRUE; - result->executed = TRUE; - executed = TRUE; - } else { - /* This is bad; try to salvage as much as possible */ - if (commit_status == SIEVE_EXEC_OK) { - commit_status = cstatus; - if (!executed) { - /* We haven't executed anything yet; continue as rollback */ - status = cstatus; - } - } - impl_keep = TRUE; +static void sieve_result_action_rollback +(struct sieve_result *result, struct sieve_result_action *rac) +{ + struct sieve_action *act = &rac->action; + struct sieve_result_side_effect *rsef; + + if ( act->def->rollback != NULL ) { + act->def->rollback + (act, &result->action_env, rac->tr_context, rac->success); + } + + /* Rollback side effects */ + rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL; + while ( rsef != NULL ) { + struct sieve_side_effect *sef = &rsef->seffect; + if ( sef->def && sef->def->rollback != NULL ) + sef->def->rollback + (sef, act, &result->action_env, rac->tr_context, rac->success); + rsef = rsef->next; + } +} + +static int sieve_result_action_commit_or_rollback +(struct sieve_result *result, struct sieve_result_action *rac, + int status, bool *implicit_keep, bool *keep, int *commit_status) +{ + struct sieve_action *act = &rac->action; + + if ( status == SIEVE_EXEC_OK ) { + bool impl_keep = TRUE; + int cstatus = SIEVE_EXEC_OK; + + if ( rac->keep && keep != NULL ) *keep = TRUE; + + /* Skip non-actions (inactive keep) and executed ones */ + if ( act->def == NULL || act->executed ) + return status; + + cstatus = sieve_result_action_commit(result, rac, &impl_keep); + if (cstatus != SIEVE_EXEC_OK) { + /* This is bad; try to salvage as much as possible */ + if (*commit_status == SIEVE_EXEC_OK) { + *commit_status = cstatus; + if (!result->executed) { + /* We haven't executed anything yet; continue as rollback */ + status = cstatus; } } + impl_keep = TRUE; + } - if ( cstatus == SIEVE_EXEC_OK ) { - /* Execute post_commit event of side effects */ - rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL; - while ( rsef != NULL ) { - sef = &rsef->seffect; - if ( sef->def->post_commit != NULL ) - sef->def->post_commit - (sef, act, &result->action_env, rac->tr_context, &impl_keep); - rsef = rsef->next; - } - } + *implicit_keep = *implicit_keep && impl_keep; + } else { + /* Skip non-actions (inactive keep) and executed ones */ + if ( act->def == NULL || act->executed ) + return status; - implicit_keep = implicit_keep && impl_keep; - } else { - /* Skip non-actions (inactive keep) and executed ones */ - if ( act->def == NULL || act->executed ) { - rac = rac->next; - continue; - } + sieve_result_action_rollback(result, rac); + } - if ( act->def->rollback != NULL ) { - act->def->rollback - (act, &result->action_env, rac->tr_context, rac->success); - } + return status; +} - /* Rollback side effects */ - rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL; - while ( rsef != NULL ) { - sef = &rsef->seffect; - if ( sef->def && sef->def->rollback != NULL ) - sef->def->rollback - (sef, act, &result->action_env, rac->tr_context, rac->success); - rsef = rsef->next; - } +static int sieve_result_transaction_commit_or_rollback +(struct sieve_result *result, int status, + struct sieve_result_action *first, + struct sieve_result_action *last, + bool *implicit_keep, bool *keep) +{ + struct sieve_result_action *rac; + int commit_status = status; + + /* First commit/rollback all storage actions */ + rac = first; + while ( rac != NULL && rac != last ) { + struct sieve_action *act = &rac->action; + + if (act->def == NULL || + (act->def->flags & SIEVE_ACTFLAG_MAIL_STORAGE) == 0) { + rac = rac->next; + continue; } + status = sieve_result_action_commit_or_rollback + (result, rac, status, implicit_keep, keep, &commit_status); + rac = rac->next; } - if ( implicit_keep && keep != NULL ) *keep = TRUE; + /* Then commit/rollback all other actions */ + rac = first; + while ( rac != NULL && rac != last ) { + struct sieve_action *act = &rac->action; - /* Perform implicit keep if necessary */ + if (act->def != NULL && + (act->def->flags & SIEVE_ACTFLAG_MAIL_STORAGE) != 0) { + rac = rac->next; + continue; + } - result_status = commit_status; - if ( executed || commit_status != SIEVE_EXEC_TEMP_FAILURE ) { - /* Execute implicit keep if the transaction failed or when the implicit From pigeonhole at rename-it.nl Fri Oct 17 19:07:47 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 17 Oct 2014 21:07:47 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: Flush duplicate database befo... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/971eba8c3361 changeset: 1925:971eba8c3361 user: Stephan Bosch date: Fri Oct 17 21:07:36 2014 +0200 description: lib-sieve: Flush duplicate database before committing storage transactions. diffstat: src/lib-sieve/sieve-actions.c | 9 +++++++++ src/lib-sieve/sieve-actions.h | 2 ++ src/lib-sieve/sieve-result.c | 7 +++++++ src/lib-sieve/sieve-types.h | 2 ++ src/plugins/lda-sieve/lda-sieve-plugin.c | 9 +++++++++ 5 files changed, 29 insertions(+), 0 deletions(-) diffs (95 lines): diff -r a856f89b54ca -r 971eba8c3361 src/lib-sieve/sieve-actions.c --- a/src/lib-sieve/sieve-actions.c Fri Oct 17 20:49:57 2014 +0200 +++ b/src/lib-sieve/sieve-actions.c Fri Oct 17 21:07:36 2014 +0200 @@ -780,6 +780,15 @@ senv->duplicate_mark(senv, id, id_size, time); } +void sieve_action_duplicate_flush +(const struct sieve_script_env *senv) +{ + if ( senv->duplicate_flush == NULL ) + return; + senv->duplicate_flush(senv); +} + + /* Rejecting the mail */ static bool sieve_action_do_reject_mail diff -r a856f89b54ca -r 971eba8c3361 src/lib-sieve/sieve-actions.h --- a/src/lib-sieve/sieve-actions.h Fri Oct 17 20:49:57 2014 +0200 +++ b/src/lib-sieve/sieve-actions.h Fri Oct 17 21:07:36 2014 +0200 @@ -265,6 +265,8 @@ void sieve_action_duplicate_mark (const struct sieve_script_env *senv, const void *id, size_t id_size, time_t time); +void sieve_action_duplicate_flush + (const struct sieve_script_env *senv); /* Rejecting mail */ diff -r a856f89b54ca -r 971eba8c3361 src/lib-sieve/sieve-result.c --- a/src/lib-sieve/sieve-result.c Fri Oct 17 20:49:57 2014 +0200 +++ b/src/lib-sieve/sieve-result.c Fri Oct 17 21:07:36 2014 +0200 @@ -1248,8 +1248,10 @@ struct sieve_result_action *last, bool *implicit_keep, bool *keep) { + const struct sieve_script_env *senv = result->action_env.scriptenv; struct sieve_result_action *rac; int commit_status = status; + bool dup_flushed = FALSE; /* First commit/rollback all storage actions */ rac = first; @@ -1262,6 +1264,11 @@ continue; } + if (!dup_flushed) { + sieve_action_duplicate_flush(senv); + dup_flushed = TRUE; + } + status = sieve_result_action_commit_or_rollback (result, rac, status, implicit_keep, keep, &commit_status); diff -r a856f89b54ca -r 971eba8c3361 src/lib-sieve/sieve-types.h --- a/src/lib-sieve/sieve-types.h Fri Oct 17 20:49:57 2014 +0200 +++ b/src/lib-sieve/sieve-types.h Fri Oct 17 21:07:36 2014 +0200 @@ -206,6 +206,8 @@ void (*duplicate_mark) (const struct sieve_script_env *senv, const void *id, size_t id_size, time_t time); + void (*duplicate_flush) + (const struct sieve_script_env *senv); /* Interface for rejecting mail */ int (*reject_mail)(const struct sieve_script_env *senv, diff -r a856f89b54ca -r 971eba8c3361 src/plugins/lda-sieve/lda-sieve-plugin.c --- a/src/plugins/lda-sieve/lda-sieve-plugin.c Fri Oct 17 20:49:57 2014 +0200 +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c Fri Oct 17 21:07:36 2014 +0200 @@ -132,6 +132,14 @@ duplicate_mark(dctx->dup_ctx, id, id_size, senv->user->username, time); } +static void lda_sieve_duplicate_flush +(const struct sieve_script_env *senv) +{ + struct mail_deliver_context *dctx = + (struct mail_deliver_context *) senv->script_context; + duplicate_flush(dctx->dup_ctx); +} + /* * Plugin implementation */ @@ -906,6 +914,7 @@ scriptenv.smtp_finish = lda_sieve_smtp_finish; scriptenv.duplicate_mark = lda_sieve_duplicate_mark; scriptenv.duplicate_check = lda_sieve_duplicate_check; + scriptenv.duplicate_flush = lda_sieve_duplicate_flush; scriptenv.reject_mail = lda_sieve_reject_mail; scriptenv.script_context = (void *) mdctx; scriptenv.exec_status = &estatus; From dovecot at dovecot.org Fri Oct 17 22:55:51 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 17 Oct 2014 22:55:51 +0000 Subject: dovecot-2.2: lib-storage: If we detect a broken cached message s... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/babddd4c9ca9 changeset: 17963:babddd4c9ca9 user: Timo Sirainen date: Sat Oct 18 01:55:02 2014 +0300 description: lib-storage: If we detect a broken cached message size, log more information about it. Also try to include one of the cached headers in the message, which could allow detecting if the cached data pointed to a completely different message. diffstat: src/lib-storage/index/istream-mail.c | 36 +++++++++++++++++++++++++++++++++--- 1 files changed, 33 insertions(+), 3 deletions(-) diffs (59 lines): diff -r 6142d6b2ae98 -r babddd4c9ca9 src/lib-storage/index/istream-mail.c --- a/src/lib-storage/index/istream-mail.c Fri Oct 17 10:02:54 2014 -0700 +++ b/src/lib-storage/index/istream-mail.c Sat Oct 18 01:55:02 2014 +0300 @@ -31,11 +31,36 @@ return mstream->expected_size != (uoff_t)-1; } +static const char * +i_stream_mail_get_cached_mail_id(struct mail_istream *mstream) +{ + static const char *headers[] = { + "Message-Id", + "Date", + "Subject" + }; + struct mail *mail = mstream->mail; + enum mail_lookup_abort orig_lookup_abort; + const char *value, *ret = ""; + unsigned int i; + + orig_lookup_abort = mail->lookup_abort; + mail->lookup_abort = MAIL_LOOKUP_ABORT_NOT_IN_CACHE; + for (i = 0; i < N_ELEMENTS(headers); i++) { + if (mail_get_first_header(mail, headers[i], &value) > 0) { + ret = t_strdup_printf("%s=%s", headers[i], value); + break; + } + } + mail->lookup_abort = orig_lookup_abort; + return ret; +} + static void i_stream_mail_set_size_corrupted(struct mail_istream *mstream, size_t size) { uoff_t cur_size = mstream->istream.istream.v_offset + size; - const char *str; + const char *str, *mail_id; char chr; if (mstream->expected_size < cur_size) { @@ -46,10 +71,15 @@ chr = '>'; } + mail_id = i_stream_mail_get_cached_mail_id(mstream); + if (mail_id[0] != '\0') + mail_id = t_strconcat(", cached ", mail_id, NULL); io_stream_set_error(&mstream->istream.iostream, "Cached message size %s than expected " - "(%"PRIuUOFF_T" %c %"PRIuUOFF_T")", str, - mstream->expected_size, chr, cur_size); + "(%"PRIuUOFF_T" %c %"PRIuUOFF_T", box=%s, UID=%u%s)", str, + mstream->expected_size, chr, cur_size, + mailbox_get_vname(mstream->mail->box), + mstream->mail->uid, mail_id); mail_storage_set_critical(mstream->mail->box->storage, "%s", mstream->istream.iostream.error); mail_set_cache_corrupted(mstream->mail, MAIL_FETCH_PHYSICAL_SIZE); From dovecot at dovecot.org Fri Oct 17 23:13:46 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 17 Oct 2014 23:13:46 +0000 Subject: dovecot-2.2: lib-storage: When logging about corrupted cached me... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b0bc1fac94a3 changeset: 17964:b0bc1fac94a3 user: Timo Sirainen date: Sat Oct 18 02:12:47 2014 +0300 description: lib-storage: When logging about corrupted cached message size, log the filename also. diffstat: src/lib-storage/index/istream-mail.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r babddd4c9ca9 -r b0bc1fac94a3 src/lib-storage/index/istream-mail.c --- a/src/lib-storage/index/istream-mail.c Sat Oct 18 01:55:02 2014 +0300 +++ b/src/lib-storage/index/istream-mail.c Sat Oct 18 02:12:47 2014 +0300 @@ -80,7 +80,8 @@ mstream->expected_size, chr, cur_size, mailbox_get_vname(mstream->mail->box), mstream->mail->uid, mail_id); - mail_storage_set_critical(mstream->mail->box->storage, "%s", + mail_storage_set_critical(mstream->mail->box->storage, "read(%s) failed: %s", + i_stream_get_name(&mstream->istream.istream), mstream->istream.iostream.error); mail_set_cache_corrupted(mstream->mail, MAIL_FETCH_PHYSICAL_SIZE); mstream->istream.istream.stream_errno = EINVAL; From dovecot at dovecot.org Fri Oct 17 23:14:24 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 17 Oct 2014 23:14:24 +0000 Subject: dovecot-2.2: doveadm fetch: If istream reading fails, log a bett... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cd5dba84d8de changeset: 17965:cd5dba84d8de user: Timo Sirainen date: Sat Oct 18 02:13:30 2014 +0300 description: doveadm fetch: If istream reading fails, log a better error message. diffstat: src/doveadm/doveadm-mail-fetch.c | 12 ++++++++---- 1 files changed, 8 insertions(+), 4 deletions(-) diffs (43 lines): diff -r b0bc1fac94a3 -r cd5dba84d8de src/doveadm/doveadm-mail-fetch.c --- a/src/doveadm/doveadm-mail-fetch.c Sat Oct 18 02:12:47 2014 +0300 +++ b/src/doveadm/doveadm-mail-fetch.c Sat Oct 18 02:13:30 2014 +0300 @@ -128,7 +128,8 @@ i_stream_skip(input, size); } if (input->stream_errno != 0) { - i_error("read() failed: %m"); + i_error("read(%s) failed: %s", i_stream_get_name(input), + i_stream_get_error(input)); ret = -1; } i_stream_unref(&input); @@ -222,7 +223,8 @@ i_stream_skip(input, size); } if (input->stream_errno != 0) { - i_error("read() failed: %m"); + i_error("read(%s) failed: %s", i_stream_get_name(input), + i_stream_get_error(input)); ret = -1; } doveadm_print_stream("", 0); @@ -248,7 +250,8 @@ i_stream_skip(input, size); } if (input->stream_errno != 0) { - i_error("read() failed: %m"); + i_error("read(%s) failed: %s", i_stream_get_name(input), + i_stream_get_error(input)); ret = -1; } doveadm_print_stream("", 0); @@ -300,7 +303,8 @@ doveadm_print_stream("", 0); if (input->stream_errno != 0) { - i_error("read() failed: %m"); + i_error("read(%s) failed: %s", i_stream_get_name(input), + i_stream_get_error(input)); return -1; } return 0; From pigeonhole at rename-it.nl Sat Oct 18 23:02:30 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 19 Oct 2014 01:02:30 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: Improved (temporary) error ha... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/465dbd029556 changeset: 1926:465dbd029556 user: Stephan Bosch date: Sun Oct 19 01:02:02 2014 +0200 description: lib-sieve: Improved (temporary) error handling from mail storage and io streams. diffstat: src/lib-sieve/cmd-redirect.c | 28 ++- src/lib-sieve/plugins/body/ext-body-common.c | 90 +++++-- src/lib-sieve/plugins/body/ext-body-common.h | 4 +- src/lib-sieve/plugins/body/tst-body.c | 7 +- src/lib-sieve/plugins/duplicate/tst-duplicate.c | 19 +- src/lib-sieve/plugins/enotify/cmd-notify.c | 6 +- src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c | 52 ++-- src/lib-sieve/plugins/enotify/sieve-ext-enotify.h | 9 +- src/lib-sieve/plugins/notify/cmd-notify.c | 33 +- src/lib-sieve/plugins/notify/ext-notify-common.c | 61 ++++- src/lib-sieve/plugins/notify/ext-notify-common.h | 2 +- src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c | 33 ++- src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.h | 4 +- src/lib-sieve/plugins/spamvirustest/tst-spamvirustest.c | 4 +- src/lib-sieve/plugins/vacation/cmd-vacation.c | 111 ++++++--- src/lib-sieve/sieve-actions.c | 20 +- src/lib-sieve/sieve-interpreter.c | 19 + src/lib-sieve/sieve-interpreter.h | 3 + src/lib-sieve/sieve-message.c | 7 +- src/lib-sieve/sieve-result.c | 35 +++ src/lib-sieve/sieve-result.h | 7 + src/lib-sieve/tst-exists.c | 12 +- src/plugins/sieve-extprograms/cmd-execute.c | 10 +- src/plugins/sieve-extprograms/cmd-filter.c | 10 +- src/plugins/sieve-extprograms/cmd-pipe.c | 10 +- 25 files changed, 411 insertions(+), 185 deletions(-) diffs (truncated from 1305 to 300 lines): diff -r 971eba8c3361 -r 465dbd029556 src/lib-sieve/cmd-redirect.c --- a/src/lib-sieve/cmd-redirect.c Fri Oct 17 21:07:36 2014 +0200 +++ b/src/lib-sieve/cmd-redirect.c Sun Oct 19 01:02:02 2014 +0200 @@ -332,8 +332,10 @@ return SIEVE_EXEC_FAILURE; } - if (mail_get_stream(mail, NULL, NULL, &input) < 0) - return SIEVE_EXEC_TEMP_FAILURE; + if (mail_get_stream(mail, NULL, NULL, &input) < 0) { + return sieve_result_mail_error(aenv, mail, + "redirect action: failed to read input message"); + } /* Determine which sender to use @@ -386,6 +388,13 @@ } T_END; o_stream_send_istream(output, input); + if (input->stream_errno != 0) { + sieve_result_critical(aenv, + "redirect action: failed to read input message", + "redirect action: failed to read message stream: %s", + i_stream_get_error(input)); + return SIEVE_EXEC_TEMP_FAILURE; + } i_stream_unref(&input); /* Close SMTP transport */ @@ -424,10 +433,19 @@ int ret; /* Prevent mail loops if possible */ - (void)mail_get_first_header(msgdata->mail, "resent-message-id", &resent_id); + if ( mail_get_first_header + (msgdata->mail, "resent-message-id", &resent_id) < 0 ) { + return sieve_result_mail_error(aenv, mail, + "failed to read header field `resent-message-id'"); + } if ( msgdata->id != NULL || resent_id != NULL ) { - if ( resent_id == NULL ) - (void)mail_get_first_header(msgdata->mail, "resent-from", &resent_from); + if ( resent_id == NULL ) { + if ( mail_get_first_header + (msgdata->mail, "resent-from", &resent_from) < 0 ) { + return sieve_result_mail_error(aenv, mail, + "failed to read header field `resent-from'"); + } + } dupeid = t_strdup_printf("%s-%s-%s-%s", (msgdata->id == NULL ? "" : msgdata->id), orig_recipient, ctx->to_address, diff -r 971eba8c3361 -r 465dbd029556 src/lib-sieve/plugins/body/ext-body-common.c --- a/src/lib-sieve/plugins/body/ext-body-common.c Fri Oct 17 21:07:36 2014 +0200 +++ b/src/lib-sieve/plugins/body/ext-body-common.c Sun Oct 19 01:02:02 2014 +0200 @@ -211,11 +211,12 @@ /* ext_body_parts_add_missing(): * Add requested message body parts to the cache that are missing. */ -static bool ext_body_parts_add_missing -(struct sieve_message_context *msgctx, struct ext_body_message_context *ctx, - const char * const *content_types, bool decode_to_plain) +static int ext_body_parts_add_missing +(const struct sieve_runtime_env *renv, + struct ext_body_message_context *ctx, + const char *const *content_types, bool decode_to_plain) { - struct mail *mail = sieve_message_get_mail(msgctx); + struct mail *mail = sieve_message_get_mail(renv->msgctx); struct ext_body_part_cached *body_part = NULL, *header_part = NULL; struct message_parser_ctx *parser; struct message_decoder_context *decoder; @@ -230,15 +231,18 @@ /* First check whether any are missing */ if (ext_body_get_return_parts(ctx, content_types, decode_to_plain)) { /* Cache hit; all are present */ - return TRUE; + return SIEVE_EXEC_OK; } /* Get the message stream */ - if ( mail_get_stream(mail, NULL, NULL, &input) < 0 ) - return FALSE; - - if (mail_get_parts(mail, &parts) < 0) - return FALSE; + if ( mail_get_stream(mail, NULL, NULL, &input) < 0 ) { + return sieve_runtime_mail_error(renv, mail, + "body test: failed to read input message"); + } + if (mail_get_parts(mail, &parts) < 0) { + return sieve_runtime_mail_error(renv, mail, + "body test: failed to parse input message"); + } if ( (want_multipart=_want_multipart_content_type(content_types)) ) { t_array_init(&part_index, 8); @@ -408,7 +412,14 @@ message_decoder_deinit(&decoder); /* Return status */ - return ( input->stream_errno == 0 ); + if ( input->stream_errno != 0 ) { + sieve_runtime_critical(renv, NULL, + "body test: failed to read input message", + "body test: failed to read message stream: %s", + i_stream_get_error(input)); + return SIEVE_EXEC_TEMP_FAILURE; + } + return SIEVE_EXEC_OK; } static struct ext_body_message_context *ext_body_get_context @@ -440,33 +451,33 @@ return ctx; } -static bool ext_body_get_content +static int ext_body_get_content (const struct sieve_runtime_env *renv, const char * const *content_types, int decode_to_plain, struct ext_body_part **parts_r) { const struct sieve_extension *this_ext = renv->oprtn->ext; struct ext_body_message_context *ctx = ext_body_get_context(this_ext, renv->msgctx); - bool result = TRUE; + int status; T_BEGIN { /* Fill the return_body_parts array */ - if ( !ext_body_parts_add_missing - (renv->msgctx, ctx, content_types, decode_to_plain != 0) ) - result = FALSE; + status = ext_body_parts_add_missing + (renv, ctx, content_types, decode_to_plain != 0); } T_END; /* Check status */ - if ( !result ) return FALSE; + if ( status <= 0 ) + return status; /* Return the array of body items */ (void) array_append_space(&ctx->return_body_parts); /* NULL-terminate */ *parts_r = array_idx_modifiable(&ctx->return_body_parts, 0); - return result; + return status; } -static bool ext_body_get_raw +static int ext_body_get_raw (const struct sieve_runtime_env *renv, struct ext_body_part **parts_r) { const struct sieve_extension *this_ext = renv->oprtn->ext; @@ -486,8 +497,10 @@ ctx->raw_body = buf = buffer_create_dynamic(ctx->pool, 1024*64); /* Get stream for message */ - if ( mail_get_stream(mail, &hdr_size, &body_size, &input) < 0 ) - return FALSE; + if ( mail_get_stream(mail, &hdr_size, &body_size, &input) < 0 ) { + return sieve_runtime_mail_error(renv, mail, + "body test: failed to read input message"); + } /* Skip stream to beginning of body */ i_stream_skip(input, hdr_size.physical_size); @@ -499,8 +512,13 @@ i_stream_skip(input, size); } - if ( ret == -1 && input->stream_errno != 0 ) - return FALSE; + if ( ret == -1 && input->stream_errno != 0 ) { + sieve_runtime_critical(renv, NULL, + "body test: failed to read input message as raw", + "body test: failed to read raw message stream: %s", + i_stream_get_error(input)); + return SIEVE_EXEC_TEMP_FAILURE; + } } else { buf = ctx->raw_body; } @@ -522,7 +540,7 @@ (void) array_append_space(&ctx->return_body_parts); /* NULL-terminate */ *parts_r = array_idx_modifiable(&ctx->return_body_parts, 0); - return TRUE; + return SIEVE_EXEC_OK; } /* @@ -541,30 +559,35 @@ struct ext_body_part *body_parts_iter; }; -struct sieve_stringlist *ext_body_get_part_list +int ext_body_get_part_list (const struct sieve_runtime_env *renv, enum tst_body_transform transform, - const char * const *content_types) + const char * const *content_types, struct sieve_stringlist **strlist_r) { static const char * const _no_content_types[] = { "", NULL }; struct ext_body_stringlist *strlist; struct ext_body_part *body_parts; + int ret; + + *strlist_r = NULL; if ( content_types == NULL ) content_types = _no_content_types; switch ( transform ) { case TST_BODY_TRANSFORM_RAW: - if ( !ext_body_get_raw(renv, &body_parts) ) - return NULL; + if ( (ret=ext_body_get_raw(renv, &body_parts)) <= 0 ) + return ret; break; case TST_BODY_TRANSFORM_CONTENT: /* FIXME: check these parameters */ - if ( !ext_body_get_content(renv, content_types, TRUE, &body_parts) ) - return NULL; + if ( (ret=ext_body_get_content + (renv, content_types, TRUE, &body_parts)) <= 0 ) + return ret; break; case TST_BODY_TRANSFORM_TEXT: /* FIXME: check these parameters */ - if ( !ext_body_get_content(renv, content_types, TRUE, &body_parts) ) - return NULL; + if ( (ret=ext_body_get_content + (renv, content_types, TRUE, &body_parts)) <= 0 ) + return ret; break; default: i_unreached(); @@ -577,7 +600,8 @@ strlist->body_parts = body_parts; strlist->body_parts_iter = body_parts; - return &strlist->strlist; + *strlist_r = &strlist->strlist; + return SIEVE_EXEC_OK; } static int ext_body_stringlist_next_item diff -r 971eba8c3361 -r 465dbd029556 src/lib-sieve/plugins/body/ext-body-common.h --- a/src/lib-sieve/plugins/body/ext-body-common.h Fri Oct 17 21:07:36 2014 +0200 +++ b/src/lib-sieve/plugins/body/ext-body-common.h Sun Oct 19 01:02:02 2014 +0200 @@ -36,8 +36,8 @@ * Message body part extraction */ -struct sieve_stringlist *ext_body_get_part_list +int ext_body_get_part_list (const struct sieve_runtime_env *renv, enum tst_body_transform transform, - const char * const *content_types); + const char * const *content_types, struct sieve_stringlist **strlist_r); #endif /* __EXT_BODY_COMMON_H */ diff -r 971eba8c3361 -r 465dbd029556 src/lib-sieve/plugins/body/tst-body.c --- a/src/lib-sieve/plugins/body/tst-body.c Fri Oct 17 21:07:36 2014 +0200 +++ b/src/lib-sieve/plugins/body/tst-body.c Sun Oct 19 01:02:02 2014 +0200 @@ -370,10 +370,9 @@ sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "body test"); /* Extract requested parts */ - value_list = ext_body_get_part_list - (renv, (enum tst_body_transform) transform, content_types); - if ( value_list == FALSE ) - return SIEVE_EXEC_FAILURE; + if ( (ret=ext_body_get_part_list(renv, + (enum tst_body_transform) transform, content_types,&value_list)) <= 0 ) + return ret; /* Disable match values processing as required by RFC */ mvalues_active = sieve_match_values_set_enabled(renv, FALSE); diff -r 971eba8c3361 -r 465dbd029556 src/lib-sieve/plugins/duplicate/tst-duplicate.c --- a/src/lib-sieve/plugins/duplicate/tst-duplicate.c Fri Oct 17 21:07:36 2014 +0200 +++ b/src/lib-sieve/plugins/duplicate/tst-duplicate.c Sun Oct 19 01:02:02 2014 +0200 @@ -316,6 +316,7 @@ const struct sieve_extension *ext = renv->oprtn->ext; const struct ext_duplicate_config *config = (const struct ext_duplicate_config *) ext->context; + struct mail *mail = renv->msgdata->mail; int opt_code = 0; string_t *handle = NULL, *header = NULL, *uniqueid = NULL; const char *val = NULL; @@ -380,13 +381,21 @@ val_len = str_len(uniqueid); } else { if ( header == NULL ) { - ret = mail_get_first_header_utf8 - (renv->msgdata->mail, "Message-ID", &val); + ret = mail_get_first_header_utf8(mail, "Message-ID", &val); + if ( ret < 0 ) { + return sieve_runtime_mail_error (renv, mail, + "duplicate test: " From pigeonhole at rename-it.nl Sun Oct 19 07:34:39 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 19 Oct 2014 09:34:39 +0200 Subject: dovecot-2.2-pigeonhole: managesieve: Fixed handling of o_stream_... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/e15298e74253 changeset: 1927:e15298e74253 user: Stephan Bosch date: Sun Oct 19 09:34:03 2014 +0200 description: managesieve: Fixed handling of o_stream_send_istream() errors during GETSCRIPT command. diffstat: src/managesieve/cmd-getscript.c | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-) diffs (22 lines): diff -r 465dbd029556 -r e15298e74253 src/managesieve/cmd-getscript.c --- a/src/managesieve/cmd-getscript.c Sun Oct 19 01:02:02 2014 +0200 +++ b/src/managesieve/cmd-getscript.c Sun Oct 19 09:34:03 2014 +0200 @@ -54,9 +54,15 @@ ret = o_stream_send_istream(client->output, ctx->script_stream); if ( ret < 0 ) { - sieve_storage_set_critical(ctx->storage, - "o_stream_send_istream() failed for script `%s' from %s: %m", - sieve_script_name(ctx->script), sieve_script_location(ctx->script)); + if ( ctx->script_stream->stream_errno != 0 ) { + sieve_storage_set_critical(ctx->storage, + "o_stream_send_istream() failed for script `%s' from %s: %s", + sieve_script_name(ctx->script), + sieve_script_location(ctx->script), + i_stream_get_error(ctx->script_stream)); + } else { + client_disconnect(ctx->client, NULL); + } ctx->failed = TRUE; return cmd_getscript_finish(ctx); } From pigeonhole at rename-it.nl Sun Oct 19 07:37:56 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 19 Oct 2014 09:37:56 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: Removed implicitly resolved F... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/05225545cdeb changeset: 1928:05225545cdeb user: Stephan Bosch date: Sun Oct 19 09:37:48 2014 +0200 description: lib-sieve: Removed implicitly resolved FIXME. diffstat: src/lib-sieve/sieve-actions.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diffs (11 lines): diff -r e15298e74253 -r 05225545cdeb src/lib-sieve/sieve-actions.c --- a/src/lib-sieve/sieve-actions.c Sun Oct 19 09:34:03 2014 +0200 +++ b/src/lib-sieve/sieve-actions.c Sun Oct 19 09:37:48 2014 +0200 @@ -463,7 +463,6 @@ (void)array_append_space(keywords); kwds = array_idx(keywords, 0); - /* FIXME: Do we need to clear duplicates? */ if ( mailbox_keywords_create(box, kwds, &box_keywords) < 0) { sieve_result_error(aenv, "invalid keywords set for stored message"); return NULL; From pigeonhole at rename-it.nl Sun Oct 19 09:01:27 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 19 Oct 2014 11:01:27 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: Improved handling of stream e... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/e11f41c437a5 changeset: 1929:e11f41c437a5 user: Stephan Bosch date: Sun Oct 19 11:01:17 2014 +0200 description: lib-sieve: Improved handling of stream errors in lexical scannner. diffstat: src/lib-sieve/sieve-lexer.c | 168 ++++++++++++++++++++++++++++--------------- 1 files changed, 108 insertions(+), 60 deletions(-) diffs (267 lines): diff -r 05225545cdeb -r e11f41c437a5 src/lib-sieve/sieve-lexer.c --- a/src/lib-sieve/sieve-lexer.c Sun Oct 19 09:37:48 2014 +0200 +++ b/src/lib-sieve/sieve-lexer.c Sun Oct 19 11:01:17 2014 +0200 @@ -277,17 +277,61 @@ return t_strdup_printf("0x%02x", ch); } +static bool +sieve_lexer_scan_hash_comment(struct sieve_lexical_scanner *scanner) +{ + struct sieve_lexer *lexer = &scanner->lexer; + + while ( sieve_lexer_curchar(scanner) != '\n' ) { + switch( sieve_lexer_curchar(scanner) ) { + case -1: + if ( scanner->input->eof ) { + sieve_lexer_warning(lexer, + "no newline (CRLF) at end of hash comment at end of file"); + lexer->token_type = STT_WHITESPACE; + } else { + lexer->token_type = STT_ERROR; + } + return TRUE; + case '\0': + sieve_lexer_error + (lexer, "encountered NUL character in hash comment"); + lexer->token_type = STT_ERROR; + return FALSE; + default: + break; + } + + /* Stray CR is ignored */ + + sieve_lexer_shift(scanner); + } + + sieve_lexer_shift(scanner); + + lexer->token_type = STT_WHITESPACE; + return TRUE; +} + /* sieve_lexer_scan_raw_token: * Scans valid tokens and whitespace */ -static bool sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner) +static bool +sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner) { struct sieve_lexer *lexer = &scanner->lexer; string_t *str; + int ret; /* Read first character */ if ( lexer->token_type == STT_NONE ) { - i_stream_read(scanner->input); + if ( (ret=i_stream_read(scanner->input)) < 0 ) { + i_assert( ret != -2 ); + if ( !scanner->input->eof ) { + lexer->token_type = STT_ERROR; + return FALSE; + } + } sieve_lexer_shift(scanner); } @@ -300,32 +344,7 @@ // hash-comment = ( "#" *CHAR-NOT-CRLF CRLF ) case '#': sieve_lexer_shift(scanner); - - while ( sieve_lexer_curchar(scanner) != '\n' ) { - switch( sieve_lexer_curchar(scanner) ) { - case -1: - sieve_lexer_warning - (lexer, "no newline (CRLF) at end of hash comment at end of file"); - lexer->token_type = STT_WHITESPACE; - return TRUE; - case '\0': - sieve_lexer_error - (lexer, "encountered NUL character in hash comment"); - lexer->token_type = STT_ERROR; - return FALSE; - default: - break; - } - - /* Stray CR is ignored */ - - sieve_lexer_shift(scanner); - } - - sieve_lexer_shift(scanner); - - lexer->token_type = STT_WHITESPACE; - return TRUE; + return sieve_lexer_scan_hash_comment(scanner); // bracket-comment = "/*" *(CHAR-NOT-STAR / ("*" CHAR-NOT-SLASH)) "*/" // ;; No */ allowed inside a comment. @@ -341,9 +360,11 @@ while ( TRUE ) { switch ( sieve_lexer_curchar(scanner) ) { case -1: - sieve_lexer_error(lexer, - "end of file before end of bracket comment ('/* ... */') " - "started at line %d", lexer->token_line); + if ( scanner->input->eof ) { + sieve_lexer_error(lexer, + "end of file before end of bracket comment ('/* ... */') " + "started at line %d", lexer->token_line); + } lexer->token_type = STT_ERROR; return FALSE; case '*': @@ -407,17 +428,18 @@ str = lexer->token_str_value; while ( sieve_lexer_curchar(scanner) != '"' ) { - if ( sieve_lexer_curchar(scanner) == '\\' ) { + if ( sieve_lexer_curchar(scanner) == '\\' ) sieve_lexer_shift(scanner); - } switch ( sieve_lexer_curchar(scanner) ) { /* End of file */ case -1: - sieve_lexer_error(lexer, - "end of file before end of quoted string " - "started at line %d", lexer->token_line); + if ( scanner->input->eof ) { + sieve_lexer_error(lexer, + "end of file before end of quoted string " + "started at line %d", lexer->token_line); + } lexer->token_type = STT_ERROR; return FALSE; @@ -510,7 +532,10 @@ /* EOF */ case -1: - lexer->token_type = STT_EOF; + if ( scanner->input->eof ) + lexer->token_type = STT_EOF; + else + lexer->token_type = STT_ERROR; return TRUE; default: @@ -627,24 +652,30 @@ sieve_lexer_shift(scanner); /* Discard hash comment or handle single CRLF */ - switch ( sieve_lexer_curchar(scanner) ) { + if ( sieve_lexer_curchar(scanner) == '\r' ) + sieve_lexer_shift(scanner); + switch ( sieve_lexer_curchar(scanner) ) { case '#': - while ( sieve_lexer_curchar(scanner) != '\n' ) - sieve_lexer_shift(scanner); + if ( !sieve_lexer_scan_hash_comment(scanner) ) + return FALSE; + if ( scanner->input->eof ) { + sieve_lexer_error(lexer, + "end of file before end of multi-line string"); + lexer->token_type = STT_ERROR; + return FALSE; + } else if ( scanner->input->stream_errno != 0 ) { + lexer->token_type = STT_ERROR; + return FALSE; + } break; - case '\r': - sieve_lexer_shift(scanner); - break; - } - - /* Terminating LF required */ - switch ( sieve_lexer_curchar(scanner) ) { case '\n': sieve_lexer_shift(scanner); break; case -1: - sieve_lexer_error(lexer, - "end of file before end of multi-line string"); + if ( scanner->input->eof ) { + sieve_lexer_error(lexer, + "end of file before end of multi-line string"); + } lexer->token_type = STT_ERROR; return FALSE; default: @@ -692,9 +723,12 @@ return TRUE; } else if ( cr_shifted ) { /* Seen CR, but no LF */ - sieve_lexer_error(lexer, - "found stray carriage-return (CR) character " - "in multi-line string started at line %d", lexer->token_line); + if ( sieve_lexer_curchar(scanner) != -1 || + !scanner->input->eof ) { + sieve_lexer_error(lexer, + "found stray carriage-return (CR) character " + "in multi-line string started at line %d", lexer->token_line); + } lexer->token_type = STT_ERROR; return FALSE; } @@ -712,8 +746,10 @@ switch ( sieve_lexer_curchar(scanner) ) { case -1: - sieve_lexer_error(lexer, - "end of file before end of multi-line string"); + if ( scanner->input->eof ) { + sieve_lexer_error(lexer, + "end of file before end of multi-line string"); + } lexer->token_type = STT_ERROR; return FALSE; case '\0': @@ -731,15 +767,17 @@ } /* If exited loop due to CR, skip it */ - if ( sieve_lexer_curchar(scanner) == '\r' ) { + if ( sieve_lexer_curchar(scanner) == '\r' ) sieve_lexer_shift(scanner); - } /* Now we must see an LF */ if ( sieve_lexer_curchar(scanner) != '\n' ) { - sieve_lexer_error(lexer, - "found stray carriage-return (CR) character " - "in multi-line string started at line %d", lexer->token_line); + if ( sieve_lexer_curchar(scanner) != -1 || + !scanner->input->eof ) { + sieve_lexer_error(lexer, + "found stray carriage-return (CR) character " + "in multi-line string started at line %d", lexer->token_line); + } lexer->token_type = STT_ERROR; return FALSE; } @@ -782,8 +820,18 @@ { /* Scan token while skipping whitespace */ do { - if ( !sieve_lexer_scan_raw_token(lexer->scanner) ) + struct sieve_lexical_scanner *scanner = lexer->scanner; + + if ( !sieve_lexer_scan_raw_token(scanner) ) { + if ( !scanner->input->eof && scanner->input->stream_errno != 0 ) { + sieve_critical(scanner->svinst, scanner->ehandler, + sieve_error_script_location(scanner->script, scanner->current_line), + "error reading script", + "error reading script during lexical analysis: %s", + i_stream_get_error(scanner->input)); + } return FALSE; + } } while ( lexer->token_type == STT_WHITESPACE ); return TRUE; From pigeonhole at rename-it.nl Sun Oct 19 11:37:48 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 19 Oct 2014 13:37:48 +0200 Subject: dovecot-2.2-pigeonhole: managesieve: Changed managesieve parser'... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/bf2531a05b30 changeset: 1930:bf2531a05b30 user: Stephan Bosch date: Sun Oct 19 13:10:27 2014 +0200 description: managesieve: Changed managesieve parser's quoted string stream to use io_stream_set_error(). diffstat: src/managesieve-login/client-authenticate.c | 21 +++++++-------------- src/managesieve/cmd-putscript.c | 20 +++++++++----------- 2 files changed, 16 insertions(+), 25 deletions(-) diffs (68 lines): diff -r e11f41c437a5 -r bf2531a05b30 src/managesieve-login/client-authenticate.c --- a/src/managesieve-login/client-authenticate.c Sun Oct 19 11:01:17 2014 +0200 +++ b/src/managesieve-login/client-authenticate.c Sun Oct 19 13:10:27 2014 +0200 @@ -221,20 +221,13 @@ if ( ret == 0 ) return 0; if ( msieve_client->auth_response_input->stream_errno != 0 ) { - if ( msieve_client->auth_response_input->stream_errno == EIO ) { - error = managesieve_parser_get_error(msieve_client->parser, &fatal); - if (error != NULL ) { - if (fatal) { - client_send_bye(client, error); - client_destroy(client, t_strconcat - ("Disconnected: parse error during auth: ", error, NULL)); - } else { - msieve_client->skip_line = TRUE; - *error_r = t_strconcat - ("Error in AUTHENTICATE response string: ", error, NULL); - } - return -1; - } + if ( !client->input->eof && + msieve_client->auth_response_input->stream_errno == EINVAL ) { + msieve_client->skip_line = TRUE; + *error_r = t_strconcat + ("Error in AUTHENTICATE response string: ", + i_stream_get_error(msieve_client->auth_response_input), NULL); + return -1; } client_destroy(client, "Disconnected"); diff -r e11f41c437a5 -r bf2531a05b30 src/managesieve/cmd-putscript.c --- a/src/managesieve/cmd-putscript.c Sun Oct 19 11:01:17 2014 +0200 +++ b/src/managesieve/cmd-putscript.c Sun Oct 19 13:10:27 2014 +0200 @@ -356,7 +356,9 @@ } ret = i_stream_read(ctx->input); - if (sieve_storage_save_continue(ctx->save_ctx) < 0) { + if ((ret != -1 || ctx->input->stream_errno != EINVAL || + client->input->eof) && + sieve_storage_save_continue(ctx->save_ctx) < 0) { /* we still have to finish reading the script from client */ sieve_storage_save_cancel(&ctx->save_ctx); @@ -378,16 +380,12 @@ bool all_written = FALSE; if ( ctx->script_size == 0 ) { - if ( ctx->input->stream_errno == EIO ) { - bool fatal; - const char *parse_error; - - parse_error = managesieve_parser_get_error(ctx->save_parser, &fatal); - if ( parse_error != NULL) { - client_send_command_error(cmd, parse_error); - client->input_skip_line = TRUE; - failed = TRUE; - } + if ( !client->input->eof && + ctx->input->stream_errno == EINVAL ) { + client_send_command_error(cmd, t_strdup_printf( + "Invalid input: %s", i_stream_get_error(ctx->input))); + client->input_skip_line = TRUE; + failed = TRUE; } all_written = ( ctx->input->eof && ctx->input->stream_errno == 0 ); From pigeonhole at rename-it.nl Sun Oct 19 11:37:48 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 19 Oct 2014 13:37:48 +0200 Subject: dovecot-2.2-pigeonhole: managesieve-login: Fixed handling of inv... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/02332881adc6 changeset: 1932:02332881adc6 user: Stephan Bosch date: Sun Oct 19 13:37:38 2014 +0200 description: managesieve-login: Fixed handling of invalid initial response argument to AUTHENTICATE command. diffstat: src/managesieve-login/client-authenticate.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (15 lines): diff -r ea047cff5763 -r 02332881adc6 src/managesieve-login/client-authenticate.c --- a/src/managesieve-login/client-authenticate.c Sun Oct 19 13:36:57 2014 +0200 +++ b/src/managesieve-login/client-authenticate.c Sun Oct 19 13:37:38 2014 +0200 @@ -304,8 +304,10 @@ msieve_client->skip_line = FALSE; if ( (ret=managesieve_client_auth_read_response(msieve_client, TRUE, &error)) < 0 ) { - if ( error != NULL ) + if ( error != NULL ) { + msieve_client->auth_mech_name_parsed = FALSE; client_send_no(client, error); + } return 1; } From pigeonhole at rename-it.nl Sun Oct 19 11:37:48 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 19 Oct 2014 13:37:48 +0200 Subject: dovecot-2.2-pigeonhole: Forgot one file in last commit. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/ea047cff5763 changeset: 1931:ea047cff5763 user: Stephan Bosch date: Sun Oct 19 13:36:57 2014 +0200 description: Forgot one file in last commit. diffstat: src/lib-managesieve/managesieve-parser.c | 26 +++++++++++++++----------- 1 files changed, 15 insertions(+), 11 deletions(-) diffs (58 lines): diff -r bf2531a05b30 -r ea047cff5763 src/lib-managesieve/managesieve-parser.c --- a/src/lib-managesieve/managesieve-parser.c Sun Oct 19 13:10:27 2014 +0200 +++ b/src/lib-managesieve/managesieve-parser.c Sun Oct 19 13:36:57 2014 +0200 @@ -101,6 +101,7 @@ if ( parser->str_stream != NULL ) i_stream_unref(&parser->str_stream); + parser->str_stream = NULL; } const char *managesieve_parser_get_error @@ -634,13 +635,15 @@ if (size == 0) { ret = i_stream_read(stream->parent); if (ret <= 0 && (ret != -2 || stream->skip == 0)) { - if ( stream->istream.eof && stream->istream.stream_errno == 0 ) { - stream->istream.eof = 0; - stream->istream.stream_errno = EIO; - } else { - stream->istream.stream_errno = stream->parent->stream_errno; - stream->istream.eof = stream->parent->eof; + if ( stream->parent->eof && stream->parent->stream_errno == 0 ) { + io_stream_set_error(&stream->iostream, + "Quoted string ends without closing quotes"); + stream->istream.stream_errno = EINVAL; + return -1; } + + stream->istream.stream_errno = stream->parent->stream_errno; + stream->istream.eof = stream->parent->eof; return ret; } data = i_stream_get_data(stream->parent, &size); @@ -671,9 +674,9 @@ slash = FALSE; } else if ( slash ) { if ( !IS_QUOTED_SPECIAL(data[i]) ) { - qsstream->parser->error = - "Escaped quoted-string character is not a QUOTED-SPECIAL."; - stream->istream.stream_errno = EIO; + io_stream_set_error(&stream->iostream, + "Escaped quoted-string character is not a QUOTED-SPECIAL"); + stream->istream.stream_errno = EINVAL; ret = -1; break; } @@ -681,8 +684,9 @@ } if ( (data[i] & 0x80) == 0 && ( data[i] == '\r' || data[i] == '\n' ) ) { - qsstream->parser->error = "String contains invalid character."; - stream->istream.stream_errno = EIO; + io_stream_set_error(&stream->iostream, + "Quoted string contains an invalid character"); + stream->istream.stream_errno = EINVAL; ret = -1; break; } From pigeonhole at rename-it.nl Sun Oct 19 11:39:46 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 19 Oct 2014 13:39:46 +0200 Subject: dovecot-2.2-pigeonhole: managesieve-login: The AUTHENTICATE comm... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/1040bbe3b924 changeset: 1933:1040bbe3b924 user: Stephan Bosch date: Sun Oct 19 13:39:37 2014 +0200 description: managesieve-login: The AUTHENTICATE command returned bogus ALERT response code. diffstat: src/managesieve-login/client-authenticate.c | 4 ---- 1 files changed, 0 insertions(+), 4 deletions(-) diffs (15 lines): diff -r 02332881adc6 -r 1040bbe3b924 src/managesieve-login/client-authenticate.c --- a/src/managesieve-login/client-authenticate.c Sun Oct 19 13:37:38 2014 +0200 +++ b/src/managesieve-login/client-authenticate.c Sun Oct 19 13:39:37 2014 +0200 @@ -83,11 +83,7 @@ } break; case CLIENT_AUTH_RESULT_ABORTED: - client_send_no(client, text); - break; case CLIENT_AUTH_RESULT_AUTHFAILED_REASON: - client_send_noresp(client, "ALERT", text); - break; case CLIENT_AUTH_RESULT_AUTHZFAILED: client_send_no(client, text); break; From pigeonhole at rename-it.nl Sun Oct 19 16:14:33 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 19 Oct 2014 18:14:33 +0200 Subject: dovecot-2.2-pigeonhole: doveadm-sieve plugin: Improved debugging... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/aad132a56c88 changeset: 1934:aad132a56c88 user: Stephan Bosch date: Sun Oct 19 18:14:20 2014 +0200 description: doveadm-sieve plugin: Improved debugging a bit. diffstat: src/plugins/doveadm-sieve/doveadm-sieve-plugin.c | 21 ++++++++++++++++++--- 1 files changed, 18 insertions(+), 3 deletions(-) diffs (45 lines): diff -r 1040bbe3b924 -r aad132a56c88 src/plugins/doveadm-sieve/doveadm-sieve-plugin.c --- a/src/plugins/doveadm-sieve/doveadm-sieve-plugin.c Sun Oct 19 13:39:37 2014 +0200 +++ b/src/plugins/doveadm-sieve/doveadm-sieve-plugin.c Sun Oct 19 18:14:20 2014 +0200 @@ -4,6 +4,7 @@ #include "lib.h" #include "str.h" #include "ioloop.h" +#include "time-util.h" #include "istream.h" #include "istream-concat.h" #include "mail-storage-private.h" @@ -360,16 +361,30 @@ { struct mail_user *user = t->box->storage->user; union mailbox_module_context *sbox = SIEVE_MAIL_CONTEXT(t->box); - time_t ts = value->last_change != 0 ? value->last_change : ioloop_time; if (t->box->storage->user->dsyncing && type == MAIL_ATTRIBUTE_TYPE_PRIVATE && strncmp(key, MAILBOX_ATTRIBUTE_PREFIX_SIEVE, strlen(MAILBOX_ATTRIBUTE_PREFIX_SIEVE)) == 0) { + time_t ts = + (value->last_change != 0 ? value->last_change : ioloop_time); + if (sieve_attribute_set_sieve(t->box->storage, key, value) < 0) return -1; - if (user->mail_debug) - i_debug("doveadm-sieve: Assigned value for key `%s'", key); + + if (user->mail_debug) { + const char *change; + if (value->last_change != 0) { + change = t_strflocaltime + ("(last change: %Y-%m-%d %H:%M:%S)", value->last_change); + } else { + change = t_strflocaltime + ("(time: %Y-%m-%d %H:%M:%S)", ioloop_time); + } + i_debug("doveadm-sieve: Assigned value for key `%s' %s", + key, change); + } + /* FIXME: set value len to sieve script size / active name length */ if (value->value != NULL || value->value_stream != NULL) From dovecot at dovecot.org Sun Oct 19 18:25:05 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 19 Oct 2014 18:25:05 +0000 Subject: dovecot-2.2: imap, pop3, lmtp: If client gets disconnected due t... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/086c70441f26 changeset: 17966:086c70441f26 user: Timo Sirainen date: Sun Oct 19 11:24:12 2014 -0700 description: imap, pop3, lmtp: If client gets disconnected due to iostream error, log the full error. diffstat: src/imap/imap-client.c | 8 ++++++-- src/lmtp/client.c | 9 ++++++--- src/pop3/pop3-client.c | 9 ++++++--- 3 files changed, 18 insertions(+), 8 deletions(-) diffs (58 lines): diff -r cd5dba84d8de -r 086c70441f26 src/imap/imap-client.c --- a/src/imap/imap-client.c Sat Oct 18 02:13:30 2014 +0300 +++ b/src/imap/imap-client.c Sun Oct 19 11:24:12 2014 -0700 @@ -223,8 +223,12 @@ errno = client->input->stream_errno != 0 ? client->input->stream_errno : client->output->stream_errno; - return errno == 0 || errno == EPIPE ? "Connection closed" : - t_strdup_printf("Connection closed: %m"); + if (errno == 0 || errno == EPIPE) + return "Connection closed"; + return t_strdup_printf("Connection closed: %s", + client->input->stream_errno != 0 ? + i_stream_get_error(client->input) : + o_stream_get_error(client->output)); } void client_destroy(struct client *client, const char *reason) diff -r cd5dba84d8de -r 086c70441f26 src/lmtp/client.c --- a/src/lmtp/client.c Sat Oct 18 02:13:30 2014 +0300 +++ b/src/lmtp/client.c Sun Oct 19 11:24:12 2014 -0700 @@ -293,10 +293,13 @@ errno = client->input->stream_errno != 0 ? client->input->stream_errno : client->output->stream_errno; - return errno == 0 || errno == EPIPE ? "Connection closed" : - t_strdup_printf("Connection closed: %m"); + if (errno == 0 || errno == EPIPE) + return "Connection closed"; + return t_strdup_printf("Connection closed: %s", + client->input->stream_errno != 0 ? + i_stream_get_error(client->input) : + o_stream_get_error(client->output)); } - void client_disconnect(struct client *client, const char *prefix, const char *reason) { diff -r cd5dba84d8de -r 086c70441f26 src/pop3/pop3-client.c --- a/src/pop3/pop3-client.c Sat Oct 18 02:13:30 2014 +0300 +++ b/src/pop3/pop3-client.c Sun Oct 19 11:24:12 2014 -0700 @@ -557,10 +557,13 @@ errno = client->input->stream_errno != 0 ? client->input->stream_errno : client->output->stream_errno; - return errno == 0 || errno == EPIPE ? "Connection closed" : - t_strdup_printf("Connection closed: %m"); + if (errno == 0 || errno == EPIPE) + return "Connection closed"; + return t_strdup_printf("Connection closed: %s", + client->input->stream_errno != 0 ? + i_stream_get_error(client->input) : + o_stream_get_error(client->output)); } - void client_destroy(struct client *client, const char *reason) { client->v.destroy(client, reason); From dovecot at dovecot.org Sun Oct 19 19:34:22 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 19 Oct 2014 19:34:22 +0000 Subject: dovecot-2.2: man: Reworked some formatting requests. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/dcfb0baba621 changeset: 17967:dcfb0baba621 user: Pascal Volk date: Sun Oct 19 19:29:34 2014 +0000 description: man: Reworked some formatting requests. On some systems, for example SunOS 5.10, the example commands were cut off. diffstat: doc/man/doveadm-altmove.1.in | 8 +++++--- doc/man/doveadm-auth.1.in | 6 ++++-- doc/man/doveadm-batch.1.in | 8 +++++--- doc/man/doveadm-deduplicate.1.in | 14 +++++++++----- doc/man/doveadm-expunge.1.in | 8 +++++--- doc/man/doveadm-flags.1.in | 14 +++++++++----- doc/man/doveadm-mailbox.1.in | 20 ++++++++++++++------ doc/man/doveadm-move.1.in | 10 ++++++---- doc/man/doveadm-search.1.in | 18 +++++++++++------- doc/man/doveadm-sync.1.in | 16 +++++++++++----- doc/man/doveconf.1.in | 28 ++++++++++++++++++++-------- 11 files changed, 99 insertions(+), 51 deletions(-) diffs (truncated from 381 to 300 lines): diff -r 086c70441f26 -r dcfb0baba621 doc/man/doveadm-altmove.1.in --- a/doc/man/doveadm-altmove.1.in Sun Oct 19 11:24:12 2014 -0700 +++ b/doc/man/doveadm-altmove.1.in Sun Oct 19 19:29:34 2014 +0000 @@ -1,5 +1,5 @@ -.\" Copyright (c) 2010-2011 Dovecot authors, see the included COPYING file -.TH DOVEADM\-ALTMOVE 1 "2011-09-15" "Dovecot v2.2" "Dovecot" +.\" Copyright (c) 2010-2014 Dovecot authors, see the included COPYING file +.TH DOVEADM\-ALTMOVE 1 "2014-10-19" "Dovecot v2.2" "Dovecot" .SH NAME doveadm\-altmove \- Move matching mails to the alternative storage (dbox\-only) .\"------------------------------------------------------------------------ @@ -81,7 +81,9 @@ .fi .PP .nf -.B doveadm altmove \-u johnd at example.com seen savedbefore 1w +.ft B +doveadm altmove \-u johnd at example.com seen savedbefore 1w +.ft P .fi .\"------------------------------------------------------------------------ @INCLUDE:reporting-bugs@ diff -r 086c70441f26 -r dcfb0baba621 doc/man/doveadm-auth.1.in --- a/doc/man/doveadm-auth.1.in Sun Oct 19 11:24:12 2014 -0700 +++ b/doc/man/doveadm-auth.1.in Sun Oct 19 19:29:34 2014 +0000 @@ -1,5 +1,5 @@ .\" Copyright (c) 2010-2014 Dovecot authors, see the included COPYING file -.TH DOVEADM\-AUTH 1 "2014-08-30" "Dovecot v2.2" "Dovecot" +.TH DOVEADM\-AUTH 1 "2014-10-19" "Dovecot v2.2" "Dovecot" .SH NAME doveadm\-auth \- Flush/lookup/test authentication data .\"------------------------------------------------------------------------ @@ -173,7 +173,9 @@ 192.0.2.143. .PP .nf -.B doveadm auth test \-x service=imap \-x rip=192.0.2.143 john +.ft B +doveadm auth test \-x service=imap \-x rip=192.0.2.143 john +.ft P Password: passdb: john auth succeeded extra fields: diff -r 086c70441f26 -r dcfb0baba621 doc/man/doveadm-batch.1.in --- a/doc/man/doveadm-batch.1.in Sun Oct 19 11:24:12 2014 -0700 +++ b/doc/man/doveadm-batch.1.in Sun Oct 19 19:29:34 2014 +0000 @@ -1,5 +1,5 @@ -.\" Copyright (c) 2013 Dovecot authors, see the included COPYING file -.TH DOVEADM\-BATCH 1 "2013-11-17" "Dovecot v2.2" "Dovecot" +.\" Copyright (c) 2013-2014 Dovecot authors, see the included COPYING file +.TH DOVEADM\-BATCH 1 "2014-10-19" "Dovecot v2.2" "Dovecot" .SH NAME doveadm\-batch \- Execute multiple commands for multiple users .\"------------------------------------------------------------------------ @@ -79,7 +79,9 @@ primary storage. .PP .nf -.B doveadm batch \-u \(rs*@example.net : altmove seen savedbefore 30d : purge +.ft B +doveadm batch \-u \(rs*@example.net : altmove seen savedbefore 30d : purge +.ft P .fi .\"------------------------------------------------------------------------ @INCLUDE:reporting-bugs@ diff -r 086c70441f26 -r dcfb0baba621 doc/man/doveadm-deduplicate.1.in --- a/doc/man/doveadm-deduplicate.1.in Sun Oct 19 11:24:12 2014 -0700 +++ b/doc/man/doveadm-deduplicate.1.in Sun Oct 19 19:29:34 2014 +0000 @@ -1,5 +1,5 @@ -.\" Copyright (c) 2013 Dovecot authors, see the included COPYING file -.TH DOVEADM\-DEDUPLICATE 1 "2013-08-03" "Dovecot v2.2" "Dovecot" +.\" Copyright (c) 2013-2014 Dovecot authors, see the included COPYING file +.TH DOVEADM\-DEDUPLICATE 1 "2014-10-19" "Dovecot v2.2" "Dovecot" .SH NAME doveadm\-deduplicate \- expunge duplicate messages .\"------------------------------------------------------------------------ @@ -59,15 +59,19 @@ mailbox. .sp .nf -.B doveadm \-f table fetch \-u jane \(aqguid uid\(aq mailbox a_Box | sort +.ft B +doveadm \-f table fetch \-u jane \(aqguid uid\(aq mailbox a_Box | sort +.ft P guid uid 8aad0f0a30169f4bea620000ca356bad 18751 8aad0f0a30169f4bea620000ca356bad 18756 923e301ab9219b4b4f440000ca356bad 18748 923e301ab9219b4b4f440000ca356bad 18753 \&... -.B doveadm deduplicate \-u jane mailbox a_Box -.B doveadm \-f table fetch \-u jane \(aqguid uid\(aq mailbox a_Box | sort +.ft B +doveadm deduplicate \-u jane mailbox a_Box +doveadm \-f table fetch \-u jane \(aqguid uid\(aq mailbox a_Box | sort +.ft P guid uid 8aad0f0a30169f4bea620000ca356bad 18751 923e301ab9219b4b4f440000ca356bad 18748 diff -r 086c70441f26 -r dcfb0baba621 doc/man/doveadm-expunge.1.in --- a/doc/man/doveadm-expunge.1.in Sun Oct 19 11:24:12 2014 -0700 +++ b/doc/man/doveadm-expunge.1.in Sun Oct 19 19:29:34 2014 +0000 @@ -1,5 +1,5 @@ -.\" Copyright (c) 2010-2013 Dovecot authors, see the included COPYING file -.TH DOVEADM\-EXPUNGE 1 "2013-11-24" "Dovecot v2.2" "Dovecot" +.\" Copyright (c) 2010-2014 Dovecot authors, see the included COPYING file +.TH DOVEADM\-EXPUNGE 1 "2014-10-19" "Dovecot v2.2" "Dovecot" .SH NAME doveadm\-expunge \- Expunge messages matching given search query .\"------------------------------------------------------------------------ @@ -72,7 +72,9 @@ there more than two weeks ago: .PP .nf -.B doveadm expunge \-u jane.doe at example.org mailbox Spam savedbefore 2w +.ft B +doveadm expunge \-u jane.doe at example.org mailbox Spam savedbefore 2w +.ft P .fi .\"------------------------------------------------------------------------ @INCLUDE:reporting-bugs@ diff -r 086c70441f26 -r dcfb0baba621 doc/man/doveadm-flags.1.in --- a/doc/man/doveadm-flags.1.in Sun Oct 19 11:24:12 2014 -0700 +++ b/doc/man/doveadm-flags.1.in Sun Oct 19 19:29:34 2014 +0000 @@ -1,5 +1,5 @@ -.\" Copyright (c) 2013 Dovecot authors, see the included COPYING file -.TH DOVEADM\-FLAGS 1 "2013-08-02" "Dovecot v2.2" "Dovecot" +.\" Copyright (c) 2013-2014 Dovecot authors, see the included COPYING file +.TH DOVEADM\-FLAGS 1 "2014-10-19" "Dovecot v2.2" "Dovecot" .SH NAME doveadm\-flags \- add, remove or replace messages\(aq flags .\"------------------------------------------------------------------------ @@ -86,13 +86,17 @@ List and manipulate the message flags of the message with uid 81563 .sp .nf -.B doveadm fetch \-u bob \(aquid flags\(aq mailbox dovecot uid 81563 +.ft B +doveadm fetch \-u bob \(aquid flags\(aq mailbox dovecot uid 81563 +.ft P uid: 81563 flags: \(rsAnswered \(rsSeen NonJunk -.B doveadm flags \-u bob remove NonJunk mailbox dovecot uid 81563 -.B doveadm flags \-u bob add \(aq\(rsFlagged \(DoForwarded\(aq \ +.ft B +doveadm flags \-u bob remove NonJunk mailbox dovecot uid 81563 +doveadm flags \-u bob add \(aq\(rsFlagged \(DoForwarded\(aq \ mailbox dovecot uid 81563 +.ft P .fi .\"------------------------------------------------------------------------ @INCLUDE:reporting-bugs@ diff -r 086c70441f26 -r dcfb0baba621 doc/man/doveadm-mailbox.1.in --- a/doc/man/doveadm-mailbox.1.in Sun Oct 19 11:24:12 2014 -0700 +++ b/doc/man/doveadm-mailbox.1.in Sun Oct 19 19:29:34 2014 +0000 @@ -1,5 +1,5 @@ -.\" Copyright (c) 2010-2013 Dovecot authors, see the included COPYING file -.TH DOVEADM\-MAILBOX 1 "2013-11-24" "Dovecot v2.2" "Dovecot" +.\" Copyright (c) 2010-2014 Dovecot authors, see the included COPYING file +.TH DOVEADM\-MAILBOX 1 "2014-10-19" "Dovecot v2.2" "Dovecot" .SH NAME doveadm\-mailbox \- Commands related to handling mailboxes .\"------------------------------------------------------------------------ @@ -260,7 +260,9 @@ List subscribed mailboxes, beginning with \(aqdovecot\(aq, of user bob. .sp .nf -.B doveadm mailbox list \-s \-u bob dovecot* +.ft B +doveadm mailbox list \-s \-u bob dovecot* +.ft P dovecot dovecot/pigeonhole dovecot/pigeonhole/2.0 @@ -270,7 +272,9 @@ Now have a look at the status of user bob\(aqs dovecot mailboxes. .sp .nf -.B doveadm \-f table mailbox status \-u bob \(dqmessages vsize\(dq dovecot* +.ft B +doveadm \-f table mailbox status \-u bob \(dqmessages vsize\(dq dovecot* +.ft P mailbox messages vsize dovecot 20501 93968492 dovecot/pigeonhole 0 0 @@ -282,9 +286,13 @@ vice versa. .sp .nf -.B doveadm mailbox mutf7 \-7 \(dq~peter/mail/&U,BTFw\-/&ZeVnLIqe\-\(dq +.ft B +doveadm mailbox mutf7 \-7 \(dq~peter/mail/&U,BTFw\-/&ZeVnLIqe\-\(dq +.ft P ~peter/mail/??/??? -.B doveadm mailbox mutf7 ~peter/mail/??/??? +.ft B +doveadm mailbox mutf7 ~peter/mail/??/??? +.ft P ~peter/mail/&U,BTFw\-/&ZeVnLIqe\- .fi .\"------------------------------------------------------------------------ diff -r 086c70441f26 -r dcfb0baba621 doc/man/doveadm-move.1.in --- a/doc/man/doveadm-move.1.in Sun Oct 19 11:24:12 2014 -0700 +++ b/doc/man/doveadm-move.1.in Sun Oct 19 19:29:34 2014 +0000 @@ -1,5 +1,5 @@ -.\" Copyright (c) 2011-2013 Dovecot authors, see the included COPYING file -.TH DOVEADM\-MOVE 1 "2013-11-23" "Dovecot v2.2" "Dovecot" +.\" Copyright (c) 2011-2014 Dovecot authors, see the included COPYING file +.TH DOVEADM\-MOVE 1 "2014-10-19" "Dovecot v2.2" "Dovecot" .SH NAME doveadm\-move \- Move messages matching the given search query into another mailbox @@ -131,8 +131,10 @@ into her archive. .PP .nf -.B doveadm move \-u jane Archive/2011/09 mailbox INBOX BEFORE \(rs -.B 2011\-10\-01 SINCE 01\-Sep\-2011 +.ft B +doveadm move \-u jane Archive/2011/09 mailbox INBOX BEFORE \(rs +2011\-10\-01 SINCE 01\-Sep\-2011 +.ft P .fi .\"------------------------------------------------------------------------ @INCLUDE:reporting-bugs@ diff -r 086c70441f26 -r dcfb0baba621 doc/man/doveadm-search.1.in --- a/doc/man/doveadm-search.1.in Sun Oct 19 11:24:12 2014 -0700 +++ b/doc/man/doveadm-search.1.in Sun Oct 19 19:29:34 2014 +0000 @@ -1,5 +1,5 @@ -.\" Copyright (c) 2010 Dovecot authors, see the included COPYING file -.TH DOVEADM\-SEARCH 1 "2010-11-25" "Dovecot v2.2" "Dovecot" +.\" Copyright (c) 2010-2014 Dovecot authors, see the included COPYING file +.TH DOVEADM\-SEARCH 1 "2014-10-19" "Dovecot v2.2" "Dovecot" .SH NAME doveadm\-search \- Show a list of mailbox GUIDs and message UIDs matching \ given search query. @@ -86,7 +86,9 @@ all messages, which contains the word \(dqtodo\(dq in the Subject: header. .PP .nf -.B doveadm search \-u bob mailbox dovecot\(rs* subject todo +.ft B +doveadm search \-u bob mailbox dovecot\(rs* subject todo +.ft P 3a94c928d66ebe4bda04000015811c6a 8 3a94c928d66ebe4bda04000015811c6a 25 3a94c928d66ebe4bda04000015811c6a 45 @@ -98,10 +100,12 @@ that have "todo" in subject, use: .PP .nf -.B doveadm search \-u bob mailbox INBOX subject todo | -.B while read guid uid; do -.B \ \ doveadm fetch \-u bob body mailbox\-guid $guid uid $uid > msg.$uid -.B done +.ft B +doveadm search \-u bob mailbox INBOX subject todo | +while read guid uid; do +\ \ doveadm fetch \-u bob body mailbox\-guid $guid uid $uid > msg.$uid +done +.ft P .fi .\"------------------------------------------------------------------------ @INCLUDE:reporting-bugs@ diff -r 086c70441f26 -r dcfb0baba621 doc/man/doveadm-sync.1.in --- a/doc/man/doveadm-sync.1.in Sun Oct 19 11:24:12 2014 -0700 +++ b/doc/man/doveadm-sync.1.in Sun Oct 19 19:29:34 2014 +0000 @@ -1,5 +1,5 @@ .\" Copyright (c) 2014 Dovecot authors, see the included COPYING file -.TH DOVEADM\-SYNC 1 "2014-10-05" "Dovecot v2.2" "Dovecot" +.TH DOVEADM\-SYNC 1 "2014-10-19" "Dovecot v2.2" "Dovecot" .SH NAME doveadm\-sync \- Dovecot\(aqs two\-way mailbox synchronization utility .br @@ -269,7 +269,9 @@ .PP .RS .nf -.B doveadm sync \-u username at example.com remote:server\-replica.example.com +.ft B +doveadm sync \-u username at example.com remote:server\-replica.example.com +.ft P .fi .RE .PP @@ -277,8 +279,10 @@ .PP .RS .nf -.B doveadm sync \-u username at example.com ssh \-i id_dsa.dovecot \(rs -.B mailuser at example.com doveadm dsync\-server \-u username at example.com +.ft B +doveadm sync \-u username at example.com ssh \-i id_dsa.dovecot \(rs +mailuser at example.com doveadm dsync\-server \-u username at example.com +.ft P .fi .RE .\"------------------------------------------------------------------------ @@ -295,7 +299,9 @@ From pigeonhole at rename-it.nl Sun Oct 19 20:50:40 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 19 Oct 2014 22:50:40 +0200 Subject: dovecot-2.2-pigeonhole: managesieve: If client gets disconnected... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/819b8fb22034 changeset: 1935:819b8fb22034 user: Stephan Bosch date: Sun Oct 19 22:50:23 2014 +0200 description: managesieve: If client gets disconnected due to iostream error, log the full error. diffstat: src/managesieve/managesieve-client.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diffs (18 lines): diff -r aad132a56c88 -r 819b8fb22034 src/managesieve/managesieve-client.c --- a/src/managesieve/managesieve-client.c Sun Oct 19 18:14:20 2014 +0200 +++ b/src/managesieve/managesieve-client.c Sun Oct 19 22:50:23 2014 +0200 @@ -200,8 +200,12 @@ errno = client->input->stream_errno != 0 ? client->input->stream_errno : client->output->stream_errno; - return errno == 0 || errno == EPIPE ? "Connection closed" : - t_strdup_printf("Connection closed: %m"); + if (errno == 0 || errno == EPIPE) + return "Connection closed"; + return t_strdup_printf("Connection closed: %s", + client->input->stream_errno != 0 ? + i_stream_get_error(client->input) : + o_stream_get_error(client->output)); } void client_destroy(struct client *client, const char *reason) From dovecot at dovecot.org Mon Oct 20 15:55:24 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Oct 2014 15:55:24 +0000 Subject: dovecot-2.2: lib-http: client: Fixed handling of connection time... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c5f81685571f changeset: 17968:c5f81685571f user: Stephan Bosch date: Mon Oct 20 08:54:26 2014 -0700 description: lib-http: client: Fixed handling of connection timeouts. A timeout caused an assert failure, because the connection status was altered before the peer_connection_failure handler was called. diffstat: src/lib-http/http-client-connection.c | 41 +++++++++++++++++----------------- src/lib-http/http-client-private.h | 1 + 2 files changed, 22 insertions(+), 20 deletions(-) diffs (153 lines): diff -r dcfb0baba621 -r c5f81685571f src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Sun Oct 19 19:29:34 2014 +0000 +++ b/src/lib-http/http-client-connection.c Mon Oct 20 08:54:26 2014 -0700 @@ -89,8 +89,6 @@ http_client_connection_debug(conn, "Server explicitly closed connection"); - http_client_connection_disconnect(conn); - array_foreach_modifiable(&conn->request_wait_list, req) { if ((*req)->state < HTTP_REQUEST_STATE_FINISHED) http_client_request_resubmit(*req); @@ -101,7 +99,7 @@ if (conn->client->ioloop != NULL) io_loop_stop(conn->client->ioloop); - http_client_connection_unref(_conn); + http_client_connection_close(_conn); } static void @@ -113,15 +111,13 @@ http_client_connection_debug(conn, "Aborting connection: %s", error); - http_client_connection_disconnect(conn); - array_foreach_modifiable(&conn->request_wait_list, req) { i_assert((*req)->submitted); http_client_request_error(*req, status, error); http_client_request_unref(req); } array_clear(&conn->request_wait_list); - http_client_connection_unref(_conn); + http_client_connection_close(_conn); } static void @@ -151,10 +147,8 @@ http_client_connection_debug(conn, "Aborting connection with temporary error: %s", error); - http_client_connection_disconnect(conn); - http_client_connection_retry_requests(conn, status, error); - http_client_connection_unref(_conn); + http_client_connection_close(_conn); } bool http_client_connection_is_ready(struct http_client_connection *conn) @@ -207,8 +201,7 @@ /* cannot get here unless connection was established at some point */ i_assert(conn->connect_succeeded); - http_client_connection_disconnect(conn); - http_client_connection_unref(&conn); + http_client_connection_close(&conn); } void http_client_connection_check_idle(struct http_client_connection *conn) @@ -377,9 +370,6 @@ const char *error; unsigned int msecs; - conn->closing = TRUE; - conn->connected = FALSE; - switch (_conn->disconnect_reason) { case CONNECTION_DISCONNECT_CONNECT_TIMEOUT: if (conn->connected_timestamp.tv_sec == 0) { @@ -410,7 +400,7 @@ break; } - http_client_connection_unref(&conn); + http_client_connection_close(&conn); } static void http_client_payload_finished(struct http_client_connection *conn) @@ -598,7 +588,7 @@ if (req == NULL) { /* server sent response without any requests in the wait list */ http_client_connection_debug(conn, "Got unexpected input from server"); - http_client_connection_unref(&conn); + http_client_connection_close(&conn); return; } req->response_time = ioloop_timeval; @@ -867,7 +857,7 @@ http_client_connection_debug(conn, "No raw connect requests pending; closing useless connection"); - http_client_connection_unref(&conn); + http_client_connection_close(&conn); return; } @@ -955,7 +945,7 @@ if (http_client_connection_ssl_init(conn, &error) < 0) { http_client_peer_connection_failure(conn->peer, error); http_client_connection_debug(conn, "%s", error); - http_client_connection_unref(&conn); + http_client_connection_close(&conn); } return; } @@ -988,7 +978,7 @@ timeout_remove(&conn->to_input); errno = conn->connect_errno; http_client_connection_connected(&conn->conn, FALSE); - http_client_connection_unref(&conn); + http_client_connection_close(&conn); } static void http_client_connect_timeout(struct http_client_connection *conn) @@ -1025,7 +1015,7 @@ static void http_client_connect_tunnel_timeout(struct http_client_connection *conn) { - http_client_connection_unref(&conn); + http_client_connection_close(&conn); } // FIXME: put something like this in lib/connection.c @@ -1248,6 +1238,17 @@ *_conn = NULL; } +void http_client_connection_close(struct http_client_connection **_conn) +{ + struct http_client_connection *conn = *_conn; + + http_client_connection_debug(conn, "Connection close"); + + http_client_connection_disconnect(conn); + + http_client_connection_unref(_conn); +} + void http_client_connection_switch_ioloop(struct http_client_connection *conn) { if (conn->io_req_payload != NULL) diff -r dcfb0baba621 -r c5f81685571f src/lib-http/http-client-private.h --- a/src/lib-http/http-client-private.h Sun Oct 19 19:29:34 2014 +0000 +++ b/src/lib-http/http-client-private.h Mon Oct 20 08:54:26 2014 -0700 @@ -283,6 +283,7 @@ http_client_connection_create(struct http_client_peer *peer); void http_client_connection_ref(struct http_client_connection *conn); void http_client_connection_unref(struct http_client_connection **_conn); +void http_client_connection_close(struct http_client_connection **_conn); int http_client_connection_output(struct http_client_connection *conn); unsigned int http_client_connection_count_pending(struct http_client_connection *conn); From dovecot at dovecot.org Mon Oct 20 15:55:24 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Oct 2014 15:55:24 +0000 Subject: dovecot-2.2: lib-http: client: Fixed behavior for max_connect_at... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c9ea647cba87 changeset: 17969:c9ea647cba87 user: Stephan Bosch date: Mon Oct 20 08:54:27 2014 -0700 description: lib-http: client: Fixed behavior for max_connect_attempts with fewer IPs than attempts. This was broken by earlier 'fix'. diffstat: src/lib-http/http-client-private.h | 5 ++--- src/lib-http/http-client-queue.c | 34 +++++++++++++++++++++------------- 2 files changed, 23 insertions(+), 16 deletions(-) diffs (87 lines): diff -r c5f81685571f -r c9ea647cba87 src/lib-http/http-client-private.h --- a/src/lib-http/http-client-private.h Mon Oct 20 08:54:26 2014 -0700 +++ b/src/lib-http/http-client-private.h Mon Oct 20 08:54:27 2014 -0700 @@ -347,9 +347,8 @@ void http_client_queue_connection_success(struct http_client_queue *queue, const struct http_client_peer_addr *addr); -bool -http_client_queue_connection_failure(struct http_client_queue *queue, - const struct http_client_peer_addr *addr, const char *reason); +void http_client_queue_connection_failure(struct http_client_queue *queue, + const struct http_client_peer_addr *addr, const char *reason); void http_client_queue_switch_ioloop(struct http_client_queue *queue); struct http_client_host * diff -r c5f81685571f -r c9ea647cba87 src/lib-http/http-client-queue.c --- a/src/lib-http/http-client-queue.c Mon Oct 20 08:54:26 2014 -0700 +++ b/src/lib-http/http-client-queue.c Mon Oct 20 08:54:27 2014 -0700 @@ -318,10 +318,12 @@ } } -bool +void http_client_queue_connection_failure(struct http_client_queue *queue, const struct http_client_peer_addr *addr, const char *reason) { + const struct http_client_settings *set = + &queue->client->set; struct http_client_host *host = queue->host; http_client_queue_debug(queue, "Failed to set up connection to %s%s: %s " @@ -332,6 +334,7 @@ (array_is_created(&queue->pending_peers) ? array_count(&queue->pending_peers): 0), array_count(&queue->requests)); + if (array_is_created(&queue->pending_peers) && array_count(&queue->pending_peers) > 0) { struct http_client_peer *const *peer_idx; @@ -350,7 +353,7 @@ if (array_count(&queue->pending_peers) > 0) { http_client_queue_debug(queue, "Waiting for remaining pending peers."); - return TRUE; + return; } } @@ -361,21 +364,26 @@ timeout_remove(&queue->to_connect); if (http_client_queue_is_last_connect_ip(queue)) { - http_client_queue_debug(queue, - "Failed to set up any connection; failing all queued requests"); - - /* all IPs failed, but retry all of them again on the - next request. */ + /* all IPs failed, but retry all of them again if we have more + connect attempts left or on the next request. */ queue->ips_connect_idx = queue->ips_connect_start_idx = (queue->ips_connect_idx + 1) % host->ips_count; - queue->connect_attempts = 0; - http_client_queue_fail(queue, - HTTP_CLIENT_REQUEST_ERROR_CONNECT_FAILED, reason); - return FALSE; + + if (set->max_connect_attempts == 0 || + queue->connect_attempts >= set->max_connect_attempts) { + http_client_queue_debug(queue, + "Failed to set up any connection; failing all queued requests"); + queue->connect_attempts = 0; + http_client_queue_fail(queue, + HTTP_CLIENT_REQUEST_ERROR_CONNECT_FAILED, reason); + return; + } + } else { + queue->ips_connect_idx = (queue->ips_connect_idx + 1) % host->ips_count; } - queue->ips_connect_idx = (queue->ips_connect_idx + 1) % host->ips_count; + http_client_queue_connection_setup(queue); - return TRUE; + return; } /* From dovecot at dovecot.org Mon Oct 20 15:55:24 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Oct 2014 15:55:24 +0000 Subject: dovecot-2.2: lib-http: client: Connection erroneously indicated ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7d3325713356 changeset: 17970:7d3325713356 user: Stephan Bosch date: Mon Oct 20 08:54:27 2014 -0700 description: lib-http: client: Connection erroneously indicated that it was ready while SSL handshake was not yet completed. diffstat: src/lib-http/http-client-connection.c | 59 ++++++++++++++++++++++++++++++---- 1 files changed, 52 insertions(+), 7 deletions(-) diffs (114 lines): diff -r c9ea647cba87 -r 7d3325713356 src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Mon Oct 20 08:54:27 2014 -0700 +++ b/src/lib-http/http-client-connection.c Mon Oct 20 08:54:27 2014 -0700 @@ -44,6 +44,7 @@ * Connection */ +static void http_client_connection_ready(struct http_client_connection *conn); static void http_client_connection_input(struct connection *_conn); static void http_client_connection_disconnect(struct http_client_connection *conn); @@ -382,7 +383,7 @@ msecs = timeval_diff_msecs(&ioloop_timeval, &conn->connected_timestamp); error = t_strdup_printf( - "SSL handshaking to %s failed: Connection timed out in %u.%03u secs", + "SSL handshaking with %s failed: Connection timed out in %u.%03u secs", _conn->name, msecs/1000, msecs%1000); } http_client_connection_debug(conn, "%s", error); @@ -556,6 +557,41 @@ i_assert(conn->incoming_payload == NULL); + if (conn->ssl_iostream != NULL && + !ssl_iostream_is_handshaked(conn->ssl_iostream)) { + /* finish SSL negotiation by reading from input stream */ + while ((ret=i_stream_read(conn->conn.input)) > 0) { + if (ssl_iostream_is_handshaked(conn->ssl_iostream)) + break; + } + if (ret < 0) { + int stream_errno = conn->conn.input->stream_errno; + + /* failed somehow */ + i_assert(ret != -2); + error = t_strdup_printf( + "SSL handshaking with %s failed: " + "read(%s) failed: %s", + _conn->name, + i_stream_get_name(conn->conn.input), + stream_errno != 0 ? + i_stream_get_error(conn->conn.input) : "EOF"); + http_client_peer_connection_failure(conn->peer, error); + http_client_connection_debug(conn, "%s", error); + http_client_connection_close(&conn); + return; + } + + if (!ssl_iostream_is_handshaked(conn->ssl_iostream)) { + /* not finished */ + i_assert(ret == 0); + return; + } + + /* ready for first request */ + http_client_connection_ready(conn); + } + if (conn->to_input != NULL) { /* We came here from a timeout added by http_client_payload_destroyed(). The IO couldn't be added @@ -763,6 +799,10 @@ return ret; } + if (conn->ssl_iostream != NULL && + !ssl_iostream_is_handshaked(conn->ssl_iostream)) + return 1; + if (array_count(&conn->request_wait_list) > 0 && conn->output_locked) { req_idx = array_idx(&conn->request_wait_list, array_count(&conn->request_wait_list)-1); @@ -815,12 +855,12 @@ static void http_client_connection_ready(struct http_client_connection *conn) { + http_client_connection_debug(conn, "Ready for requests"); + /* connected */ conn->connected = TRUE; conn->last_ioloop = current_ioloop; - if (conn->to_connect != NULL && - (conn->ssl_iostream == NULL || - ssl_iostream_is_handshaked(conn->ssl_iostream))) + if (conn->to_connect != NULL) timeout_remove(&conn->to_connect); /* indicate connection success */ @@ -883,8 +923,6 @@ *error_r = error; return -1; } - if (conn->to_connect != NULL) - timeout_remove(&conn->to_connect); return 0; } @@ -924,7 +962,14 @@ return -1; } - http_client_connection_ready(conn); + if (ssl_iostream_is_handshaked(conn->ssl_iostream)) { + http_client_connection_ready(conn); + } else { + /* wait for handshake to complete; connection input handler does the rest + by reading from the input stream */ + o_stream_set_flush_callback(conn->conn.output, + http_client_connection_output, conn); + } return 0; } From dovecot at dovecot.org Mon Oct 20 15:55:24 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Oct 2014 15:55:24 +0000 Subject: dovecot-2.2: lib-http: client: Fixed behavior of connection back... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1ddc6c86de78 changeset: 17971:1ddc6c86de78 user: Stephan Bosch date: Mon Oct 20 08:54:27 2014 -0700 description: lib-http: client: Fixed behavior of connection backoff timer when multiple IPs are returned for hostname. Peer backoff data was lost because peer was destroyed quickly. Now the peer object is retained during the backoff period, so that new connection attempts adhere to the backoff period. diffstat: src/lib-http/http-client-peer.c | 38 +++++++++++++++++++++++++++++++------- 1 files changed, 31 insertions(+), 7 deletions(-) diffs (87 lines): diff -r 7d3325713356 -r 1ddc6c86de78 src/lib-http/http-client-peer.c --- a/src/lib-http/http-client-peer.c Mon Oct 20 08:54:27 2014 -0700 +++ b/src/lib-http/http-client-peer.c Mon Oct 20 08:54:27 2014 -0700 @@ -91,7 +91,6 @@ } } - static void http_client_peer_connect_backoff(struct http_client_peer *peer) { @@ -101,18 +100,25 @@ "Backoff timer expired"); timeout_remove(&peer->to_backoff); + + if (array_count(&peer->queues) == 0) { + http_client_peer_free(&peer); + return; + } + http_client_peer_do_connect(peer, 1); } -static void -http_client_peer_connect(struct http_client_peer *peer, unsigned int count) +static bool +http_client_peer_start_backoff_timer(struct http_client_peer *peer) { if (peer->to_backoff != NULL) - return; + return TRUE; if (peer->last_failure.tv_sec > 0) { int backoff_time_spent = timeval_diff_msecs(&ioloop_timeval, &peer->last_failure); + if (backoff_time_spent < (int)peer->backoff_time_msecs) { http_client_peer_debug(peer, "Starting backoff timer for %d msecs", @@ -120,9 +126,21 @@ peer->to_backoff = timeout_add ((unsigned int)(peer->backoff_time_msecs - backoff_time_spent), http_client_peer_connect_backoff, peer); - return; + return TRUE; } + + http_client_peer_debug(peer, + "Backoff time already exceeded by %d msecs", + backoff_time_spent - peer->backoff_time_msecs); } + return FALSE; +} + +static void +http_client_peer_connect(struct http_client_peer *peer, unsigned int count) +{ + if (http_client_peer_start_backoff_timer(peer)) + return; http_client_peer_do_connect(peer, count); } @@ -483,8 +501,10 @@ if (*queue_idx == queue) { array_delete(&peer->queues, array_foreach_idx(&peer->queues, queue_idx), 1); - if (array_count(&peer->queues) == 0) - http_client_peer_free(&peer); + if (array_count(&peer->queues) == 0) { + if (!http_client_peer_start_backoff_timer(peer)) + http_client_peer_free(&peer); + } return; } } @@ -511,6 +531,10 @@ { struct http_client_queue *const *queue; + http_client_peer_debug(peer, + "Successfully connected (connections=%u)", + array_count(&peer->conns)); + peer->last_failure.tv_sec = peer->last_failure.tv_usec = 0; peer->backoff_time_msecs = 0; From dovecot at dovecot.org Mon Oct 20 15:55:25 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Oct 2014 15:55:25 +0000 Subject: dovecot-2.2: lib-http: client: Created list of all submitted req... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3a1d89b45c12 changeset: 17972:3a1d89b45c12 user: Stephan Bosch date: Mon Oct 20 08:54:27 2014 -0700 description: lib-http: client: Created list of all submitted requests. Currently only needed to improve debugging of hanging requests. diffstat: src/lib-http/http-client-private.h | 5 ++++- src/lib-http/http-client-request.c | 17 ++++++++++++----- src/lib-http/http-client.c | 8 ++++---- 3 files changed, 20 insertions(+), 10 deletions(-) diffs (107 lines): diff -r 1ddc6c86de78 -r 3a1d89b45c12 src/lib-http/http-client-private.h --- a/src/lib-http/http-client-private.h Mon Oct 20 08:54:27 2014 -0700 +++ b/src/lib-http/http-client-private.h Mon Oct 20 08:54:27 2014 -0700 @@ -52,6 +52,8 @@ unsigned int refcount; const char *label; + struct http_client_request *prev, *next; + const char *method, *target; struct http_url origin_url; @@ -245,7 +247,8 @@ struct http_client_host *hosts_list; HASH_TABLE_TYPE(http_client_peer) peers; struct http_client_peer *peers_list; - unsigned int pending_requests; + struct http_client_request *requests_list; + unsigned int requests_count; }; int http_client_init_ssl_ctx(struct http_client *client, const char **error_r); diff -r 1ddc6c86de78 -r 3a1d89b45c12 src/lib-http/http-client-request.c --- a/src/lib-http/http-client-request.c Mon Oct 20 08:54:27 2014 -0700 +++ b/src/lib-http/http-client-request.c Mon Oct 20 08:54:27 2014 -0700 @@ -5,6 +5,7 @@ #include "str.h" #include "hash.h" #include "array.h" +#include "llist.h" #include "time-util.h" #include "istream.h" #include "ostream.h" @@ -164,16 +165,18 @@ } /* only decrease pending request counter if this request was submitted */ - if (req->state > HTTP_REQUEST_STATE_NEW) - req->client->pending_requests--; + if (req->submitted) { + DLLIST_REMOVE(&client->requests_list, req); + client->requests_count--; + } http_client_request_debug(req, "Destroy (requests left=%d)", - client->pending_requests); + client->requests_count); if (req->queue != NULL) http_client_queue_drop_request(req->queue, req); - if (client->pending_requests == 0 && client->ioloop != NULL) + if (client->requests_count == 0 && client->ioloop != NULL) io_loop_stop(client->ioloop); if (req->delayed_error != NULL) @@ -483,12 +486,16 @@ void http_client_request_submit(struct http_client_request *req) { - req->client->pending_requests++; + struct http_client *client = req->client; + req->submit_time = ioloop_timeval; http_client_request_do_submit(req); http_client_request_debug(req, "Submitted"); + req->submitted = TRUE; + DLLIST_PREPEND(&client->requests_list, req); + client->requests_count++; } static void diff -r 1ddc6c86de78 -r 3a1d89b45c12 src/lib-http/http-client.c --- a/src/lib-http/http-client.c Mon Oct 20 08:54:27 2014 -0700 +++ b/src/lib-http/http-client.c Mon Oct 20 08:54:27 2014 -0700 @@ -228,7 +228,7 @@ i_assert(client->ioloop == NULL); - if (client->pending_requests == 0) + if (client->requests_count == 0) return; client->ioloop = io_loop_create(); @@ -242,9 +242,9 @@ do { http_client_debug(client, - "Waiting for %d requests to finish", client->pending_requests); + "Waiting for %d requests to finish", client->requests_count); io_loop_run(client->ioloop); - } while (client->pending_requests > 0); + } while (client->requests_count > 0); http_client_debug(client, "All requests finished"); @@ -258,7 +258,7 @@ unsigned int http_client_get_pending_request_count(struct http_client *client) { - return client->pending_requests; + return client->requests_count; } int http_client_init_ssl_ctx(struct http_client *client, const char **error_r) From dovecot at dovecot.org Mon Oct 20 23:49:16 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Oct 2014 23:49:16 +0000 Subject: dovecot-2.2: lib: test-buffer was randomly crashing with SIGFPE Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a9503b723f8c changeset: 17973:a9503b723f8c user: Timo Sirainen date: Tue Oct 21 02:48:20 2014 +0300 description: lib: test-buffer was randomly crashing with SIGFPE diffstat: src/lib/test-buffer.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 3a1d89b45c12 -r a9503b723f8c src/lib/test-buffer.c --- a/src/lib/test-buffer.c Mon Oct 20 08:54:27 2014 -0700 +++ b/src/lib/test-buffer.c Tue Oct 21 02:48:20 2014 +0300 @@ -97,7 +97,7 @@ } break; case 4: - if (shadowbuf_size == 0) + if (shadowbuf_size <= 1) break; pos = rand() % (shadowbuf_size-1); /* dest */ pos2 = rand() % (shadowbuf_size-1); /* source */ From dovecot at dovecot.org Tue Oct 21 01:00:11 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 21 Oct 2014 01:00:11 +0000 Subject: dovecot-2.2: lib-storage: Added mailbox_list_index_delete_entry() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c92472804eb8 changeset: 17974:c92472804eb8 user: Timo Sirainen date: Tue Oct 21 03:58:56 2014 +0300 description: lib-storage: Added mailbox_list_index_delete_entry() diffstat: src/lib-storage/list/mailbox-list-index-backend.c | 69 +--------------------- src/lib-storage/list/mailbox-list-index-sync.c | 55 ++++++++++++++++++ src/lib-storage/list/mailbox-list-index-sync.h | 3 + 3 files changed, 63 insertions(+), 64 deletions(-) diffs (187 lines): diff -r a9503b723f8c -r c92472804eb8 src/lib-storage/list/mailbox-list-index-backend.c --- a/src/lib-storage/list/mailbox-list-index-backend.c Tue Oct 21 02:48:20 2014 +0300 +++ b/src/lib-storage/list/mailbox-list-index-backend.c Tue Oct 21 03:58:56 2014 +0300 @@ -413,10 +413,9 @@ } static void -index_list_try_delete(struct index_mailbox_list *list, const char *name, +index_list_try_delete(struct mailbox_list *_list, const char *name, enum mailbox_list_path_type type) { - struct mailbox_list *_list = &list->list; const char *mailbox_path, *path; if (mailbox_list_get_path(_list, name, MAILBOX_LIST_PATH_TYPE_MAILBOX, @@ -446,7 +445,7 @@ } static void -index_list_delete_finish(struct index_mailbox_list *list, const char *name) +index_list_delete_finish(struct mailbox_list *list, const char *name) { index_list_try_delete(list, name, MAILBOX_LIST_PATH_TYPE_INDEX); index_list_try_delete(list, name, MAILBOX_LIST_PATH_TYPE_CONTROL); @@ -454,65 +453,8 @@ } static int -index_list_delete_entry(struct index_mailbox_list *list, const char *name, - bool delete_selectable) -{ - struct mailbox_list_index_sync_context *sync_ctx; - struct mailbox_list_index_record rec; - struct mailbox_list_index_node *node; - const void *data; - bool expunged; - uint32_t seq; - - if (mailbox_list_index_sync_begin(&list->list, &sync_ctx) < 0) - return -1; - - node = mailbox_list_index_lookup(&list->list, name); - if (node == NULL) { - (void)mailbox_list_index_sync_end(&sync_ctx, FALSE); - mailbox_list_set_error(&list->list, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); - return -1; - } - if (!mail_index_lookup_seq(sync_ctx->view, node->uid, &seq)) - i_panic("mailbox list index: lost uid=%u", node->uid); - if (delete_selectable) { - /* make it at least non-selectable */ - node->flags = MAILBOX_LIST_INDEX_FLAG_NOSELECT; - mail_index_update_flags(sync_ctx->trans, seq, MODIFY_REPLACE, - (enum mail_flags)node->flags); - - mail_index_lookup_ext(sync_ctx->view, seq, - sync_ctx->ilist->ext_id, - &data, &expunged); - i_assert(data != NULL && !expunged); - memcpy(&rec, data, sizeof(rec)); - rec.uid_validity = 0; - memset(&rec.guid, 0, sizeof(rec.guid)); - mail_index_update_ext(sync_ctx->trans, seq, - sync_ctx->ilist->ext_id, &rec, NULL); - } - if (node->children != NULL) { - /* can't delete this directory before its children, - but we may have made it non-selectable already */ - if (mailbox_list_index_sync_end(&sync_ctx, TRUE) < 0) - return -1; - return 0; - } - - /* we can remove the entire node */ - mail_index_expunge(sync_ctx->trans, seq); - mailbox_list_index_node_unlink(sync_ctx->ilist, node); - - if (mailbox_list_index_sync_end(&sync_ctx, TRUE) < 0) - return -1; - return 1; -} - -static int index_list_delete_mailbox(struct mailbox_list *_list, const char *name) { - struct index_mailbox_list *list = (struct index_mailbox_list *)_list; const char *path; int ret; @@ -532,9 +474,9 @@ } if (ret == 0 || (_list->props & MAILBOX_LIST_PROP_AUTOCREATE_DIRS) != 0) - index_list_delete_finish(list, name); + index_list_delete_finish(_list, name); if (ret == 0) { - if (index_list_delete_entry(list, name, TRUE) < 0) + if (mailbox_list_index_delete_entry(_list, name, TRUE) < 0) return -1; } return ret; @@ -543,10 +485,9 @@ static int index_list_delete_dir(struct mailbox_list *_list, const char *name) { - struct index_mailbox_list *list = (struct index_mailbox_list *)_list; int ret; - if ((ret = index_list_delete_entry(list, name, FALSE)) < 0) + if ((ret = mailbox_list_index_delete_entry(_list, name, FALSE)) < 0) return -1; if (ret == 0) { mailbox_list_set_error(_list, MAIL_ERROR_EXISTS, diff -r a9503b723f8c -r c92472804eb8 src/lib-storage/list/mailbox-list-index-sync.c --- a/src/lib-storage/list/mailbox-list-index-sync.c Tue Oct 21 02:48:20 2014 +0300 +++ b/src/lib-storage/list/mailbox-list-index-sync.c Tue Oct 21 03:58:56 2014 +0300 @@ -394,3 +394,58 @@ ret = mailbox_list_index_sync_list(sync_ctx); return mailbox_list_index_sync_end(&sync_ctx, ret == 0); } + +int mailbox_list_index_delete_entry(struct mailbox_list *list, const char *name, + bool delete_selectable) +{ + struct mailbox_list_index_sync_context *sync_ctx; + struct mailbox_list_index_record rec; + struct mailbox_list_index_node *node; + const void *data; + bool expunged; + uint32_t seq; + + if (mailbox_list_index_sync_begin(list, &sync_ctx) < 0) + return -1; + + node = mailbox_list_index_lookup(list, name); + if (node == NULL) { + (void)mailbox_list_index_sync_end(&sync_ctx, FALSE); + mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + return -1; + } + if (!mail_index_lookup_seq(sync_ctx->view, node->uid, &seq)) + i_panic("mailbox list index: lost uid=%u", node->uid); + if (delete_selectable) { + /* make it at least non-selectable */ + node->flags = MAILBOX_LIST_INDEX_FLAG_NOSELECT; + mail_index_update_flags(sync_ctx->trans, seq, MODIFY_REPLACE, + (enum mail_flags)node->flags); + + mail_index_lookup_ext(sync_ctx->view, seq, + sync_ctx->ilist->ext_id, + &data, &expunged); + i_assert(data != NULL && !expunged); + memcpy(&rec, data, sizeof(rec)); + rec.uid_validity = 0; + memset(&rec.guid, 0, sizeof(rec.guid)); + mail_index_update_ext(sync_ctx->trans, seq, + sync_ctx->ilist->ext_id, &rec, NULL); + } + if (node->children != NULL) { + /* can't delete this directory before its children, + but we may have made it non-selectable already */ + if (mailbox_list_index_sync_end(&sync_ctx, TRUE) < 0) + return -1; + return 0; + } + + /* we can remove the entire node */ + mail_index_expunge(sync_ctx->trans, seq); + mailbox_list_index_node_unlink(sync_ctx->ilist, node); + + if (mailbox_list_index_sync_end(&sync_ctx, TRUE) < 0) + return -1; + return 1; +} diff -r a9503b723f8c -r c92472804eb8 src/lib-storage/list/mailbox-list-index-sync.h --- a/src/lib-storage/list/mailbox-list-index-sync.h Tue Oct 21 02:48:20 2014 +0300 +++ b/src/lib-storage/list/mailbox-list-index-sync.h Tue Oct 21 03:58:56 2014 +0300 @@ -29,4 +29,7 @@ struct mailbox_list_index_node **node_r, bool *created_r); +int mailbox_list_index_delete_entry(struct mailbox_list *list, const char *name, + bool delete_selectable); + #endif From dovecot at dovecot.org Tue Oct 21 02:47:21 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 21 Oct 2014 02:47:21 +0000 Subject: dovecot-2.2: lib-storage: Partially reverted previous change. Ad... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d9f49ebe5e78 changeset: 17975:d9f49ebe5e78 user: Timo Sirainen date: Tue Oct 21 05:44:09 2014 +0300 description: lib-storage: Partially reverted previous change. Added mailbox_list_index_sync_delete() instead. diffstat: src/lib-storage/list/mailbox-list-index-backend.c | 19 +++++++++++++++++-- src/lib-storage/list/mailbox-list-index-sync.c | 18 ++++-------------- src/lib-storage/list/mailbox-list-index-sync.h | 4 ++-- 3 files changed, 23 insertions(+), 18 deletions(-) diffs (104 lines): diff -r c92472804eb8 -r d9f49ebe5e78 src/lib-storage/list/mailbox-list-index-backend.c --- a/src/lib-storage/list/mailbox-list-index-backend.c Tue Oct 21 03:58:56 2014 +0300 +++ b/src/lib-storage/list/mailbox-list-index-backend.c Tue Oct 21 05:44:09 2014 +0300 @@ -453,6 +453,21 @@ } static int +index_list_delete_entry(struct mailbox_list *list, const char *name, + bool delete_selectable) +{ + struct mailbox_list_index_sync_context *sync_ctx; + int ret; + + if (mailbox_list_index_sync_begin(list, &sync_ctx) < 0) + return -1; + ret = mailbox_list_index_sync_delete(sync_ctx, name, delete_selectable); + if (mailbox_list_index_sync_end(&sync_ctx, TRUE) < 0) + return -1; + return ret; +} + +static int index_list_delete_mailbox(struct mailbox_list *_list, const char *name) { const char *path; @@ -476,7 +491,7 @@ if (ret == 0 || (_list->props & MAILBOX_LIST_PROP_AUTOCREATE_DIRS) != 0) index_list_delete_finish(_list, name); if (ret == 0) { - if (mailbox_list_index_delete_entry(_list, name, TRUE) < 0) + if (index_list_delete_entry(_list, name, TRUE) < 0) return -1; } return ret; @@ -487,7 +502,7 @@ { int ret; - if ((ret = mailbox_list_index_delete_entry(_list, name, FALSE)) < 0) + if ((ret = index_list_delete_entry(_list, name, FALSE)) < 0) return -1; if (ret == 0) { mailbox_list_set_error(_list, MAIL_ERROR_EXISTS, diff -r c92472804eb8 -r d9f49ebe5e78 src/lib-storage/list/mailbox-list-index-sync.c --- a/src/lib-storage/list/mailbox-list-index-sync.c Tue Oct 21 03:58:56 2014 +0300 +++ b/src/lib-storage/list/mailbox-list-index-sync.c Tue Oct 21 05:44:09 2014 +0300 @@ -395,23 +395,18 @@ return mailbox_list_index_sync_end(&sync_ctx, ret == 0); } -int mailbox_list_index_delete_entry(struct mailbox_list *list, const char *name, - bool delete_selectable) +int mailbox_list_index_sync_delete(struct mailbox_list_index_sync_context *sync_ctx, + const char *name, bool delete_selectable) { - struct mailbox_list_index_sync_context *sync_ctx; struct mailbox_list_index_record rec; struct mailbox_list_index_node *node; const void *data; bool expunged; uint32_t seq; - if (mailbox_list_index_sync_begin(list, &sync_ctx) < 0) - return -1; - - node = mailbox_list_index_lookup(list, name); + node = mailbox_list_index_lookup(sync_ctx->list, name); if (node == NULL) { - (void)mailbox_list_index_sync_end(&sync_ctx, FALSE); - mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, + mailbox_list_set_error(sync_ctx->list, MAIL_ERROR_NOTFOUND, T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); return -1; } @@ -436,16 +431,11 @@ if (node->children != NULL) { /* can't delete this directory before its children, but we may have made it non-selectable already */ - if (mailbox_list_index_sync_end(&sync_ctx, TRUE) < 0) - return -1; return 0; } /* we can remove the entire node */ mail_index_expunge(sync_ctx->trans, seq); mailbox_list_index_node_unlink(sync_ctx->ilist, node); - - if (mailbox_list_index_sync_end(&sync_ctx, TRUE) < 0) - return -1; return 1; } diff -r c92472804eb8 -r d9f49ebe5e78 src/lib-storage/list/mailbox-list-index-sync.h --- a/src/lib-storage/list/mailbox-list-index-sync.h Tue Oct 21 03:58:56 2014 +0300 +++ b/src/lib-storage/list/mailbox-list-index-sync.h Tue Oct 21 05:44:09 2014 +0300 @@ -29,7 +29,7 @@ struct mailbox_list_index_node **node_r, bool *created_r); -int mailbox_list_index_delete_entry(struct mailbox_list *list, const char *name, - bool delete_selectable); +int mailbox_list_index_sync_delete(struct mailbox_list_index_sync_context *sync_ctx, + const char *name, bool delete_selectable); #endif From dovecot at dovecot.org Tue Oct 21 02:47:21 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 21 Oct 2014 02:47:21 +0000 Subject: dovecot-2.2: lib-storage: LAYOUT=index no longer keeps list inde... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0de24ac413c4 changeset: 17976:0de24ac413c4 user: Timo Sirainen date: Tue Oct 21 05:46:22 2014 +0300 description: lib-storage: LAYOUT=index no longer keeps list index locked while creating mailbox. Mailbox opening can be slow and complicated and could even try to lock the list index again. So it's a bit more racy now, but all mailbox formats can already handle races with mailbox creation. diffstat: src/lib-storage/list/mailbox-list-index-backend.c | 21 ++++++++++++++------- 1 files changed, 14 insertions(+), 7 deletions(-) diffs (66 lines): diff -r d9f49ebe5e78 -r 0de24ac413c4 src/lib-storage/list/mailbox-list-index-backend.c --- a/src/lib-storage/list/mailbox-list-index-backend.c Tue Oct 21 05:44:09 2014 +0300 +++ b/src/lib-storage/list/mailbox-list-index-backend.c Tue Oct 21 05:46:22 2014 +0300 @@ -262,9 +262,8 @@ static int index_list_mailbox_create_selectable(struct mailbox *box, - const struct mailbox_update *update) + const guid_128_t mailbox_guid) { - struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box); struct index_mailbox_list *list = (struct index_mailbox_list *)box->list; struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(box->list); @@ -272,7 +271,7 @@ struct mailbox_list_index_record rec; struct mailbox_list_index_node *node; const void *data; - bool expunged, created, success; + bool expunged, created; uint32_t seq; if (mailbox_list_index_sync_begin(&list->list, &sync_ctx) < 0) @@ -297,11 +296,10 @@ node->flags = 0; mail_index_update_flags(sync_ctx->trans, seq, MODIFY_REPLACE, 0); - memcpy(rec.guid, update->mailbox_guid, sizeof(rec.guid)); + memcpy(rec.guid, mailbox_guid, sizeof(rec.guid)); mail_index_update_ext(sync_ctx->trans, seq, ilist->ext_id, &rec, NULL); - success = ibox->module_ctx.super.create_box(box, update, FALSE) == 0; - if (mailbox_list_index_sync_end(&sync_ctx, success) < 0) { + if (mailbox_list_index_sync_end(&sync_ctx, TRUE) < 0) { /* make sure we forget any changes done internally */ mailbox_list_index_reset(ilist); return -1; @@ -313,6 +311,7 @@ index_list_mailbox_create(struct mailbox *box, const struct mailbox_update *update, bool directory) { + struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box); struct index_mailbox_list *list = (struct index_mailbox_list *)box->list; struct mailbox_update new_update; @@ -339,11 +338,19 @@ new_update = *update; if (guid_128_is_empty(new_update.mailbox_guid)) guid_128_generate(new_update.mailbox_guid); - ret = index_list_mailbox_create_selectable(box, &new_update); + ret = index_list_mailbox_create_selectable(box, new_update.mailbox_guid); if (ret < 0) { mail_storage_copy_list_error(box->storage, box->list); return -1; } + if (ret > 0) { + /* mailbox entry was created. create the mailbox + itself now after the mailbox list index is already + unlocked (to avoid deadlocks in case the create_box() + goes back to updating mailbox list index). */ + if (ibox->module_ctx.super.create_box(box, update, FALSE) < 0) + return -1; + } } else { ret = 0; } From dovecot at dovecot.org Tue Oct 21 20:59:53 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 21 Oct 2014 20:59:53 +0000 Subject: dovecot-2.2: lib-http: client: If peer is unlinked from queue an... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/df5be9847b13 changeset: 17977:df5be9847b13 user: Stephan Bosch date: Tue Oct 21 23:34:50 2014 +0300 description: lib-http: client: If peer is unlinked from queue and no other links remain, close any pending connections. Those pending connections would no longer serve any purpose. diffstat: src/lib-http/http-client-peer.c | 42 ++++++++++++++++++++++++++++++---------- 1 files changed, 31 insertions(+), 11 deletions(-) diffs (81 lines): diff -r 0de24ac413c4 -r df5be9847b13 src/lib-http/http-client-peer.c --- a/src/lib-http/http-client-peer.c Tue Oct 21 05:46:22 2014 +0300 +++ b/src/lib-http/http-client-peer.c Tue Oct 21 23:34:50 2014 +0300 @@ -157,6 +157,23 @@ return FALSE; } +static void +http_client_peer_disconnect(struct http_client_peer *peer) +{ + struct http_client_connection **conn; + ARRAY_TYPE(http_client_connection) conns; + + http_client_peer_debug(peer, "Peer disconnect"); + + /* make a copy of the connection array; freed connections modify it */ + t_array_init(&conns, array_count(&peer->conns)); + array_copy(&conns.arr, 0, &peer->conns.arr, 0, array_count(&peer->conns)); + array_foreach_modifiable(&conns, conn) { + http_client_connection_unref(conn); + } + i_assert(array_count(&peer->conns) == 0); +} + static void http_client_peer_check_idle(struct http_client_peer *peer) { struct http_client_connection *const *conn_idx; @@ -200,6 +217,13 @@ /* FIXME: limit the number of requests handled in one run to prevent I/O starvation. */ + /* disconnect if we're not linked to any queue anymore */ + if (array_count(&peer->queues) == 0) { + i_assert(peer->to_backoff != NULL); + http_client_peer_disconnect(peer); + return; + } + /* don't do anything unless we have pending requests */ num_pending = http_client_peer_requests_pending(peer, &num_urgent); if (num_pending == 0) { @@ -426,8 +450,6 @@ void http_client_peer_free(struct http_client_peer **_peer) { struct http_client_peer *peer = *_peer; - struct http_client_connection **conn; - ARRAY_TYPE(http_client_connection) conns; if (peer->destroyed) return; @@ -440,14 +462,7 @@ if (peer->to_backoff != NULL) timeout_remove(&peer->to_backoff); - /* make a copy of the connection array; freed connections modify it */ - t_array_init(&conns, array_count(&peer->conns)); - array_copy(&conns.arr, 0, &peer->conns.arr, 0, array_count(&peer->conns)); - array_foreach_modifiable(&conns, conn) { - http_client_connection_unref(conn); - } - - i_assert(array_count(&peer->conns) == 0); + http_client_peer_disconnect(peer); array_free(&peer->conns); array_free(&peer->queues); @@ -502,8 +517,13 @@ array_delete(&peer->queues, array_foreach_idx(&peer->queues, queue_idx), 1); if (array_count(&peer->queues) == 0) { - if (!http_client_peer_start_backoff_timer(peer)) + if (http_client_peer_start_backoff_timer(peer)) { + /* will disconnect any pending connections */ + http_client_peer_trigger_request_handler(peer); + } else { + /* drop peer immediately */ http_client_peer_free(&peer); + } } return; } From dovecot at dovecot.org Wed Oct 22 00:00:17 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 22 Oct 2014 00:00:17 +0000 Subject: dovecot-2.2: lib: Added guid_128_copy() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/40cca8d452f5 changeset: 17978:40cca8d452f5 user: Timo Sirainen date: Wed Oct 22 02:59:22 2014 +0300 description: lib: Added guid_128_copy() diffstat: src/lib/guid.h | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r df5be9847b13 -r 40cca8d452f5 src/lib/guid.h --- a/src/lib/guid.h Tue Oct 21 23:34:50 2014 +0300 +++ b/src/lib/guid.h Wed Oct 22 02:59:22 2014 +0300 @@ -14,6 +14,11 @@ bool guid_128_is_empty(const guid_128_t guid); /* Returns TRUE if two GUIDs are equal. */ bool guid_128_equals(const guid_128_t guid1, const guid_128_t guid2); +/* Copy GUID */ +static inline void guid_128_copy(guid_128_t dest, const guid_128_t src) +{ + memcpy(dest, src, GUID_128_SIZE); +} /* Returns GUID as a hex string. */ const char *guid_128_to_string(const guid_128_t guid); From dovecot at dovecot.org Wed Oct 22 02:41:39 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 22 Oct 2014 02:41:39 +0000 Subject: dovecot-2.2: lib: Added unit tests for guid_128_*() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/07c709075598 changeset: 17979:07c709075598 user: Timo Sirainen date: Wed Oct 22 05:40:44 2014 +0300 description: lib: Added unit tests for guid_128_*() diffstat: src/lib/Makefile.am | 1 + src/lib/test-guid.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/test-lib.c | 1 + src/lib/test-lib.h | 1 + 4 files changed, 84 insertions(+), 0 deletions(-) diffs (118 lines): diff -r 40cca8d452f5 -r 07c709075598 src/lib/Makefile.am --- a/src/lib/Makefile.am Wed Oct 22 02:59:22 2014 +0300 +++ b/src/lib/Makefile.am Wed Oct 22 05:40:44 2014 +0300 @@ -282,6 +282,7 @@ test-buffer.c \ test-crc32.c \ test-data-stack.c \ + test-guid.c \ test-hash.c \ test-hash-format.c \ test-hash-method.c \ diff -r 40cca8d452f5 -r 07c709075598 src/lib/test-guid.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/test-guid.c Wed Oct 22 05:40:44 2014 +0300 @@ -0,0 +1,81 @@ +/* Copyright (c) 2014 Dovecot authors, see the included COPYING file */ + +#include "test-lib.h" +#include "guid.h" + +void test_guid(void) +{ + static const guid_128_t test_guid = + { 0x01, 0x23, 0x45, 0x67, 0x89, + 0xab, 0xcd, 0xef, + 0xAB, 0xCD, 0xEF, + 0x00, 0x00, 0x00, 0x00, 0x00 }; + guid_128_t guid1, guid2, guid3, empty_guid; + const char *str; + char guidbuf[GUID_128_SIZE*2 + 2]; + unsigned int i; + + memset(empty_guid, 0, sizeof(empty_guid)); + + test_begin("guid_128_generate()"); + guid_128_generate(guid1); + guid_128_generate(guid2); + test_assert(!guid_128_equals(guid1, guid2)); + test_assert(guid_128_cmp(guid1, guid2) != 0); + test_end(); + + test_begin("guid_128_is_empty()"); + test_assert(!guid_128_is_empty(guid1)); + test_assert(!guid_128_is_empty(guid2)); + test_assert(guid_128_is_empty(empty_guid)); + test_end(); + + test_begin("guid_128_copy()"); + guid_128_copy(guid3, guid1); + test_assert(guid_128_equals(guid3, guid1)); + test_assert(!guid_128_equals(guid3, guid2)); + guid_128_copy(guid3, guid2); + test_assert(!guid_128_equals(guid3, guid1)); + test_assert(guid_128_equals(guid3, guid2)); + test_end(); + + test_begin("guid_128_to_string()"); + str = guid_128_to_string(guid1); + test_assert(guid_128_from_string(str, guid3) == 0); + test_assert(guid_128_equals(guid3, guid1)); + test_end(); + + test_begin("guid_128_from_string()"); + /* empty */ + memset(guidbuf, '0', GUID_128_SIZE*2); + guidbuf[GUID_128_SIZE*2] = '\0'; + guidbuf[GUID_128_SIZE*2+1] = '\0'; + test_assert(guid_128_from_string(guidbuf, guid3) == 0); + test_assert(guid_128_is_empty(guid3)); + /* too large */ + guidbuf[GUID_128_SIZE*2] = '0'; + test_assert(guid_128_from_string(guidbuf, guid3) < 0); + /* too small */ + guidbuf[GUID_128_SIZE*2-1] = '\0'; + test_assert(guid_128_from_string(guidbuf, guid3) < 0); + /* reset to normal */ + guidbuf[GUID_128_SIZE*2-1] = '0'; + guidbuf[GUID_128_SIZE*2] = '\0'; + test_assert(guid_128_from_string(guidbuf, guid3) == 0); + /* upper + lowercase hex chars */ + i_assert(GUID_128_SIZE*2 > 16 + 6); + for (i = 0; i < 10; i++) + guidbuf[i] = '0' + i; + for (i = 0; i < 6; i++) + guidbuf[10 + i] = 'a' + i; + for (i = 0; i < 6; i++) + guidbuf[16 + i] = 'A' + i; + test_assert(guid_128_from_string(guidbuf, guid3) == 0); + test_assert(guid_128_equals(guid3, test_guid)); + /* non-hex chars */ + guidbuf[0] = 'g'; + test_assert(guid_128_from_string(guidbuf, guid3) < 0); + guidbuf[0] = ' '; + test_assert(guid_128_from_string(guidbuf, guid3) < 0); + test_end(); +} diff -r 40cca8d452f5 -r 07c709075598 src/lib/test-lib.c --- a/src/lib/test-lib.c Wed Oct 22 02:59:22 2014 +0300 +++ b/src/lib/test-lib.c Wed Oct 22 05:40:44 2014 +0300 @@ -13,6 +13,7 @@ test_buffer, test_crc32, test_data_stack, + test_guid, test_hash, test_hash_format, test_hash_method, diff -r 40cca8d452f5 -r 07c709075598 src/lib/test-lib.h --- a/src/lib/test-lib.h Wed Oct 22 02:59:22 2014 +0300 +++ b/src/lib/test-lib.h Wed Oct 22 05:40:44 2014 +0300 @@ -13,6 +13,7 @@ void test_crc32(void); void test_data_stack(void); enum fatal_test_state fatal_data_stack(int); +void test_guid(void); void test_hash(void); void test_hash_format(void); void test_hash_method(void); From dovecot at dovecot.org Wed Oct 22 21:16:13 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 22 Oct 2014 21:16:13 +0000 Subject: dovecot-2.2: replication plugin: Use low priority for mail copyi... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c373aa97644c changeset: 17980:c373aa97644c user: Timo Sirainen date: Wed Oct 22 14:15:23 2014 -0700 description: replication plugin: Use low priority for mail copying operations. diffstat: src/plugins/replication/replication-plugin.c | 13 ++++++++++--- 1 files changed, 10 insertions(+), 3 deletions(-) diffs (27 lines): diff -r 07c709075598 -r c373aa97644c src/plugins/replication/replication-plugin.c --- a/src/plugins/replication/replication-plugin.c Wed Oct 22 05:40:44 2014 +0300 +++ b/src/plugins/replication/replication-plugin.c Wed Oct 22 14:15:23 2014 -0700 @@ -228,13 +228,20 @@ ctx->new_messages = TRUE; } -static void replication_mail_copy(void *txn, struct mail *src ATTR_UNUSED, - struct mail *dst ATTR_UNUSED) +static void replication_mail_copy(void *txn, struct mail *src, + struct mail *dst) { struct replication_mail_txn_context *ctx = (struct replication_mail_txn_context *)txn; - ctx->new_messages = TRUE; + if (src->box->storage != dst->box->storage) { + /* copy between storages, e.g. new mail delivery */ + ctx->new_messages = TRUE; + } else { + /* copy within storage, which isn't as high priority since the + mail already exists. and especially copies to Trash or to + lazy-expunge namespace is pretty low priority. */ + } } static void From dovecot at dovecot.org Thu Oct 23 00:11:05 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Oct 2014 00:11:05 +0000 Subject: dovecot-2.2: lib-storage: Make sure mailbox names are valid UTF-... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b534125f8baf changeset: 17981:b534125f8baf user: Timo Sirainen date: Thu Oct 23 03:10:12 2014 +0300 description: lib-storage: Make sure mailbox names are valid UTF-8 with LAYOUT=index diffstat: src/lib-storage/list/mailbox-list-index.c | 22 ++++++++++++++++------ 1 files changed, 16 insertions(+), 6 deletions(-) diffs (55 lines): diff -r c373aa97644c -r b534125f8baf src/lib-storage/list/mailbox-list-index.c --- a/src/lib-storage/list/mailbox-list-index.c Wed Oct 22 14:15:23 2014 -0700 +++ b/src/lib-storage/list/mailbox-list-index.c Thu Oct 23 03:10:12 2014 +0300 @@ -169,15 +169,18 @@ static int mailbox_list_index_parse_header(struct mailbox_list_index *ilist, struct mail_index_view *view) { - const void *data, *p; + const void *data, *name_start, *p; size_t i, len, size; uint32_t id, prev_id = 0; + string_t *str; char *name; + int ret = 0; mail_index_map_get_header_ext(view, view->map, ilist->ext_id, &data, &size); if (size == 0) return 0; + str = t_str_new(128); for (i = sizeof(struct mailbox_list_index_header); i < size; ) { /* get id */ if (i + sizeof(id) > size) @@ -195,11 +198,18 @@ p = memchr(CONST_PTR_OFFSET(data, i), '\0', size-i); if (p == NULL) return -1; - len = (const char *)p - - (const char *)(CONST_PTR_OFFSET(data, i)); + name_start = CONST_PTR_OFFSET(data, i); + len = (const char *)p - (const char *)name_start; - name = p_strndup(ilist->mailbox_pool, - CONST_PTR_OFFSET(data, i), len); + if (uni_utf8_get_valid_data(name_start, len, str)) { + name = p_strndup(ilist->mailbox_pool, name_start, len); + } else { + /* corrupted index. fix the name. */ + name = p_strdup(ilist->mailbox_pool, str_c(str)); + str_truncate(str, 0); + ret = -1; + } + i += len + 1; /* add id => name to hash table */ @@ -207,7 +217,7 @@ ilist->highest_name_id = id; } i_assert(i == size); - return 0; + return ret; } static void From dovecot at dovecot.org Thu Oct 23 01:17:45 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Oct 2014 01:17:45 +0000 Subject: dovecot-2.2: dsync: Fixed assert-crash / memory leak on error ha... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d92c1c666bc3 changeset: 17982:d92c1c666bc3 user: Timo Sirainen date: Thu Oct 23 04:16:48 2014 +0300 description: dsync: Fixed assert-crash / memory leak on error handling path. diffstat: src/doveadm/dsync/dsync-mailbox-import.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r b534125f8baf -r d92c1c666bc3 src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Thu Oct 23 03:10:12 2014 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Thu Oct 23 04:16:48 2014 +0300 @@ -2064,6 +2064,7 @@ error_field, mail->uid, mailbox_get_last_error(importer->box, NULL)); importer->failed = TRUE; + mailbox_save_cancel(&save_ctx); return; } dsync_mailbox_save_set_nonminimal(save_ctx, &mail2); From dovecot at dovecot.org Thu Oct 23 02:05:31 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Oct 2014 02:05:31 +0000 Subject: dovecot-2.2: lib-index: Detect broken log_file_tail_offset updat... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/575dcd85b4be changeset: 17983:575dcd85b4be user: Timo Sirainen date: Thu Oct 23 05:04:37 2014 +0300 description: lib-index: Detect broken log_file_tail_offset updates without assert-crashing. diffstat: src/lib-index/mail-transaction-log-file.c | 10 +++++++--- 1 files changed, 7 insertions(+), 3 deletions(-) diffs (37 lines): diff -r d92c1c666bc3 -r 575dcd85b4be src/lib-index/mail-transaction-log-file.c --- a/src/lib-index/mail-transaction-log-file.c Thu Oct 23 04:16:48 2014 +0300 +++ b/src/lib-index/mail-transaction-log-file.c Thu Oct 23 05:04:37 2014 +0300 @@ -935,10 +935,11 @@ static int log_file_track_mailbox_sync_offset_hdr(struct mail_transaction_log_file *file, - const void *data, unsigned int size) + const void *data, unsigned int trans_size) { const struct mail_transaction_header_update *u = data; const struct mail_index_header *ihdr; + const unsigned int size = trans_size - sizeof(struct mail_transaction_header); const unsigned int offset_pos = offsetof(struct mail_index_header, log_file_tail_offset); const unsigned int offset_size = sizeof(ihdr->log_file_tail_offset); @@ -961,6 +962,10 @@ if (tail_offset < file->saved_tail_offset) { /* ignore shrinking tail offsets */ return 1; + } else if (tail_offset > file->sync_offset + trans_size) { + mail_transaction_log_file_set_corrupted(file, + "log_file_tail_offset %u goes past sync offset %"PRIuUOFF_T, + tail_offset, file->sync_offset + trans_size); } else { file->saved_tail_offset = tail_offset; if (tail_offset > file->max_tail_offset) @@ -1277,8 +1282,7 @@ case MAIL_TRANSACTION_HEADER_UPDATE: /* see if this updates mailbox_sync_offset */ ret = log_file_track_mailbox_sync_offset_hdr(file, data, - trans_size - - sizeof(*hdr)); + trans_size); if (ret != 0) return ret < 0 ? -1 : 1; break; From dovecot at dovecot.org Thu Oct 23 02:56:51 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Oct 2014 02:56:51 +0000 Subject: dovecot-2.2: lib-http: client: Clear req->conn when request is f... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/bce536c20d32 changeset: 17984:bce536c20d32 user: Stephan Bosch date: Thu Oct 23 05:55:51 2014 +0300 description: lib-http: client: Clear req->conn when request is finished. This prevents a spurious assert failure. diffstat: src/lib-http/http-client-connection.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (27 lines): diff -r 575dcd85b4be -r bce536c20d32 src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Thu Oct 23 05:04:37 2014 +0300 +++ b/src/lib-http/http-client-connection.c Thu Oct 23 05:55:51 2014 +0300 @@ -438,6 +438,7 @@ the payload. make sure here that it's switched back. */ net_set_nonblock(conn->conn.fd_in, TRUE); + req->conn = NULL; conn->incoming_payload = NULL; conn->pending_request = NULL; http_client_request_finish(&req); @@ -495,6 +496,7 @@ retrying = !http_client_request_callback(req, response); http_client_connection_unref(&conn); if (conn == NULL) { + req->conn = NULL; /* the callback managed to get this connection destroyed */ if (!retrying) http_client_request_finish(&req); @@ -531,6 +533,7 @@ http_client_payload_finished(conn); } } else { + req->conn = NULL; http_client_request_finish(&req); http_client_request_unref(&req); } From dovecot at dovecot.org Thu Oct 23 02:56:51 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Oct 2014 02:56:51 +0000 Subject: dovecot-2.2: lib-http: client: Assertion in http_client_queue_fa... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e479bce0633b changeset: 17985:e479bce0633b user: Stephan Bosch date: Thu Oct 23 05:55:51 2014 +0300 description: lib-http: client: Assertion in http_client_queue_fail() was wrong. It is not guaranteed that all queue lists are empty, because new requests can be submitted from the callbacks. Changed this into a proper invariant check, which asserts tbat the number of requests in sub-queues add up to the total number in the main queue. diffstat: src/lib-http/http-client-queue.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) diffs (20 lines): diff -r bce536c20d32 -r e479bce0633b src/lib-http/http-client-queue.c --- a/src/lib-http/http-client-queue.c Thu Oct 23 05:55:51 2014 +0300 +++ b/src/lib-http/http-client-queue.c Thu Oct 23 05:55:51 2014 +0300 @@ -151,10 +151,12 @@ } array_clear(req_arr); - /* all queues must be empty now */ - i_assert(array_count(&queue->delayed_requests) == 0); - i_assert(array_count(&queue->queued_requests) == 0); - i_assert(array_count(&queue->queued_urgent_requests) == 0); + /* all queues should be empty now... unless new requests were submitted + from the callback. this invariant captures it all: */ + i_assert((array_count(&queue->delayed_requests) + + array_count(&queue->queued_requests) + + array_count(&queue->queued_urgent_requests)) == + array_count(&queue->requests)); } /* From dovecot at dovecot.org Thu Oct 23 02:56:51 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Oct 2014 02:56:51 +0000 Subject: dovecot-2.2: lib-http: client: Implemented maximum for connectio... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/44fd142fac1e changeset: 17986:44fd142fac1e user: Stephan Bosch date: Thu Oct 23 05:55:51 2014 +0300 description: lib-http: client: Implemented maximum for connection backoff time. Without a maximum, the backoff time grows exponentially to enormous values, because it isn't reset until the connection succeeds. This causes recovery from connection failures to become very slow. Current maximum is one minute. diffstat: src/lib-http/http-client-peer.c | 2 ++ src/lib-http/http-client-private.h | 1 + src/lib-http/http-client.c | 4 ++++ src/lib-http/http-client.h | 2 ++ 4 files changed, 9 insertions(+), 0 deletions(-) diffs (49 lines): diff -r e479bce0633b -r 44fd142fac1e src/lib-http/http-client-peer.c --- a/src/lib-http/http-client-peer.c Thu Oct 23 05:55:51 2014 +0300 +++ b/src/lib-http/http-client-peer.c Thu Oct 23 05:55:51 2014 +0300 @@ -592,6 +592,8 @@ peer->backoff_time_msecs = set->connect_backoff_time_msecs; else peer->backoff_time_msecs *= 2; + if (peer->backoff_time_msecs > set->connect_backoff_max_time_msecs) + peer->backoff_time_msecs = set->connect_backoff_max_time_msecs; } if (pending > 1) { diff -r e479bce0633b -r 44fd142fac1e src/lib-http/http-client-private.h --- a/src/lib-http/http-client-private.h Thu Oct 23 05:55:51 2014 +0300 +++ b/src/lib-http/http-client-private.h Thu Oct 23 05:55:51 2014 +0300 @@ -14,6 +14,7 @@ #define HTTP_CLIENT_CONTINUE_TIMEOUT_MSECS (1000*2) #define HTTP_CLIENT_DEFAULT_REQUEST_TIMEOUT_MSECS (1000*60*5) #define HTTP_CLIENT_DEFAULT_BACKOFF_TIME_MSECS (100) +#define HTTP_CLIENT_DEFAULT_BACKOFF_MAX_TIME_MSECS (1000*60) enum http_response_payload_type; diff -r e479bce0633b -r 44fd142fac1e src/lib-http/http-client.c --- a/src/lib-http/http-client.c Thu Oct 23 05:55:51 2014 +0300 +++ b/src/lib-http/http-client.c Thu Oct 23 05:55:51 2014 +0300 @@ -125,6 +125,10 @@ set->connect_backoff_time_msecs == 0 ? HTTP_CLIENT_DEFAULT_BACKOFF_TIME_MSECS : set->connect_backoff_time_msecs; + client->set.connect_backoff_max_time_msecs = + set->connect_backoff_max_time_msecs == 0 ? + HTTP_CLIENT_DEFAULT_BACKOFF_MAX_TIME_MSECS : + set->connect_backoff_max_time_msecs; client->set.no_auto_redirect = set->no_auto_redirect; client->set.no_ssl_tunnel = set->no_ssl_tunnel; client->set.max_redirects = set->max_redirects; diff -r e479bce0633b -r 44fd142fac1e src/lib-http/http-client.h --- a/src/lib-http/http-client.h Thu Oct 23 05:55:51 2014 +0300 +++ b/src/lib-http/http-client.h Thu Oct 23 05:55:51 2014 +0300 @@ -95,6 +95,8 @@ /* Initial backoff time; doubled at each connection failure */ unsigned int connect_backoff_time_msecs; + /* Maximum backoff time */ + unsigned int connect_backoff_max_time_msecs; /* response header limits */ struct http_header_limits response_hdr_limits; From dovecot at dovecot.org Thu Oct 23 02:56:51 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Oct 2014 02:56:51 +0000 Subject: dovecot-2.2: lib-http: client: Fixed proxied client connect time... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/43728039836c changeset: 17987:43728039836c user: Stephan Bosch date: Thu Oct 23 05:55:51 2014 +0300 description: lib-http: client: Fixed proxied client connect timeout. Timeout didn't cause requests to be aborted with error. diffstat: src/lib-http/http-client-connection.c | 22 +++++++++++++++++++--- src/lib-http/http-client-private.h | 1 + 2 files changed, 20 insertions(+), 3 deletions(-) diffs (78 lines): diff -r 44fd142fac1e -r 43728039836c src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Thu Oct 23 05:55:51 2014 +0300 +++ b/src/lib-http/http-client-connection.c Thu Oct 23 05:55:51 2014 +0300 @@ -1063,6 +1063,18 @@ static void http_client_connect_tunnel_timeout(struct http_client_connection *conn) { + const char *error, *name = http_client_peer_addr2str(&conn->peer->addr); + unsigned int msecs; + + msecs = timeval_diff_msecs(&ioloop_timeval, + &conn->connect_start_timestamp); + error = t_strdup_printf( + "Tunnel connect(%s) failed: " + "Connection timed out in %u.%03u secs", + name, msecs/1000, msecs%1000); + + http_client_connection_debug(conn, "%s", error); + http_client_peer_connection_failure(conn->peer, error); http_client_connection_close(&conn); } @@ -1111,7 +1123,7 @@ if (response->status != 200) { http_client_peer_connection_failure(conn->peer, t_strdup_printf( - "tunnel connect(%s) failed: %d %s", name, + "Tunnel connect(%s) failed: %d %s", name, response->status, response->reason)); conn->connect_request = NULL; return; @@ -1122,6 +1134,7 @@ _connection_init_from_streams (conn->client->conn_list, &conn->conn, name, tunnel.input, tunnel.output); + conn->connect_initialized = TRUE; } static void @@ -1184,6 +1197,7 @@ } else { connection_init_client_ip (peer->client->conn_list, &conn->conn, &addr->ip, addr->port); + conn->connect_initialized = TRUE; http_client_connection_connect(conn); } @@ -1217,7 +1231,8 @@ conn->incoming_payload = NULL; } - connection_disconnect(&conn->conn); + if (conn->connect_initialized) + connection_disconnect(&conn->conn); if (conn->io_req_payload != NULL) io_remove(&conn->io_req_payload); @@ -1269,7 +1284,8 @@ if (conn->ssl_iostream != NULL) ssl_iostream_unref(&conn->ssl_iostream); - connection_deinit(&conn->conn); + if (conn->connect_initialized) + connection_deinit(&conn->conn); /* remove this connection from the list */ conn_arr = &conn->peer->conns; diff -r 44fd142fac1e -r 43728039836c src/lib-http/http-client-private.h --- a/src/lib-http/http-client-private.h Thu Oct 23 05:55:51 2014 +0300 +++ b/src/lib-http/http-client-private.h Thu Oct 23 05:55:51 2014 +0300 @@ -142,6 +142,7 @@ unsigned int connected:1; /* connection is connected */ unsigned int tunneling:1; /* last sent request turns this connection into tunnel */ + unsigned int connect_initialized:1; /* connection was initialized */ unsigned int connect_succeeded:1; unsigned int closing:1; unsigned int close_indicated:1; From dovecot at dovecot.org Thu Oct 23 03:39:36 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Oct 2014 03:39:36 +0000 Subject: dovecot-2.2: doveadm: Added doveadm_print_istream() for easily p... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5d3898cacf8b changeset: 17988:5d3898cacf8b user: Timo Sirainen date: Thu Oct 23 06:37:30 2014 +0300 description: doveadm: Added doveadm_print_istream() for easily printing istreams. diffstat: src/doveadm/doveadm-print.c | 21 +++++++++++++++++++++ src/doveadm/doveadm-print.h | 2 ++ 2 files changed, 23 insertions(+), 0 deletions(-) diffs (50 lines): diff -r 43728039836c -r 5d3898cacf8b src/doveadm/doveadm-print.c --- a/src/doveadm/doveadm-print.c Thu Oct 23 05:55:51 2014 +0300 +++ b/src/doveadm/doveadm-print.c Thu Oct 23 06:37:30 2014 +0300 @@ -2,6 +2,7 @@ #include "lib.h" #include "array.h" +#include "istream.h" #include "doveadm-print-private.h" #include @@ -101,6 +102,26 @@ } } +int doveadm_print_istream(struct istream *input) +{ + const unsigned char *data; + size_t size; + ssize_t ret; + + while ((ret = i_stream_read_data(input, &data, &size, 0)) > 0) { + doveadm_print_stream(data, size); + i_stream_skip(input, size); + } + i_assert(ret == -1); + doveadm_print_stream("", 0); + if (input->stream_errno != 0) { + i_error("read(%s) failed: %s", i_stream_get_name(input), + i_stream_get_error(input)); + return -1; + } + return 0; +} + void doveadm_print_sticky(const char *key, const char *value) { struct doveadm_print_header_context *hdr; diff -r 43728039836c -r 5d3898cacf8b src/doveadm/doveadm-print.h --- a/src/doveadm/doveadm-print.h Thu Oct 23 05:55:51 2014 +0300 +++ b/src/doveadm/doveadm-print.h Thu Oct 23 06:37:30 2014 +0300 @@ -23,6 +23,8 @@ void doveadm_print_num(uintmax_t value); /* Stream for same field continues until len=0 */ void doveadm_print_stream(const void *value, size_t size); +/* Print the whole input stream. Returns 0 if ok, -1 if stream read() failed */ +int doveadm_print_istream(struct istream *input); void doveadm_print_sticky(const char *key, const char *value); void doveadm_print_flush(void); void doveadm_print_unstick_headers(void); From dovecot at dovecot.org Thu Oct 23 03:39:36 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Oct 2014 03:39:36 +0000 Subject: dovecot-2.2: doveadm fetch: Use doveadm_print_istream() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/89cbc0e91a77 changeset: 17989:89cbc0e91a77 user: Timo Sirainen date: Thu Oct 23 06:37:48 2014 +0300 description: doveadm fetch: Use doveadm_print_istream() diffstat: src/doveadm/doveadm-mail-fetch.c | 58 ++------------------------------------- 1 files changed, 4 insertions(+), 54 deletions(-) diffs (94 lines): diff -r 5d3898cacf8b -r 89cbc0e91a77 src/doveadm/doveadm-mail-fetch.c --- a/src/doveadm/doveadm-mail-fetch.c Thu Oct 23 06:37:30 2014 +0300 +++ b/src/doveadm/doveadm-mail-fetch.c Thu Oct 23 06:37:48 2014 +0300 @@ -111,29 +111,14 @@ { struct istream *input; struct message_size hdr_size; - const unsigned char *data; - size_t size; - int ret = 0; + int ret; if (mail_get_hdr_stream(ctx->mail, &hdr_size, &input) < 0) return -1; input = i_stream_create_limit(input, hdr_size.physical_size); - while (!i_stream_is_eof(input)) { - if (i_stream_read_data(input, &data, &size, 0) == -1) - break; - if (size == 0) - break; - doveadm_print_stream(data, size); - i_stream_skip(input, size); - } - if (input->stream_errno != 0) { - i_error("read(%s) failed: %s", i_stream_get_name(input), - i_stream_get_error(input)); - ret = -1; - } + ret = doveadm_print_istream(input); i_stream_unref(&input); - doveadm_print_stream("", 0); return ret; } @@ -206,56 +191,21 @@ { struct istream *input; struct message_size hdr_size; - const unsigned char *data; - size_t size; - int ret = 0; if (mail_get_stream(ctx->mail, &hdr_size, NULL, &input) < 0) return -1; i_stream_skip(input, hdr_size.physical_size); - while (!i_stream_is_eof(input)) { - if (i_stream_read_data(input, &data, &size, 0) == -1) - break; - if (size == 0) - break; - doveadm_print_stream(data, size); - i_stream_skip(input, size); - } - if (input->stream_errno != 0) { - i_error("read(%s) failed: %s", i_stream_get_name(input), - i_stream_get_error(input)); - ret = -1; - } - doveadm_print_stream("", 0); - return ret; + return doveadm_print_istream(input); } static int fetch_text(struct fetch_cmd_context *ctx) { struct istream *input; - const unsigned char *data; - size_t size; - int ret = 0; if (mail_get_stream(ctx->mail, NULL, NULL, &input) < 0) return -1; - - while (!i_stream_is_eof(input)) { - if (i_stream_read_data(input, &data, &size, 0) == -1) - break; - if (size == 0) - break; - doveadm_print_stream(data, size); - i_stream_skip(input, size); - } - if (input->stream_errno != 0) { - i_error("read(%s) failed: %s", i_stream_get_name(input), - i_stream_get_error(input)); - ret = -1; - } - doveadm_print_stream("", 0); - return ret; + return doveadm_print_istream(input); } static int fetch_text_utf8(struct fetch_cmd_context *ctx) From dovecot at dovecot.org Thu Oct 23 03:39:36 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Oct 2014 03:39:36 +0000 Subject: dovecot-2.2: doveadm: Added metadata set/unset/get/list commands. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4fe5b4e121a4 changeset: 17990:4fe5b4e121a4 user: Timo Sirainen date: Thu Oct 23 06:38:20 2014 +0300 description: doveadm: Added metadata set/unset/get/list commands. diffstat: src/doveadm/Makefile.am | 1 + src/doveadm/doveadm-mail-mailbox-metadata.c | 289 ++++++++++++++++++++++++++++ src/doveadm/doveadm-mail.c | 4 + src/doveadm/doveadm-mail.h | 4 + 4 files changed, 298 insertions(+), 0 deletions(-) diffs (truncated from 332 to 300 lines): diff -r 89cbc0e91a77 -r 4fe5b4e121a4 src/doveadm/Makefile.am --- a/src/doveadm/Makefile.am Thu Oct 23 06:37:48 2014 +0300 +++ b/src/doveadm/Makefile.am Thu Oct 23 06:38:20 2014 +0300 @@ -71,6 +71,7 @@ doveadm-mail-index.c \ doveadm-mail-iter.c \ doveadm-mail-mailbox.c \ + doveadm-mail-mailbox-metadata.c \ doveadm-mail-mailbox-status.c \ doveadm-mail-copymove.c \ doveadm-mailbox-list-iter.c \ diff -r 89cbc0e91a77 -r 4fe5b4e121a4 src/doveadm/doveadm-mail-mailbox-metadata.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doveadm/doveadm-mail-mailbox-metadata.c Thu Oct 23 06:38:20 2014 +0300 @@ -0,0 +1,289 @@ +/* Copyright (c) 2014 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "str.h" +#include "mail-namespace.h" +#include "mail-storage.h" +#include "doveadm-print.h" +#include "doveadm-mail.h" +#include "doveadm-mailbox-list-iter.h" + +struct metadata_cmd_context { + struct doveadm_mail_cmd_context ctx; + const char *mailbox; + enum mail_attribute_type key_type; + const char *key; + struct mail_attribute_value value; +}; + +static int +cmd_mailbox_metadata_set_run(struct doveadm_mail_cmd_context *_ctx, + struct mail_user *user) +{ + struct metadata_cmd_context *ctx = (struct metadata_cmd_context *)_ctx; + struct mail_namespace *ns; + struct mailbox *box; + struct mailbox_transaction_context *trans; + int ret; + + ns = mail_namespace_find(user->namespaces, ctx->mailbox); + box = mailbox_alloc(ns->list, ctx->mailbox, 0); + + if (mailbox_open(box) < 0) { + i_error("Failed to open mailbox: %s", + mailbox_get_last_error(box, NULL)); + mailbox_free(&box); + return -1; + } + trans = mailbox_transaction_begin(box, 0); + + ret = ctx->value.value == NULL ? + mailbox_attribute_unset(trans, ctx->key_type, ctx->key) : + mailbox_attribute_set(trans, ctx->key_type, ctx->key, &ctx->value); + if (ret < 0) { + i_error("Failed to set attribute: %s", + mailbox_get_last_error(box, NULL)); + mailbox_transaction_rollback(&trans); + } else if (mailbox_transaction_commit(&trans) < 0) { + i_error("Failed to commit transaction: %s", + mailbox_get_last_error(box, NULL)); + ret = -1; + } + + mailbox_free(&box); + return ret; +} + +static void +cmd_mailbox_metadata_parse_key(const char *arg, + enum mail_attribute_type *type_r, + const char **key_r) +{ + if (strncmp(arg, "/private/", 9) == 0) { + *type_r = MAIL_ATTRIBUTE_TYPE_PRIVATE; + *key_r = arg + 9; + } else if (strncmp(arg, "/shared/", 8) == 0) { + *type_r = MAIL_ATTRIBUTE_TYPE_SHARED; + *key_r = arg + 8; + } else if (strcmp(arg, "/private") == 0) { + *type_r = MAIL_ATTRIBUTE_TYPE_PRIVATE; + *key_r = ""; + } else if (strcmp(arg, "/shared") == 0) { + *type_r = MAIL_ATTRIBUTE_TYPE_SHARED; + *key_r = ""; + } else { + i_fatal_status(EX_USAGE, "Invalid metadata key '%s': " + "Must begin with /private or /shared", arg); + } +} + +static void +cmd_mailbox_metadata_set_init(struct doveadm_mail_cmd_context *_ctx, + const char *const args[]) +{ + struct metadata_cmd_context *ctx = (struct metadata_cmd_context *)_ctx; + const char *key; + + if (str_array_length(args) != 3) + doveadm_mail_help_name("mailbox metadata set"); + cmd_mailbox_metadata_parse_key(args[1], &ctx->key_type, &key); + + ctx->mailbox = p_strdup(_ctx->pool, args[0]); + ctx->key = p_strdup(_ctx->pool, key); + ctx->value.value = p_strdup(_ctx->pool, args[2]); +} + +static struct doveadm_mail_cmd_context *cmd_mailbox_metadata_set_alloc(void) +{ + struct metadata_cmd_context *ctx; + + ctx = doveadm_mail_cmd_alloc(struct metadata_cmd_context); + ctx->ctx.v.init = cmd_mailbox_metadata_set_init; + ctx->ctx.v.run = cmd_mailbox_metadata_set_run; + return &ctx->ctx; +} + +static void +cmd_mailbox_metadata_unset_init(struct doveadm_mail_cmd_context *_ctx, + const char *const args[]) +{ + struct metadata_cmd_context *ctx = (struct metadata_cmd_context *)_ctx; + const char *key; + + if (str_array_length(args) != 2) + doveadm_mail_help_name("mailbox metadata unset"); + cmd_mailbox_metadata_parse_key(args[1], &ctx->key_type, &key); + + ctx->mailbox = p_strdup(_ctx->pool, args[0]); + ctx->key = p_strdup(_ctx->pool, key); +} + +static struct doveadm_mail_cmd_context *cmd_mailbox_metadata_unset_alloc(void) +{ + struct metadata_cmd_context *ctx; + + ctx = doveadm_mail_cmd_alloc(struct metadata_cmd_context); + ctx->ctx.v.init = cmd_mailbox_metadata_unset_init; + ctx->ctx.v.run = cmd_mailbox_metadata_set_run; + return &ctx->ctx; +} + +static int +cmd_mailbox_metadata_get_run(struct doveadm_mail_cmd_context *_ctx, + struct mail_user *user) +{ + struct metadata_cmd_context *ctx = (struct metadata_cmd_context *)_ctx; + struct mail_namespace *ns; + struct mailbox *box; + struct mailbox_transaction_context *trans; + struct mail_attribute_value value; + int ret; + + ns = mail_namespace_find(user->namespaces, ctx->mailbox); + box = mailbox_alloc(ns->list, ctx->mailbox, 0); + + if (mailbox_open(box) < 0) { + i_error("Failed to open mailbox: %s", + mailbox_get_last_error(box, NULL)); + mailbox_free(&box); + return -1; + } + trans = mailbox_transaction_begin(box, 0); + + ret = mailbox_attribute_get_stream(trans, ctx->key_type, ctx->key, &value); + if (ret < 0) { + i_error("Failed to get attribute: %s", + mailbox_get_last_error(box, NULL)); + } else if (ret == 0) { + /* not found, print as empty */ + doveadm_print(""); + } else if (value.value_stream != NULL) { + doveadm_print_istream(value.value_stream); + } else { + doveadm_print(value.value); + } + + (void)mailbox_transaction_commit(&trans); + mailbox_free(&box); + return ret; +} + +static void +cmd_mailbox_metadata_get_init(struct doveadm_mail_cmd_context *_ctx, + const char *const args[]) +{ + struct metadata_cmd_context *ctx = (struct metadata_cmd_context *)_ctx; + const char *key; + + if (str_array_length(args) != 2) + doveadm_mail_help_name("mailbox metadata get"); + cmd_mailbox_metadata_parse_key(args[1], &ctx->key_type, &key); + + ctx->mailbox = p_strdup(_ctx->pool, args[0]); + ctx->key = p_strdup(_ctx->pool, key); + doveadm_print_header("value", "value", + DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE); +} + +static struct doveadm_mail_cmd_context *cmd_mailbox_metadata_get_alloc(void) +{ + struct metadata_cmd_context *ctx; + + ctx = doveadm_mail_cmd_alloc(struct metadata_cmd_context); + ctx->ctx.v.init = cmd_mailbox_metadata_get_init; + ctx->ctx.v.run = cmd_mailbox_metadata_get_run; + doveadm_print_init(DOVEADM_PRINT_TYPE_FLOW); + return &ctx->ctx; +} + +static int +cmd_mailbox_metadata_list_run_iter(struct metadata_cmd_context *ctx, + struct mailbox *box, + enum mail_attribute_type type) +{ + struct mailbox_attribute_iter *iter; + const char *key; + + iter = mailbox_attribute_iter_init(box, type, ctx->key); + while ((key = mailbox_attribute_iter_next(iter)) != NULL) + doveadm_print(key); + return mailbox_attribute_iter_deinit(&iter); +} + +static int +cmd_mailbox_metadata_list_run(struct doveadm_mail_cmd_context *_ctx, + struct mail_user *user) +{ + struct metadata_cmd_context *ctx = (struct metadata_cmd_context *)_ctx; + struct mail_namespace *ns; + struct mailbox *box; + int ret = 0; + + ns = mail_namespace_find(user->namespaces, ctx->mailbox); + box = mailbox_alloc(ns->list, ctx->mailbox, 0); + + if (mailbox_open(box) < 0) { + i_error("Failed to open mailbox: %s", + mailbox_get_last_error(box, NULL)); + mailbox_free(&box); + return -1; + } + + if (ctx->key == NULL || ctx->key_type == MAIL_ATTRIBUTE_TYPE_PRIVATE) { + if (cmd_mailbox_metadata_list_run_iter(ctx, box, MAIL_ATTRIBUTE_TYPE_PRIVATE) < 0) + ret = -1; + } + if (ctx->key == NULL || ctx->key_type == MAIL_ATTRIBUTE_TYPE_SHARED) { + if (cmd_mailbox_metadata_list_run_iter(ctx, box, MAIL_ATTRIBUTE_TYPE_SHARED) < 0) + ret = -1; + } + mailbox_free(&box); + return ret; +} + +static void +cmd_mailbox_metadata_list_init(struct doveadm_mail_cmd_context *_ctx, + const char *const args[]) +{ + struct metadata_cmd_context *ctx = (struct metadata_cmd_context *)_ctx; + const char *key; + + if (args[0] == NULL) + doveadm_mail_help_name("mailbox metadata list"); + if (args[1] != NULL) + cmd_mailbox_metadata_parse_key(args[1], &ctx->key_type, &key); + ctx->mailbox = p_strdup(_ctx->pool, args[0]); + doveadm_print_header("key", "key", + DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE); +} + +static struct doveadm_mail_cmd_context *cmd_mailbox_metadata_list_alloc(void) +{ + struct metadata_cmd_context *ctx; + + ctx = doveadm_mail_cmd_alloc(struct metadata_cmd_context); + ctx->ctx.v.init = cmd_mailbox_metadata_list_init; + ctx->ctx.v.run = cmd_mailbox_metadata_list_run; + doveadm_print_init(DOVEADM_PRINT_TYPE_FLOW); + return &ctx->ctx; +} + +struct doveadm_mail_cmd cmd_mailbox_metadata_set = { + cmd_mailbox_metadata_set_alloc, "mailbox metadata set", + " " +}; + +struct doveadm_mail_cmd cmd_mailbox_metadata_unset = { + cmd_mailbox_metadata_unset_alloc, "mailbox metadata unset", + " " +}; + +struct doveadm_mail_cmd cmd_mailbox_metadata_get = { + cmd_mailbox_metadata_get_alloc, "mailbox metadata get", + " " +}; + From dovecot at dovecot.org Fri Oct 24 00:55:15 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Oct 2014 00:55:15 +0000 Subject: dovecot-2.2: login proxy: If proxy_timeout is set, try to reconn... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/52ad54b23e24 changeset: 17991:52ad54b23e24 user: Timo Sirainen date: Fri Oct 24 03:54:21 2014 +0300 description: login proxy: If proxy_timeout is set, try to reconnect until the timeout is reached. This allows quickly restarting/upgrading backend servers without returning login failures. diffstat: src/login-common/login-proxy.c | 82 +++++++++++++++++++++++++++++++---------- 1 files changed, 61 insertions(+), 21 deletions(-) diffs (153 lines): diff -r 4fe5b4e121a4 -r 52ad54b23e24 src/login-common/login-proxy.c --- a/src/login-common/login-proxy.c Thu Oct 23 06:38:20 2014 +0300 +++ b/src/login-common/login-proxy.c Fri Oct 24 03:54:21 2014 +0300 @@ -23,6 +23,7 @@ #define LOGIN_PROXY_IPC_NAME "proxy" #define KILLED_BY_ADMIN_REASON "Killed by admin" #define PROXY_IMMEDIATE_FAILURE_SECS 30 +#define PROXY_CONNECT_RETRY_MSECS 1000 struct login_proxy { struct login_proxy *prev, *next; @@ -44,6 +45,7 @@ unsigned int port; unsigned int connect_timeout_msecs; unsigned int notify_refresh_secs; + unsigned int reconnect_count; enum login_proxy_ssl_flags ssl_flags; proxy_callback_t *callback; @@ -58,6 +60,8 @@ static struct login_proxy *login_proxies_pending = NULL; static struct ipc_server *login_proxy_ipc_server; +static int login_proxy_connect(struct login_proxy *proxy); +static void login_proxy_disconnect(struct login_proxy *proxy); static void login_proxy_ipc_cmd(struct ipc_cmd *cmd, const char *line); static void @@ -224,6 +228,8 @@ } str_printfa(str, " (after %u secs", (unsigned int)(ioloop_time - proxy->created.tv_sec)); + if (proxy->reconnect_count > 0) + str_printfa(str, ", %u reconnects", proxy->reconnect_count); if (proxy->server_fd != -1 && net_getsockname(proxy->server_fd, &local_ip, &local_port) == 0) { @@ -238,13 +244,40 @@ i_error("%s", str_c(str)); } +static void proxy_reconnect_timeout(struct login_proxy *proxy) +{ + timeout_remove(&proxy->to); + (void)login_proxy_connect(proxy); +} + +static bool proxy_try_reconnect(struct login_proxy *proxy) +{ + int since_started_msecs, left_msecs; + + since_started_msecs = + timeval_diff_msecs(&ioloop_timeval, &proxy->created); + if (since_started_msecs < 0) + return FALSE; /* time moved backwards */ + left_msecs = proxy->connect_timeout_msecs - since_started_msecs; + if (left_msecs <= 0) + return FALSE; + + login_proxy_disconnect(proxy); + proxy->to = timeout_add(I_MIN(PROXY_CONNECT_RETRY_MSECS, left_msecs), + proxy_reconnect_timeout, proxy); + proxy->reconnect_count++; + return TRUE; +} + static void proxy_wait_connect(struct login_proxy *proxy) { errno = net_geterror(proxy->server_fd); if (errno != 0) { - proxy_log_connect_error(proxy); proxy_fail_connect(proxy); - login_proxy_free(&proxy); + if (!proxy_try_reconnect(proxy)) { + proxy_log_connect_error(proxy); + login_proxy_free(&proxy); + } return; } proxy->connected = TRUE; @@ -278,6 +311,11 @@ struct login_proxy_record *rec; rec = login_proxy_state_get(proxy_state, &proxy->ip, proxy->port); + if (rec->last_success.tv_sec == 0) { + /* first connect to this IP. don't start immediately failing + the check below. */ + rec->last_success.tv_sec = ioloop_timeval.tv_sec - 1; + } if (timeval_cmp(&rec->last_failure, &rec->last_success) > 0 && rec->last_failure.tv_sec - rec->last_success.tv_sec > PROXY_IMMEDIATE_FAILURE_SECS && rec->num_waiting_connections != 0) { @@ -358,6 +396,26 @@ return 0; } +static void login_proxy_disconnect(struct login_proxy *proxy) +{ + if (proxy->to != NULL) + timeout_remove(&proxy->to); + if (proxy->to_notify != NULL) + timeout_remove(&proxy->to_notify); + + if (proxy->state_rec != NULL) + proxy->state_rec->num_waiting_connections--; + + if (proxy->server_io != NULL) + io_remove(&proxy->server_io); + if (proxy->server_input != NULL) + i_stream_destroy(&proxy->server_input); + if (proxy->server_output != NULL) + o_stream_destroy(&proxy->server_output); + if (proxy->server_fd != -1) + net_disconnect(proxy->server_fd); +} + static void ATTR_NULL(2) login_proxy_free_reason(struct login_proxy **_proxy, const char *reason) { @@ -371,22 +429,7 @@ return; proxy->destroying = TRUE; - if (proxy->to != NULL) - timeout_remove(&proxy->to); - if (proxy->to_notify != NULL) - timeout_remove(&proxy->to_notify); - - if (proxy->state_rec != NULL) - proxy->state_rec->num_waiting_connections--; - if (proxy->to != NULL) - timeout_remove(&proxy->to); - - if (proxy->server_io != NULL) - io_remove(&proxy->server_io); - if (proxy->server_input != NULL) - i_stream_destroy(&proxy->server_input); - if (proxy->server_output != NULL) - o_stream_destroy(&proxy->server_output); + login_proxy_disconnect(proxy); if (proxy->client_fd != -1) { /* detached proxy */ @@ -414,9 +457,6 @@ proxy->callback(proxy->client); } - if (proxy->server_fd != -1) - net_disconnect(proxy->server_fd); - if (proxy->ssl_server_proxy != NULL) ssl_proxy_free(&proxy->ssl_server_proxy); i_free(proxy->host); From dovecot at dovecot.org Fri Oct 24 00:59:29 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Oct 2014 00:59:29 +0000 Subject: dovecot-2.2: dsync: Removed in/out state from debugging. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2c8d458f120f changeset: 17992:2c8d458f120f user: Timo Sirainen date: Fri Oct 24 03:58:35 2014 +0300 description: dsync: Removed in/out state from debugging. This was initially added for debugging hangs, but those haven't existed for a long time now. Maybe we should eventually make debug categories configurable, but for now nobody wants to see these messages. diffstat: src/doveadm/dsync/dsync-brain-mails.c | 14 -------------- src/doveadm/dsync/dsync-brain.c | 9 --------- 2 files changed, 0 insertions(+), 23 deletions(-) diffs (56 lines): diff -r 52ad54b23e24 -r 2c8d458f120f src/doveadm/dsync/dsync-brain-mails.c --- a/src/doveadm/dsync/dsync-brain-mails.c Fri Oct 24 03:54:21 2014 +0300 +++ b/src/doveadm/dsync/dsync-brain-mails.c Fri Oct 24 03:58:35 2014 +0300 @@ -315,13 +315,6 @@ i_assert(brain->box != NULL); - if (brain->debug) { - i_debug("brain %c: in box '%s' recv_state=%s send_state=%s", - brain->master_brain ? 'M' : 'S', - mailbox_get_vname(brain->box), - dsync_box_state_names[brain->box_recv_state], - dsync_box_state_names[brain->box_send_state]); - } switch (brain->box_recv_state) { case DSYNC_BOX_STATE_MAILBOX: changed = dsync_brain_master_sync_recv_mailbox(brain); @@ -372,12 +365,5 @@ break; } } - if (brain->debug) { - i_debug("brain %c: out box '%s' recv_state=%s send_state=%s changed=%d", - brain->master_brain ? 'M' : 'S', - brain->box == NULL ? "" : mailbox_get_vname(brain->box), - dsync_box_state_names[brain->box_recv_state], - dsync_box_state_names[brain->box_send_state], changed); - } return changed; } diff -r 52ad54b23e24 -r 2c8d458f120f src/doveadm/dsync/dsync-brain.c --- a/src/doveadm/dsync/dsync-brain.c Fri Oct 24 03:54:21 2014 +0300 +++ b/src/doveadm/dsync/dsync-brain.c Fri Oct 24 03:58:35 2014 +0300 @@ -539,10 +539,6 @@ if (brain->failed) return FALSE; - if (brain->debug) { - i_debug("brain %c: in state=%s", brain->master_brain ? 'M' : 'S', - dsync_state_names[brain->state]); - } switch (brain->state) { case DSYNC_STATE_MASTER_RECV_HANDSHAKE: changed = dsync_brain_master_recv_handshake(brain); @@ -586,11 +582,6 @@ ret = FALSE; break; } - if (brain->debug) { - i_debug("brain %c: out state=%s changed=%d", - brain->master_brain ? 'M' : 'S', - dsync_state_names[brain->state], changed); - } if (brain->verbose_proctitle) { if (orig_state != brain->state || orig_box_recv_state != brain->box_recv_state || From dovecot at dovecot.org Fri Oct 24 01:25:35 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Oct 2014 01:25:35 +0000 Subject: dovecot-2.2: dsync: Added some debugging output for mailbox trees. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3dda0b301c20 changeset: 17993:3dda0b301c20 user: Timo Sirainen date: Fri Oct 24 04:24:40 2014 +0300 description: dsync: Added some debugging output for mailbox trees. diffstat: src/doveadm/dsync/dsync-brain-mailbox-tree.c | 50 +++++++++++++++++++++++---- src/doveadm/dsync/dsync-mailbox-tree.c | 24 +++++++++++++ src/doveadm/dsync/dsync-mailbox-tree.h | 4 ++ 3 files changed, 70 insertions(+), 8 deletions(-) diffs (195 lines): diff -r 2c8d458f120f -r 3dda0b301c20 src/doveadm/dsync/dsync-brain-mailbox-tree.c --- a/src/doveadm/dsync/dsync-brain-mailbox-tree.c Fri Oct 24 03:58:35 2014 +0300 +++ b/src/doveadm/dsync/dsync-brain-mailbox-tree.c Fri Oct 24 04:24:40 2014 +0300 @@ -66,6 +66,7 @@ dsync_mailbox_tree_iter_init(brain->local_mailbox_tree); } + void dsync_brain_send_mailbox_tree(struct dsync_brain *brain) { struct dsync_mailbox_node *node; @@ -79,6 +80,12 @@ T_BEGIN { const char *const *parts; + if (brain->debug) { + i_debug("brain %c: Local mailbox tree: %s %s", + brain->master_brain ? 'M' : 'S', full_name, + dsync_mailbox_node_to_string(node)); + } + parts = t_strsplit(full_name, sep); ret = dsync_ibc_send_mailbox_tree_node(brain->ibc, parts, node); @@ -301,15 +308,21 @@ char sep[2]; bool changed = FALSE; + sep[0] = brain->hierarchy_sep; sep[1] = '\0'; while ((ret = dsync_ibc_recv_mailbox_tree_node(brain->ibc, &parts, &remote_node)) > 0) { if (dsync_get_mailbox_name(brain, parts, &name, &ns) < 0) { - sep[0] = brain->hierarchy_sep; sep[1] = '\0'; i_error("Couldn't find namespace for mailbox %s", t_strarray_join(parts, sep)); brain->failed = TRUE; return TRUE; } + if (brain->debug) { + i_debug("brain %c: Remote mailbox tree: %s %s", + brain->master_brain ? 'M' : 'S', + t_strarray_join(parts, sep), + dsync_mailbox_node_to_string(remote_node)); + } node = dsync_mailbox_tree_get(brain->remote_mailbox_tree, name); node->ns = ns; dsync_mailbox_node_copy_data(node, remote_node); @@ -335,7 +348,9 @@ static void dsync_brain_mailbox_tree_add_delete(struct dsync_mailbox_tree *tree, struct dsync_mailbox_tree *other_tree, - const struct dsync_mailbox_delete *other_del) + const struct dsync_mailbox_delete *other_del, + const struct dsync_mailbox_node **node_r, + const char **status_r) { const struct dsync_mailbox_node *node; struct dsync_mailbox_node *other_node, *old_node; @@ -343,9 +358,11 @@ /* see if we can find the deletion based on mailbox tree that should still have the mailbox */ - node = dsync_mailbox_tree_find_delete(tree, other_del); - if (node == NULL) + node = *node_r = dsync_mailbox_tree_find_delete(tree, other_del); + if (node == NULL) { + *status_r = "not found"; return; + } switch (other_del->type) { case DSYNC_MAILBOX_DELETE_TYPE_MAILBOX: @@ -355,6 +372,7 @@ if (other_del->timestamp <= node->last_renamed_or_created) { /* we don't want to delete this directory, we already have a newer timestamp for it */ + *status_r = "keep directory, we have a newer timestamp"; return; } break; @@ -362,6 +380,7 @@ if (other_del->timestamp <= node->last_subscription_change) { /* we don't want to unsubscribe, since we already have a newer subscription timestamp */ + *status_r = "keep subscription, we have a newer timestamp"; return; } break; @@ -376,6 +395,7 @@ other_del->type != DSYNC_MAILBOX_DELETE_TYPE_MAILBOX)) { /* other side has already created a new mailbox or directory with this name, we can't delete it */ + *status_r = "name has already been recreated"; return; } @@ -390,14 +410,17 @@ possible that one side has created mailboxes that conflict with another namespace's prefix. since we're here because one of the mailboxes was deleted, we'll just ignore this. */ + *status_r = "namespace mismatch"; return; } other_node->ns = node->ns; - if (other_del->type != DSYNC_MAILBOX_DELETE_TYPE_UNSUBSCRIBE) + if (other_del->type != DSYNC_MAILBOX_DELETE_TYPE_UNSUBSCRIBE) { other_node->existence = DSYNC_MAILBOX_NODE_DELETED; - else { + *status_r = "marked as deleted"; + } else { other_node->last_subscription_change = other_del->timestamp; other_node->subscribed = FALSE; + *status_r = "marked as unsubscribed"; } if (dsync_mailbox_tree_guid_hash_add(other_tree, other_node, @@ -407,6 +430,8 @@ bool dsync_brain_recv_mailbox_tree_deletes(struct dsync_brain *brain) { + const struct dsync_mailbox_node *node; + const char *status; const struct dsync_mailbox_delete *deletes; unsigned int i, count; char sep; @@ -420,7 +445,16 @@ for (i = 0; i < count; i++) { dsync_brain_mailbox_tree_add_delete(brain->local_mailbox_tree, brain->remote_mailbox_tree, - &deletes[i]); + &deletes[i], &node, &status); + if (brain->debug) { + const char *node_name = node == NULL ? "" : + dsync_mailbox_node_get_full_name(brain->local_mailbox_tree, node); + i_debug("brain %c: Remote mailbox tree deletion: guid=%s type=%s timestamp=%ld name=%s local update=%s", + brain->master_brain ? 'M' : 'S', + guid_128_to_string(deletes[i].guid), + dsync_mailbox_delete_type_to_string(deletes[i].type), + deletes[i].timestamp, node_name, status); + } } /* apply local mailbox deletions based on remote tree */ @@ -431,7 +465,7 @@ for (i = 0; i < count; i++) { dsync_brain_mailbox_tree_add_delete(brain->remote_mailbox_tree, brain->local_mailbox_tree, - &deletes[i]); + &deletes[i], &node, &status); } dsync_brain_mailbox_trees_sync(brain); diff -r 2c8d458f120f -r 3dda0b301c20 src/doveadm/dsync/dsync-mailbox-tree.c --- a/src/doveadm/dsync/dsync-mailbox-tree.c Fri Oct 24 03:58:35 2014 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-tree.c Fri Oct 24 04:24:40 2014 +0300 @@ -494,3 +494,27 @@ } T_END; return ret; } + +const char *dsync_mailbox_node_to_string(const struct dsync_mailbox_node *node) +{ + return t_strdup_printf("guid=%s uid_validity=%u uid_next=%u subs=%s last_change=%ld last_subs=%ld", + guid_128_to_string(node->mailbox_guid), + node->uid_validity, node->uid_next, + node->subscribed ? "yes" : "no", + (long)node->last_renamed_or_created, + (long)node->last_subscription_change); +} + +const char * +dsync_mailbox_delete_type_to_string(enum dsync_mailbox_delete_type type) +{ + switch (type) { + case DSYNC_MAILBOX_DELETE_TYPE_MAILBOX: + return "mailbox"; + case DSYNC_MAILBOX_DELETE_TYPE_DIR: + return "dir"; + case DSYNC_MAILBOX_DELETE_TYPE_UNSUBSCRIBE: + return "unsubscribe"; + } + return t_strdup_printf("unknown #%u", type); +} diff -r 2c8d458f120f -r 3dda0b301c20 src/doveadm/dsync/dsync-mailbox-tree.h --- a/src/doveadm/dsync/dsync-mailbox-tree.h Fri Oct 24 03:58:35 2014 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-tree.h Fri Oct 24 04:24:40 2014 +0300 @@ -188,4 +188,8 @@ dsync_mailbox_trees_sync_next(struct dsync_mailbox_tree_sync_ctx *ctx); void dsync_mailbox_trees_sync_deinit(struct dsync_mailbox_tree_sync_ctx **ctx); +const char *dsync_mailbox_node_to_string(const struct dsync_mailbox_node *node); +const char * +dsync_mailbox_delete_type_to_string(enum dsync_mailbox_delete_type type); + #endif From dovecot at dovecot.org Fri Oct 24 19:11:21 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Oct 2014 19:11:21 +0000 Subject: dovecot-2.2: lib: Added "istream-seekable: " error message prefi... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/277dd641c533 changeset: 17994:277dd641c533 user: Timo Sirainen date: Fri Oct 24 22:10:25 2014 +0300 description: lib: Added "istream-seekable: " error message prefixes. diffstat: src/lib/istream-seekable.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) diffs (47 lines): diff -r 3dda0b301c20 -r 277dd641c533 src/lib/istream-seekable.c --- a/src/lib/istream-seekable.c Fri Oct 24 04:24:40 2014 +0300 +++ b/src/lib/istream-seekable.c Fri Oct 24 22:10:25 2014 +0300 @@ -95,7 +95,7 @@ /* copy our currently read buffer to it */ if (write_full(fd, sstream->membuf->data, sstream->membuf->used) < 0) { if (!ENOSPACE(errno)) - i_error("write_full(%s) failed: %m", path); + i_error("istream-seekable: write_full(%s) failed: %m", path); i_close_fd(&fd); return -1; } @@ -217,7 +217,7 @@ data = buffer_append_space_unsafe(sstream->membuf, sstream->write_peak); if (pread_full(sstream->fd, data, sstream->write_peak, 0) < 0) { - i_error("read(%s) failed: %m", sstream->temp_path); + i_error("istream-seekable: read(%s) failed: %m", sstream->temp_path); buffer_free(&sstream->membuf); return -1; } @@ -266,7 +266,7 @@ ret = write(sstream->fd, data, size); if (ret <= 0) { if (ret < 0 && !ENOSPACE(errno)) { - i_error("write_full(%s) failed: %m", + i_error("istream-seekable: write_full(%s) failed: %m", sstream->temp_path); } if (i_stream_seekable_write_failed(sstream) < 0) @@ -448,14 +448,14 @@ str_append(path, temp_path_prefix); fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1); if (fd == -1) { - i_error("safe_mkstemp(%s) failed: %m", str_c(path)); + i_error("istream-seekable: safe_mkstemp(%s) failed: %m", str_c(path)); return -1; } /* we just want the fd, unlink it */ if (unlink(str_c(path)) < 0) { /* shouldn't happen.. */ - i_error("unlink(%s) failed: %m", str_c(path)); + i_error("istream-seekable: unlink(%s) failed: %m", str_c(path)); i_close_fd(&fd); return -1; } From dovecot at dovecot.org Fri Oct 24 19:19:30 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Oct 2014 19:19:30 +0000 Subject: dovecot-2.2: lib-storage: Added data stack frames for most calls. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ce4ec584e756 changeset: 17995:ce4ec584e756 user: Timo Sirainen date: Fri Oct 24 22:11:50 2014 +0300 description: lib-storage: Added data stack frames for most calls. So neither the callers nor the implementations need to worry about those so much. diffstat: src/lib-storage/mail-storage.c | 27 +++++++++++--- src/lib-storage/mail.c | 76 ++++++++++++++++++++++++++++++++++------- 2 files changed, 83 insertions(+), 20 deletions(-) diffs (241 lines): diff -r 277dd641c533 -r ce4ec584e756 src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Fri Oct 24 22:10:25 2014 +0300 +++ b/src/lib-storage/mail-storage.c Fri Oct 24 22:11:50 2014 +0300 @@ -1952,7 +1952,9 @@ { struct mail_save_context *ctx; - ctx = t->box->v.save_alloc(t); + T_BEGIN { + ctx = t->box->v.save_alloc(t); + } T_END; i_assert(!ctx->unfinished); ctx->unfinished = TRUE; ctx->data.received_date = (time_t)-1; @@ -2069,9 +2071,9 @@ mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE, "Saving messages not supported"); ret = -1; - } else { + } else T_BEGIN { ret = box->v.save_begin(*ctx, input); - } + } T_END; if (ret < 0) { mailbox_save_cancel(ctx); @@ -2082,7 +2084,12 @@ int mailbox_save_continue(struct mail_save_context *ctx) { - return ctx->transaction->box->v.save_continue(ctx); + int ret; + + T_BEGIN { + ret = ctx->transaction->box->v.save_continue(ctx); + } T_END; + return ret; } static void @@ -2119,7 +2126,9 @@ *_ctx = NULL; ctx->finishing = TRUE; - ret = t->box->v.save_finish(ctx); + T_BEGIN { + ret = t->box->v.save_finish(ctx); + } T_END; ctx->finishing = FALSE; if (ret == 0 && !copying_via_save) { @@ -2141,7 +2150,9 @@ struct mail_private *mail; *_ctx = NULL; - ctx->transaction->box->v.save_cancel(ctx); + T_BEGIN { + ctx->transaction->box->v.save_cancel(ctx); + } T_END; if (keywords != NULL && !ctx->finishing) mailbox_keywords_unref(&keywords); if (ctx->dest_mail != NULL) { @@ -2185,7 +2196,9 @@ return -1; } ctx->finishing = TRUE; - ret = t->box->v.copy(ctx, backend_mail); + T_BEGIN { + ret = t->box->v.copy(ctx, backend_mail); + } T_END; ctx->finishing = FALSE; if (ret == 0) { if (pvt_flags != 0) diff -r 277dd641c533 -r ce4ec584e756 src/lib-storage/mail.c --- a/src/lib-storage/mail.c Fri Oct 24 22:10:25 2014 +0300 +++ b/src/lib-storage/mail.c Fri Oct 24 22:11:50 2014 +0300 @@ -59,8 +59,12 @@ bool mail_prefetch(struct mail *mail) { struct mail_private *p = (struct mail_private *)mail; + bool ret; - return p->v.prefetch(mail); + T_BEGIN { + ret = p->v.prefetch(mail); + } T_END; + return ret; } void mail_add_temp_wanted_fields(struct mail *mail, @@ -110,75 +114,115 @@ int mail_get_parts(struct mail *mail, struct message_part **parts_r) { struct mail_private *p = (struct mail_private *)mail; + int ret; - return p->v.get_parts(mail, parts_r); + T_BEGIN { + ret = p->v.get_parts(mail, parts_r); + } T_END; + return ret; } int mail_get_date(struct mail *mail, time_t *date_r, int *timezone_r) { struct mail_private *p = (struct mail_private *)mail; + int ret; - return p->v.get_date(mail, date_r, timezone_r); + T_BEGIN { + ret = p->v.get_date(mail, date_r, timezone_r); + } T_END; + return ret; } int mail_get_received_date(struct mail *mail, time_t *date_r) { struct mail_private *p = (struct mail_private *)mail; + int ret; - return p->v.get_received_date(mail, date_r); + T_BEGIN { + ret = p->v.get_received_date(mail, date_r); + } T_END; + return ret; } int mail_get_save_date(struct mail *mail, time_t *date_r) { struct mail_private *p = (struct mail_private *)mail; + int ret; - return p->v.get_save_date(mail, date_r); + T_BEGIN { + ret = p->v.get_save_date(mail, date_r); + } T_END; + return ret; } int mail_get_virtual_size(struct mail *mail, uoff_t *size_r) { struct mail_private *p = (struct mail_private *)mail; + int ret; - return p->v.get_virtual_size(mail, size_r); + T_BEGIN { + ret = p->v.get_virtual_size(mail, size_r); + } T_END; + return ret; } int mail_get_physical_size(struct mail *mail, uoff_t *size_r) { struct mail_private *p = (struct mail_private *)mail; + int ret; - return p->v.get_physical_size(mail, size_r); + T_BEGIN { + ret = p->v.get_physical_size(mail, size_r); + } T_END; + return ret; } int mail_get_first_header(struct mail *mail, const char *field, const char **value_r) { struct mail_private *p = (struct mail_private *)mail; + int ret; - return p->v.get_first_header(mail, field, FALSE, value_r); + T_BEGIN { + ret = p->v.get_first_header(mail, field, FALSE, value_r); + } T_END; + return ret; } int mail_get_first_header_utf8(struct mail *mail, const char *field, const char **value_r) { struct mail_private *p = (struct mail_private *)mail; + int ret; - return p->v.get_first_header(mail, field, TRUE, value_r); + T_BEGIN { + ret = p->v.get_first_header(mail, field, TRUE, value_r); + } T_END; + return ret; } int mail_get_headers(struct mail *mail, const char *field, const char *const **value_r) { struct mail_private *p = (struct mail_private *)mail; + int ret; - return p->v.get_headers(mail, field, FALSE, value_r); + T_BEGIN { + ret = p->v.get_headers(mail, field, FALSE, value_r); + } T_END; + return ret; } int mail_get_headers_utf8(struct mail *mail, const char *field, const char *const **value_r) { struct mail_private *p = (struct mail_private *)mail; + int ret; - return p->v.get_headers(mail, field, TRUE, value_r); + T_BEGIN { + ret = p->v.get_headers(mail, field, TRUE, value_r); + } T_END; + return ret; } int mail_get_header_stream(struct mail *mail, @@ -186,8 +230,12 @@ struct istream **stream_r) { struct mail_private *p = (struct mail_private *)mail; + int ret; - return p->v.get_header_stream(mail, headers, stream_r); + T_BEGIN { + ret = p->v.get_header_stream(mail, headers, stream_r); + } T_END; + return ret; } void mail_set_aborted(struct mail *mail) @@ -333,7 +381,9 @@ { struct mail_private *p = (struct mail_private *)mail; - p->v.expunge(mail); + T_BEGIN { + p->v.expunge(mail); + } T_END; } void mail_set_expunged(struct mail *mail) From dovecot at dovecot.org Fri Oct 24 19:19:31 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Oct 2014 19:19:31 +0000 Subject: dovecot-2.2: Use i_stream_get_error() wherever possible instead ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7681fcd1ba43 changeset: 17996:7681fcd1ba43 user: Timo Sirainen date: Fri Oct 24 22:18:29 2014 +0300 description: Use i_stream_get_error() wherever possible instead of %m diffstat: src/director/notify-connection.c | 3 ++- src/lib-imap-storage/imap-msgpart.c | 3 ++- src/lib-settings/settings-parser.c | 3 ++- src/lib-storage/index/index-search.c | 7 +++++-- src/lib-storage/index/mbox/mbox-save.c | 3 ++- src/lib-storage/mail-copy.c | 3 ++- src/lib-storage/mail-storage.c | 5 +++-- src/plugins/fts/fts-indexer.c | 4 +++- src/plugins/fts/fts-parser-script.c | 3 ++- 9 files changed, 23 insertions(+), 11 deletions(-) diffs (131 lines): diff -r ce4ec584e756 -r 7681fcd1ba43 src/director/notify-connection.c --- a/src/director/notify-connection.c Fri Oct 24 22:11:50 2014 +0300 +++ b/src/director/notify-connection.c Fri Oct 24 22:18:29 2014 +0300 @@ -42,7 +42,8 @@ i_error("notify: read() unexpectedly returned EOF"); notify_connection_deinit(&conn); } else if (conn->input->stream_errno != 0) { - i_error("notify: read() failed: %m"); + i_error("notify: read() failed: %s", + i_stream_get_error(conn->input)); notify_connection_deinit(&conn); } } diff -r ce4ec584e756 -r 7681fcd1ba43 src/lib-imap-storage/imap-msgpart.c --- a/src/lib-imap-storage/imap-msgpart.c Fri Oct 24 22:11:50 2014 +0300 +++ b/src/lib-imap-storage/imap-msgpart.c Fri Oct 24 22:18:29 2014 +0300 @@ -365,7 +365,8 @@ if (message_get_header_size(input, &hdr_size, &has_nuls) < 0) { errno = input->stream_errno; mail_storage_set_critical(mail->box->storage, - "read(%s) failed: %m", i_stream_get_name(mail_input)); + "read(%s) failed: %s", i_stream_get_name(mail_input), + i_stream_get_error(mail_input)); i_stream_unref(&input); return -1; } diff -r ce4ec584e756 -r 7681fcd1ba43 src/lib-settings/settings-parser.c --- a/src/lib-settings/settings-parser.c Fri Oct 24 22:11:50 2014 +0300 +++ b/src/lib-settings/settings-parser.c Fri Oct 24 22:18:29 2014 +0300 @@ -962,7 +962,8 @@ break; if (input->stream_errno != 0) { ctx->error = p_strdup_printf(ctx->parser_pool, - "read() failed: %m"); + "read(%s) failed: %s", i_stream_get_name(input), + i_stream_get_error(input)); } else if (input->v_offset == 0) { ctx->error = p_strdup_printf(ctx->parser_pool, "read(%s) disconnected before receiving any data", diff -r ce4ec584e756 -r 7681fcd1ba43 src/lib-storage/index/index-search.c --- a/src/lib-storage/index/index-search.c Fri Oct 24 22:11:50 2014 +0300 +++ b/src/lib-storage/index/index-search.c Fri Oct 24 22:18:29 2014 +0300 @@ -646,7 +646,8 @@ } if (ctx->input->stream_errno != 0) { mail_storage_set_critical(ctx->index_ctx->box->storage, - "read(%s) failed: %m", i_stream_get_name(ctx->input)); + "read(%s) failed: %s", i_stream_get_name(ctx->input), + i_stream_get_error(ctx->input)); } ARG_SET_RESULT(arg, ret); @@ -716,7 +717,9 @@ search_header, &hdr_ctx); if (input->stream_errno != 0) { mail_storage_set_critical(ctx->box->storage, - "read(%s) failed: %m", i_stream_get_name(input)); + "read(%s) failed: %s", + i_stream_get_name(input), + i_stream_get_error(input)); failed = TRUE; } } diff -r ce4ec584e756 -r 7681fcd1ba43 src/lib-storage/index/mbox/mbox-save.c --- a/src/lib-storage/index/mbox/mbox-save.c Fri Oct 24 22:11:50 2014 +0300 +++ b/src/lib-storage/index/mbox/mbox-save.c Fri Oct 24 22:18:29 2014 +0300 @@ -635,7 +635,8 @@ if (ret == 0) return 0; if (ctx->input->stream_errno != 0) { - i_error("read(%s) failed: %m", i_stream_get_name(ctx->input)); + i_error("read(%s) failed: %s", i_stream_get_name(ctx->input), + i_stream_get_error(ctx->input)); ctx->failed = TRUE; return -1; } diff -r ce4ec584e756 -r 7681fcd1ba43 src/lib-storage/mail-copy.c --- a/src/lib-storage/mail-copy.c Fri Oct 24 22:11:50 2014 +0300 +++ b/src/lib-storage/mail-copy.c Fri Oct 24 22:18:29 2014 +0300 @@ -83,7 +83,8 @@ if (input->stream_errno != 0) { mail_storage_set_critical(ctx->transaction->box->storage, - "copy: i_stream_read() failed: %m"); + "copy: i_stream_read(%s) failed: %s", + i_stream_get_name(input), i_stream_get_error(input)); return -1; } return 0; diff -r ce4ec584e756 -r 7681fcd1ba43 src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Fri Oct 24 22:11:50 2014 +0300 +++ b/src/lib-storage/mail-storage.c Fri Oct 24 22:18:29 2014 +0300 @@ -1644,8 +1644,9 @@ i_stream_skip(value->value_stream, size); } if (value->value_stream->stream_errno != 0) { - mail_storage_set_critical(storage, "read(%s) failed: %m", - i_stream_get_name(value->value_stream)); + mail_storage_set_critical(storage, "read(%s) failed: %s", + i_stream_get_name(value->value_stream), + i_stream_get_error(value->value_stream)); return -1; } i_assert(value->value_stream->eof); diff -r ce4ec584e756 -r 7681fcd1ba43 src/plugins/fts/fts-indexer.c --- a/src/plugins/fts/fts-indexer.c Fri Oct 24 22:11:50 2014 +0300 +++ b/src/plugins/fts/fts-indexer.c Fri Oct 24 22:18:29 2014 +0300 @@ -192,7 +192,9 @@ } } if (ctx->input->stream_errno != 0) { - i_error("indexer read() failed: %m"); + i_error("indexer read(%s) failed: %s", + i_stream_get_name(ctx->input), + i_stream_get_error(ctx->input)); return -1; } if (ctx->input->eof) { diff -r ce4ec584e756 -r 7681fcd1ba43 src/plugins/fts/fts-parser-script.c --- a/src/plugins/fts/fts-parser-script.c Fri Oct 24 22:11:50 2014 +0300 +++ b/src/plugins/fts/fts-parser-script.c Fri Oct 24 22:18:29 2014 +0300 @@ -100,7 +100,8 @@ content->extensions = (const void *)(args+1); } if (input->stream_errno != 0) { - i_error("parser script read() failed: %m"); + i_error("parser script read(%s) failed: %s", path, + i_stream_get_error(input)); ret = -1; } else if (!eof_seen) { if (input->v_offset == 0) From dovecot at dovecot.org Fri Oct 24 20:01:52 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Oct 2014 20:01:52 +0000 Subject: dovecot-2.2: lib-fs: Improved error logging Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d4570546b51c changeset: 17997:d4570546b51c user: Timo Sirainen date: Fri Oct 24 23:00:56 2014 +0300 description: lib-fs: Improved error logging diffstat: src/lib-fs/fs-api.c | 20 ++++++++++++-------- 1 files changed, 12 insertions(+), 8 deletions(-) diffs (50 lines): diff -r 7681fcd1ba43 -r d4570546b51c src/lib-fs/fs-api.c --- a/src/lib-fs/fs-api.c Fri Oct 24 22:18:29 2014 +0300 +++ b/src/lib-fs/fs-api.c Fri Oct 24 23:00:56 2014 +0300 @@ -331,8 +331,9 @@ return -1; } if (ret < 0 && file->pending_read_input->stream_errno != 0) { - fs_set_error(file->fs, "read(%s) failed: %m", - i_stream_get_name(file->pending_read_input)); + fs_set_error(file->fs, "read(%s) failed: %s", + i_stream_get_name(file->pending_read_input), + i_stream_get_error(file->pending_read_input)); } else { ret = I_MIN(size, data_size); memcpy(buf, data, ret); @@ -422,8 +423,9 @@ output = fs_write_stream(file); if ((ret = o_stream_send(output, data, size)) < 0) { err = errno; - fs_set_error(file->fs, "fs_write(%s) failed: %m", - o_stream_get_name(output)); + fs_set_error(file->fs, "fs_write(%s) failed: %s", + o_stream_get_name(output), + o_stream_get_error(output)); fs_write_stream_abort(file, &output); errno = err; return -1; @@ -612,16 +614,18 @@ while (o_stream_send_istream(dest->copy_output, dest->copy_input) > 0) ; if (dest->copy_input->stream_errno != 0) { errno = dest->copy_input->stream_errno; - fs_set_error(dest->fs, "read(%s) failed: %m", - i_stream_get_name(dest->copy_input)); + fs_set_error(dest->fs, "read(%s) failed: %s", + i_stream_get_name(dest->copy_input), + i_stream_get_error(dest->copy_input)); i_stream_unref(&dest->copy_input); fs_write_stream_abort(dest, &dest->copy_output); return -1; } if (dest->copy_output->stream_errno != 0) { errno = dest->copy_output->stream_errno; - fs_set_error(dest->fs, "write(%s) failed: %m", - o_stream_get_name(dest->copy_output)); + fs_set_error(dest->fs, "write(%s) failed: %s", + o_stream_get_name(dest->copy_output), + o_stream_get_error(dest->copy_output)); i_stream_unref(&dest->copy_input); fs_write_stream_abort(dest, &dest->copy_output); return -1; From dovecot at dovecot.org Fri Oct 24 22:39:46 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Oct 2014 22:39:46 +0000 Subject: dovecot-2.2: lib-http: client: Aborted requests were not counted... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9c6318786455 changeset: 17998:9c6318786455 user: Stephan Bosch date: Sat Oct 25 01:38:42 2014 +0300 description: lib-http: client: Aborted requests were not counted as finished in the connection's response receive loop. This caused a hang. diffstat: src/lib-http/http-client-connection.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (15 lines): diff -r d4570546b51c -r 9c6318786455 src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Fri Oct 24 23:00:56 2014 +0300 +++ b/src/lib-http/http-client-connection.c Sat Oct 25 01:38:42 2014 +0300 @@ -725,9 +725,9 @@ if (!http_client_connection_return_response(conn, req, &response)) return; } + } - finished++; - } + finished++; /* server closing connection? */ if (conn->close_indicated) { From dovecot at dovecot.org Fri Oct 24 22:39:46 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Oct 2014 22:39:46 +0000 Subject: dovecot-2.2: lib-http: client: Fixed cleanup of remaining waitin... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d913fe3a926a changeset: 17999:d913fe3a926a user: Stephan Bosch date: Sat Oct 25 01:38:42 2014 +0300 description: lib-http: client: Fixed cleanup of remaining waiting requests at connection destroy. Forgot to dereference the requests for the reference that the connection itself holds for each waiting request. diffstat: src/lib-http/http-client-connection.c | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-) diffs (32 lines): diff -r 9c6318786455 -r d913fe3a926a src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Sat Oct 25 01:38:42 2014 +0300 +++ b/src/lib-http/http-client-connection.c Sat Oct 25 01:38:42 2014 +0300 @@ -1265,18 +1265,24 @@ http_client_connection_disconnect(conn); + /* abort all pending requests (not supposed to happen here) */ if (array_is_created(&conn->request_wait_list)) { - /* abort all pending requests */ array_foreach_modifiable(&conn->request_wait_list, req) { i_assert((*req)->submitted); - http_client_request_error(*req, HTTP_CLIENT_REQUEST_ERROR_ABORTED, + http_client_request_error(*req, + HTTP_CLIENT_REQUEST_ERROR_ABORTED, "Aborting"); + http_client_request_unref(req); } array_free(&conn->request_wait_list); } if (conn->pending_request != NULL) { - http_client_request_error(conn->pending_request, - HTTP_CLIENT_REQUEST_ERROR_ABORTED, "Aborting"); + struct http_client_request *pending_req = conn->pending_request; + conn->pending_request = NULL; + http_client_request_error(pending_req, + HTTP_CLIENT_REQUEST_ERROR_ABORTED, + "Aborting"); + http_client_request_unref(&pending_req); } if (conn->http_parser != NULL) From dovecot at dovecot.org Fri Oct 24 22:39:46 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Oct 2014 22:39:46 +0000 Subject: dovecot-2.2: lib-http: client: Fixed conflict between request ab... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/84b5e075c62c changeset: 18000:84b5e075c62c user: Stephan Bosch date: Sat Oct 25 01:38:42 2014 +0300 description: lib-http: client: Fixed conflict between request abort and request delayed error. diffstat: src/lib-http/http-client-private.h | 2 -- src/lib-http/http-client-request.c | 12 +++++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diffs (61 lines): diff -r d913fe3a926a -r 84b5e075c62c src/lib-http/http-client-private.h --- a/src/lib-http/http-client-private.h Sat Oct 25 01:38:42 2014 +0300 +++ b/src/lib-http/http-client-private.h Sat Oct 25 01:38:42 2014 +0300 @@ -273,8 +273,6 @@ void http_client_request_resubmit(struct http_client_request *req); void http_client_request_retry(struct http_client_request *req, unsigned int status, const char *error); -void http_client_request_send_error(struct http_client_request *req, - unsigned int status, const char *error); void http_client_request_error_delayed(struct http_client_request **_req); void http_client_request_error(struct http_client_request *req, unsigned int status, const char *error); diff -r d913fe3a926a -r 84b5e075c62c src/lib-http/http-client-request.c --- a/src/lib-http/http-client-request.c Sat Oct 25 01:38:42 2014 +0300 +++ b/src/lib-http/http-client-request.c Sat Oct 25 01:38:42 2014 +0300 @@ -54,6 +54,10 @@ * Request */ +static void +http_client_request_send_error(struct http_client_request *req, + unsigned int status, const char *error); + static struct http_client_request * http_client_request_new(struct http_client *client, const char *method, http_client_request_callback_t *callback, void *context) @@ -861,15 +865,13 @@ return TRUE; } -void +static void http_client_request_send_error(struct http_client_request *req, unsigned int status, const char *error) { http_client_request_callback_t *callback; bool sending = (req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT); - if (req->state >= HTTP_REQUEST_STATE_FINISHED) - return; req->state = HTTP_REQUEST_STATE_ABORTED; callback = req->callback; @@ -890,8 +892,7 @@ { struct http_client_request *req = *_req; - if (req->state >= HTTP_REQUEST_STATE_FINISHED) - return; + i_assert(req->state == HTTP_REQUEST_STATE_ABORTED); i_assert(req->delayed_error != NULL && req->delayed_error_status != 0); http_client_request_send_error(req, req->delayed_error_status, @@ -906,6 +907,7 @@ { if (req->state >= HTTP_REQUEST_STATE_FINISHED) return; + req->state = HTTP_REQUEST_STATE_ABORTED; if (req->queue != NULL) http_client_queue_drop_request(req->queue, req); From dovecot at dovecot.org Fri Oct 24 22:39:47 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Oct 2014 22:39:47 +0000 Subject: dovecot-2.2: lib-http: client: Fixed handling of requests aborte... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cffa8349f167 changeset: 18001:cffa8349f167 user: Stephan Bosch date: Sat Oct 25 01:38:42 2014 +0300 description: lib-http: client: Fixed handling of requests aborted while still sending payload to server. diffstat: src/lib-http/http-client-connection.c | 79 +++++++++++++++++++++++++++------- src/lib-http/http-client-private.h | 1 + 2 files changed, 63 insertions(+), 17 deletions(-) diffs (200 lines): diff -r 84b5e075c62c -r cffa8349f167 src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Sat Oct 25 01:38:42 2014 +0300 +++ b/src/lib-http/http-client-connection.c Sat Oct 25 01:38:42 2014 +0300 @@ -165,7 +165,7 @@ return FALSE; } - if (!conn->connected || conn->output_locked || + if (!conn->connected || conn->output_locked || conn->output_broken || conn->close_indicated || conn->tunneling || http_client_connection_count_pending(conn) >= conn->client->set.max_pipelined_requests) @@ -209,6 +209,9 @@ { unsigned int timeout, count; + i_assert(!conn->close_indicated); + i_assert(!conn->output_broken); + if (conn->connected && array_is_created(&conn->request_wait_list) && array_count(&conn->request_wait_list) == 0 && @@ -312,6 +315,8 @@ if (req == NULL) return 0; + i_assert(req->state == HTTP_REQUEST_STATE_QUEUED); + if (conn->to_idle != NULL) timeout_remove(&conn->to_idle); @@ -328,7 +333,6 @@ if (conn->peer->no_payload_sync) req->payload_sync = FALSE; - i_assert(req->state == HTTP_REQUEST_STATE_QUEUED); array_append(&conn->request_wait_list, &req, 1); http_client_request_ref(req); @@ -552,11 +556,12 @@ struct http_client_connection *conn = (struct http_client_connection *)_conn; struct http_response response; - struct http_client_request *const *req_idx; + struct http_client_request *const *reqs; struct http_client_request *req = NULL; + enum http_response_payload_type payload_type; + unsigned int count; int finished = 0, ret; const char *error; - enum http_response_payload_type payload_type; i_assert(conn->incoming_payload == NULL); @@ -608,9 +613,9 @@ timeout_reset(conn->to_requests); /* get first waiting request */ - if (array_count(&conn->request_wait_list) > 0) { - req_idx = array_idx(&conn->request_wait_list, 0); - req = req_idx[0]; + reqs = array_get(&conn->request_wait_list, &count); + if (count > 0) { + req = reqs[0]; /* determine whether to expect a response payload */ payload_type = http_client_request_get_payload_type(req); @@ -619,6 +624,14 @@ payload_type = HTTP_RESPONSE_PAYLOAD_TYPE_ALLOWED; } + /* drop connection with broken output if last possible input was + received */ + if (conn->output_broken && (count == 0 || + (count == 1 && req->state == HTTP_REQUEST_STATE_ABORTED))) { + http_client_connection_server_close(&conn); + return; + } + // FIXME: handle somehow if server replies before request->input is at EOF while ((ret=http_response_parse_next (conn->http_parser, payload_type, &response, &error)) > 0) { @@ -648,11 +661,21 @@ "Got 100-continue response after timeout"); continue; } + conn->peer->no_payload_sync = FALSE; conn->peer->seen_100_response = TRUE; conn->payload_continue = TRUE; + http_client_connection_debug(conn, "Got expected 100-continue response"); + + if (req->state == HTTP_REQUEST_STATE_ABORTED) { + http_client_connection_debug(conn, + "Request aborted before sending payload was complete."); + http_client_connection_close(&conn); + return; + } + if (http_client_request_send_more(req, &error) < 0) { http_client_connection_abort_temp_error(&conn, HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, @@ -660,11 +683,11 @@ } return; } else if (response.status / 100 == 1) { - /* ignore them for now */ + /* ignore other 1xx for now */ http_client_connection_debug(conn, "Got unexpected %u response; ignoring", response.status); continue; - } + } http_client_connection_debug(conn, "Got %u response for request %s (took %u ms + %u ms in queue)", @@ -736,9 +759,9 @@ } /* get next waiting request */ - if (array_count(&conn->request_wait_list) > 0) { - req_idx = array_idx(&conn->request_wait_list, 0); - req = req_idx[0]; + reqs = array_get(&conn->request_wait_list, &count); + if (count > 0) { + req = reqs[0]; /* determine whether to expect a response payload */ payload_type = http_client_request_get_payload_type(req); @@ -749,6 +772,14 @@ req = NULL; payload_type = HTTP_RESPONSE_PAYLOAD_TYPE_ALLOWED; } + + /* drop connection with broken output if last possible input was + received */ + if (conn->output_broken && (count == 0 || + (count == 1 && req->state == HTTP_REQUEST_STATE_ABORTED))) { + http_client_connection_server_close(&conn); + return; + } } if (ret <= 0 && @@ -783,8 +814,9 @@ int http_client_connection_output(struct http_client_connection *conn) { - struct http_client_request *const *req_idx, *req; + struct http_client_request *const *reqs; struct ostream *output = conn->conn.output; + unsigned int count; const char *error; int ret; @@ -802,14 +834,27 @@ return ret; } + i_assert(!conn->output_broken); + if (conn->ssl_iostream != NULL && !ssl_iostream_is_handshaked(conn->ssl_iostream)) return 1; - if (array_count(&conn->request_wait_list) > 0 && conn->output_locked) { - req_idx = array_idx(&conn->request_wait_list, - array_count(&conn->request_wait_list)-1); - req = req_idx[0]; + reqs = array_get(&conn->request_wait_list, &count); + if (count > 0 && conn->output_locked) { + struct http_client_request *req = reqs[count-1]; + + if (req->state == HTTP_REQUEST_STATE_ABORTED) { + http_client_connection_debug(conn, + "Request aborted before sending payload was complete."); + if (count == 1) { + http_client_connection_close(&conn); + } else { + o_stream_unset_flush_callback(output); + conn->output_broken = TRUE; + } + return 1; + } if (!req->payload_sync || conn->payload_continue) { if (http_client_request_send_more(req, &error) < 0) { diff -r 84b5e075c62c -r cffa8349f167 src/lib-http/http-client-private.h --- a/src/lib-http/http-client-private.h Sat Oct 25 01:38:42 2014 +0300 +++ b/src/lib-http/http-client-private.h Sat Oct 25 01:38:42 2014 +0300 @@ -147,6 +147,7 @@ unsigned int closing:1; unsigned int close_indicated:1; unsigned int output_locked:1; /* output is locked; no pipelining */ + unsigned int output_broken:1; /* output is broken; no more requests */ unsigned int payload_continue:1; /* received 100-continue for current request */ unsigned int in_req_callback:1; /* performin request callback (busy) */ From dovecot at dovecot.org Fri Oct 24 22:39:49 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Oct 2014 22:39:49 +0000 Subject: dovecot-2.2: lib-http: client: Handle situation in which server ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4dc3c0cacd25 changeset: 18002:4dc3c0cacd25 user: Stephan Bosch date: Sat Oct 25 01:38:43 2014 +0300 description: lib-http: client: Handle situation in which server sends response before request payload is fully sent. diffstat: src/lib-http/http-client-connection.c | 25 +++++++++++++++++++++++-- 1 files changed, 23 insertions(+), 2 deletions(-) diffs (51 lines): diff -r cffa8349f167 -r 4dc3c0cacd25 src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Sat Oct 25 01:38:42 2014 +0300 +++ b/src/lib-http/http-client-connection.c Sat Oct 25 01:38:43 2014 +0300 @@ -632,10 +632,9 @@ return; } - // FIXME: handle somehow if server replies before request->input is at EOF while ((ret=http_response_parse_next (conn->http_parser, payload_type, &response, &error)) > 0) { - bool aborted; + bool aborted, early = FALSE; if (req == NULL) { /* server sent response without any requests in the wait list */ @@ -687,6 +686,16 @@ http_client_connection_debug(conn, "Got unexpected %u response; ignoring", response.status); continue; + } else if (!req->payload_sync && + req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT) { + /* got early response from server while we're still sending request + payload. we cannot recover from this reliably, so we stop sending + payload and close the connection once the response is processed */ + http_client_connection_debug(conn, + "Got early input from server; " + "request payload not completely sent (will close connection)"); + o_stream_unset_flush_callback(conn->conn.output); + conn->output_broken = early = TRUE; } http_client_connection_debug(conn, @@ -710,6 +719,18 @@ if (!aborted) { bool handled = FALSE; + /* response cannot be 2xx if request payload was not completely sent + */ + if (early && response.status / 100 == 2) { + http_client_request_error(req, + HTTP_CLIENT_REQUEST_ERROR_BAD_RESPONSE, + "Server responded with success response " + "before all payload was sent"); + http_client_request_unref(&req); + http_client_connection_close(&conn); + return; + } + /* don't redirect/retry if we're sending data in small blocks via http_client_request_send_payload() and we're not waiting for 100 continue */ From dovecot at dovecot.org Fri Oct 24 23:14:30 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Oct 2014 23:14:30 +0000 Subject: dovecot-2.2: virtual plugin: Fixed assert-crash when backend mai... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/37a3c6c001b7 changeset: 18003:37a3c6c001b7 user: Timo Sirainen date: Sat Oct 25 02:13:36 2014 +0300 description: virtual plugin: Fixed assert-crash when backend mailbox was auto-closed while it had pending expunges. diffstat: src/plugins/virtual/virtual-storage.c | 19 +++++++++++++++++-- src/plugins/virtual/virtual-sync.c | 11 ++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) diffs (65 lines): diff -r 4dc3c0cacd25 -r 37a3c6c001b7 src/plugins/virtual/virtual-storage.c --- a/src/plugins/virtual/virtual-storage.c Sat Oct 25 01:38:43 2014 +0300 +++ b/src/plugins/virtual/virtual-storage.c Sat Oct 25 02:13:36 2014 +0300 @@ -271,6 +271,21 @@ } } +static bool virtual_backend_box_can_close(struct virtual_backend_box *bbox) +{ + if (bbox->box->notify_callback != NULL) { + /* FIXME: IMAP IDLE running - we should support closing this + also if mailbox_list_index=yes */ + return FALSE; + } + if (array_count(&bbox->sync_pending_removes) > 0) { + /* FIXME: we could probably close this by making + syncing support it? */ + return FALSE; + } + return TRUE; +} + static bool virtual_backend_box_close_any_except(struct virtual_mailbox *mbox, struct virtual_backend_box *except_bbox) @@ -285,7 +300,7 @@ if (bbox != except_bbox && bbox->box->transaction_count == 0 && - bbox->box->notify_callback == NULL) { + virtual_backend_box_can_close(bbox)) { i_assert(bbox->sync_mail == NULL); virtual_backend_box_close(mbox, bbox); return TRUE; @@ -298,7 +313,7 @@ if (bbox != except_bbox && bbox->sync_mail != NULL && bbox->box->transaction_count == 1 && - bbox->box->notify_callback == NULL) { + virtual_backend_box_can_close(bbox)) { virtual_backend_box_sync_mail_unset(bbox); i_assert(bbox->box->transaction_count == 0); virtual_backend_box_close(mbox, bbox); diff -r 4dc3c0cacd25 -r 37a3c6c001b7 src/plugins/virtual/virtual-sync.c --- a/src/plugins/virtual/virtual-sync.c Sat Oct 25 01:38:43 2014 +0300 +++ b/src/plugins/virtual/virtual-sync.c Sat Oct 25 02:13:36 2014 +0300 @@ -1108,12 +1108,13 @@ MAILBOX_SYNC_FLAG_FAST); if (bbox->search_result == NULL) { - /* first sync in this process. first try to quickly check - if the mailbox has changed. if we can do that check from - mailbox list index, we don't even need to open the - mailbox. */ + /* a) first sync in this process. + b) we had auto-closed this backend mailbox. + + first try to quickly check if the mailbox has changed. + if we can do that check from mailbox list index, we don't + even need to open the mailbox. */ i_assert(array_count(&bbox->sync_pending_removes) == 0); - if (bbox_index_opened || bbox->open_failed) { /* a) index already opened, refresh it b) delayed error handling for mailbox_open() From dovecot at dovecot.org Fri Oct 24 23:43:46 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Oct 2014 23:43:46 +0000 Subject: dovecot-2.2: auth: allow_nets=local matches now connections with... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d1aefed4589b changeset: 18004:d1aefed4589b user: Timo Sirainen date: Sat Oct 25 02:39:00 2014 +0300 description: auth: allow_nets=local matches now connections without any IP address diffstat: src/auth/auth-request.c | 23 +++++++++++++---------- 1 files changed, 13 insertions(+), 10 deletions(-) diffs (47 lines): diff -r 37a3c6c001b7 -r d1aefed4589b src/auth/auth-request.c --- a/src/auth/auth-request.c Sat Oct 25 02:13:36 2014 +0300 +++ b/src/auth/auth-request.c Sat Oct 25 02:39:00 2014 +0300 @@ -1279,30 +1279,33 @@ unsigned int bits; bool found = FALSE; - if (request->remote_ip.family == 0) { - /* IP not known */ - auth_request_log_info(request, AUTH_SUBSYS_DB, - "allow_nets check failed: Remote IP not known"); - request->failed = TRUE; - return; - } - for (net = t_strsplit_spaces(networks, ", "); *net != NULL; net++) { auth_request_log_debug(request, AUTH_SUBSYS_DB, "allow_nets: Matching for network %s", *net); + if (strcmp(*net, "local") == 0 && request->remote_ip.family == 0) { + found = TRUE; + break; + } + if (net_parse_range(*net, &net_ip, &bits) < 0) { auth_request_log_info(request, AUTH_SUBSYS_DB, "allow_nets: Invalid network '%s'", *net); } - if (net_is_in_network(&request->remote_ip, &net_ip, bits)) { + if (request->remote_ip.family != 0 && + net_is_in_network(&request->remote_ip, &net_ip, bits)) { found = TRUE; break; } } - if (!found) { + if (found) + ; + else if (request->remote_ip.family == 0) { + auth_request_log_info(request, AUTH_SUBSYS_DB, + "allow_nets check failed: Remote IP not known and 'local' missing"); + } else if (!found) { auth_request_log_info(request, AUTH_SUBSYS_DB, "allow_nets check failed: IP not in allowed networks"); } From dovecot at dovecot.org Fri Oct 24 23:43:46 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Oct 2014 23:43:46 +0000 Subject: dovecot-2.2: auth: Some unsuccessful passdb lookups weren't retu... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3a8b417b0b80 changeset: 18005:3a8b417b0b80 user: Timo Sirainen date: Sat Oct 25 02:42:47 2014 +0300 description: auth: Some unsuccessful passdb lookups weren't returned as failures to passdb lookups. These lookups were only being done internally, so it usually didn't matter. Also this only affected things like allow_nets checking and some non-common passdb {?result_* } settings. diffstat: src/auth/auth-master-connection.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (14 lines): diff -r d1aefed4589b -r 3a8b417b0b80 src/auth/auth-master-connection.c --- a/src/auth/auth-master-connection.c Sat Oct 25 02:39:00 2014 +0300 +++ b/src/auth/auth-master-connection.c Sat Oct 25 02:42:47 2014 +0300 @@ -326,6 +326,10 @@ str = t_str_new(128); switch (result) { case PASSDB_RESULT_OK: + if (auth_request->failed || !auth_request->passdb_success) { + str_printfa(str, "FAIL\t%u", auth_request->id); + break; + } str_printfa(str, "PASS\t%u\tuser=", auth_request->id); str_append_tabescaped(str, auth_request->user); if (!auth_fields_is_empty(auth_request->extra_fields)) { From dovecot at dovecot.org Fri Oct 24 23:54:52 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Oct 2014 23:54:52 +0000 Subject: dovecot-2.2: quota: Fixed NetBSD quota Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/221f3f59901f changeset: 18006:221f3f59901f user: Timo Sirainen date: Sat Oct 25 02:52:50 2014 +0300 description: quota: Fixed NetBSD quota I guess it's because quota is refreshed only at quota_open() time. Based on patch by Manuel Bouyer diffstat: src/plugins/quota/quota-fs.c | 31 ++++++++++++++++--------------- 1 files changed, 16 insertions(+), 15 deletions(-) diffs (54 lines): diff -r 3a8b417b0b80 -r 221f3f59901f src/plugins/quota/quota-fs.c --- a/src/plugins/quota/quota-fs.c Sat Oct 25 02:42:47 2014 +0300 +++ b/src/plugins/quota/quota-fs.c Sat Oct 25 02:52:50 2014 +0300 @@ -673,34 +673,35 @@ { struct quotakey qk; struct quotaval qv; + struct quotahandle *qh; + int ret; - if (root->qh == NULL) { - if ((root->qh = quota_open(root->mount->mount_path)) == NULL) { - i_error("cannot open quota for %s: %m", - root->mount->mount_path); - fs_quota_root_disable(root, group); - return 0; - } - } + if ((qh = quota_open(root->mount->mount_path)) == NULL) { + i_error("cannot open quota for %s: %m", + root->mount->mount_path); + fs_quota_root_disable(root, group); + return 0; + } qk.qk_idtype = group ? QUOTA_IDTYPE_GROUP : QUOTA_IDTYPE_USER; qk.qk_id = group ? root->gid : root->uid; qk.qk_objtype = bytes ? QUOTA_OBJTYPE_BLOCKS : QUOTA_OBJTYPE_FILES; - if (quota_get(root->qh, &qk, &qv) != 0) { + if (quota_get(qh, &qk, &qv) != 0) { if (errno == ESRCH) { fs_quota_root_disable(root, group); return 0; } i_error("quotactl(Q_GETQUOTA, %s) failed: %m", root->mount->mount_path); - return -1; + ret = -1; + } else { + *value_r = qv.qv_usage * DEV_BSIZE; + *limit_r = qv.qv_softlimit * DEV_BSIZE; + ret = 1; } - - *value_r = qv.qv_usage * DEV_BSIZE; - *limit_r = qv.qv_softlimit * DEV_BSIZE; - - return 1; + quota_close(qh); + return ret; } #endif From dovecot at dovecot.org Fri Oct 24 23:54:52 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Oct 2014 23:54:52 +0000 Subject: dovecot-2.2: quota: Fixed including the right system quota.h wit... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/eb3ab11bcd86 changeset: 18007:eb3ab11bcd86 user: Timo Sirainen date: Sat Oct 25 02:53:55 2014 +0300 description: quota: Fixed including the right system quota.h with NetBSD Patch by Manuel Bouyer. I guess the quota.h could be renamed to something at some point.. diffstat: src/plugins/quota/quota-fs.h | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 221f3f59901f -r eb3ab11bcd86 src/plugins/quota/quota-fs.h --- a/src/plugins/quota/quota-fs.h Sat Oct 25 02:52:50 2014 +0300 +++ b/src/plugins/quota/quota-fs.h Sat Oct 25 02:53:55 2014 +0300 @@ -7,7 +7,8 @@ #endif #ifdef HAVE_QUOTA_OPEN -# include /* NetBSD with libquota */ +/* absolute path to avoid confusion with ./quota.h */ +# include "/usr/include/quota.h" /* NetBSD with libquota */ #endif #ifdef HAVE_SYS_QUOTA_H From dovecot at dovecot.org Fri Oct 24 23:57:39 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Oct 2014 23:57:39 +0000 Subject: dovecot-2.2: lib-index: Don't assert-crash if expunge event hand... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1886e0616ab5 changeset: 18008:1886e0616ab5 user: Timo Sirainen date: Sat Oct 25 02:56:42 2014 +0300 description: lib-index: Don't assert-crash if expunge event handling finds that everything is already expunged. diffstat: src/lib-index/mail-index-sync-update.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diffs (20 lines): diff -r eb3ab11bcd86 -r 1886e0616ab5 src/lib-index/mail-index-sync-update.c --- a/src/lib-index/mail-index-sync-update.c Sat Oct 25 02:53:55 2014 +0300 +++ b/src/lib-index/mail-index-sync-update.c Sat Oct 25 02:56:42 2014 +0300 @@ -243,11 +243,14 @@ unsigned int i, count; uint32_t dest_seq1, prev_seq2, orig_rec_count; + range = array_get(seqs, &count); + if (count == 0) + return; + i_assert(count > 0); + map = mail_index_sync_get_atomic_map(ctx); /* 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, From dovecot at dovecot.org Sat Oct 25 03:21:20 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 25 Oct 2014 03:21:20 +0000 Subject: dovecot-2.2: lib-storage: Fully unreference indexes when deletin... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5c15c7f57253 changeset: 18009:5c15c7f57253 user: Timo Sirainen date: Sat Oct 25 06:16:47 2014 +0300 description: lib-storage: Fully unreference indexes when deleting mailboxes. diffstat: src/lib-storage/index/index-storage.c | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletions(-) diffs (32 lines): diff -r 1886e0616ab5 -r 5c15c7f57253 src/lib-storage/index/index-storage.c --- a/src/lib-storage/index/index-storage.c Sat Oct 25 02:56:42 2014 +0300 +++ b/src/lib-storage/index/index-storage.c Sat Oct 25 06:16:47 2014 +0300 @@ -377,7 +377,7 @@ ibox->sync_last_check = 0; } -void index_storage_mailbox_free(struct mailbox *box) +static void index_storage_mailbox_unref_indexes(struct mailbox *box) { if (box->index_pvt != NULL) mail_index_alloc_cache_unref(&box->index_pvt); @@ -385,6 +385,11 @@ mail_index_alloc_cache_unref(&box->index); } +void index_storage_mailbox_free(struct mailbox *box) +{ + index_storage_mailbox_unref_indexes(box); +} + static void index_storage_mailbox_update_cache(struct mailbox *box, const struct mailbox_update *update) @@ -730,6 +735,7 @@ implementations if indexes are opened by another session, but that can't really be helped. */ mailbox_close(box); + index_storage_mailbox_unref_indexes(box); mail_index_alloc_cache_destroy_unrefed(); if (box->list->v.delete_mailbox(box->list, box->name) < 0) { From dovecot at dovecot.org Sat Oct 25 03:21:20 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 25 Oct 2014 03:21:20 +0000 Subject: dovecot-2.2: lib-storage: When mailbox is deleted, reset its cac... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5e4a7fd9782c changeset: 18010:5e4a7fd9782c user: Timo Sirainen date: Sat Oct 25 06:18:06 2014 +0300 description: lib-storage: When mailbox is deleted, reset its cached paths. If mailbox is still later on recreated, the paths may have changed. diffstat: src/lib-storage/mail-storage.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-) diffs (28 lines): diff -r 5c15c7f57253 -r 5e4a7fd9782c src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Sat Oct 25 06:16:47 2014 +0300 +++ b/src/lib-storage/mail-storage.c Sat Oct 25 06:18:06 2014 +0300 @@ -1329,6 +1329,13 @@ return 0; } +static void mailbox_close_reset_path(struct mailbox *box) +{ + memset(&box->_perm, 0, sizeof(box->_perm)); + box->_path = NULL; + box->_index_path = NULL; +} + int mailbox_delete(struct mailbox *box) { int ret; @@ -1357,6 +1364,10 @@ box->deleting = FALSE; mailbox_close(box); + + /* if mailbox is reopened, its path may be different with + LAYOUT=index */ + mailbox_close_reset_path(box); return ret; } From dovecot at dovecot.org Sat Oct 25 03:21:20 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 25 Oct 2014 03:21:20 +0000 Subject: dovecot-2.2: lib-storage: Don't update mailbox list index status... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2b964521f5ab changeset: 18011:2b964521f5ab user: Timo Sirainen date: Sat Oct 25 06:18:45 2014 +0300 description: lib-storage: Don't update mailbox list index status fields when deleting a mailbox. diffstat: src/lib-storage/list/mailbox-list-index-status.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diffs (16 lines): diff -r 5e4a7fd9782c -r 2b964521f5ab src/lib-storage/list/mailbox-list-index-status.c --- a/src/lib-storage/list/mailbox-list-index-status.c Sat Oct 25 06:18:06 2014 +0300 +++ b/src/lib-storage/list/mailbox-list-index-status.c Sat Oct 25 06:18:45 2014 +0300 @@ -397,6 +397,12 @@ if (ilist->syncing || ilist->updating_status) return 0; + if (box->deleting) { + /* don't update status info while mailbox is being deleted. + especially not a good idea if we're rollbacking a created + mailbox that somebody else had just created */ + return 0; + } if (MAILBOX_IS_NEVER_IN_INDEX(box)) return 0; From dovecot at dovecot.org Sat Oct 25 03:21:20 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 25 Oct 2014 03:21:20 +0000 Subject: dovecot-2.2: lib-storage: LAYOUT=index now first creates the bac... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/004b9a36c92f changeset: 18012:004b9a36c92f user: Timo Sirainen date: Sat Oct 25 06:19:41 2014 +0300 description: lib-storage: LAYOUT=index now first creates the backend mailbox and only then adds it to list index. This avoids any race conditions with mailbox creation and opening it. diffstat: src/lib-storage/list/mailbox-list-index-backend.c | 71 +++++++++++++++++----- 1 files changed, 55 insertions(+), 16 deletions(-) diffs (131 lines): diff -r 2b964521f5ab -r 004b9a36c92f src/lib-storage/list/mailbox-list-index-backend.c --- a/src/lib-storage/list/mailbox-list-index-backend.c Sat Oct 25 06:18:45 2014 +0300 +++ b/src/lib-storage/list/mailbox-list-index-backend.c Sat Oct 25 06:19:41 2014 +0300 @@ -16,6 +16,9 @@ struct index_mailbox_list { struct mailbox_list list; const char *temp_prefix; + + const char *create_mailbox_name; + guid_128_t create_mailbox_guid; }; extern struct mailbox_list index_mailbox_list; @@ -136,6 +139,13 @@ if (!mailbox_list_set_get_root_path(&_list->set, type, &root_dir)) return 0; + if (list->create_mailbox_name != NULL && + strcmp(list->create_mailbox_name, name) == 0) { + *path_r = index_get_guid_path(_list, root_dir, + list->create_mailbox_guid); + return 1; + } + if (ilist->sync_ctx != NULL) { /* we could get here during sync from index_list_mailbox_create_selectable() */ @@ -338,19 +348,39 @@ new_update = *update; if (guid_128_is_empty(new_update.mailbox_guid)) guid_128_generate(new_update.mailbox_guid); - ret = index_list_mailbox_create_selectable(box, new_update.mailbox_guid); - if (ret < 0) { - mail_storage_copy_list_error(box->storage, box->list); - return -1; + + /* create the backend mailbox first before it exists in the + list. the mailbox creation wants to use get_path() though, + so use a bit kludgy create_mailbox_* variables during the + creation to return the path. we'll also support recursively + creating more mailboxes in here. */ + const char *old_name; + guid_128_t old_guid; + + old_name = list->create_mailbox_name; + guid_128_copy(old_guid, list->create_mailbox_guid); + + list->create_mailbox_name = box->name; + guid_128_copy(list->create_mailbox_guid, new_update.mailbox_guid); + + ret = ibox->module_ctx.super.create_box(box, &new_update, FALSE); + + if (ret == 0) { + /* backend mailbox was successfully created. now add it + to the list. */ + ret = index_list_mailbox_create_selectable(box, new_update.mailbox_guid); + if (ret < 0) + mail_storage_copy_list_error(box->storage, box->list); + if (ret <= 0) { + /* failed to add to list. rollback the backend + mailbox creation */ + (void)mailbox_delete(box); + } } - if (ret > 0) { - /* mailbox entry was created. create the mailbox - itself now after the mailbox list index is already - unlocked (to avoid deadlocks in case the create_box() - goes back to updating mailbox list index). */ - if (ibox->module_ctx.super.create_box(box, update, FALSE) < 0) - return -1; - } + list->create_mailbox_name = old_name; + guid_128_copy(list->create_mailbox_guid, old_guid); + if (ret < 0) + return ret; } else { ret = 0; } @@ -460,13 +490,20 @@ } static int -index_list_delete_entry(struct mailbox_list *list, const char *name, +index_list_delete_entry(struct index_mailbox_list *list, const char *name, bool delete_selectable) { struct mailbox_list_index_sync_context *sync_ctx; int ret; - if (mailbox_list_index_sync_begin(list, &sync_ctx) < 0) + if (strcmp(name, list->create_mailbox_name) == 0) { + /* we're rollbacking a failed create. if the name exists in the + list, it was done by somebody else so we don't want to + remove it. */ + return 0; + } + + if (mailbox_list_index_sync_begin(&list->list, &sync_ctx) < 0) return -1; ret = mailbox_list_index_sync_delete(sync_ctx, name, delete_selectable); if (mailbox_list_index_sync_end(&sync_ctx, TRUE) < 0) @@ -477,6 +514,7 @@ static int index_list_delete_mailbox(struct mailbox_list *_list, const char *name) { + struct index_mailbox_list *list = (struct index_mailbox_list *)_list; const char *path; int ret; @@ -498,7 +536,7 @@ if (ret == 0 || (_list->props & MAILBOX_LIST_PROP_AUTOCREATE_DIRS) != 0) index_list_delete_finish(_list, name); if (ret == 0) { - if (index_list_delete_entry(_list, name, TRUE) < 0) + if (index_list_delete_entry(list, name, TRUE) < 0) return -1; } return ret; @@ -507,9 +545,10 @@ static int index_list_delete_dir(struct mailbox_list *_list, const char *name) { + struct index_mailbox_list *list = (struct index_mailbox_list *)_list; int ret; - if ((ret = index_list_delete_entry(_list, name, FALSE)) < 0) + if ((ret = index_list_delete_entry(list, name, FALSE)) < 0) return -1; if (ret == 0) { mailbox_list_set_error(_list, MAIL_ERROR_EXISTS, From dovecot at dovecot.org Sat Oct 25 03:38:31 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 25 Oct 2014 03:38:31 +0000 Subject: dovecot-2.2: lmtp: Added missing session_id to mail_user Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/380b723f37ef changeset: 18013:380b723f37ef user: Timo Sirainen date: Sat Oct 25 06:37:35 2014 +0300 description: lmtp: Added missing session_id to mail_user diffstat: src/lmtp/commands.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 004b9a36c92f -r 380b723f37ef src/lmtp/commands.c --- a/src/lmtp/commands.c Sat Oct 25 06:19:41 2014 +0300 +++ b/src/lmtp/commands.c Sat Oct 25 06:37:35 2014 +0300 @@ -541,6 +541,7 @@ input.remote_ip = client->remote_ip; input.local_port = client->local_port; input.remote_port = client->remote_port; + input.session_id = client->state.session_id; ret = mail_storage_service_lookup(storage_service, &input, &rcpt.service_user, &error); From dovecot at dovecot.org Sat Oct 25 03:43:04 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 25 Oct 2014 03:43:04 +0000 Subject: dovecot-2.2: lmtp: Use mail_log_prefix while mails are being del... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e861c21875cc changeset: 18014:e861c21875cc user: Timo Sirainen date: Sat Oct 25 06:40:03 2014 +0300 description: lmtp: Use mail_log_prefix while mails are being delivered. diffstat: src/lmtp/commands.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diffs (31 lines): diff -r 380b723f37ef -r e861c21875cc src/lmtp/commands.c --- a/src/lmtp/commands.c Sat Oct 25 06:37:35 2014 +0300 +++ b/src/lmtp/commands.c Sat Oct 25 06:40:03 2014 +0300 @@ -11,6 +11,7 @@ #include "ostream.h" #include "istream-dot.h" #include "safe-mkstemp.h" +#include "var-expand.h" #include "restrict-access.h" #include "settings-parser.h" #include "master-service.h" @@ -626,6 +627,7 @@ struct setting_parser_context *set_parser; void **sets; const char *line, *error, *username; + string_t *str; enum mail_error mail_error; int ret; @@ -655,6 +657,11 @@ rcpt->address); return -1; } + str = t_str_new(256); + var_expand(str, client->state.dest_user->set->mail_log_prefix, + mail_user_var_expand_table(client->state.dest_user)); + i_set_failure_prefix("%s", str_c(str)); + sets = mail_storage_service_user_get_set(rcpt->service_user); lda_set = sets[1]; settings_var_expand(&lda_setting_parser_info, lda_set, client->pool, From dovecot at dovecot.org Sat Oct 25 04:13:17 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 25 Oct 2014 04:13:17 +0000 Subject: dovecot-2.2: Released v2.2.15. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e8b793f2c409 changeset: 18015:e8b793f2c409 user: Timo Sirainen date: Sat Oct 25 06:57:11 2014 +0300 description: Released v2.2.15. diffstat: NEWS | 23 +++++++++++++++++++++++ configure.ac | 4 ++-- 2 files changed, 25 insertions(+), 2 deletions(-) diffs (44 lines): diff -r e861c21875cc -r e8b793f2c409 NEWS --- a/NEWS Sat Oct 25 06:40:03 2014 +0300 +++ b/NEWS Sat Oct 25 06:57:11 2014 +0300 @@ -1,3 +1,26 @@ +v2.2.15 2014-10-24 Timo Sirainen + + * Plugins can now print a banner comment in doveconf output + (typically the plugin version) + * Replication plugin now triggers low (instead of high) priority for + mail copying operations. + * IMAP/POP3/ManageSieve proxy: If destination server can't be + connected to, retry connecting once per second up to the value of + proxy_timeout. This allows quick restarts/upgrades on the backend + server without returning login failures. + * Internal passdb lookups (e.g. done by lmtp/doveadm proxy) wasn't + returning failure in some situations where it should have (e.g. + allow_nets mismatch) + * LMTP uses mail_log_prefix now for logging mail deliveries instead of + a hardcoded prefix. The non-delivery log prefix is still hardcoded + though. + + + passdb allow_nets=local matches lookups that don't contain an IP + address (internally done by Dovecot services) + + Various debug logging and error logging improvements + - Various race condition fixes to LAYOUT=index + - v2.2.14 virtual plugin crashed in some situations + v2.2.14 2014-10-14 Timo Sirainen * lmtp: Delivered-To: header no longer contains <> around the email diff -r e861c21875cc -r e8b793f2c409 configure.ac --- a/configure.ac Sat Oct 25 06:40:03 2014 +0300 +++ b/configure.ac Sat Oct 25 06:57:11 2014 +0300 @@ -2,8 +2,8 @@ # Be sure to update ABI version also if anything changes that might require # recompiling plugins. Most importantly that means if any structs are changed. -AC_INIT([Dovecot],[2.2.14],[dovecot at dovecot.org]) -AC_DEFINE_UNQUOTED([DOVECOT_ABI_VERSION], "2.2.ABIv14($PACKAGE_VERSION)", [Dovecot ABI version]) +AC_INIT([Dovecot],[2.2.15],[dovecot at dovecot.org]) +AC_DEFINE_UNQUOTED([DOVECOT_ABI_VERSION], "2.2.ABIv15($PACKAGE_VERSION)", [Dovecot ABI version]) AC_CONFIG_SRCDIR([src]) From dovecot at dovecot.org Sat Oct 25 04:13:23 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 25 Oct 2014 04:13:23 +0000 Subject: dovecot-2.2: Added tag 2.2.15 for changeset e8b793f2c409 Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7f031e43def3 changeset: 18016:7f031e43def3 user: Timo Sirainen date: Sat Oct 25 06:57:11 2014 +0300 description: Added tag 2.2.15 for changeset e8b793f2c409 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r e8b793f2c409 -r 7f031e43def3 .hgtags --- a/.hgtags Sat Oct 25 06:57:11 2014 +0300 +++ b/.hgtags Sat Oct 25 06:57:11 2014 +0300 @@ -120,3 +120,4 @@ c55c660d6e9dd0b433768c906c1462cf6e8d71d5 2.2.13 34e52cbeb83725178c0c0a282ffa5ef1c161e3cb 2.2.14.rc1 6dad1f6e8930940f3c763cf3f27aaa7a9c979520 2.2.14 +e8b793f2c4091f76075e66d5166b38cf82e598bd 2.2.15 From dovecot at dovecot.org Sat Oct 25 04:13:23 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 25 Oct 2014 04:13:23 +0000 Subject: dovecot-2.2: Added signature for changeset e8b793f2c409 Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/096706c5b616 changeset: 18017:096706c5b616 user: Timo Sirainen date: Sat Oct 25 06:57:25 2014 +0300 description: Added signature for changeset e8b793f2c409 diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 7f031e43def3 -r 096706c5b616 .hgsigs --- a/.hgsigs Sat Oct 25 06:57:11 2014 +0300 +++ b/.hgsigs Sat Oct 25 06:57:25 2014 +0300 @@ -83,3 +83,4 @@ c55c660d6e9dd0b433768c906c1462cf6e8d71d5 0 iEYEABECAAYFAlNv0HUACgkQyUhSUUBVisllBwCePV2jKcugiF0QYnIFLGJytMsW22kAn2bGBQ5hD/LrpTml5h9aCchkpSL3 34e52cbeb83725178c0c0a282ffa5ef1c161e3cb 0 iEYEABECAAYFAlQuvlIACgkQyUhSUUBVislFdwCfTD1ctLwAmkwWzuIugFdnLBo7wYoAoJbAtUIRsFyyxdgvslqT9aJ6Mg0A 6dad1f6e8930940f3c763cf3f27aaa7a9c979520 0 iEYEABECAAYFAlQ9VDQACgkQyUhSUUBVisk1fgCfdmFGZA/0DGz9vQFDeBTFK/JLhAEAnA966b+cMBaRegwj/v0Zta7c62lS +e8b793f2c4091f76075e66d5166b38cf82e598bd 0 iEYEABECAAYFAlRLH5gACgkQyUhSUUBVisn+6gCfcGV1kM2OS9udaFxY7MVtqaaGwYAAnRxUc/RGeUhvJGdg9LvSSzBFPCfz From pigeonhole at rename-it.nl Sat Oct 25 19:51:25 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 25 Oct 2014 21:51:25 +0200 Subject: dovecot-2.2-pigeonhole: Adjusted to datastack-related changes in... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/15b2910b145c changeset: 1936:15b2910b145c user: Stephan Bosch date: Sat Oct 25 21:51:16 2014 +0200 description: Adjusted to datastack-related changes in Dovecot lib-storage. diffstat: src/lib-sieve/util/edit-mail.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 819b8fb22034 -r 15b2910b145c src/lib-sieve/util/edit-mail.c --- a/src/lib-sieve/util/edit-mail.c Sun Oct 19 22:50:23 2014 +0200 +++ b/src/lib-sieve/util/edit-mail.c Sat Oct 25 21:51:16 2014 +0200 @@ -1473,7 +1473,7 @@ (&edmail->wrapped->mail, field_name, decode_to_utf8, value_r); } - t_array_init(&header_values, 1); + p_array_init(&header_values, edmail->mail.pool, 1); (void)array_append_space(&header_values); *value_r = array_idx(&header_values, 0); return 0; @@ -1489,7 +1489,7 @@ } /* Fill result array */ - t_array_init(&header_values, 32); + p_array_init(&header_values, edmail->mail.pool, 32); field_idx = header_idx->first; while ( field_idx != NULL ) { From dovecot at dovecot.org Sat Oct 25 19:54:35 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 25 Oct 2014 19:54:35 +0000 Subject: dovecot-2.2: dsync: Added debug logging for attribute importing Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4155055df7a9 changeset: 18018:4155055df7a9 user: Timo Sirainen date: Sat Oct 25 22:53:35 2014 +0300 description: dsync: Added debug logging for attribute importing diffstat: src/doveadm/dsync/dsync-mailbox-import.c | 33 ++++++++++++++++++++++++++++--- 1 files changed, 29 insertions(+), 4 deletions(-) diffs (92 lines): diff -r 096706c5b616 -r 4155055df7a9 src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Sat Oct 25 06:57:25 2014 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Sat Oct 25 22:53:35 2014 +0300 @@ -370,8 +370,10 @@ return dsync_attributes_cmp_values(attr, local_attr, cmp_r); } -int dsync_mailbox_import_attribute(struct dsync_mailbox_importer *importer, - const struct dsync_mailbox_attribute *attr) +static int +dsync_mailbox_import_attribute_real(struct dsync_mailbox_importer *importer, + const struct dsync_mailbox_attribute *attr, + const char **result_r) { struct dsync_mailbox_attribute *local_attr; struct mail_attribute_value value; @@ -386,25 +388,31 @@ if (attr->deleted && (local_attr == NULL || !DSYNC_ATTR_HAS_VALUE(local_attr))) { /* attribute doesn't exist on either side -> ignore */ + *result_r = "Nonexistent in both sides"; return 0; } if (local_attr == NULL) { /* we haven't seen this locally -> use whatever remote has */ + *result_r = "Nonexistent locally"; } else if (local_attr->modseq <= importer->last_common_modseq && attr->modseq > importer->last_common_modseq && importer->last_common_modseq > 0) { /* we're doing incremental syncing, and we can see that the attribute was changed remotely, but not locally -> use it */ + *result_r = "Changed remotely"; } else if (local_attr->modseq > importer->last_common_modseq && attr->modseq <= importer->last_common_modseq && importer->last_common_modseq > 0) { /* we're doing incremental syncing, and we can see that the attribute was changed locally, but not remotely -> ignore */ + *result_r = "Changed locally"; ignore = TRUE; } else if (attr->last_change > local_attr->last_change) { /* remote has a newer timestamp -> use it */ + *result_r = "Remote has newer timestamp"; } else if (attr->last_change < local_attr->last_change) { /* remote has an older timestamp -> ignore */ + *result_r = "Local has newer timestamp"; ignore = TRUE; } else { /* the timestamps are the same. now we're down to guessing @@ -418,17 +426,22 @@ } if (cmp == 0) { /* identical scripts */ + *result_r = "Unchanged value"; return 0; } if (attr->modseq > local_attr->modseq) { /* remote has a higher modseq -> use it */ + *result_r = "Remote has newer modseq"; } else if (attr->modseq < local_attr->modseq) { /* remote has an older modseq -> ignore */ + *result_r = "Local has newer modseq"; ignore = TRUE; + } else if (cmp < 0) { + ignore = TRUE; + *result_r = "Value changed, but unknown which is newer - picking local"; } else { - if (cmp < 0) - ignore = TRUE; + *result_r = "Value changed, but unknown which is newer - picking remote"; } } if (ignore) { @@ -454,6 +467,18 @@ return 0; } +int dsync_mailbox_import_attribute(struct dsync_mailbox_importer *importer, + const struct dsync_mailbox_attribute *attr) +{ + const char *result; + int ret; + + ret = dsync_mailbox_import_attribute_real(importer, attr, &result); + imp_debug(importer, "Import attribute %s: %s", attr->key, + ret < 0 ? "failed" : result); + return ret; +} + static void dsync_mail_error(struct dsync_mailbox_importer *importer, struct mail *mail, const char *field) { From dovecot at dovecot.org Sat Oct 25 21:09:01 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 25 Oct 2014 21:09:01 +0000 Subject: dovecot-2.2: master: Don't start new processes while shutting down. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d35288713625 changeset: 18019:d35288713625 user: Timo Sirainen date: Sun Oct 26 00:08:05 2014 +0300 description: master: Don't start new processes while shutting down. diffstat: src/master/service-monitor.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 4155055df7a9 -r d35288713625 src/master/service-monitor.c --- a/src/master/service-monitor.c Sat Oct 25 22:53:35 2014 +0300 +++ b/src/master/service-monitor.c Sun Oct 26 00:08:05 2014 +0300 @@ -652,7 +652,7 @@ if (throttle) service_monitor_throttle(service); service_stopped = service->status_fd[0] == -1; - if (!service_stopped) { + if (!service_stopped && !service->list->destroying) { service_monitor_start_extra_avail(service); /* if there are no longer listening processes, start listening for more */ From dovecot at dovecot.org Sat Oct 25 22:01:33 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 25 Oct 2014 22:01:33 +0000 Subject: dovecot-2.2: lib: If i_stream_seek() works by reading forward an... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/503b4b1b7aa1 changeset: 18020:503b4b1b7aa1 user: Timo Sirainen date: Sun Oct 26 01:00:36 2014 +0300 description: lib: If i_stream_seek() works by reading forward and read() fails, don't override the error message. diffstat: src/lib/istream.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (14 lines): diff -r d35288713625 -r 503b4b1b7aa1 src/lib/istream.c --- a/src/lib/istream.c Sun Oct 26 00:08:05 2014 +0300 +++ b/src/lib/istream.c Sun Oct 26 01:00:36 2014 +0300 @@ -749,6 +749,10 @@ available = stream->pos - stream->skip; if (available == 0) { + if (stream->istream.stream_errno != 0) { + /* read failed */ + return; + } io_stream_set_error(&stream->iostream, "Can't seek to offset %"PRIuUOFF_T ", because we have data only up to offset %" From dovecot at dovecot.org Sat Oct 25 22:03:08 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 25 Oct 2014 22:03:08 +0000 Subject: dovecot-2.2: man: Global options includes: Added description of ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e9607c048f1d changeset: 18021:e9607c048f1d user: Pascal Volk date: Sat Oct 25 21:24:06 2014 +0000 description: man: Global options includes: Added description of `-o setting=value'. diffstat: doc/man/global-options-formatter.inc | 13 ++++++++++++- doc/man/global-options.inc | 13 ++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diffs (44 lines): diff -r 503b4b1b7aa1 -r e9607c048f1d doc/man/global-options-formatter.inc --- a/doc/man/global-options-formatter.inc Sun Oct 26 01:00:36 2014 +0300 +++ b/doc/man/global-options-formatter.inc Sat Oct 25 21:24:06 2014 +0000 @@ -31,5 +31,16 @@ prints a table header followed by adjusted value lines. .RE .TP +.BI \-o\ setting = value +Overrides the configuration +.I setting +from +.I @pkgsysconfdir@/dovecot.conf +and from the userdb with the given +.IR value . +In order to override multiple settings, the +.B \-o +option may be specified multiple times. +.TP .B \-v -Enables verbosity, including progress counter. +Enables verbosity, including progress counter. \ No newline at end of file diff -r 503b4b1b7aa1 -r e9607c048f1d doc/man/global-options.inc --- a/doc/man/global-options.inc Sun Oct 26 01:00:36 2014 +0300 +++ b/doc/man/global-options.inc Sat Oct 25 21:24:06 2014 +0000 @@ -6,5 +6,16 @@ .B \-D Enables verbosity and debug messages. .TP +.BI \-o\ setting = value +Overrides the configuration +.I setting +from +.I @pkgsysconfdir@/dovecot.conf +and from the userdb with the given +.IR value . +In order to override multiple settings, the +.B \-o +option may be specified multiple times. +.TP .B \-v -Enables verbosity, including progress counter. +Enables verbosity, including progress counter. \ No newline at end of file From dovecot at dovecot.org Sat Oct 25 22:21:09 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 25 Oct 2014 22:21:09 +0000 Subject: dovecot-2.2: man: Global options includes: Added back the newlin... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e5c58f244c5b changeset: 18022:e5c58f244c5b user: Pascal Volk date: Sat Oct 25 22:18:07 2014 +0000 description: man: Global options includes: Added back the newline at end of files. They were accidentally removed in the previous commit. diffstat: doc/man/global-options-formatter.inc | 2 +- doc/man/global-options.inc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diffs (20 lines): diff -r e9607c048f1d -r e5c58f244c5b doc/man/global-options-formatter.inc --- a/doc/man/global-options-formatter.inc Sat Oct 25 21:24:06 2014 +0000 +++ b/doc/man/global-options-formatter.inc Sat Oct 25 22:18:07 2014 +0000 @@ -43,4 +43,4 @@ option may be specified multiple times. .TP .B \-v -Enables verbosity, including progress counter. \ No newline at end of file +Enables verbosity, including progress counter. diff -r e9607c048f1d -r e5c58f244c5b doc/man/global-options.inc --- a/doc/man/global-options.inc Sat Oct 25 21:24:06 2014 +0000 +++ b/doc/man/global-options.inc Sat Oct 25 22:18:07 2014 +0000 @@ -18,4 +18,4 @@ option may be specified multiple times. .TP .B \-v -Enables verbosity, including progress counter. \ No newline at end of file +Enables verbosity, including progress counter. From dovecot at dovecot.org Sat Oct 25 23:00:07 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 25 Oct 2014 23:00:07 +0000 Subject: dovecot-2.2: lib-http server: If i/ostream fails, don't return w... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5cd30ecff35d changeset: 18023:5cd30ecff35d user: Timo Sirainen date: Sun Oct 26 01:59:05 2014 +0300 description: lib-http server: If i/ostream fails, don't return wrong "stream input size changed" error. Also handle the real case in a bit nicer way. diffstat: src/lib-http/http-server-response.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) diffs (20 lines): diff -r e5c58f244c5b -r 5cd30ecff35d src/lib-http/http-server-response.c --- a/src/lib-http/http-server-response.c Sat Oct 25 22:18:07 2014 +0000 +++ b/src/lib-http/http-server-response.c Sun Oct 26 01:59:05 2014 +0300 @@ -259,10 +259,12 @@ } if (ret < 0 || i_stream_is_eof(resp->payload_input)) { - if (!resp->payload_chunked && - resp->payload_input->v_offset - resp->payload_offset != resp->payload_size) { - i_error("stream input size changed"); //FIXME - return -1; + if (ret >= 0 && !resp->payload_chunked && + resp->payload_input->v_offset - resp->payload_offset != resp->payload_size) { + *error_r = t_strdup_printf( + "Input stream %s size changed unexpectedly", + i_stream_get_name(resp->payload_input)); + ret = -1; } http_server_response_finish_payload_out(resp); From dovecot at dovecot.org Sat Oct 25 23:04:17 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 25 Oct 2014 23:04:17 +0000 Subject: dovecot-2.2: fs-posix: fs_copy() no longer fails if destination ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d50151444c9a changeset: 18024:d50151444c9a user: Timo Sirainen date: Sun Oct 26 02:03:22 2014 +0300 description: fs-posix: fs_copy() no longer fails if destination exists and FS_OPEN_MODE_REPLACE is used diffstat: src/lib-fs/fs-posix.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diffs (22 lines): diff -r 5cd30ecff35d -r d50151444c9a src/lib-fs/fs-posix.c --- a/src/lib-fs/fs-posix.c Sun Oct 26 01:59:05 2014 +0300 +++ b/src/lib-fs/fs-posix.c Sun Oct 26 02:03:22 2014 +0300 @@ -610,11 +610,18 @@ static int fs_posix_copy(struct fs_file *_src, struct fs_file *_dest) { + struct posix_fs_file *dest = (struct posix_fs_file *)_dest; struct posix_fs *fs = (struct posix_fs *)_src->fs; unsigned int try_count = 0; int ret; ret = link(_src->path, _dest->path); + if (errno == EEXIST && dest->open_mode == FS_OPEN_MODE_REPLACE) { + /* destination file already exists - replace it */ + if (unlink(_dest->path) < 0 && errno != ENOENT) + i_error("unlink(%s) failed: %m", _dest->path); + ret = link(_src->path, _dest->path); + } while (ret < 0 && errno == ENOENT && try_count <= MAX_MKDIR_RETRY_COUNT) { if (fs_posix_mkdir_parents(fs, _dest->path) < 0) From pigeonhole at rename-it.nl Sun Oct 26 13:10:37 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 26 Oct 2014 14:10:37 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: storage: Fixed bug in synchro... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/79988ab8b2df changeset: 1937:79988ab8b2df user: Stephan Bosch date: Sun Oct 26 14:10:27 2014 +0100 description: lib-sieve: storage: Fixed bug in synchronization intialization. Storage flag checks were bogus. diffstat: src/lib-sieve/sieve-storage-sync.c | 16 ++++++++++------ 1 files changed, 10 insertions(+), 6 deletions(-) diffs (35 lines): diff -r 15b2910b145c -r 79988ab8b2df src/lib-sieve/sieve-storage-sync.c --- a/src/lib-sieve/sieve-storage-sync.c Sat Oct 25 21:51:16 2014 +0200 +++ b/src/lib-sieve/sieve-storage-sync.c Sun Oct 26 14:10:27 2014 +0100 @@ -26,21 +26,25 @@ { struct mail_namespace *ns; struct mailbox *box; - enum mailbox_flags flags = MAILBOX_FLAG_IGNORE_ACLS; + enum sieve_storage_flags sflags = storage->flags; + enum mailbox_flags mflags = MAILBOX_FLAG_IGNORE_ACLS; enum mail_error error; - - if ( (flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) == 0 && - (flags & SIEVE_STORAGE_FLAG_READWRITE) == 0 ) + + if ( (sflags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) == 0 && + (sflags & SIEVE_STORAGE_FLAG_READWRITE) == 0 ) return 0; if ( !storage->allows_synchronization ) { - if ( (flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) != 0 ) + if ( (sflags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) != 0 ) return -1; return 0; } + sieve_storage_sys_debug(storage, "sync: " + "Opening INBOX for attribute modifications"); + ns = mail_namespace_find_inbox(user->namespaces); - storage->sync_inbox = box = mailbox_alloc(ns->list, "INBOX", flags); + storage->sync_inbox = box = mailbox_alloc(ns->list, "INBOX", mflags); if (mailbox_open(box) == 0) return 0; From dovecot at dovecot.org Sun Oct 26 16:44:58 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 26 Oct 2014 16:44:58 +0000 Subject: dovecot-2.2: lib-http: client: The asserts recently added to htt... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/583215301ba7 changeset: 18025:583215301ba7 user: Stephan Bosch date: Sun Oct 26 18:43:57 2014 +0200 description: lib-http: client: The asserts recently added to http_connection_check_idle() are bogus. diffstat: src/lib-http/http-client-connection.c | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diffs (13 lines): diff -r d50151444c9a -r 583215301ba7 src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Sun Oct 26 02:03:22 2014 +0300 +++ b/src/lib-http/http-client-connection.c Sun Oct 26 18:43:57 2014 +0200 @@ -209,9 +209,6 @@ { unsigned int timeout, count; - i_assert(!conn->close_indicated); - i_assert(!conn->output_broken); - if (conn->connected && array_is_created(&conn->request_wait_list) && array_count(&conn->request_wait_list) == 0 && From dovecot at dovecot.org Sun Oct 26 16:44:58 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 26 Oct 2014 16:44:58 +0000 Subject: dovecot-2.2: lib-http: client: Removed asssert in http_client_co... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/69af57dcd274 changeset: 18026:69af57dcd274 user: Stephan Bosch date: Sun Oct 26 18:43:57 2014 +0200 description: lib-http: client: Removed asssert in http_client_connection_is_ready(). There is no reason why the input stream couldn't be full. diffstat: src/lib-http/http-client-connection.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diffs (15 lines): diff -r 583215301ba7 -r 69af57dcd274 src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Sun Oct 26 18:43:57 2014 +0200 +++ b/src/lib-http/http-client-connection.c Sun Oct 26 18:43:57 2014 +0200 @@ -176,10 +176,9 @@ /* Active ioloop is different from what we saw earlier; we may have missed a disconnection event on this connection. Verify status by reading from connection. */ - if ((ret=i_stream_read(conn->conn.input)) < 0) { + if ((ret=i_stream_read(conn->conn.input)) == -1) { int stream_errno = conn->conn.input->stream_errno; - i_assert(ret != -2); i_assert(conn->conn.input->stream_errno != 0 || conn->conn.input->eof); http_client_connection_abort_temp_error(&conn, HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, From dovecot at dovecot.org Sun Oct 26 16:44:59 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 26 Oct 2014 16:44:59 +0000 Subject: dovecot-2.2: lib-http: server: Fixed a hang occurring sometimes ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c7629d149d7a changeset: 18027:c7629d149d7a user: Stephan Bosch date: Sun Oct 26 18:43:57 2014 +0200 description: lib-http: server: Fixed a hang occurring sometimes when response is sent for a request that had payload. Forgot to always trigger sending response when processing request payload finishes. diffstat: src/lib-http/http-server-connection.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (21 lines): diff -r 69af57dcd274 -r c7629d149d7a src/lib-http/http-server-connection.c --- a/src/lib-http/http-server-connection.c Sun Oct 26 18:43:57 2014 +0200 +++ b/src/lib-http/http-server-connection.c Sun Oct 26 18:43:57 2014 +0200 @@ -229,6 +229,8 @@ req->state = HTTP_SERVER_REQUEST_STATE_PROCESSING; if (req->response != NULL && req->response->submitted) http_server_request_submit_response(req); + } else if (req->state == HTTP_SERVER_REQUEST_STATE_SUBMITTED_RESPONSE) { + http_server_request_ready_to_respond(req); } /* input stream may have pending input. make sure input handler @@ -749,7 +751,7 @@ bool http_server_connection_pending_payload(struct http_server_connection *conn) { - return http_request_parser_pending_payload(conn->http_parser); + return conn->incoming_payload != NULL; } static struct connection_settings http_server_connection_set = { From dovecot at dovecot.org Mon Oct 27 18:11:18 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 27 Oct 2014 18:11:18 +0000 Subject: dovecot-2.2: lib-storage: Recent change broke deleting mailboxes... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/78f24e681302 changeset: 18028:78f24e681302 user: Timo Sirainen date: Mon Oct 27 17:05:52 2014 +0200 description: lib-storage: Recent change broke deleting mailboxes with LAYOUT=index diffstat: src/lib-storage/list/mailbox-list-index-backend.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r c7629d149d7a -r 78f24e681302 src/lib-storage/list/mailbox-list-index-backend.c --- a/src/lib-storage/list/mailbox-list-index-backend.c Sun Oct 26 18:43:57 2014 +0200 +++ b/src/lib-storage/list/mailbox-list-index-backend.c Mon Oct 27 17:05:52 2014 +0200 @@ -496,7 +496,8 @@ struct mailbox_list_index_sync_context *sync_ctx; int ret; - if (strcmp(name, list->create_mailbox_name) == 0) { + if (list->create_mailbox_name != NULL && + strcmp(name, list->create_mailbox_name) == 0) { /* we're rollbacking a failed create. if the name exists in the list, it was done by somebody else so we don't want to remove it. */ From dovecot at dovecot.org Mon Oct 27 18:11:18 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 27 Oct 2014 18:11:18 +0000 Subject: dovecot-2.2: master: Added an assert to catch duplicate fork() P... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f97ca2bde414 changeset: 18029:f97ca2bde414 user: Timo Sirainen date: Mon Oct 27 20:10:19 2014 +0200 description: master: Added an assert to catch duplicate fork() PIDs. This really shouldn't be happening, but apparently it does sometimes. This should make it easier to debug. diffstat: src/master/service-process.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 78f24e681302 -r f97ca2bde414 src/master/service-process.c --- a/src/master/service-process.c Mon Oct 27 17:05:52 2014 +0200 +++ b/src/master/service-process.c Mon Oct 27 20:10:19 2014 +0200 @@ -334,6 +334,7 @@ drop_privileges(service); process_exec(service->executable, NULL); } + i_assert(hash_table_lookup(service_pids, POINTER_CAST(pid)) == NULL); process = i_new(struct service_process, 1); process->service = service; From dovecot at dovecot.org Mon Oct 27 18:15:45 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 27 Oct 2014 18:15:45 +0000 Subject: dovecot-2.2: log: Don't crash if master sends a negative service... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c77d602d4be4 changeset: 18030:c77d602d4be4 user: Timo Sirainen date: Mon Oct 27 20:14:47 2014 +0200 description: log: Don't crash if master sends a negative service_fd number. diffstat: src/log/log-connection.c | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) diffs (36 lines): diff -r f97ca2bde414 -r c77d602d4be4 src/log/log-connection.c --- a/src/log/log-connection.c Mon Oct 27 20:10:19 2014 +0200 +++ b/src/log/log-connection.c Mon Oct 27 20:14:47 2014 +0200 @@ -143,26 +143,26 @@ struct log_client *client; const char *p, *p2, *cmd; unsigned int count; - int service_fd; + unsigned int service_fd; pid_t pid; p = strchr(line, ' '); - if (p == NULL || (p2 = strchr(++p, ' ')) == NULL) { + if (p == NULL || (p2 = strchr(++p, ' ')) == NULL || + str_to_uint(t_strcut(line, ' '), &service_fd) < 0) { i_error("Received invalid input from master: %s", line); return; } - service_fd = atoi(t_strcut(line, ' ')); pid = strtol(t_strcut(p, ' '), NULL, 10); cmd = p2 + 1; logs = array_get(&logs_by_fd, &count); - if (service_fd >= (int)count || logs[service_fd] == NULL) { - if (strcmp(cmd, "BYE") == 0 && service_fd < (int)count) { + if (service_fd >= count || logs[service_fd] == NULL) { + if (strcmp(cmd, "BYE") == 0 && service_fd < count) { /* master is probably shutting down and we already noticed the log fd closing */ return; } - i_error("Received master input for invalid service_fd %d: %s", + i_error("Received master input for invalid service_fd %u: %s", service_fd, line); return; } From dovecot at dovecot.org Mon Oct 27 18:25:34 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 27 Oct 2014 18:25:34 +0000 Subject: dovecot-2.2: master: Don't send broken BYE notifications to log ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/03889e81929e changeset: 18031:03889e81929e user: Timo Sirainen date: Mon Oct 27 20:24:34 2014 +0200 description: master: Don't send broken BYE notifications to log process. diffstat: src/master/service-log.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r c77d602d4be4 -r 03889e81929e src/master/service-log.c --- a/src/master/service-log.c Mon Oct 27 20:14:47 2014 +0200 +++ b/src/master/service-log.c Mon Oct 27 20:24:34 2014 +0200 @@ -55,6 +55,11 @@ { const char *data; + if (process->service->log_process_internal_fd == -1) { + /* another log process was just destroyed */ + return 0; + } + data = t_strdup_printf("%d %s BYE\n", process->service->log_process_internal_fd, dec2str(process->pid)); From pigeonhole at rename-it.nl Mon Oct 27 20:58:31 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Mon, 27 Oct 2014 21:58:31 +0100 Subject: dovecot-2.2-pigeonhole: doveadm-sieve: Fixed problem with synchr... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/79d66ccc9bfc changeset: 1938:79d66ccc9bfc user: Stephan Bosch date: Mon Oct 27 21:58:13 2014 +0100 description: doveadm-sieve: Fixed problem with synchronizing the active script. diffstat: src/lib-sieve/sieve-script.c | 8 ++++- src/lib-sieve/sieve-storage-private.h | 6 ++++ src/lib-sieve/sieve-storage-sync.c | 30 ++++++++++++++++++++++++ src/lib-sieve/sieve-storage.c | 7 ++++- src/plugins/doveadm-sieve/doveadm-sieve-plugin.c | 2 +- 5 files changed, 48 insertions(+), 5 deletions(-) diffs (105 lines): diff -r 79988ab8b2df -r 79d66ccc9bfc src/lib-sieve/sieve-script.c --- a/src/lib-sieve/sieve-script.c Sun Oct 26 14:10:27 2014 +0100 +++ b/src/lib-sieve/sieve-script.c Mon Oct 27 21:58:13 2014 +0100 @@ -520,15 +520,19 @@ int sieve_script_activate(struct sieve_script *script, time_t mtime) { + struct sieve_storage *storage = script->storage; int ret; - i_assert( (script->storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0 ); + i_assert( (storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0 ); i_assert( script->open ); // FIXME: auto-open? i_assert( script->v.activate != NULL ); ret = script->v.activate(script); - sieve_storage_set_modified(script->storage, mtime); + if (ret >= 0) { + sieve_storage_set_modified(storage, mtime); + sieve_storage_sync_script_activate(storage); + } return ret; } diff -r 79988ab8b2df -r 79d66ccc9bfc src/lib-sieve/sieve-storage-private.h --- a/src/lib-sieve/sieve-storage-private.h Sun Oct 26 14:10:27 2014 +0100 +++ b/src/lib-sieve/sieve-storage-private.h Mon Oct 27 21:58:13 2014 +0100 @@ -243,4 +243,10 @@ void sieve_storage_sync_script_delete (struct sieve_storage *storage, const char *name); +void sieve_storage_sync_script_activate +(struct sieve_storage *storage); +void sieve_storage_sync_deactivate +(struct sieve_storage *storage); + + #endif diff -r 79988ab8b2df -r 79d66ccc9bfc src/lib-sieve/sieve-storage-sync.c --- a/src/lib-sieve/sieve-storage-sync.c Sun Oct 26 14:10:27 2014 +0100 +++ b/src/lib-sieve/sieve-storage-sync.c Mon Oct 27 21:58:13 2014 +0100 @@ -134,3 +134,33 @@ mail_index_attribute_unset(t->itrans, TRUE, key, ioloop_time); sieve_storage_sync_transaction_finish(storage, &t); } + +void sieve_storage_sync_script_activate +(struct sieve_storage *storage) +{ + struct mailbox_transaction_context *t; + + if (storage->sync_inbox == NULL) + return; + + t = mailbox_transaction_begin(storage->sync_inbox, 0); + mail_index_attribute_set + (t->itrans, TRUE, MAILBOX_ATTRIBUTE_SIEVE_DEFAULT, ioloop_time, 0); + sieve_storage_sync_transaction_finish(storage, &t); +} + +void sieve_storage_sync_deactivate +(struct sieve_storage *storage) +{ + struct mailbox_transaction_context *t; + + if (storage->sync_inbox == NULL) + return; + + t = mailbox_transaction_begin(storage->sync_inbox, 0); + mail_index_attribute_unset + (t->itrans, TRUE, MAILBOX_ATTRIBUTE_SIEVE_DEFAULT, ioloop_time); + sieve_storage_sync_transaction_finish(storage, &t); +} + + diff -r 79988ab8b2df -r 79d66ccc9bfc src/lib-sieve/sieve-storage.c --- a/src/lib-sieve/sieve-storage.c Sun Oct 26 14:10:27 2014 +0100 +++ b/src/lib-sieve/sieve-storage.c Mon Oct 27 21:58:13 2014 +0100 @@ -670,8 +670,11 @@ i_assert(storage->v.deactivate != NULL); ret = storage->v.deactivate(storage); - - sieve_storage_set_modified(storage, mtime); + + if (ret >= 0) { + sieve_storage_set_modified(storage, mtime); + sieve_storage_sync_deactivate(storage); + } return ret; } diff -r 79988ab8b2df -r 79d66ccc9bfc src/plugins/doveadm-sieve/doveadm-sieve-plugin.c --- a/src/plugins/doveadm-sieve/doveadm-sieve-plugin.c Sun Oct 26 14:10:27 2014 +0100 +++ b/src/plugins/doveadm-sieve/doveadm-sieve-plugin.c Mon Oct 27 21:58:13 2014 +0100 @@ -188,7 +188,7 @@ { int ret; - if ((ret=sieve_storage_is_singular(svstorage)) <= 0) { + if ((ret=sieve_storage_is_singular(svstorage)) != 0) { if (ret < 0) mail_storage_set_internal_error(storage); return ret; From dovecot at dovecot.org Mon Oct 27 21:42:33 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 27 Oct 2014 21:42:33 +0000 Subject: dovecot-2.2: lib: Make sure ostream.last_failed_errno is always ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/39e2455a5e2d changeset: 18034:39e2455a5e2d user: Timo Sirainen date: Mon Oct 27 23:29:39 2014 +0200 description: lib: Make sure ostream.last_failed_errno is always set when stream_errno is set. diffstat: src/lib/ostream.c | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletions(-) diffs (33 lines): diff -r 3402a3d19f40 -r 39e2455a5e2d src/lib/ostream.c --- a/src/lib/ostream.c Mon Oct 27 23:26:10 2014 +0200 +++ b/src/lib/ostream.c Mon Oct 27 23:29:39 2014 +0200 @@ -55,8 +55,12 @@ stream->closed = TRUE; } - if (stream->stream_errno == 0) + if (stream->stream_errno != 0) + i_assert(stream->last_failed_errno != 0); + else { stream->stream_errno = EPIPE; + stream->last_failed_errno = EPIPE; + } } void o_stream_destroy(struct ostream **stream) @@ -516,6 +520,7 @@ uoff_t offset ATTR_UNUSED) { _stream->ostream.stream_errno = ESPIPE; + _stream->ostream.last_failed_errno = ESPIPE; return -1; } @@ -525,6 +530,7 @@ size_t size ATTR_UNUSED, uoff_t offset ATTR_UNUSED) { _stream->ostream.stream_errno = ESPIPE; + _stream->ostream.last_failed_errno = ESPIPE; return -1; } From pigeonhole at rename-it.nl Mon Oct 27 23:54:27 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 28 Oct 2014 00:54:27 +0100 Subject: dovecot-2.2-pigeonhole: doveadm-sieve: Fixed timeout leaks occur... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/68c7a4bdea66 changeset: 1939:68c7a4bdea66 user: Stephan Bosch date: Tue Oct 28 00:54:15 2014 +0100 description: doveadm-sieve: Fixed timeout leaks occuring while running doveadm. This was caused by a circular reference. diffstat: src/lib-sieve/sieve-script.c | 6 +- src/lib-sieve/sieve-storage-private.h | 12 +- src/lib-sieve/sieve-storage-sync.c | 148 +++++++++++++++++++-------------- src/lib-sieve/sieve-storage.c | 6 +- 4 files changed, 99 insertions(+), 73 deletions(-) diffs (truncated from 324 to 300 lines): diff -r 79d66ccc9bfc -r 68c7a4bdea66 src/lib-sieve/sieve-script.c --- a/src/lib-sieve/sieve-script.c Mon Oct 27 21:58:13 2014 +0100 +++ b/src/lib-sieve/sieve-script.c Tue Oct 28 00:54:15 2014 +0100 @@ -478,7 +478,7 @@ /* rename INBOX mailbox attribute */ if ( ret >= 0 && oldname != NULL ) - sieve_storage_sync_script_rename(storage, oldname, newname); + (void)sieve_storage_sync_script_rename(storage, oldname, newname); return ret; } @@ -504,7 +504,7 @@ /* unset INBOX mailbox attribute */ if ( ret >= 0 ) - sieve_storage_sync_script_delete(storage, script->name); + (void)sieve_storage_sync_script_delete(storage, script->name); /* Always deinitialize the script object */ sieve_script_unref(_script); @@ -531,7 +531,7 @@ if (ret >= 0) { sieve_storage_set_modified(storage, mtime); - sieve_storage_sync_script_activate(storage); + (void)sieve_storage_sync_script_activate(storage); } return ret; diff -r 79d66ccc9bfc -r 68c7a4bdea66 src/lib-sieve/sieve-storage-private.h --- a/src/lib-sieve/sieve-storage-private.h Mon Oct 27 21:58:13 2014 +0100 +++ b/src/lib-sieve/sieve-storage-private.h Tue Oct 28 00:54:15 2014 +0100 @@ -109,7 +109,7 @@ const char *script_name; const char *bin_dir; - struct mailbox *sync_inbox; + struct mail_namespace *sync_inbox_ns; enum sieve_storage_flags flags; @@ -235,17 +235,17 @@ void sieve_storage_sync_deinit (struct sieve_storage *storage); -void sieve_storage_sync_script_save +int sieve_storage_sync_script_save (struct sieve_storage *storage, const char *name); -void sieve_storage_sync_script_rename +int sieve_storage_sync_script_rename (struct sieve_storage *storage, const char *oldname, const char *newname); -void sieve_storage_sync_script_delete +int sieve_storage_sync_script_delete (struct sieve_storage *storage, const char *name); -void sieve_storage_sync_script_activate +int sieve_storage_sync_script_activate (struct sieve_storage *storage); -void sieve_storage_sync_deactivate +int sieve_storage_sync_deactivate (struct sieve_storage *storage); diff -r 79d66ccc9bfc -r 68c7a4bdea66 src/lib-sieve/sieve-storage-sync.c --- a/src/lib-sieve/sieve-storage-sync.c Mon Oct 27 21:58:13 2014 +0100 +++ b/src/lib-sieve/sieve-storage-sync.c Tue Oct 28 00:54:15 2014 +0100 @@ -24,11 +24,7 @@ int sieve_storage_sync_init (struct sieve_storage *storage, struct mail_user *user) { - struct mail_namespace *ns; - struct mailbox *box; enum sieve_storage_flags sflags = storage->flags; - enum mailbox_flags mflags = MAILBOX_FLAG_IGNORE_ACLS; - enum mail_error error; if ( (sflags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) == 0 && (sflags & SIEVE_STORAGE_FLAG_READWRITE) == 0 ) @@ -41,126 +37,156 @@ } sieve_storage_sys_debug(storage, "sync: " - "Opening INBOX for attribute modifications"); + "Synchronization active"); - ns = mail_namespace_find_inbox(user->namespaces); - storage->sync_inbox = box = mailbox_alloc(ns->list, "INBOX", mflags); - if (mailbox_open(box) == 0) - return 0; - - sieve_storage_sys_warning(storage, "sync: " - "Failed to open user INBOX for attribute modifications: %s", - mailbox_get_last_error(box, &error)); - return -1; + storage->sync_inbox_ns = mail_namespace_find_inbox(user->namespaces); + return 0; } void sieve_storage_sync_deinit -(struct sieve_storage *storage) +(struct sieve_storage *storage ATTR_UNUSED) { - if (storage->sync_inbox != NULL) - mailbox_free(&storage->sync_inbox); + /* nothing */ } /* * Sync attributes */ -static void sieve_storage_sync_transaction_finish -(struct sieve_storage *storage, struct mailbox_transaction_context **t) +static int sieve_storage_sync_transaction_begin +(struct sieve_storage *storage, struct mailbox_transaction_context **trans_r) { - struct mailbox *inbox = storage->sync_inbox; + enum mailbox_flags mflags = MAILBOX_FLAG_IGNORE_ACLS; + struct mail_namespace *ns = storage->sync_inbox_ns; + struct mailbox *inbox; + enum mail_error error; - i_assert( storage->sync_inbox != NULL ); + if (ns == NULL) + return 0; - if (mailbox_transaction_commit(t) < 0) { + inbox = mailbox_alloc(ns->list, "INBOX", mflags); + if (mailbox_open(inbox) < 0) { + sieve_storage_sys_warning(storage, "sync: " + "Failed to open user INBOX for attribute modifications: %s", + mailbox_get_last_error(inbox, &error)); + return -1; + } + + *trans_r = mailbox_transaction_begin(inbox, 0); + return 1; +} + +static int sieve_storage_sync_transaction_finish +(struct sieve_storage *storage, struct mailbox_transaction_context **trans) +{ + struct mailbox *inbox; + int ret; + + inbox = mailbox_transaction_get_mailbox(*trans); + + if ((ret=mailbox_transaction_commit(trans)) < 0) { enum mail_error error; sieve_storage_sys_warning(storage, "sync: " "Failed to update INBOX attributes: %s", mail_storage_get_last_error(mailbox_get_storage(inbox), &error)); } + + mailbox_free(&inbox); + return ret; } -void sieve_storage_sync_script_save +int sieve_storage_sync_script_save (struct sieve_storage *storage, const char *name) { - struct mailbox_transaction_context *t; + struct mailbox_transaction_context *trans; const char *key; + int ret; - if (storage->sync_inbox == NULL) - return; + if ((ret=sieve_storage_sync_transaction_begin + (storage, &trans)) <= 0) + return ret; key = t_strconcat (MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, name, NULL); - t = mailbox_transaction_begin(storage->sync_inbox, 0); - mail_index_attribute_set(t->itrans, TRUE, key, ioloop_time, 0); - sieve_storage_sync_transaction_finish(storage, &t); + + mail_index_attribute_set(trans->itrans, TRUE, key, ioloop_time, 0); + + return sieve_storage_sync_transaction_finish(storage, &trans); } -void sieve_storage_sync_script_rename +int sieve_storage_sync_script_rename (struct sieve_storage *storage, const char *oldname, const char *newname) { - struct mailbox_transaction_context *t; + struct mailbox_transaction_context *trans; const char *oldkey, *newkey; + int ret; - if (storage->sync_inbox == NULL) - return; + if ((ret=sieve_storage_sync_transaction_begin + (storage, &trans)) <= 0) + return ret; oldkey = t_strconcat (MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, oldname, NULL); newkey = t_strconcat (MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, newname, NULL); - t = mailbox_transaction_begin(storage->sync_inbox, 0); - mail_index_attribute_unset(t->itrans, TRUE, oldkey, ioloop_time); - mail_index_attribute_set(t->itrans, TRUE, newkey, ioloop_time, 0); - sieve_storage_sync_transaction_finish(storage, &t); + mail_index_attribute_unset(trans->itrans, TRUE, oldkey, ioloop_time); + mail_index_attribute_set(trans->itrans, TRUE, newkey, ioloop_time, 0); + + return sieve_storage_sync_transaction_finish(storage, &trans); } -void sieve_storage_sync_script_delete +int sieve_storage_sync_script_delete (struct sieve_storage *storage, const char *name) { - struct mailbox_transaction_context *t; + struct mailbox_transaction_context *trans; const char *key; + int ret; - if (storage->sync_inbox == NULL) - return; + if ((ret=sieve_storage_sync_transaction_begin + (storage, &trans)) <= 0) + return ret; key = t_strconcat (MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, name, NULL); - - t = mailbox_transaction_begin(storage->sync_inbox, 0); - mail_index_attribute_unset(t->itrans, TRUE, key, ioloop_time); - sieve_storage_sync_transaction_finish(storage, &t); + + mail_index_attribute_unset(trans->itrans, TRUE, key, ioloop_time); + + return sieve_storage_sync_transaction_finish(storage, &trans); } -void sieve_storage_sync_script_activate +int sieve_storage_sync_script_activate (struct sieve_storage *storage) { - struct mailbox_transaction_context *t; + struct mailbox_transaction_context *trans; + int ret; - if (storage->sync_inbox == NULL) - return; + if ((ret=sieve_storage_sync_transaction_begin + (storage, &trans)) <= 0) + return ret; - t = mailbox_transaction_begin(storage->sync_inbox, 0); - mail_index_attribute_set - (t->itrans, TRUE, MAILBOX_ATTRIBUTE_SIEVE_DEFAULT, ioloop_time, 0); - sieve_storage_sync_transaction_finish(storage, &t); + mail_index_attribute_set(trans->itrans, + TRUE, MAILBOX_ATTRIBUTE_SIEVE_DEFAULT, ioloop_time, 0); + + return sieve_storage_sync_transaction_finish(storage, &trans); } -void sieve_storage_sync_deactivate +int sieve_storage_sync_deactivate (struct sieve_storage *storage) { - struct mailbox_transaction_context *t; + struct mailbox_transaction_context *trans; + int ret; - if (storage->sync_inbox == NULL) - return; + if ((ret=sieve_storage_sync_transaction_begin + (storage, &trans)) <= 0) + return ret; - t = mailbox_transaction_begin(storage->sync_inbox, 0); - mail_index_attribute_unset - (t->itrans, TRUE, MAILBOX_ATTRIBUTE_SIEVE_DEFAULT, ioloop_time); - sieve_storage_sync_transaction_finish(storage, &t); + mail_index_attribute_unset(trans->itrans, + TRUE, MAILBOX_ATTRIBUTE_SIEVE_DEFAULT, ioloop_time); + + return sieve_storage_sync_transaction_finish(storage, &trans); } diff -r 79d66ccc9bfc -r 68c7a4bdea66 src/lib-sieve/sieve-storage.c --- a/src/lib-sieve/sieve-storage.c Mon Oct 27 21:58:13 2014 +0100 +++ b/src/lib-sieve/sieve-storage.c Tue Oct 28 00:54:15 2014 +0100 @@ -482,7 +482,7 @@ if (--storage->refcount != 0) return; From pigeonhole at rename-it.nl Tue Oct 28 00:49:01 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 28 Oct 2014 01:49:01 +0100 Subject: dovecot-2.2-pigeonhole: Added tag 0.4.4 for changeset b3303f675157 Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/55d584079a79 changeset: 1941:55d584079a79 user: Stephan Bosch date: Tue Oct 28 01:39:32 2014 +0100 description: Added tag 0.4.4 for changeset b3303f675157 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r b3303f675157 -r 55d584079a79 .hgtags --- a/.hgtags Tue Oct 28 01:39:14 2014 +0100 +++ b/.hgtags Tue Oct 28 01:39:32 2014 +0100 @@ -20,3 +20,4 @@ f1535e2255cd84849d8b4fad6d82bdd6e01f810f 0.4.1 2176d400eca4fa5d89597793a09c0b194eaed05f 0.4.2 1c6130ff5dd6933f03a40666b7f73ae51c9f90fe 0.4.3 +b3303f675157c954d2de08599e2c83db5a772450 0.4.4 From pigeonhole at rename-it.nl Tue Oct 28 00:49:01 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 28 Oct 2014 01:49:01 +0100 Subject: dovecot-2.2-pigeonhole: Released v0.4.4 for Dovecot v2.2.15. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/b3303f675157 changeset: 1940:b3303f675157 user: Stephan Bosch date: Tue Oct 28 01:39:14 2014 +0100 description: Released v0.4.4 for Dovecot v2.2.15. diffstat: NEWS | 33 +++++++++++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 34 insertions(+), 1 deletions(-) diffs (49 lines): diff -r 68c7a4bdea66 -r b3303f675157 NEWS --- a/NEWS Tue Oct 28 00:54:15 2014 +0100 +++ b/NEWS Tue Oct 28 01:39:14 2014 +0100 @@ -1,3 +1,36 @@ +v0.4.4 28-10-2014 Stephan Bosch + + * Added support for Japanese mail addresses with dots at non-standard places + in localpart. + * Changed handling of ENOSPACE into a normal temporary failure and added + handling of ENOQUOTA as a user error. + * Restructured result execution, so that all actions which involve mail + storage are always committed before all others. + + Implemented support for generic Sieve storages. Using alternative storages + now also possible for sieve_before/sieve_after. + + Implemented storage driver for retrieving Sieve scripts from LDAP. This + currently cannot be used with ManageSieve. + + Implemented sieve_redirect_envelope_from setting, which allows configuring + the envelope sender of redirected messages. + - Fixed handling of mail storage errors occurring while evaluating the input + message. + - managesieve-login: + - Removed bogus ALERT response code returned for AUTHENTICATE command. + - Fixed handling of invalid initial response argument to AUTHENTICATE + command. + - Fixed handling of stream errors in lexical scanner. + - Fixed handling of SMTP errors. Permanent and temporary errors were mixed up. + - Fixed several problems reported by CLang 3.4. + - duplicate extension: Fixed erroneous compile error about conflicting tags + when `:handle' argument was used last. + - relational extension: Fixed error handling of `:value' match. + - editheader extension: Fixed header unfolding and header iteration. + - mailbox extension: Fixed the `:create' tag, which erroneously subscribed an + existing folder. + - extprograms plugin: Fixed handling of error codes. + - doveadm-sieve plugin: Fixed several bugs. Synchronization of symbolic link + in the file storage should now also work properly. + v0.4.3 12-05-2014 Stephan Bosch * Editheader extension: Made control characters allowed for editheader, except diff -r 68c7a4bdea66 -r b3303f675157 configure.ac --- a/configure.ac Tue Oct 28 00:54:15 2014 +0100 +++ b/configure.ac Tue Oct 28 01:39:14 2014 +0100 @@ -1,4 +1,4 @@ -AC_INIT([Pigeonhole], [0.4.3], [dovecot at dovecot.org], [dovecot-2.2-pigeonhole]) +AC_INIT([Pigeonhole], [0.4.4], [dovecot at dovecot.org], [dovecot-2.2-pigeonhole]) AC_CONFIG_AUX_DIR([.]) AC_CONFIG_SRCDIR([src]) AC_CONFIG_MACRO_DIR([m4]) From pigeonhole at rename-it.nl Tue Oct 28 00:53:23 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 28 Oct 2014 01:53:23 +0100 Subject: dovecot-2.2-pigeonhole: Added signature for changeset b3303f675157 Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/1f897ed258ea changeset: 1942:1f897ed258ea user: Stephan Bosch date: Tue Oct 28 01:53:46 2014 +0100 description: Added signature for changeset b3303f675157 diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 55d584079a79 -r 1f897ed258ea .hgsigs --- a/.hgsigs Tue Oct 28 01:39:32 2014 +0100 +++ b/.hgsigs Tue Oct 28 01:53:46 2014 +0100 @@ -14,3 +14,4 @@ f1535e2255cd84849d8b4fad6d82bdd6e01f810f 0 iQEcBAABAgAGBQJR1IRdAAoJEATWKx49+7T0uKMIANauBvbSO72bhrg8EI3Cvr2qy5nZrgqdgtZI0ZtIHbRBa9aBmxbX5lGqjWNLZaXwLc9dk7aeDoZds73kjiCYB+ac3UaXBaRscKNArkigTKFE0L2UZ5X5T/76iJ6diPFs8Eo/4ajYERDa3UQgUqHJ/8Fe2884bFDXMRmjbtVu2ceCw8Dlkee4kiVfjzuPRWud2jjtXcCoJXkFIQSbGcKsjlhd2yAGToJ9iw06tPNAFjupht9/wozyaZiZqJj7AnNvflHGMO1FDhOQJYxjz9JYA61h9F1vytGwfm1n3BVANpWSBJtkkuM/Tjp9GxeDB2jNrUbMikicSUceNtRLg9i0b+A= 2176d400eca4fa5d89597793a09c0b194eaed05f 0 iQEcBAABAgAGBQJSRI5JAAoJEATWKx49+7T0kGcIAKNHvRh/4idzHekHk5L81e0nu1IZRLyXg6YLkviF52ZYsB4WSbsiVhVYGoVS0XdSCvouQFq//In5S8nkUaSc1r4/2VK/vEchisYxwnF0YyLz5o7CaixLBCARLGGbjZTCyHvqOCHj6sRTJtc7GP1cdFXzYo7yIGg+W1hZn7yBB32p6stE+9SurxinK312LGFvBRrJ9t7y9gIeP1aV9yd0AhTorAP0XsOMflNQnnxsNXR/8LhwsqpOt9TR8hTVdGZHi2ZqjqK37/XAGYAJpBvpQRFq2UPWj6fEGNRLsh9TzGodQh/RoESvTeoHpEVy5o2yHUcnY71bYfMpb2IJH7NHKAA= 1c6130ff5dd6933f03a40666b7f73ae51c9f90fe 0 iQEcBAABAgAGBQJTcR2fAAoJEATWKx49+7T0tcwIANUB68pzhOoVHY/BhReqVfFLJCZLdDpsTFYkPhS99lcI4LwTNrNDe4OjpNNdk3UESOvUi19pIzDCewXSkk1gVAK4CGFbYNgvLpaX+8xjfBiPv8Ct47ALCISpT74TCMXR8t+tQ3jqaPFD/0j7tAt3sP9vYDNKt1QJ8YLSH1z9aSEYng+LJT9rZxMkw6/SnZw4GVFmQyuPWFBEe7oBE/RdURvQ+i+luuBIs7BaJWe3HkMD9giEafxHzBtib4QDSUOeloUOl+7ezeBJDxdcp+CzbjU4J0QfpokuU8YhEEnnzZ+9x+Tmmnv04qzB5BP8msVVCldxfymQdGx/qxCLj26H6Uk= +b3303f675157c954d2de08599e2c83db5a772450 0 iQEcBAABAgAGBQJUTukTAAoJEATWKx49+7T0nWQH/3enKf5GbOe8eDBU83MvlYARFAbGEGb70coH3sVFhC50SjPSyIAU+Am048jVmLKvy2r/ABYXHwVn73rRbgR+X92iH4Q+ivYI7ZtUEr7iUoEUVetwks6YkUezthnzCVyWk+Hy9BnkoTEN08zPGkLnVt/e5SPAqQ1tZttpKOO+HZp3JxzGtMFBY/k+ZX8fU6PZKM6FZEPu8S8m2PnQUGaCgREZrt+ikMAzgwqgpEtYoiT6M6yQLyAVRpDvFsIU3q56vA3Zc3rl6vdJjBY9AMflyd1fEYv1IfUkVPjKZg/9JL42qRRQLccEGU2W+xpd7HYi1WfI+60buVmjPNTNr/GYPfo= From dovecot at dovecot.org Tue Oct 28 03:47:01 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 28 Oct 2014 03:47:01 +0000 Subject: dovecot-2.2: dsync: Fixed notifying replicator (-U parameter) if... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8a91b47d5a46 changeset: 18035:8a91b47d5a46 user: Timo Sirainen date: Tue Oct 28 05:45:59 2014 +0200 description: dsync: Fixed notifying replicator (-U parameter) if it didn't answer instantly. diffstat: src/doveadm/doveadm-dsync.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 39e2455a5e2d -r 8a91b47d5a46 src/doveadm/doveadm-dsync.c --- a/src/doveadm/doveadm-dsync.c Mon Oct 27 23:29:39 2014 +0200 +++ b/src/doveadm/doveadm-dsync.c Tue Oct 28 05:45:59 2014 +0200 @@ -500,6 +500,8 @@ i_error("net_connect_unix(%s) failed: %m", path); return; } + fd_set_nonblock(fd, FALSE); + str = t_str_new(128); str_append(str, REPLICATOR_HANDSHAKE"NOTIFY\t"); str_append_tabescaped(str, ctx->ctx.cur_mail_user->username); From dovecot at dovecot.org Tue Oct 28 04:44:09 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 28 Oct 2014 04:44:09 +0000 Subject: dovecot-2.2: lib-http: If there's an error reading chunked http ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f08b79e8d22e changeset: 18036:f08b79e8d22e user: Timo Sirainen date: Mon Oct 27 21:43:10 2014 -0700 description: lib-http: If there's an error reading chunked http stream, set the error to the istream. Previously the error string was set, but it was never read by anything. diffstat: src/lib-http/http-transfer-chunked.c | 47 ++++++++++++++++++++--------------- 1 files changed, 27 insertions(+), 20 deletions(-) diffs (154 lines): diff -r 8a91b47d5a46 -r f08b79e8d22e src/lib-http/http-transfer-chunked.c --- a/src/lib-http/http-transfer-chunked.c Tue Oct 28 05:45:59 2014 +0200 +++ b/src/lib-http/http-transfer-chunked.c Mon Oct 27 21:43:10 2014 -0700 @@ -44,7 +44,6 @@ uoff_t chunk_size, chunk_v_offset, chunk_pos; uoff_t size, max_size; - const char *error; struct http_header_parser *header_parser; @@ -78,7 +77,7 @@ size = *tcstream->cur-'a' + 10; else { if (tcstream->parsed_chars == 0) { - tcstream->error = t_strdup_printf( + io_stream_set_error(&tcstream->istream.iostream, "Expected chunk size digit, but found %s", _chr_sanitize(*tcstream->cur)); return -1; @@ -89,7 +88,8 @@ tcstream->chunk_size <<= 4; tcstream->chunk_size += size; if (tcstream->chunk_size < prev) { - tcstream->error = "Chunk size exceeds integer limit"; + io_stream_set_error(&tcstream->istream.iostream, + "Chunk size exceeds integer limit"); return -1; } tcstream->parsed_chars++; @@ -178,8 +178,10 @@ case HTTP_CHUNKED_PARSE_STATE_EXT_NAME: /* chunk-ext-name = token */ if ((ret=http_transfer_chunked_skip_token(tcstream)) <= 0) { - if (ret < 0) - tcstream->error = "Invalid chunked extension name"; + if (ret < 0) { + io_stream_set_error(&tcstream->istream.iostream, + "Invalid chunked extension name"); + } return ret; } tcstream->state = HTTP_CHUNKED_PARSE_STATE_EXT_EQ; @@ -212,8 +214,10 @@ 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"; + if (ret < 0) { + io_stream_set_error(&tcstream->istream.iostream, + "Invalid chunked extension value"); + } return ret; } else if (*tcstream->cur == '\\') { tcstream->cur++; @@ -221,7 +225,7 @@ if (tcstream->cur >= tcstream->end) return 0; } else { - tcstream->error = t_strdup_printf( + io_stream_set_error(&tcstream->istream.iostream, "Invalid character %s in chunked extension value string", _chr_sanitize(*tcstream->cur)); return -1; @@ -230,7 +234,7 @@ case HTTP_CHUNKED_PARSE_STATE_EXT_VALUE_ESCAPE: /* ( HTAB / SP / VCHAR / obs-text ) */ if (!http_char_is_text(*tcstream->cur)) { - tcstream->error = t_strdup_printf( + io_stream_set_error(&tcstream->istream.iostream, "Escaped invalid character %s in chunked extension value string", _chr_sanitize(*tcstream->cur)); return -1; @@ -241,8 +245,10 @@ break; case HTTP_CHUNKED_PARSE_STATE_EXT_VALUE_TOKEN: if ((ret=http_transfer_chunked_skip_token(tcstream)) <= 0) { - if (ret < 0) - tcstream->error = "Invalid chunked extension value"; + if (ret < 0) { + io_stream_set_error(&tcstream->istream.iostream, + "Invalid chunked extension value"); + } return ret; } tcstream->state = HTTP_CHUNKED_PARSE_STATE_EXT; @@ -257,7 +263,7 @@ /* fall through */ case HTTP_CHUNKED_PARSE_STATE_LF: if (*tcstream->cur != '\n') { - tcstream->error = t_strdup_printf( + io_stream_set_error(&tcstream->istream.iostream, "Expected new line after chunk size, but found %s", _chr_sanitize(*tcstream->cur)); return -1; @@ -280,7 +286,7 @@ /* fall through */ case HTTP_CHUNKED_PARSE_STATE_DATA_LF: if (*tcstream->cur != '\n') { - tcstream->error = t_strdup_printf( + io_stream_set_error(&tcstream->istream.iostream, "Expected new line after chunk data, but found %s", _chr_sanitize(*tcstream->cur)); return -1; @@ -323,7 +329,8 @@ tcstream->size += tcstream->chunk_size; if (tcstream->max_size > 0 && tcstream->size > tcstream->max_size) { - tcstream->error = "Total chunked payload size exceeds maximum"; + io_stream_set_error(&tcstream->istream.iostream, + "Total chunked payload size exceeds maximum"); stream->istream.stream_errno = EMSGSIZE; return -1; } @@ -337,11 +344,11 @@ if (ret < 0) { if ( stream->parent->eof && stream->parent->stream_errno == 0 ) { /* unexpected EOF */ - tcstream->error = "Unexpected end of payload"; + io_stream_set_error(&tcstream->istream.iostream, + "Unexpected end of payload"); stream->istream.stream_errno = EIO; } else { /* parent stream error */ - tcstream->error = "Stream error"; stream->istream.stream_errno = stream->parent->stream_errno; } } @@ -374,11 +381,11 @@ if (ret <= 0 && (ret != -2 || stream->skip == 0)) { if ( stream->parent->eof && stream->parent->stream_errno == 0 ) { /* unexpected EOF */ - tcstream->error = "Unexpected end of payload"; + io_stream_set_error(&tcstream->istream.iostream, + "Unexpected end of payload"); stream->istream.stream_errno = EIO; } else { /* parent stream error */ - tcstream->error = "Stream error"; stream->istream.stream_errno = stream->parent->stream_errno; } return ret; @@ -437,8 +444,8 @@ if (ret <= 0) { if (ret < 0) { - tcstream->error = t_strdup_printf - ("Failed to parse chunked trailer: %s", error); + io_stream_set_error(&stream->iostream, + "Failed to parse chunked trailer: %s", error); stream->istream.stream_errno = EIO; } return ret; From dovecot at dovecot.org Tue Oct 28 04:49:31 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 28 Oct 2014 04:49:31 +0000 Subject: dovecot-2.2: lib: istream-timeout logs how long the stream was o... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/aa5dde56424f changeset: 18037:aa5dde56424f user: Timo Sirainen date: Mon Oct 27 21:48:29 2014 -0700 description: lib: istream-timeout logs how long the stream was open if parent read fails with ECONNRESET/EPIPE. diffstat: src/lib/istream-timeout.c | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-) diffs (33 lines): diff -r f08b79e8d22e -r aa5dde56424f src/lib/istream-timeout.c --- a/src/lib/istream-timeout.c Mon Oct 27 21:43:10 2014 -0700 +++ b/src/lib/istream-timeout.c Mon Oct 27 21:48:29 2014 -0700 @@ -11,6 +11,7 @@ struct timeout *to; struct timeval last_read_timestamp; + time_t created; unsigned int timeout_msecs; bool update_timestamp; @@ -75,6 +76,13 @@ ret = i_stream_read_copy_from_parent(&stream->istream); if (ret < 0) { /* failed */ + if (errno == ECONNRESET || errno == EPIPE) { + int diff = ioloop_time - tstream->created; + + io_stream_set_error(&tstream->istream.iostream, + "%s (opened %d secs ago)", + i_stream_get_error(stream->parent), diff); + } } else if (tstream->to == NULL) { /* first read. add the timeout here instead of in init in case the stream is created long before it's actually @@ -111,6 +119,7 @@ tstream->timeout_msecs = timeout_msecs; tstream->istream.max_buffer_size = input->real_stream->max_buffer_size; tstream->istream.stream_size_passthrough = TRUE; + tstream->created = ioloop_time; tstream->istream.read = i_stream_timeout_read; tstream->istream.switch_ioloop = i_stream_timeout_switch_ioloop; From pigeonhole at rename-it.nl Tue Oct 28 13:53:51 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 28 Oct 2014 14:53:51 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: Fixed potential segfault bug ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/5ba10b28d630 changeset: 1943:5ba10b28d630 user: Stephan Bosch date: Tue Oct 28 14:53:39 2014 +0100 description: lib-sieve: Fixed potential segfault bug in file storage driver. diffstat: src/lib-sieve/storage/file/sieve-file-script.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 1f897ed258ea -r 5ba10b28d630 src/lib-sieve/storage/file/sieve-file-script.c --- a/src/lib-sieve/storage/file/sieve-file-script.c Tue Oct 28 01:53:46 2014 +0100 +++ b/src/lib-sieve/storage/file/sieve-file-script.c Tue Oct 28 14:53:39 2014 +0100 @@ -296,7 +296,7 @@ filename = sieve_script_file_from_name(name); basename = name; } - if ( filename == NULL && *filename == '\0' ) { + if ( filename == NULL || *filename == '\0' ) { sieve_script_set_critical(script, "Sieve script file path '%s' is a directory.", path); *error_r = SIEVE_ERROR_TEMP_FAILURE; From pigeonhole at rename-it.nl Tue Oct 28 21:35:27 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 28 Oct 2014 22:35:27 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: sieve script: Made sure there... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/6afd6d927f40 changeset: 1944:6afd6d927f40 user: Stephan Bosch date: Tue Oct 28 22:34:48 2014 +0100 description: lib-sieve: sieve script: Made sure there is a script name for when sieve_script_open() fails. diffstat: src/lib-sieve/storage/file/sieve-file-script.c | 50 +++++++++++++++++-------- 1 files changed, 34 insertions(+), 16 deletions(-) diffs (96 lines): diff -r 5ba10b28d630 -r 6afd6d927f40 src/lib-sieve/storage/file/sieve-file-script.c --- a/src/lib-sieve/storage/file/sieve-file-script.c Tue Oct 28 14:53:39 2014 +0100 +++ b/src/lib-sieve/storage/file/sieve-file-script.c Tue Oct 28 22:34:48 2014 +0100 @@ -52,7 +52,7 @@ static void sieve_file_script_handle_error (struct sieve_file_script *fscript, const char *path, - enum sieve_error *error_r) + const char *name, enum sieve_error *error_r) { struct sieve_script *script = &fscript->script; @@ -61,8 +61,7 @@ sieve_script_sys_debug(script, "File `%s' not found", t_abspath(path)); sieve_script_set_error(script, SIEVE_ERROR_NOT_FOUND, - "Sieve script `%s' not found", - fscript->script.name); + "Sieve script `%s' not found", name); *error_r = SIEVE_ERROR_NOT_FOUND; break; case EACCES: @@ -262,6 +261,22 @@ return 1; } +static const char * +path_split_filename(const char *path, const char **dirpath_r) +{ + const char *filename; + + filename = strrchr(path, '/'); + if ( filename == NULL ) { + *dirpath_r = ""; + filename = path; + } else { + *dirpath_r = t_strdup_until(path, filename); + filename++; + } + return filename; +} + static int sieve_file_script_open (struct sieve_script *script, enum sieve_error *error_r) { @@ -320,14 +335,7 @@ } else { /* Extract filename from path */ - filename = strrchr(path, '/'); - if ( filename == NULL ) { - dirpath = ""; - filename = path; - } else { - dirpath = t_strdup_until(path, filename); - filename++; - } + filename = path_split_filename(path, &dirpath); if ( (basename=sieve_script_file_get_scriptname(filename)) == NULL ) basename = filename; @@ -341,11 +349,21 @@ if ( success ) { if ( ret <= 0 ) { - if ( fscript->script.name == NULL ) - fscript->script.name = p_strdup(pool, basename); - sieve_file_script_handle_error(fscript, path, error_r); + /* Make sure we have a script name for the error */ + if ( name == NULL ) { + if ( basename == NULL ) { + if ( filename == NULL ) + filename = path_split_filename(path, &dirpath); + basename = sieve_script_file_get_scriptname(filename); + if ( basename == NULL ) + basename = filename; + } + name = basename; + } + sieve_file_script_handle_error(fscript, path, name, error_r); success = FALSE; - } else if (!S_ISREG(st.st_mode) ) { + + } else if ( !S_ISREG(st.st_mode) ) { sieve_script_set_critical(script, "Sieve script file '%s' is not a regular file.", path); *error_r = SIEVE_ERROR_TEMP_FAILURE; @@ -412,7 +430,7 @@ if ( (fd=open(fscript->path, O_RDONLY)) < 0 ) { sieve_file_script_handle_error - (fscript, fscript->path, error_r); + (fscript, fscript->path, fscript->script.name, error_r); return -1; } From dovecot at dovecot.org Tue Oct 28 23:13:09 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 28 Oct 2014 23:13:09 +0000 Subject: dovecot-2.2: lib-http: client: Fixed assertion failure in http_c... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d92214db89ac changeset: 18038:d92214db89ac user: Stephan Bosch date: Tue Oct 28 16:12:09 2014 -0700 description: lib-http: client: Fixed assertion failure in http_client_queue_fail(). Don't explicitly clear the request array after looping through all requests, since new requests may be added during the loop, not only removed. diffstat: src/lib-http/http-client-queue.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diffs (11 lines): diff -r aa5dde56424f -r d92214db89ac src/lib-http/http-client-queue.c --- a/src/lib-http/http-client-queue.c Mon Oct 27 21:48:29 2014 -0700 +++ b/src/lib-http/http-client-queue.c Tue Oct 28 16:12:09 2014 -0700 @@ -149,7 +149,6 @@ array_foreach_modifiable(&treqs, req_idx) { http_client_request_error(*req_idx, status, error); } - array_clear(req_arr); /* all queues should be empty now... unless new requests were submitted from the callback. this invariant captures it all: */ From dovecot at dovecot.org Wed Oct 29 00:08:28 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Oct 2014 00:08:28 +0000 Subject: dovecot-2.2: lib: io_remove() should finish closing the io befor... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1632ae08c986 changeset: 18039:1632ae08c986 user: Timo Sirainen date: Tue Oct 28 17:07:21 2014 -0700 description: lib: io_remove() should finish closing the io before unreferencing its istream. This is because the istream unreferencing may close the fd. diffstat: src/lib/ioloop.c | 15 +++++++++------ 1 files changed, 9 insertions(+), 6 deletions(-) diffs (29 lines): diff -r d92214db89ac -r 1632ae08c986 src/lib/ioloop.c --- a/src/lib/ioloop.c Tue Oct 28 16:12:09 2014 -0700 +++ b/src/lib/ioloop.c Tue Oct 28 17:07:21 2014 -0700 @@ -136,16 +136,19 @@ io_loop_notify_remove(io); else { struct io_file *io_file = (struct io_file *)io; - - if (io_file->istream != NULL) { - i_stream_unset_io(io_file->istream, io); - i_stream_unref(&io_file->istream); - io_file->istream = NULL; - } + struct istream *istream = io_file->istream; io_file_unlink(io_file); if (io_file->fd != -1) io_loop_handle_remove(io_file, closed); + + /* remove io from the ioloop before unreferencing the istream, + because a destroyed istream may automatically close the + fd. */ + if (istream != NULL) { + i_stream_unset_io(istream, io); + i_stream_unref(&istream); + } } } From dovecot at dovecot.org Wed Oct 29 00:16:29 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Oct 2014 00:16:29 +0000 Subject: dovecot-2.2: lib-http: Make sure we don't access already freed c... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0393f550fd82 changeset: 18040:0393f550fd82 user: Timo Sirainen date: Tue Oct 28 17:15:31 2014 -0700 description: lib-http: Make sure we don't access already freed client connection in payload-destroyed callback. diffstat: src/lib-http/http-client-connection.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (19 lines): diff -r 1632ae08c986 -r 0393f550fd82 src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Tue Oct 28 17:07:21 2014 -0700 +++ b/src/lib-http/http-client-connection.c Tue Oct 28 17:15:31 2014 -0700 @@ -441,6 +441,7 @@ req->conn = NULL; conn->incoming_payload = NULL; conn->pending_request = NULL; + http_client_connection_ref(conn); http_client_request_finish(&req); /* room for new requests */ @@ -457,6 +458,7 @@ i_assert(req != NULL); http_client_request_unref(&req); + http_client_connection_unref(&conn); } static bool From pigeonhole at rename-it.nl Wed Oct 29 02:05:54 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Wed, 29 Oct 2014 03:05:54 +0100 Subject: dovecot-2.2-pigeonhole: Implmented reporting full Pigeonhole ver... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/a1e57385b267 changeset: 1945:a1e57385b267 user: Stephan Bosch date: Wed Oct 29 03:05:43 2014 +0100 description: Implmented reporting full Pigeonhole version with hg tag so that builds between releases can be distinguished. Copied from Dovecot for the most part. diffstat: Makefile.am | 11 ++++++++++- src/lib-sieve/sieve-config.h | 3 ++- src/lib-sieve/sieve.c | 2 +- src/lib-sieve/storage/ldap/sieve-ldap-storage.c | 2 +- src/plugins/sieve-extprograms/sieve-extprograms-plugin.c | 2 +- 5 files changed, 15 insertions(+), 5 deletions(-) diffs (84 lines): diff -r 6afd6d927f40 -r a1e57385b267 Makefile.am --- a/Makefile.am Tue Oct 28 22:34:48 2014 +0100 +++ b/Makefile.am Wed Oct 29 03:05:43 2014 +0100 @@ -4,13 +4,17 @@ SUBDIRS = src $(DOCS) +dist_pkginclude_HEADERS = \ + pigeonhole-version.h + ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = \ tests \ examples \ COPYING.LGPL \ - ChangeLog + ChangeLog \ + update-version.sh dist-hook: rm -rf `find $(distdir)/tests -type f -name '*.svbin'` @@ -23,6 +27,11 @@ hg log --style=changelog > ChangeLog endif +pigeonhole-version.h: noop + $(SHELL) $(top_srcdir)/update-version.sh $(top_srcdir) $(top_builddir) + +noop: + # Testsuite tests (FIXME: ugly) TESTSUITE_BIN = $(top_builddir)/src/testsuite/testsuite $(TESTSUITE_OPTIONS) diff -r 6afd6d927f40 -r a1e57385b267 src/lib-sieve/sieve-config.h --- a/src/lib-sieve/sieve-config.h Tue Oct 28 22:34:48 2014 +0100 +++ b/src/lib-sieve/sieve-config.h Wed Oct 29 03:05:43 2014 +0100 @@ -5,8 +5,9 @@ #define __SIEVE_CONFIG_H #include "pigeonhole-config.h" +#include "pigeonhole-version.h" -#define SIEVE_IMPLEMENTATION PIGEONHOLE_NAME " Sieve " PIGEONHOLE_VERSION +#define SIEVE_IMPLEMENTATION PIGEONHOLE_NAME " Sieve " PIGEONHOLE_VERSION_FULL #define SIEVE_SCRIPT_FILEEXT "sieve" #define SIEVE_BINARY_FILEEXT "svbin" diff -r 6afd6d927f40 -r a1e57385b267 src/lib-sieve/sieve.c --- a/src/lib-sieve/sieve.c Tue Oct 28 22:34:48 2014 +0100 +++ b/src/lib-sieve/sieve.c Wed Oct 29 03:05:43 2014 +0100 @@ -92,7 +92,7 @@ if ( debug ) { sieve_sys_debug(svinst, "%s version %s initializing", - PIGEONHOLE_NAME, PIGEONHOLE_VERSION); + PIGEONHOLE_NAME, PIGEONHOLE_VERSION_FULL); } /* Read configuration */ diff -r 6afd6d927f40 -r a1e57385b267 src/lib-sieve/storage/ldap/sieve-ldap-storage.c --- a/src/lib-sieve/storage/ldap/sieve-ldap-storage.c Tue Oct 28 22:34:48 2014 +0100 +++ b/src/lib-sieve/storage/ldap/sieve-ldap-storage.c Wed Oct 29 03:05:43 2014 +0100 @@ -196,7 +196,7 @@ if ( svinst->debug ) { sieve_sys_debug(svinst, "Sieve LDAP storage plugin for %s version %s loaded", - PIGEONHOLE_NAME, PIGEONHOLE_VERSION); + PIGEONHOLE_NAME, PIGEONHOLE_VERSION_FULL); } } diff -r 6afd6d927f40 -r a1e57385b267 src/plugins/sieve-extprograms/sieve-extprograms-plugin.c --- a/src/plugins/sieve-extprograms/sieve-extprograms-plugin.c Tue Oct 28 22:34:48 2014 +0100 +++ b/src/plugins/sieve-extprograms/sieve-extprograms-plugin.c Wed Oct 29 03:05:43 2014 +0100 @@ -32,7 +32,7 @@ if ( svinst->debug ) { sieve_sys_debug(svinst, "Sieve Extprograms plugin for %s version %s loaded", - PIGEONHOLE_NAME, PIGEONHOLE_VERSION); + PIGEONHOLE_NAME, PIGEONHOLE_VERSION_FULL); } *context = (void *)pctx; From dovecot at dovecot.org Wed Oct 29 16:59:03 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Oct 2014 16:59:03 +0000 Subject: dovecot-2.2: lmtp: Added support for STARTTLS command. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/297192cfbd37 changeset: 18041:297192cfbd37 user: Timo Sirainen date: Wed Oct 29 09:58:01 2014 -0700 description: lmtp: Added support for STARTTLS command. diffstat: src/lmtp/Makefile.am | 1 + src/lmtp/client.c | 17 +++++++++++++++++ src/lmtp/client.h | 1 + src/lmtp/commands.c | 33 +++++++++++++++++++++++++++++++++ src/lmtp/commands.h | 1 + src/lmtp/main.c | 5 +++-- 6 files changed, 56 insertions(+), 2 deletions(-) diffs (161 lines): diff -r 0393f550fd82 -r 297192cfbd37 src/lmtp/Makefile.am --- a/src/lmtp/Makefile.am Tue Oct 28 17:15:31 2014 -0700 +++ b/src/lmtp/Makefile.am Wed Oct 29 09:58:01 2014 -0700 @@ -11,6 +11,7 @@ -I$(top_srcdir)/src/lib-index \ -I$(top_srcdir)/src/lib-master \ -I$(top_srcdir)/src/lib-lda \ + -I$(top_srcdir)/src/lib-ssl-iostream \ -I$(top_srcdir)/src/lib-storage \ -I$(top_srcdir)/src/lib-storage/index \ -I$(top_srcdir)/src/lib-storage/index/raw diff -r 0393f550fd82 -r 297192cfbd37 src/lmtp/client.c --- a/src/lmtp/client.c Tue Oct 28 17:15:31 2014 -0700 +++ b/src/lmtp/client.c Wed Oct 29 09:58:01 2014 -0700 @@ -12,7 +12,9 @@ #include "var-expand.h" #include "settings-parser.h" #include "master-service.h" +#include "master-service-ssl.h" #include "master-service-settings.h" +#include "iostream-ssl.h" #include "mail-namespace.h" #include "mail-storage.h" #include "mail-storage-service.h" @@ -69,6 +71,9 @@ if (strcmp(cmd, "LHLO") == 0) return cmd_lhlo(client, args); + if (strcmp(cmd, "STARTTLS") == 0 && + master_service_ssl_is_enabled(master_service)) + return cmd_starttls(client); if (strcmp(cmd, "MAIL") == 0) return cmd_mail(client, args); if (strcmp(cmd, "RCPT") == 0) @@ -274,6 +279,8 @@ io_remove(&client->io); if (client->to_idle != NULL) timeout_remove(&client->to_idle); + if (client->ssl_iostream != NULL) + ssl_iostream_destroy(&client->ssl_iostream); i_stream_destroy(&client->input); o_stream_destroy(&client->output); @@ -290,6 +297,16 @@ static const char *client_get_disconnect_reason(struct client *client) { + const char *err; + + if (client->ssl_iostream != NULL && + !ssl_iostream_is_handshaked(client->ssl_iostream)) { + err = ssl_iostream_get_last_error(client->ssl_iostream); + if (err != NULL) { + return t_strdup_printf("TLS handshaking failed: %s", + err); + } + } errno = client->input->stream_errno != 0 ? client->input->stream_errno : client->output->stream_errno; diff -r 0393f550fd82 -r 297192cfbd37 src/lmtp/client.h --- a/src/lmtp/client.h Tue Oct 28 17:15:31 2014 -0700 +++ b/src/lmtp/client.h Wed Oct 29 09:58:01 2014 -0700 @@ -48,6 +48,7 @@ struct io *io; struct istream *input; struct ostream *output; + struct ssl_iostream *ssl_iostream; struct timeout *to_idle; time_t last_input; diff -r 0393f550fd82 -r 297192cfbd37 src/lmtp/commands.c --- a/src/lmtp/commands.c Tue Oct 28 17:15:31 2014 -0700 +++ b/src/lmtp/commands.c Wed Oct 29 09:58:01 2014 -0700 @@ -15,6 +15,8 @@ #include "restrict-access.h" #include "settings-parser.h" #include "master-service.h" +#include "master-service-ssl.h" +#include "iostream-ssl.h" #include "rfc822-parser.h" #include "message-date.h" #include "auth-master.h" @@ -70,6 +72,9 @@ client_state_reset(client); client_send_line(client, "250-%s", client->my_domain); + if (master_service_ssl_is_enabled(master_service) && + client->ssl_iostream == NULL) + client_send_line(client, "250-STARTTLS"); if (client_is_trusted(client)) client_send_line(client, "250-XCLIENT ADDR PORT TTL TIMEOUT"); client_send_line(client, "250-8BITMIME"); @@ -82,6 +87,34 @@ return 0; } +int cmd_starttls(struct client *client) +{ + struct ostream *plain_output = client->output; + const char *error; + + if (client->ssl_iostream != NULL) { + o_stream_nsend_str(client->output, + "443 5.5.1 TLS is already active.\r\n"); + return 0; + } + + if (master_service_ssl_init(master_service, + &client->input, &client->output, + &client->ssl_iostream, &error) < 0) { + i_error("TLS initialization failed: %s", error); + o_stream_nsend_str(client->output, + "454 4.7.0 Internal error, TLS not available.\r\n"); + return 0; + } + o_stream_nsend_str(plain_output, + "220 2.0.0 Begin TLS negotiation now.\r\n"); + if (ssl_iostream_handshake(client->ssl_iostream) < 0) { + client_destroy(client, NULL, NULL); + return -1; + } + return 0; +} + static int parse_address(const char *str, const char **address_r, const char **rest_r) { diff -r 0393f550fd82 -r 297192cfbd37 src/lmtp/commands.h --- a/src/lmtp/commands.h Tue Oct 28 17:15:31 2014 -0700 +++ b/src/lmtp/commands.h Wed Oct 29 09:58:01 2014 -0700 @@ -4,6 +4,7 @@ struct client; int cmd_lhlo(struct client *client, const char *args); +int cmd_starttls(struct client *client); int cmd_mail(struct client *client, const char *args); int cmd_rcpt(struct client *client, const char *args); int cmd_quit(struct client *client, const char *args); diff -r 0393f550fd82 -r 297192cfbd37 src/lmtp/main.c --- a/src/lmtp/main.c Tue Oct 28 17:15:31 2014 -0700 +++ b/src/lmtp/main.c Wed Oct 29 09:58:01 2014 -0700 @@ -78,7 +78,8 @@ &lmtp_setting_parser_info, NULL }; - enum master_service_flags service_flags = 0; + enum master_service_flags service_flags = + MASTER_SERVICE_FLAG_USE_SSL_SETTINGS; enum mail_storage_service_flags storage_service_flags = MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT | MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP | @@ -91,7 +92,7 @@ service_flags |= MASTER_SERVICE_FLAG_STANDALONE | MASTER_SERVICE_FLAG_STD_CLIENT; } else { - service_flags |= MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN; + service_flags |= MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN ; } master_service = master_service_init("lmtp", service_flags, From dovecot at dovecot.org Wed Oct 29 18:47:52 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Oct 2014 18:47:52 +0000 Subject: dovecot-2.2: lib: connection_switch_ioloop() should switch also ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f21d7614ac0d changeset: 18042:f21d7614ac0d user: Timo Sirainen date: Wed Oct 29 11:46:50 2014 -0700 description: lib: connection_switch_ioloop() should switch also input stream's ioloop. diffstat: src/lib/connection.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 297192cfbd37 -r f21d7614ac0d src/lib/connection.c --- a/src/lib/connection.c Wed Oct 29 09:58:01 2014 -0700 +++ b/src/lib/connection.c Wed Oct 29 11:46:50 2014 -0700 @@ -360,6 +360,8 @@ conn->io = io_loop_move_io(&conn->io); if (conn->to != NULL) conn->to = io_loop_move_timeout(&conn->to); + if (conn->input != NULL) + i_stream_switch_ioloop(conn->input); if (conn->output != NULL) o_stream_switch_ioloop(conn->output); } From pigeonhole at rename-it.nl Wed Oct 29 20:37:16 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Wed, 29 Oct 2014 21:37:16 +0100 Subject: dovecot-2.2-pigeonhole: Forgot to add and ignore new files in la... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/b33926368ddf changeset: 1946:b33926368ddf user: Stephan Bosch date: Wed Oct 29 21:37:07 2014 +0100 description: Forgot to add and ignore new files in latest commit. diffstat: .hgignore | 1 + is-tagged.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++ update-version.sh | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 0 deletions(-) diffs (143 lines): diff -r a1e57385b267 -r b33926368ddf .hgignore --- a/.hgignore Wed Oct 29 03:05:43 2014 +0100 +++ b/.hgignore Wed Oct 29 21:37:07 2014 +0100 @@ -12,6 +12,7 @@ config.rpath configure configure.scan +pigeonhole-version.h libtool libtool-shared ltconfig diff -r a1e57385b267 -r b33926368ddf is-tagged.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/is-tagged.py Wed Oct 29 21:37:07 2014 +0100 @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" + Checks if the current revision of the repository is a tagged revision, + but not 'tip'. + + usage: + python is-tagged.py [/path/to/repo] + if no path is given, the current working directory will be used. + + Exit status: + 0 if the current revision is a tagged version OR + if the current revision was used for signing/tagging OR + if path is not a Mercurial repository OR + if module import should fail for some reason + 1 if the current revision has no tag, except 'tip' +""" +import re +import sys +try: + from mercurial import hg, ui +except ImportError: # no Mercurial at all + sys.exit(0) +try: + from mercurial.error import Abort, RepoError +except ImportError: + try: + from mercurial.repo import RepoError + from mercurial.util import Abort + except ImportError: # something old/new? + sys.exit(0) + +RE = r'^Added\s(?:signature|tag)\s(?:[\w\.]+\s)?for\schangeset\s[\da-f]{12,}$' + + +def main(): + if len(sys.argv) > 1: + path = sys.argv[1].strip() + else: + path = '.' + try: + repo = hg.repository(ui.ui(), path) + except (Abort, RepoError): # no/bad repo? no extra version info + return 0 + parents_id = repo.dirstate.parents()[0] + ctx = repo.changectx(parents_id) + if re.match(RE, ctx.description()): # tag or sig was added for a release + return 0 + for tag, nodeid in repo.tags().iteritems(): + if tag != 'tip' and parents_id == nodeid: # tagged + return 0 + # not tagged + return 1 + + +if __name__ == '__main__': + sys.exit(main()) diff -r a1e57385b267 -r b33926368ddf update-version.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/update-version.sh Wed Oct 29 21:37:07 2014 +0100 @@ -0,0 +1,67 @@ +#!/bin/sh + +SRCDIR="${1:-`pwd`}" +BUILDDIR="${2:-`pwd`}" +VERSION_H="pigeonhole-version.h" +VERSION_HT="pigeonhole-version.h.tmp" + +abspath() +{ #$1 the path + #$2 1 -> SRCDIR || 2 -> BUILDDIR + old=`pwd` + cd "${1}" + if [ ${2} -eq 1 ]; then + SRCDIR=`pwd` + else + BUILDDIR=`pwd` + fi + cd "$old" +} + +abspath "${SRCDIR}" 1 +abspath "${BUILDDIR}" 2 + +# when using a different BUILDDIR just copy from SRCDIR, if there is no .hg +if [ "${BUILDDIR}" != "${SRCDIR}" ]; then + if [ ! -d "${SRCDIR}/.hg" ] && [ -f "${SRCDIR}/${VERSION_H}" ]; then + cmp -s "${SRCDIR}/${VERSION_H}" "${BUILDDIR}/${VERSION_H}" + if [ $? -ne 0 ]; then + cp "${SRCDIR}/${VERSION_H}" "${BUILDDIR}/${VERSION_H}" + exit 0 + fi + fi +fi + +# Don't generate dovecot-version.h if the source tree has no .hg dir but +# a dovecot-version.h. This may be the result of a release/nightly tarball. +[ ! -d "${SRCDIR}/.hg" ] && [ -f "${BUILDDIR}/${VERSION_H}" ] && exit 0 + +# Lets generate the dovecot-version.h +[ -f "${BUILDDIR}/${VERSION_HT}" ] && rm -f "${BUILDDIR}/${VERSION_HT}" +python "${SRCDIR}/is-tagged.py" "${SRCDIR}" +if [ $? = 1 ]; then + # older hg doesn't recognize option -i + #HGID=`hg -R ${SRCDIR} id -i 2>/dev/null` + HGID=`hg -R ${SRCDIR} id 2>/dev/null | awk '{print $1}'` + cat > "${BUILDDIR}/${VERSION_HT}" < "${BUILDDIR}/${VERSION_HT}" < details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/cb25972deaec changeset: 1947:cb25972deaec user: Stephan Bosch date: Wed Oct 29 22:00:31 2014 +0100 description: Added dummy settings plugin that adds a Pigeonhole version banner to doveconf output. diffstat: configure.ac | 1 + src/plugins/Makefile.am | 3 ++- src/plugins/settings/Makefile.am | 12 ++++++++++++ src/plugins/settings/pigeonhole-settings.c | 12 ++++++++++++ 4 files changed, 27 insertions(+), 1 deletions(-) diffs (53 lines): diff -r b33926368ddf -r cb25972deaec configure.ac --- a/configure.ac Wed Oct 29 21:37:07 2014 +0100 +++ b/configure.ac Wed Oct 29 22:00:31 2014 +0100 @@ -211,6 +211,7 @@ src/plugins/doveadm-sieve/Makefile src/plugins/lda-sieve/Makefile src/plugins/sieve-extprograms/Makefile +src/plugins/settings/Makefile src/sieve-tools/Makefile src/managesieve/Makefile src/managesieve-login/Makefile diff -r b33926368ddf -r cb25972deaec src/plugins/Makefile.am --- a/src/plugins/Makefile.am Wed Oct 29 21:37:07 2014 +0100 +++ b/src/plugins/Makefile.am Wed Oct 29 22:00:31 2014 +0100 @@ -1,4 +1,5 @@ SUBDIRS = \ doveadm-sieve \ lda-sieve \ - sieve-extprograms + sieve-extprograms \ + settings diff -r b33926368ddf -r cb25972deaec src/plugins/settings/Makefile.am --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plugins/settings/Makefile.am Wed Oct 29 22:00:31 2014 +0100 @@ -0,0 +1,12 @@ +settingsdir = $(dovecot_moduledir)/settings + +AM_CPPFLAGS = \ + $(LIBDOVECOT_INCLUDE) + +libpigeonhole_settings_la_LDFLAGS = -module -avoid-version + +settings_LTLIBRARIES = \ + libpigeonhole_settings.la + +libpigeonhole_settings_la_SOURCES = \ + pigeonhole-settings.c diff -r b33926368ddf -r cb25972deaec src/plugins/settings/pigeonhole-settings.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plugins/settings/pigeonhole-settings.c Wed Oct 29 22:00:31 2014 +0100 @@ -0,0 +1,12 @@ +/* Copyright (c) 2012-2013 Dovecot Oy, see the included COPYING file */ + +#include "lib.h" +#include "pigeonhole-config.h" +#include "pigeonhole-version.h" + +/* This is currently just a dummy plugin that adds a Pigeonhole + * version banner the doveconf output. + */ + +const char *pigeonhole_settings_version = DOVECOT_ABI_VERSION; +const char *pigeonhole_settings_doveconf_banner = "Pigeonhole version "PIGEONHOLE_VERSION_FULL; From dovecot at dovecot.org Thu Oct 30 01:34:50 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Oct 2014 01:34:50 +0000 Subject: dovecot-2.2: lib-master: Removed fixed length limit for session-id. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fbc969e1543b changeset: 18043:fbc969e1543b user: Timo Sirainen date: Wed Oct 29 18:32:36 2014 -0700 description: lib-master: Removed fixed length limit for session-id. diffstat: src/lib-master/master-login.c | 7 ++----- src/lib-master/master-login.h | 4 +--- 2 files changed, 3 insertions(+), 8 deletions(-) diffs (51 lines): diff -r f21d7614ac0d -r fbc969e1543b src/lib-master/master-login.c --- a/src/lib-master/master-login.c Wed Oct 29 11:46:50 2014 -0700 +++ b/src/lib-master/master-login.c Wed Oct 29 18:32:36 2014 -0700 @@ -192,6 +192,7 @@ client->conn->refcount--; } master_login_conn_unref(&client->conn); + i_free(client->session_id); i_free(client); } @@ -419,10 +420,6 @@ break; } } - if (session_len >= sizeof(client->session_id)) { - i_error("login client: Session ID too long"); - session_len = 0; - } /* @UNSAFE: we have a request. do userdb lookup for it. */ req.data_size -= i; @@ -430,7 +427,7 @@ client->conn = conn; client->fd = client_fd; client->auth_req = req; - memcpy(client->session_id, data, session_len); + client->session_id = i_strndup(data, session_len); memcpy(client->data, data+i, req.data_size); conn->refcount++; diff -r f21d7614ac0d -r fbc969e1543b src/lib-master/master-login.h --- a/src/lib-master/master-login.h Wed Oct 29 11:46:50 2014 -0700 +++ b/src/lib-master/master-login.h Wed Oct 29 18:32:36 2014 -0700 @@ -4,15 +4,13 @@ #include "master-auth.h" #define MASTER_POSTLOGIN_TIMEOUT_DEFAULT 60 -/* base64(<48bit timestamp>) + NUL */ -#define LOGIN_MAX_SESSION_ID_LEN 33 struct master_login_client { struct master_login_connection *conn; int fd; struct master_auth_request auth_req; - char session_id[LOGIN_MAX_SESSION_ID_LEN]; + char *session_id; unsigned char data[FLEXIBLE_ARRAY_MEMBER]; }; From dovecot at dovecot.org Thu Oct 30 01:34:50 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Oct 2014 01:34:50 +0000 Subject: dovecot-2.2: imap-login: Added "x-session-ext-id" parameter for ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/865456b37bc2 changeset: 18044:865456b37bc2 user: Timo Sirainen date: Wed Oct 29 18:33:46 2014 -0700 description: imap-login: Added "x-session-ext-id" parameter for ID command. It's exactly the same as "x-session-id", but this one can be safely used by external software without having to worry about causing error messages in older versions about too long session-id. diffstat: src/imap-login/client.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r fbc969e1543b -r 865456b37bc2 src/imap-login/client.c --- a/src/imap-login/client.c Wed Oct 29 18:32:36 2014 -0700 +++ b/src/imap-login/client.c Wed Oct 29 18:33:46 2014 -0700 @@ -158,6 +158,9 @@ else if (strcasecmp(key, "x-session-id") == 0) { client->common.session_id = p_strdup(client->common.pool, value); + } else if (strcasecmp(key, "x-session-ext-id") == 0) { + client->common.session_id = + p_strdup(client->common.pool, value); } } From dovecot at dovecot.org Thu Oct 30 02:37:53 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Oct 2014 02:37:53 +0000 Subject: dovecot-2.2: *-login: And actually make the previous changes work. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0a5bd3b09ca5 changeset: 18045:0a5bd3b09ca5 user: Timo Sirainen date: Thu Oct 30 04:36:50 2014 +0200 description: *-login: And actually make the previous changes work. diffstat: src/imap-login/client.c | 12 ++++++------ src/login-common/client-common.h | 1 + src/pop3-login/client.c | 8 ++++++-- 3 files changed, 13 insertions(+), 8 deletions(-) diffs (51 lines): diff -r 865456b37bc2 -r 0a5bd3b09ca5 src/imap-login/client.c --- a/src/imap-login/client.c Wed Oct 29 18:33:46 2014 -0700 +++ b/src/imap-login/client.c Thu Oct 30 04:36:50 2014 +0200 @@ -155,12 +155,12 @@ client->common.local_port = atoi(value); else if (strcasecmp(key, "x-proxy-ttl") == 0) client->common.proxy_ttl = atoi(value); - else if (strcasecmp(key, "x-session-id") == 0) { - client->common.session_id = - p_strdup(client->common.pool, value); - } else if (strcasecmp(key, "x-session-ext-id") == 0) { - client->common.session_id = - p_strdup(client->common.pool, value); + else if (strcasecmp(key, "x-session-id") == 0 || + strcasecmp(key, "x-session-ext-id") == 0) { + if (strlen(value) <= LOGIN_MAX_SESSION_ID_LEN) { + client->common.session_id = + p_strdup(client->common.pool, value); + } } } diff -r 865456b37bc2 -r 0a5bd3b09ca5 src/login-common/client-common.h --- a/src/login-common/client-common.h Wed Oct 29 18:33:46 2014 -0700 +++ b/src/login-common/client-common.h Thu Oct 30 04:36:50 2014 +0200 @@ -6,6 +6,7 @@ #include "sasl-server.h" #include "master-login.h" /* for LOGIN_MAX_SESSION_ID_LEN */ +#define LOGIN_MAX_SESSION_ID_LEN 64 #define LOGIN_MAX_MASTER_PREFIX_LEN 128 /* max. size of input buffer. this means: diff -r 865456b37bc2 -r 0a5bd3b09ca5 src/pop3-login/client.c --- a/src/pop3-login/client.c Wed Oct 29 18:33:46 2014 -0700 +++ b/src/pop3-login/client.c Thu Oct 30 04:36:50 2014 +0200 @@ -57,8 +57,12 @@ else client->common.remote_port = remote_port; } else if (strncasecmp(*tmp, "SESSION=", 8) == 0) { - client->common.session_id = - p_strdup(client->common.pool, *tmp + 8); + const char *value = *tmp + 8; + + if (strlen(value) <= LOGIN_MAX_SESSION_ID_LEN) { + client->common.session_id = + p_strdup(client->common.pool, value); + } } else if (strncasecmp(*tmp, "TTL=", 4) == 0) { if (str_to_uint(*tmp + 4, &client->common.proxy_ttl) < 0) args_ok = FALSE; From dovecot at dovecot.org Thu Oct 30 02:42:11 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Oct 2014 02:42:11 +0000 Subject: dovecot-2.2: *-login: Also increase MASTER_AUTH_MAX_DATA_SIZE an... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/53613f102450 changeset: 18046:53613f102450 user: Timo Sirainen date: Thu Oct 30 04:41:11 2014 +0200 description: *-login: Also increase MASTER_AUTH_MAX_DATA_SIZE and add a check to make sure it's large enough. diffstat: src/imap-login/client.c | 4 ++++ src/lib-master/master-auth.h | 2 +- 2 files changed, 5 insertions(+), 1 deletions(-) diffs (26 lines): diff -r 0a5bd3b09ca5 -r 53613f102450 src/imap-login/client.c --- a/src/imap-login/client.c Thu Oct 30 04:36:50 2014 +0200 +++ b/src/imap-login/client.c Thu Oct 30 04:41:11 2014 +0200 @@ -23,6 +23,10 @@ #include +#if LOGIN_MAX_INBUF_SIZE < 1024+2 +# error LOGIN_MAX_INBUF_SIZE too short to fit all ID command parameters +#endif + /* maximum length for IMAP command line. */ #define MAX_IMAP_LINE 8192 diff -r 0a5bd3b09ca5 -r 53613f102450 src/lib-master/master-auth.h --- a/src/lib-master/master-auth.h Thu Oct 30 04:36:50 2014 +0200 +++ b/src/lib-master/master-auth.h Thu Oct 30 04:41:11 2014 +0200 @@ -18,7 +18,7 @@ values may be max. 1024 bytes plus 2 for "" quotes. (Although it could be even double of that when value is full of \" quotes, but for now lets not make it too easy to waste memory..) */ -#define MASTER_AUTH_MAX_DATA_SIZE (1024 + 128 + 33 + 2) +#define MASTER_AUTH_MAX_DATA_SIZE (1024 + 128 + 64 + 2) #define MASTER_AUTH_ERRMSG_INTERNAL_FAILURE \ "Internal error occurred. Refer to server log for more information." From pigeonhole at rename-it.nl Thu Oct 30 08:44:16 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 30 Oct 2014 09:44:16 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: Fixed handling of implicit keep. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/85039fc9befa changeset: 1948:85039fc9befa user: Stephan Bosch date: Thu Oct 30 09:43:18 2014 +0100 description: lib-sieve: Fixed handling of implicit keep. The sieve_result_execute() function returned the wrong status result. diffstat: src/lib-sieve/sieve-result.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r cb25972deaec -r 85039fc9befa src/lib-sieve/sieve-result.c --- a/src/lib-sieve/sieve-result.c Wed Oct 29 22:00:31 2014 +0100 +++ b/src/lib-sieve/sieve-result.c Thu Oct 30 09:43:18 2014 +0100 @@ -1423,7 +1423,7 @@ sieve_result_transaction_finish (result, first_action, status); - return status; + return result_status; } /* From pigeonhole at rename-it.nl Thu Oct 30 17:47:35 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 30 Oct 2014 18:47:35 +0100 Subject: dovecot-2.2-pigeonhole: New pigeonhole-version.h header was inst... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/92b568ca597c changeset: 1949:92b568ca597c user: Stephan Bosch date: Thu Oct 30 18:47:26 2014 +0100 description: New pigeonhole-version.h header was installed in the wrong directory. diffstat: Makefile.am | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) diffs (24 lines): diff -r 85039fc9befa -r 92b568ca597c Makefile.am --- a/Makefile.am Thu Oct 30 09:43:18 2014 +0100 +++ b/Makefile.am Thu Oct 30 18:47:26 2014 +0100 @@ -4,9 +4,6 @@ SUBDIRS = src $(DOCS) -dist_pkginclude_HEADERS = \ - pigeonhole-version.h - ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = \ @@ -20,7 +17,9 @@ rm -rf `find $(distdir)/tests -type f -name '*.svbin'` pkginc_libdir=$(dovecot_pkgincludedir)/sieve -nodist_pkginc_lib_HEADERS = pigeonhole-config.h +nodist_pkginc_lib_HEADERS = \ + pigeonhole-version.h \ + pigeonhole-config.h if MAINTAINER_MODE ChangeLog: .hg/dirstate From dovecot at dovecot.org Thu Oct 30 20:04:00 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Oct 2014 20:04:00 +0000 Subject: dovecot-2.2: lib: Added lib_atexit_priority() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/54eb3436c83b changeset: 18047:54eb3436c83b user: Timo Sirainen date: Thu Oct 30 22:00:14 2014 +0200 description: lib: Added lib_atexit_priority() diffstat: src/lib/lib.c | 36 +++++++++++++++++++++++++++++------- src/lib/lib.h | 7 +++++++ 2 files changed, 36 insertions(+), 7 deletions(-) diffs (93 lines): diff -r 53613f102450 -r 54eb3436c83b src/lib/lib.c --- a/src/lib/lib.c Thu Oct 30 04:41:11 2014 +0200 +++ b/src/lib/lib.c Thu Oct 30 22:00:14 2014 +0200 @@ -11,7 +11,12 @@ #include #include -static ARRAY(lib_atexit_callback_t *) atexit_callbacks = ARRAY_INIT; +struct atexit_callback { + int priority; + lib_atexit_callback_t *callback; +}; + +static ARRAY(struct atexit_callback) atexit_callbacks = ARRAY_INIT; int close_keep_errno(int *fd) { @@ -27,7 +32,13 @@ void lib_atexit(lib_atexit_callback_t *callback) { - lib_atexit_callback_t *const *callbacks; + lib_atexit_priority(callback, 0); +} + +void lib_atexit_priority(lib_atexit_callback_t *callback, int priority) +{ + struct atexit_callback *cb; + const struct atexit_callback *callbacks; unsigned int i, count; if (!array_is_created(&atexit_callbacks)) @@ -36,20 +47,31 @@ /* skip if it's already added */ callbacks = array_get(&atexit_callbacks, &count); for (i = count; i > 0; i--) { - if (callbacks[i-1] == callback) + if (callbacks[i-1].callback == callback) { + i_assert(callbacks[i-1].priority == priority); return; + } } } - array_append(&atexit_callbacks, &callback, 1); + cb = array_append_space(&atexit_callbacks); + cb->priority = priority; + cb->callback = callback; +} + +static int atexit_callback_priority_cmp(const struct atexit_callback *cb1, + const struct atexit_callback *cb2) +{ + return cb1->priority - cb2->priority; } void lib_atexit_run(void) { - lib_atexit_callback_t *const *cbp; + const struct atexit_callback *cb; if (array_is_created(&atexit_callbacks)) { - array_foreach(&atexit_callbacks, cbp) - (**cbp)(); + array_sort(&atexit_callbacks, atexit_callback_priority_cmp); + array_foreach(&atexit_callbacks, cb) + (*cb->callback)(); array_free(&atexit_callbacks); } } diff -r 53613f102450 -r 54eb3436c83b src/lib/lib.h --- a/src/lib/lib.h Thu Oct 30 04:41:11 2014 +0200 +++ b/src/lib/lib.h Thu Oct 30 22:00:14 2014 +0200 @@ -44,6 +44,10 @@ #include "strfuncs.h" #include "strnum.h" +#define LIB_ATEXIT_PRIORITY_HIGH -10 +#define LIB_ATEXIT_PRIORITY_DEFAULT 0 +#define LIB_ATEXIT_PRIORITY_LOW 10 + int close_keep_errno(int *fd); /* Call the given callback at the beginning of lib_deinit(). The main @@ -51,6 +55,9 @@ functions are still available. Also if lib_atexit() is called multiple times to the same callback, it's added only once. */ void lib_atexit(lib_atexit_callback_t *callback); +/* Specify the order in which the callback is called. Lowest numbered + priorities are called first. lib_atexit() is called with priority=0. */ +void lib_atexit_priority(lib_atexit_callback_t *callback, int priority); /* Manually run the atexit callbacks. lib_deinit() also does this if not explicitly called. */ void lib_atexit_run(void); From dovecot at dovecot.org Thu Oct 30 20:04:01 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Oct 2014 20:04:01 +0000 Subject: dovecot-2.2: lib-ssl-iostream: Destroy SSL module later in the a... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/267bca7a62fb changeset: 18048:267bca7a62fb user: Timo Sirainen date: Thu Oct 30 22:02:52 2014 +0200 description: lib-ssl-iostream: Destroy SSL module later in the atexit-callbacks. diffstat: src/lib-ssl-iostream/iostream-ssl.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (15 lines): diff -r 54eb3436c83b -r 267bca7a62fb src/lib-ssl-iostream/iostream-ssl.c --- a/src/lib-ssl-iostream/iostream-ssl.c Thu Oct 30 22:00:14 2014 +0200 +++ b/src/lib-ssl-iostream/iostream-ssl.c Thu Oct 30 22:02:52 2014 +0200 @@ -40,7 +40,10 @@ return -1; } - lib_atexit(ssl_module_unload); + /* Destroy SSL module after (most of) the others. Especially lib-fs + backends may still want to access SSL module in their own + atexit-callbacks. */ + lib_atexit_priority(ssl_module_unload, LIB_ATEXIT_PRIORITY_LOW); ssl_module_loaded = TRUE; return 0; #else From pigeonhole at rename-it.nl Thu Oct 30 21:40:39 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 30 Oct 2014 22:40:39 +0100 Subject: dovecot-2.2-pigeonhole: Fixed distcheck problem caused by pigeon... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/b5720ebf8d18 changeset: 1950:b5720ebf8d18 user: Stephan Bosch date: Thu Oct 30 22:40:16 2014 +0100 description: Fixed distcheck problem caused by pigeonhole-version.h. diffstat: Makefile.am | 6 +++++- configure.ac | 3 +++ 2 files changed, 8 insertions(+), 1 deletions(-) diffs (37 lines): diff -r 92b568ca597c -r b5720ebf8d18 Makefile.am --- a/Makefile.am Thu Oct 30 18:47:26 2014 +0100 +++ b/Makefile.am Thu Oct 30 22:40:16 2014 +0100 @@ -17,8 +17,9 @@ rm -rf `find $(distdir)/tests -type f -name '*.svbin'` pkginc_libdir=$(dovecot_pkgincludedir)/sieve +dist_pkginc_lib_HEADERS = \ + pigeonhole-version.h nodist_pkginc_lib_HEADERS = \ - pigeonhole-version.h \ pigeonhole-config.h if MAINTAINER_MODE @@ -31,6 +32,9 @@ noop: +DISTCLEANFILES = \ + $(top_builddir)/pigeonhole-version.h + # Testsuite tests (FIXME: ugly) TESTSUITE_BIN = $(top_builddir)/src/testsuite/testsuite $(TESTSUITE_OPTIONS) diff -r 92b568ca597c -r b5720ebf8d18 configure.ac --- a/configure.ac Thu Oct 30 18:47:26 2014 +0100 +++ b/configure.ac Thu Oct 30 22:40:16 2014 +0100 @@ -18,6 +18,9 @@ AM_MAINTAINER_MODE +ACLOCAL_AMFLAGS='-I $(top_srcdir)' +AC_SUBST(ACLOCAL_AMFLAGS) + AC_PROG_CC AC_PROG_CPP AC_PROG_LIBTOOL From pigeonhole at rename-it.nl Thu Oct 30 22:15:55 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 30 Oct 2014 23:15:55 +0100 Subject: dovecot-2.2-pigeonhole: Previous change actually didn't work com... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/b7754774631d changeset: 1951:b7754774631d user: Stephan Bosch date: Thu Oct 30 23:15:45 2014 +0100 description: Previous change actually didn't work completely. diffstat: configure.ac | 5 +---- 1 files changed, 1 insertions(+), 4 deletions(-) diffs (22 lines): diff -r b5720ebf8d18 -r b7754774631d configure.ac --- a/configure.ac Thu Oct 30 22:40:16 2014 +0100 +++ b/configure.ac Thu Oct 30 23:15:45 2014 +0100 @@ -18,9 +18,6 @@ AM_MAINTAINER_MODE -ACLOCAL_AMFLAGS='-I $(top_srcdir)' -AC_SUBST(ACLOCAL_AMFLAGS) - AC_PROG_CC AC_PROG_CPP AC_PROG_LIBTOOL @@ -31,7 +28,7 @@ DC_DOVECOT DC_DOVECOT_MODULEDIR LIBDOVECOT_INCLUDE="$LIBDOVECOT_INCLUDE $LIBDOVECOT_STORAGE_INCLUDE" -CFLAGS="$DOVECOT_CFLAGS" +CFLAGS="$DOVECOT_CFLAGS -I\$(top_srcdir)" LIBS="$DOVECOT_LIBS" AC_SUBST(LIBDOVECOT_INCLUDE) From pigeonhole at rename-it.nl Thu Oct 30 22:25:28 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 30 Oct 2014 23:25:28 +0100 Subject: dovecot-2.2-pigeonhole: Added tag 0.4.5 for changeset f5e3ef477a32 Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/7e3a7e8c8ff0 changeset: 1953:7e3a7e8c8ff0 user: Stephan Bosch date: Thu Oct 30 23:25:20 2014 +0100 description: Added tag 0.4.5 for changeset f5e3ef477a32 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r f5e3ef477a32 -r 7e3a7e8c8ff0 .hgtags --- a/.hgtags Thu Oct 30 23:25:07 2014 +0100 +++ b/.hgtags Thu Oct 30 23:25:20 2014 +0100 @@ -21,3 +21,4 @@ 2176d400eca4fa5d89597793a09c0b194eaed05f 0.4.2 1c6130ff5dd6933f03a40666b7f73ae51c9f90fe 0.4.3 b3303f675157c954d2de08599e2c83db5a772450 0.4.4 +f5e3ef477a32498584ac924963ff2e11c75cd477 0.4.5 From pigeonhole at rename-it.nl Thu Oct 30 22:25:28 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 30 Oct 2014 23:25:28 +0100 Subject: dovecot-2.2-pigeonhole: Released v0.4.5 for Dovecot v2.2.15. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/f5e3ef477a32 changeset: 1952:f5e3ef477a32 user: Stephan Bosch date: Thu Oct 30 23:25:07 2014 +0100 description: Released v0.4.5 for Dovecot v2.2.15. diffstat: NEWS | 9 +++++++++ configure.ac | 2 +- 2 files changed, 10 insertions(+), 1 deletions(-) diffs (25 lines): diff -r b7754774631d -r f5e3ef477a32 NEWS --- a/NEWS Thu Oct 30 23:15:45 2014 +0100 +++ b/NEWS Thu Oct 30 23:25:07 2014 +0100 @@ -1,3 +1,12 @@ +v0.4.5 30-10-2014 Stephan Bosch + + + Added a Pigeonhole version banner to doveconf output. This way, future + bug reports will also include Pigeonhole version information. + - Fixed handling of implicit keep. Last version erroneously reported that + implicit keep succeeded after an earlier failure, while it in fact had + failed. Particularly occurred for mailbox quota errors. + - Fixed segfault occurring on SunOS systems when there is no active script. + v0.4.4 28-10-2014 Stephan Bosch * Added support for Japanese mail addresses with dots at non-standard places diff -r b7754774631d -r f5e3ef477a32 configure.ac --- a/configure.ac Thu Oct 30 23:15:45 2014 +0100 +++ b/configure.ac Thu Oct 30 23:25:07 2014 +0100 @@ -1,4 +1,4 @@ -AC_INIT([Pigeonhole], [0.4.4], [dovecot at dovecot.org], [dovecot-2.2-pigeonhole]) +AC_INIT([Pigeonhole], [0.4.5], [dovecot at dovecot.org], [dovecot-2.2-pigeonhole]) AC_CONFIG_AUX_DIR([.]) AC_CONFIG_SRCDIR([src]) AC_CONFIG_MACRO_DIR([m4]) From pigeonhole at rename-it.nl Thu Oct 30 22:27:16 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 30 Oct 2014 23:27:16 +0100 Subject: dovecot-2.2-pigeonhole: Added signature for changeset f5e3ef477a32 Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/80b47902cf40 changeset: 1954:80b47902cf40 user: Stephan Bosch date: Thu Oct 30 23:27:42 2014 +0100 description: Added signature for changeset f5e3ef477a32 diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 7e3a7e8c8ff0 -r 80b47902cf40 .hgsigs --- a/.hgsigs Thu Oct 30 23:25:20 2014 +0100 +++ b/.hgsigs Thu Oct 30 23:27:42 2014 +0100 @@ -15,3 +15,4 @@ 2176d400eca4fa5d89597793a09c0b194eaed05f 0 iQEcBAABAgAGBQJSRI5JAAoJEATWKx49+7T0kGcIAKNHvRh/4idzHekHk5L81e0nu1IZRLyXg6YLkviF52ZYsB4WSbsiVhVYGoVS0XdSCvouQFq//In5S8nkUaSc1r4/2VK/vEchisYxwnF0YyLz5o7CaixLBCARLGGbjZTCyHvqOCHj6sRTJtc7GP1cdFXzYo7yIGg+W1hZn7yBB32p6stE+9SurxinK312LGFvBRrJ9t7y9gIeP1aV9yd0AhTorAP0XsOMflNQnnxsNXR/8LhwsqpOt9TR8hTVdGZHi2ZqjqK37/XAGYAJpBvpQRFq2UPWj6fEGNRLsh9TzGodQh/RoESvTeoHpEVy5o2yHUcnY71bYfMpb2IJH7NHKAA= 1c6130ff5dd6933f03a40666b7f73ae51c9f90fe 0 iQEcBAABAgAGBQJTcR2fAAoJEATWKx49+7T0tcwIANUB68pzhOoVHY/BhReqVfFLJCZLdDpsTFYkPhS99lcI4LwTNrNDe4OjpNNdk3UESOvUi19pIzDCewXSkk1gVAK4CGFbYNgvLpaX+8xjfBiPv8Ct47ALCISpT74TCMXR8t+tQ3jqaPFD/0j7tAt3sP9vYDNKt1QJ8YLSH1z9aSEYng+LJT9rZxMkw6/SnZw4GVFmQyuPWFBEe7oBE/RdURvQ+i+luuBIs7BaJWe3HkMD9giEafxHzBtib4QDSUOeloUOl+7ezeBJDxdcp+CzbjU4J0QfpokuU8YhEEnnzZ+9x+Tmmnv04qzB5BP8msVVCldxfymQdGx/qxCLj26H6Uk= b3303f675157c954d2de08599e2c83db5a772450 0 iQEcBAABAgAGBQJUTukTAAoJEATWKx49+7T0nWQH/3enKf5GbOe8eDBU83MvlYARFAbGEGb70coH3sVFhC50SjPSyIAU+Am048jVmLKvy2r/ABYXHwVn73rRbgR+X92iH4Q+ivYI7ZtUEr7iUoEUVetwks6YkUezthnzCVyWk+Hy9BnkoTEN08zPGkLnVt/e5SPAqQ1tZttpKOO+HZp3JxzGtMFBY/k+ZX8fU6PZKM6FZEPu8S8m2PnQUGaCgREZrt+ikMAzgwqgpEtYoiT6M6yQLyAVRpDvFsIU3q56vA3Zc3rl6vdJjBY9AMflyd1fEYv1IfUkVPjKZg/9JL42qRRQLccEGU2W+xpd7HYi1WfI+60buVmjPNTNr/GYPfo= +f5e3ef477a32498584ac924963ff2e11c75cd477 0 iQEcBAABAgAGBQJUUrtaAAoJEATWKx49+7T0C+AH+QGUi15egTON1XwJ0aZEuI3qQScDif04EoteSwjRN+RYFLSkMPnkjG+4kx0tAG2RahlZ9gdyr4TW5a95aQhAxYS7j0bbEyJNIAektYtVniWhuxxxo5m1LjNbI6yYIYjqAqnyfzI55E15tNT2O2VkUBxgExdWACMcv0YiMGidQ+7JVox1QFwFMrJPK17NiCsboByZN9J0xj4tg0hibkt2MZ1TaYj10TMmyYDxVvZPedwa71YRNz/T3T+reroqhUYqAL2XszSX+PSMwdcxyo8+qoErBQyacD4zNAcXhwUmhTjw2g4QtwSk1WK0FDC/BunIlb6ccFoZ6FpQhO/8lu74Wjc= From pigeonhole at rename-it.nl Thu Oct 30 23:50:36 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 31 Oct 2014 00:50:36 +0100 Subject: dovecot-2.2-pigeonhole: After make distclean the distributed tar... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/3e924b1b6c5c changeset: 1955:3e924b1b6c5c user: Stephan Bosch date: Fri Oct 31 00:50:28 2014 +0100 description: After make distclean the distributed tarball would fail to recompile. diffstat: Makefile.am | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diffs (23 lines): diff -r 80b47902cf40 -r 3e924b1b6c5c Makefile.am --- a/Makefile.am Thu Oct 30 23:27:42 2014 +0100 +++ b/Makefile.am Fri Oct 31 00:50:28 2014 +0100 @@ -2,7 +2,10 @@ DOCS = doc endif -SUBDIRS = src $(DOCS) +SUBDIRS = \ + . \ + src \ + $(DOCS) ACLOCAL_AMFLAGS = -I m4 @@ -11,6 +14,7 @@ examples \ COPYING.LGPL \ ChangeLog \ + is-tagged.py \ update-version.sh dist-hook: From dovecot at dovecot.org Fri Oct 31 23:55:11 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 31 Oct 2014 23:55:11 +0000 Subject: dovecot-2.2: lib-ssl-iostream: Support non-1024bit DH parameters... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6efd7ab25b71 changeset: 18049:6efd7ab25b71 user: Timo Sirainen date: Fri Oct 31 16:54:07 2014 -0700 description: lib-ssl-iostream: Support non-1024bit DH parameters in ssl-parameters.dat. diffstat: src/lib-ssl-iostream/iostream-openssl-context.c | 2 +- src/lib-ssl-iostream/iostream-openssl-params.c | 15 ++++++++------- src/lib-ssl-iostream/iostream-openssl.h | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diffs (58 lines): diff -r 267bca7a62fb -r 6efd7ab25b71 src/lib-ssl-iostream/iostream-openssl-context.c --- a/src/lib-ssl-iostream/iostream-openssl-context.c Thu Oct 30 22:02:52 2014 +0200 +++ b/src/lib-ssl-iostream/iostream-openssl-context.c Fri Oct 31 16:54:07 2014 -0700 @@ -77,7 +77,7 @@ if (is_export && keylength == 512 && ssl_io->ctx->dh_512 != NULL) return ssl_io->ctx->dh_512; else - return ssl_io->ctx->dh_1024; + return ssl_io->ctx->dh_default; } static int diff -r 267bca7a62fb -r 6efd7ab25b71 src/lib-ssl-iostream/iostream-openssl-params.c --- a/src/lib-ssl-iostream/iostream-openssl-params.c Thu Oct 30 22:02:52 2014 +0200 +++ b/src/lib-ssl-iostream/iostream-openssl-params.c Fri Oct 31 16:54:07 2014 -0700 @@ -93,13 +93,14 @@ switch (bits) { case 512: + if (ctx->dh_512 != NULL) + return -1; ctx->dh_512 = dh; break; - case 1024: - ctx->dh_1024 = dh; - break; default: - ret = -1; + if (ctx->dh_default != NULL) + return -1; + ctx->dh_default = dh; break; } return ret; @@ -126,8 +127,8 @@ DH_free(ctx->dh_512); ctx->dh_512 = NULL; } - if (ctx->dh_1024 != NULL) { - DH_free(ctx->dh_1024); - ctx->dh_1024 = NULL; + if (ctx->dh_default != NULL) { + DH_free(ctx->dh_default); + ctx->dh_default = NULL; } } diff -r 267bca7a62fb -r 6efd7ab25b71 src/lib-ssl-iostream/iostream-openssl.h --- a/src/lib-ssl-iostream/iostream-openssl.h Thu Oct 30 22:02:52 2014 +0200 +++ b/src/lib-ssl-iostream/iostream-openssl.h Fri Oct 31 16:54:07 2014 -0700 @@ -11,7 +11,7 @@ pool_t pool; const struct ssl_iostream_settings *set; - DH *dh_512, *dh_1024; + DH *dh_512, *dh_default; int username_nid; unsigned int client_ctx:1;