From pigeonhole at rename-it.nl Fri Mar 1 00:37:45 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 28 Feb 2013 23:37:45 +0100 Subject: dovecot-2.1-pigeonhole: Sieve: editheader: fixed bug in header c... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/994b45b58e91 changeset: 1674:994b45b58e91 user: Stephan Bosch date: Thu Feb 28 23:37:31 2013 +0100 description: Sieve: editheader: fixed bug in header cloning for snapshot. Forgot to increment count for the clone. diffstat: src/lib-sieve/edit-mail.c | 1 + tests/extensions/editheader/alternating.svtest | 59 ++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 0 deletions(-) diffs (77 lines): diff -r 13d41cc284fc -r 994b45b58e91 src/lib-sieve/edit-mail.c --- a/src/lib-sieve/edit-mail.c Thu Feb 28 23:06:47 2013 +0100 +++ b/src/lib-sieve/edit-mail.c Thu Feb 28 23:37:31 2013 +0100 @@ -321,6 +321,7 @@ (&edmail_new->header_fields_head, &edmail_new->header_fields_tail, field_idx_new); + field_idx_new->header->count++; if ( field_idx->header->first == field_idx ) field_idx_new->header->first = field_idx_new; if ( field_idx->header->last == field_idx ) diff -r 13d41cc284fc -r 994b45b58e91 tests/extensions/editheader/alternating.svtest --- a/tests/extensions/editheader/alternating.svtest Thu Feb 28 23:06:47 2013 +0100 +++ b/tests/extensions/editheader/alternating.svtest Thu Feb 28 23:37:31 2013 +0100 @@ -120,3 +120,62 @@ test_fail "wrong content in redirected mail "; } } + +test_result_reset; + +test_set "message" "${message}"; +test "Alternating - add :last; delete any" { + addheader :last "X-Some-Header" "Header content"; + + if not exists "x-some-header" { + test_fail "header not added"; + } + + if not header :is "x-some-header" "Header content" { + test_fail "wrong content added"; + } + + redirect "frop at example.com"; + + deleteheader "X-Some-Other-Header"; + + if not exists "x-some-header" { + test_fail "header somehow deleted"; + } + + fileinto :create "folder3"; + + if not test_result_execute { + test_fail "failed to execute result"; + } + + /* redirected message */ + + if not test_message :smtp 0 { + test_fail "message not redirected"; + } + + if not exists "x-some-header" { + test_fail "added header not in redirected mail"; + } + + if not header :is "x-some-header" "Header content" { + test_fail "wrong content in redirected mail "; + } + + /* stored message message */ + + if not test_message :folder "folder3" 0 { + test_fail "message not stored"; + } + + if not exists "x-some-header" { + test_fail "added header lost in stored mail"; + } + + if not header :is "x-some-header" "Header content" { + test_fail "wrong content in stored mail "; + } + +} + From pigeonhole at rename-it.nl Fri Mar 1 00:37:44 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 28 Feb 2013 23:37:44 +0100 Subject: dovecot-2.1-pigeonhole: Sieve: editheader: fixed bug in full hea... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/13d41cc284fc changeset: 1673:13d41cc284fc user: Stephan Bosch date: Thu Feb 28 23:06:47 2013 +0100 description: Sieve: editheader: fixed bug in full header parsing when addheader :last is used. diffstat: src/lib-sieve/edit-mail.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (16 lines): diff -r 32d178f5e1a2 -r 13d41cc284fc src/lib-sieve/edit-mail.c --- a/src/lib-sieve/edit-mail.c Wed Feb 06 21:24:30 2013 +0100 +++ b/src/lib-sieve/edit-mail.c Thu Feb 28 23:06:47 2013 +0100 @@ -659,9 +659,11 @@ /* Insert header field index items in main list */ if ( head != NULL && tail != NULL ) { if ( edmail->header_fields_appended != NULL ) { - if ( edmail->header_fields_appended->prev != NULL ) { + if ( edmail->header_fields_head != edmail->header_fields_appended ) { edmail->header_fields_appended->prev->next = head; head->prev = edmail->header_fields_appended->prev; + } else { + edmail->header_fields_head = head; } tail->next = edmail->header_fields_appended; From pigeonhole at rename-it.nl Sat Mar 2 23:38:07 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 02 Mar 2013 22:38:07 +0100 Subject: dovecot-2.1-pigeonhole: LDA Sieve plugin: adjusted script compil... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/5a440010d1cf changeset: 1675:5a440010d1cf user: Stephan Bosch date: Sat Mar 02 22:36:55 2013 +0100 description: LDA Sieve plugin: adjusted script compile/load error reporting. Made normal compile error an info log item in the administrator log. diffstat: src/plugins/lda-sieve/lda-sieve-plugin.c | 55 ++++++++++++++++++++----------- 1 files changed, 35 insertions(+), 20 deletions(-) diffs (84 lines): diff -r 994b45b58e91 -r 5a440010d1cf src/plugins/lda-sieve/lda-sieve-plugin.c --- a/src/plugins/lda-sieve/lda-sieve-plugin.c Thu Feb 28 23:37:31 2013 +0100 +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c Sat Mar 02 22:36:55 2013 +0100 @@ -275,25 +275,34 @@ ehandler = srctx->master_ehandler; if ( debug ) - sieve_sys_debug(svinst, "opening script %s", sieve_script_location(script)); + sieve_sys_debug(svinst, "loading script %s", sieve_script_location(script)); sieve_error_handler_reset(ehandler); - /* Open the sieve script */ + /* Load or compile the sieve script */ if ( (sbin=sieve_open_script(script, ehandler, cpflags, error_r)) == NULL ) { - if ( *error_r == SIEVE_ERROR_NOT_FOUND ) { + switch ( *error_r ) { + /* Script not found */ + case SIEVE_ERROR_NOT_FOUND: if ( debug ) { sieve_sys_debug(svinst, "script file %s is missing", sieve_script_location(script)); } - } else if ( *error_r == SIEVE_ERROR_NOT_VALID && - script == srctx->user_script && srctx->userlog != NULL ) { - sieve_sys_error(svinst, "failed to open script %s " - "(view user logfile %s for more information)", - sieve_script_location(script), srctx->userlog); - } else { + break; + /* Compile failed */ + case SIEVE_ERROR_NOT_VALID: + if (script == srctx->user_script && srctx->userlog != NULL ) { + sieve_sys_info(svinst, "failed to compile script %s " + "(view user logfile %s for more information)", + sieve_script_location(script), srctx->userlog); + break; + } + /* Fall through */ + /* Something else */ + default: sieve_sys_error(svinst, "failed to open script %s", sieve_script_location(script)); + break; } return NULL; @@ -328,19 +337,25 @@ if ( (sbin=sieve_compile_script(script, ehandler, cpflags, error_r)) == NULL ) { - if ( *error_r == SIEVE_ERROR_NOT_FOUND ) { - if ( debug ) + switch ( *error_r ) { + case SIEVE_ERROR_NOT_FOUND: + if ( debug ) { sieve_sys_debug(svinst, "script file %s is missing for re-compile", sieve_script_location(script)); - } else if ( *error_r == SIEVE_ERROR_NOT_VALID && - script == srctx->user_script && srctx->userlog != NULL ) { - sieve_sys_error(svinst, - "failed to re-compile script %s " - "(view user logfile %s for more information)", - sieve_script_location(script), srctx->userlog); - } else { - sieve_sys_error(svinst, - "failed to re-compile script %s", sieve_script_location(script)); + } + break; + case SIEVE_ERROR_NOT_VALID: + if ( script == srctx->user_script && srctx->userlog != NULL ) { + sieve_sys_info(svinst, + "failed to re-compile script %s " + "(view user logfile %s for more information)", + sieve_script_location(script), srctx->userlog); + break; + } + /* Fall through */ + default: + sieve_sys_error(svinst, "failed to open script %s for re-compile", + sieve_script_location(script)); } return NULL; From pigeonhole at rename-it.nl Sun Mar 3 00:27:27 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 02 Mar 2013 23:27:27 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: added debug message showing P... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/44721c50833e changeset: 1713:44721c50833e user: Stephan Bosch date: Sat Mar 02 23:27:13 2013 +0100 description: lib-sieve: added debug message showing Pigeonhole version at initialization. Very useful to show that debugging is enabled and what version of pigeonhole is actually running. diffstat: src/lib-sieve/sieve.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r 99eec511aa2c -r 44721c50833e src/lib-sieve/sieve.c --- a/src/lib-sieve/sieve.c Mon Jan 14 12:57:58 2013 +0100 +++ b/src/lib-sieve/sieve.c Sat Mar 02 23:27:13 2013 +0100 @@ -66,6 +66,11 @@ sieve_errors_init(svinst); + if ( debug ) { + sieve_sys_debug(svinst, "%s version %s initializing", + PIGEONHOLE_NAME, PIGEONHOLE_VERSION); + } + /* Read limits from configuration */ svinst->max_script_size = SIEVE_DEFAULT_MAX_SCRIPT_SIZE; From pigeonhole at rename-it.nl Sun Mar 3 17:52:44 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 03 Mar 2013 16:52:44 +0100 Subject: dovecot-2.1-pigeonhole: LDA Sieve plugin: fixed stupid mistake i... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/9e8392895ab7 changeset: 1676:9e8392895ab7 user: Stephan Bosch date: Sun Mar 03 16:52:39 2013 +0100 description: LDA Sieve plugin: fixed stupid mistake in error handling for multiscript. Used errno instead of error variable. diffstat: src/plugins/lda-sieve/lda-sieve-plugin.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 5a440010d1cf -r 9e8392895ab7 src/plugins/lda-sieve/lda-sieve-plugin.c --- a/src/plugins/lda-sieve/lda-sieve-plugin.c Sat Mar 02 22:36:55 2013 +0100 +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c Sun Mar 03 16:52:39 2013 +0100 @@ -219,7 +219,7 @@ (svinst, files[i], NULL, ehandler, &error); if ( script == NULL ) { - switch ( errno ) { + switch ( error ) { case SIEVE_ERROR_NOT_FOUND: /* Shouldn't normally happen, but the script could have disappeared */ sieve_sys_warning From pigeonhole at rename-it.nl Sun Mar 3 17:55:11 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 03 Mar 2013 16:55:11 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: Increased a few initial memor... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/f8fad363984d changeset: 1715:f8fad363984d user: Stephan Bosch date: Sat Jan 26 09:10:26 2013 +0100 description: lib-sieve: Increased a few initial memory pool sizes. diffstat: src/lib-sieve/plugins/editheader/ext-editheader-common.c | 2 +- src/lib-sieve/sieve-ast.c | 2 +- src/lib-sieve/sieve-binary.c | 2 +- src/lib-sieve/sieve-error.c | 4 ++-- src/lib-sieve/sieve-validator.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diffs (69 lines): diff -r ab15c5eabc09 -r f8fad363984d src/lib-sieve/plugins/editheader/ext-editheader-common.c --- a/src/lib-sieve/plugins/editheader/ext-editheader-common.c Sat Jan 26 08:52:27 2013 +0100 +++ b/src/lib-sieve/plugins/editheader/ext-editheader-common.c Sat Jan 26 09:10:26 2013 +0100 @@ -64,7 +64,7 @@ } T_BEGIN { - pool = pool_alloconly_create("editheader_config", 512); + pool = pool_alloconly_create("editheader_config", 1024); ext_config = p_new(pool, struct ext_editheader_config, 1); ext_config->pool = pool; ext_config->max_header_size = EXT_EDITHEADER_DEFAULT_MAX_HEADER_SIZE; diff -r ab15c5eabc09 -r f8fad363984d src/lib-sieve/sieve-ast.c --- a/src/lib-sieve/sieve-ast.c Sat Jan 26 08:52:27 2013 +0100 +++ b/src/lib-sieve/sieve-ast.c Sat Jan 26 09:10:26 2013 +0100 @@ -59,7 +59,7 @@ struct sieve_ast *ast; unsigned int ext_count; - pool = pool_alloconly_create("sieve_ast", 16384); + pool = pool_alloconly_create("sieve_ast", 32768); ast = p_new(pool, struct sieve_ast, 1); ast->pool = pool; ast->refcount = 1; diff -r ab15c5eabc09 -r f8fad363984d src/lib-sieve/sieve-binary.c --- a/src/lib-sieve/sieve-binary.c Sat Jan 26 08:52:27 2013 +0100 +++ b/src/lib-sieve/sieve-binary.c Sat Jan 26 09:10:26 2013 +0100 @@ -43,7 +43,7 @@ const struct sieve_extension *const *ext_preloaded; unsigned int i, ext_count; - pool = pool_alloconly_create("sieve_binary", 8192); + pool = pool_alloconly_create("sieve_binary", 16384); sbin = p_new(pool, struct sieve_binary, 1); sbin->pool = pool; sbin->refcount = 1; diff -r ab15c5eabc09 -r f8fad363984d src/lib-sieve/sieve-error.c --- a/src/lib-sieve/sieve-error.c Sat Jan 26 08:52:27 2013 +0100 +++ b/src/lib-sieve/sieve-error.c Sat Jan 26 09:10:26 2013 +0100 @@ -1221,7 +1221,7 @@ if ( parent == NULL ) return NULL; - pool = pool_alloconly_create("sieve_prefix_error_handler", 256); + pool = pool_alloconly_create("sieve_prefix_error_handler", 512); ehandler = p_new(pool, struct sieve_prefix_ehandler, 1); sieve_error_handler_init_from_parent(&ehandler->handler, pool, parent); @@ -1320,7 +1320,7 @@ return parent; } - pool = pool_alloconly_create("sieve_varexpand_error_handler", 1024); + pool = pool_alloconly_create("sieve_varexpand_error_handler", 2048); ehandler = p_new(pool, struct sieve_varexpand_ehandler, 1); sieve_error_handler_init_from_parent(&ehandler->handler, pool, parent); diff -r ab15c5eabc09 -r f8fad363984d src/lib-sieve/sieve-validator.c --- a/src/lib-sieve/sieve-validator.c Sat Jan 26 08:52:27 2013 +0100 +++ b/src/lib-sieve/sieve-validator.c Sat Jan 26 09:10:26 2013 +0100 @@ -150,7 +150,7 @@ const struct sieve_extension *const *ext_preloaded; unsigned int i, ext_count; - pool = pool_alloconly_create("sieve_validator", 8192); + pool = pool_alloconly_create("sieve_validator", 16384); valdtr = p_new(pool, struct sieve_validator, 1); valdtr->pool = pool; From pigeonhole at rename-it.nl Sun Mar 3 17:55:11 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 03 Mar 2013 16:55:11 +0100 Subject: dovecot-2.2-pigeonhole: managesieve: Fixed bug in skipping of CR... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/32d178f5e1a2 changeset: 1716:32d178f5e1a2 user: Stephan Bosch date: Wed Feb 06 21:24:30 2013 +0100 description: managesieve: Fixed bug in skipping of CRLF at end of AUTHENTICATE command. Setting skip_newline is useless when the connection is transfered to another process after successful login. diffstat: src/managesieve-login/client-authenticate.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r f8fad363984d -r 32d178f5e1a2 src/managesieve-login/client-authenticate.c --- a/src/managesieve-login/client-authenticate.c Sat Jan 26 09:10:26 2013 +0100 +++ b/src/managesieve-login/client-authenticate.c Wed Feb 06 21:24:30 2013 +0100 @@ -257,7 +257,7 @@ } if ( i_stream_next_line(client->input) == NULL ) - msieve_client->skip_line = TRUE; + return 0; return 1; } From pigeonhole at rename-it.nl Sun Mar 3 17:55:12 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 03 Mar 2013 16:55:12 +0100 Subject: dovecot-2.2-pigeonhole: Merged changes from Pigeonhole v0.3. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/feb8fca97a0e changeset: 1721:feb8fca97a0e user: Stephan Bosch date: Sun Mar 03 16:55:05 2013 +0100 description: Merged changes from Pigeonhole v0.3. diffstat: src/lib-sieve/cmd-redirect.c | 6 +- src/lib-sieve/edit-mail.c | 5 +- src/lib-sieve/plugins/editheader/ext-editheader-common.c | 2 +- src/lib-sieve/sieve-ast.c | 2 +- src/lib-sieve/sieve-binary.c | 2 +- src/lib-sieve/sieve-error.c | 4 +- src/lib-sieve/sieve-validator.c | 2 +- src/managesieve-login/client-authenticate.c | 2 +- src/plugins/lda-sieve/lda-sieve-plugin.c | 57 +++++++++----- tests/extensions/editheader/alternating.svtest | 59 ++++++++++++++++ 10 files changed, 110 insertions(+), 31 deletions(-) diffs (288 lines): diff -r 44721c50833e -r feb8fca97a0e src/lib-sieve/cmd-redirect.c --- a/src/lib-sieve/cmd-redirect.c Sat Mar 02 23:27:13 2013 +0100 +++ b/src/lib-sieve/cmd-redirect.c Sun Mar 03 16:55:05 2013 +0100 @@ -376,16 +376,18 @@ action->mail : sieve_message_get_mail(aenv->msgctx) ); const struct sieve_message_data *msgdata = aenv->msgdata; const struct sieve_script_env *senv = aenv->scriptenv; + const char *orig_recipient = sieve_message_get_orig_recipient(aenv->msgctx); const char *dupeid; /* Prevent mail loops if possible */ - dupeid = msgdata->id == NULL ? - NULL : t_strdup_printf("%s-%s", msgdata->id, ctx->to_address); + dupeid = msgdata->id == NULL ? NULL : t_strdup_printf + ("%s-%s-%s", msgdata->id, orig_recipient, ctx->to_address); if (dupeid != NULL) { /* Check whether we've seen this message before */ if (sieve_action_duplicate_check(senv, dupeid, strlen(dupeid))) { sieve_result_global_log(aenv, "discarded duplicate forward to <%s>", str_sanitize(ctx->to_address, 128)); + *keep = FALSE; return TRUE; } } diff -r 44721c50833e -r feb8fca97a0e src/lib-sieve/edit-mail.c --- a/src/lib-sieve/edit-mail.c Sat Mar 02 23:27:13 2013 +0100 +++ b/src/lib-sieve/edit-mail.c Sun Mar 03 16:55:05 2013 +0100 @@ -322,6 +322,7 @@ (&edmail_new->header_fields_head, &edmail_new->header_fields_tail, field_idx_new); + field_idx_new->header->count++; if ( field_idx->header->first == field_idx ) field_idx_new->header->first = field_idx_new; if ( field_idx->header->last == field_idx ) @@ -658,9 +659,11 @@ /* Insert header field index items in main list */ if ( head != NULL && tail != NULL ) { if ( edmail->header_fields_appended != NULL ) { - if ( edmail->header_fields_appended->prev != NULL ) { + if ( edmail->header_fields_head != edmail->header_fields_appended ) { edmail->header_fields_appended->prev->next = head; head->prev = edmail->header_fields_appended->prev; + } else { + edmail->header_fields_head = head; } tail->next = edmail->header_fields_appended; diff -r 44721c50833e -r feb8fca97a0e src/lib-sieve/plugins/editheader/ext-editheader-common.c --- a/src/lib-sieve/plugins/editheader/ext-editheader-common.c Sat Mar 02 23:27:13 2013 +0100 +++ b/src/lib-sieve/plugins/editheader/ext-editheader-common.c Sun Mar 03 16:55:05 2013 +0100 @@ -64,7 +64,7 @@ } T_BEGIN { - pool = pool_alloconly_create("editheader_config", 512); + pool = pool_alloconly_create("editheader_config", 1024); ext_config = p_new(pool, struct ext_editheader_config, 1); ext_config->pool = pool; ext_config->max_header_size = EXT_EDITHEADER_DEFAULT_MAX_HEADER_SIZE; diff -r 44721c50833e -r feb8fca97a0e src/lib-sieve/sieve-ast.c --- a/src/lib-sieve/sieve-ast.c Sat Mar 02 23:27:13 2013 +0100 +++ b/src/lib-sieve/sieve-ast.c Sun Mar 03 16:55:05 2013 +0100 @@ -59,7 +59,7 @@ struct sieve_ast *ast; unsigned int ext_count; - pool = pool_alloconly_create("sieve_ast", 16384); + pool = pool_alloconly_create("sieve_ast", 32768); ast = p_new(pool, struct sieve_ast, 1); ast->pool = pool; ast->refcount = 1; diff -r 44721c50833e -r feb8fca97a0e src/lib-sieve/sieve-binary.c --- a/src/lib-sieve/sieve-binary.c Sat Mar 02 23:27:13 2013 +0100 +++ b/src/lib-sieve/sieve-binary.c Sun Mar 03 16:55:05 2013 +0100 @@ -43,7 +43,7 @@ const struct sieve_extension *const *ext_preloaded; unsigned int i, ext_count; - pool = pool_alloconly_create("sieve_binary", 8192); + pool = pool_alloconly_create("sieve_binary", 16384); sbin = p_new(pool, struct sieve_binary, 1); sbin->pool = pool; sbin->refcount = 1; diff -r 44721c50833e -r feb8fca97a0e src/lib-sieve/sieve-error.c --- a/src/lib-sieve/sieve-error.c Sat Mar 02 23:27:13 2013 +0100 +++ b/src/lib-sieve/sieve-error.c Sun Mar 03 16:55:05 2013 +0100 @@ -1221,7 +1221,7 @@ if ( parent == NULL ) return NULL; - pool = pool_alloconly_create("sieve_prefix_error_handler", 256); + pool = pool_alloconly_create("sieve_prefix_error_handler", 512); ehandler = p_new(pool, struct sieve_prefix_ehandler, 1); sieve_error_handler_init_from_parent(&ehandler->handler, pool, parent); @@ -1320,7 +1320,7 @@ return parent; } - pool = pool_alloconly_create("sieve_varexpand_error_handler", 1024); + pool = pool_alloconly_create("sieve_varexpand_error_handler", 2048); ehandler = p_new(pool, struct sieve_varexpand_ehandler, 1); sieve_error_handler_init_from_parent(&ehandler->handler, pool, parent); diff -r 44721c50833e -r feb8fca97a0e src/lib-sieve/sieve-validator.c --- a/src/lib-sieve/sieve-validator.c Sat Mar 02 23:27:13 2013 +0100 +++ b/src/lib-sieve/sieve-validator.c Sun Mar 03 16:55:05 2013 +0100 @@ -150,7 +150,7 @@ const struct sieve_extension *const *ext_preloaded; unsigned int i, ext_count; - pool = pool_alloconly_create("sieve_validator", 8192); + pool = pool_alloconly_create("sieve_validator", 16384); valdtr = p_new(pool, struct sieve_validator, 1); valdtr->pool = pool; diff -r 44721c50833e -r feb8fca97a0e src/managesieve-login/client-authenticate.c --- a/src/managesieve-login/client-authenticate.c Sat Mar 02 23:27:13 2013 +0100 +++ b/src/managesieve-login/client-authenticate.c Sun Mar 03 16:55:05 2013 +0100 @@ -243,7 +243,7 @@ } if ( i_stream_next_line(client->input) == NULL ) - msieve_client->skip_line = TRUE; + return 0; return 1; } diff -r 44721c50833e -r feb8fca97a0e src/plugins/lda-sieve/lda-sieve-plugin.c --- a/src/plugins/lda-sieve/lda-sieve-plugin.c Sat Mar 02 23:27:13 2013 +0100 +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c Sun Mar 03 16:55:05 2013 +0100 @@ -221,7 +221,7 @@ (svinst, files[i], NULL, ehandler, &error); if ( script == NULL ) { - switch ( errno ) { + switch ( error ) { case SIEVE_ERROR_NOT_FOUND: /* Shouldn't normally happen, but the script could have disappeared */ sieve_sys_warning @@ -277,25 +277,34 @@ ehandler = srctx->master_ehandler; if ( debug ) - sieve_sys_debug(svinst, "opening script %s", sieve_script_location(script)); + sieve_sys_debug(svinst, "loading script %s", sieve_script_location(script)); sieve_error_handler_reset(ehandler); - /* Open the sieve script */ + /* Load or compile the sieve script */ if ( (sbin=sieve_open_script(script, ehandler, cpflags, error_r)) == NULL ) { - if ( *error_r == SIEVE_ERROR_NOT_FOUND ) { + switch ( *error_r ) { + /* Script not found */ + case SIEVE_ERROR_NOT_FOUND: if ( debug ) { sieve_sys_debug(svinst, "script file %s is missing", sieve_script_location(script)); } - } else if ( *error_r == SIEVE_ERROR_NOT_VALID && - script == srctx->user_script && srctx->userlog != NULL ) { - sieve_sys_error(svinst, "failed to open script %s " - "(view user logfile %s for more information)", - sieve_script_location(script), srctx->userlog); - } else { + break; + /* Compile failed */ + case SIEVE_ERROR_NOT_VALID: + if (script == srctx->user_script && srctx->userlog != NULL ) { + sieve_sys_info(svinst, "failed to compile script %s " + "(view user logfile %s for more information)", + sieve_script_location(script), srctx->userlog); + break; + } + /* Fall through */ + /* Something else */ + default: sieve_sys_error(svinst, "failed to open script %s", sieve_script_location(script)); + break; } return NULL; @@ -330,19 +339,25 @@ if ( (sbin=sieve_compile_script(script, ehandler, cpflags, error_r)) == NULL ) { - if ( *error_r == SIEVE_ERROR_NOT_FOUND ) { - if ( debug ) + switch ( *error_r ) { + case SIEVE_ERROR_NOT_FOUND: + if ( debug ) { sieve_sys_debug(svinst, "script file %s is missing for re-compile", sieve_script_location(script)); - } else if ( *error_r == SIEVE_ERROR_NOT_VALID && - script == srctx->user_script && srctx->userlog != NULL ) { - sieve_sys_error(svinst, - "failed to re-compile script %s " - "(view user logfile %s for more information)", - sieve_script_location(script), srctx->userlog); - } else { - sieve_sys_error(svinst, - "failed to re-compile script %s", sieve_script_location(script)); + } + break; + case SIEVE_ERROR_NOT_VALID: + if ( script == srctx->user_script && srctx->userlog != NULL ) { + sieve_sys_info(svinst, + "failed to re-compile script %s " + "(view user logfile %s for more information)", + sieve_script_location(script), srctx->userlog); + break; + } + /* Fall through */ + default: + sieve_sys_error(svinst, "failed to open script %s for re-compile", + sieve_script_location(script)); } return NULL; diff -r 44721c50833e -r feb8fca97a0e tests/extensions/editheader/alternating.svtest --- a/tests/extensions/editheader/alternating.svtest Sat Mar 02 23:27:13 2013 +0100 +++ b/tests/extensions/editheader/alternating.svtest Sun Mar 03 16:55:05 2013 +0100 @@ -120,3 +120,62 @@ test_fail "wrong content in redirected mail "; } } + +test_result_reset; + +test_set "message" "${message}"; +test "Alternating - add :last; delete any" { + addheader :last "X-Some-Header" "Header content"; + + if not exists "x-some-header" { + test_fail "header not added"; + } + + if not header :is "x-some-header" "Header content" { + test_fail "wrong content added"; + } + + redirect "frop at example.com"; + + deleteheader "X-Some-Other-Header"; + + if not exists "x-some-header" { + test_fail "header somehow deleted"; + } + + fileinto :create "folder3"; + + if not test_result_execute { + test_fail "failed to execute result"; + } + + /* redirected message */ + + if not test_message :smtp 0 { + test_fail "message not redirected"; + } + + if not exists "x-some-header" { + test_fail "added header not in redirected mail"; + } + + if not header :is "x-some-header" "Header content" { + test_fail "wrong content in redirected mail "; + } + + /* stored message message */ + + if not test_message :folder "folder3" 0 { + test_fail "message not stored"; + } + + if not exists "x-some-header" { + test_fail "added header lost in stored mail"; + } + + if not header :is "x-some-header" "Header content" { + test_fail "wrong content in stored mail "; + } + +} + From pigeonhole at rename-it.nl Sun Mar 3 17:55:12 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 03 Mar 2013 16:55:12 +0100 Subject: dovecot-2.2-pigeonhole: LDA Sieve plugin: fixed stupid mistake i... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/9e8392895ab7 changeset: 1720:9e8392895ab7 user: Stephan Bosch date: Sun Mar 03 16:52:39 2013 +0100 description: LDA Sieve plugin: fixed stupid mistake in error handling for multiscript. Used errno instead of error variable. diffstat: src/plugins/lda-sieve/lda-sieve-plugin.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 5a440010d1cf -r 9e8392895ab7 src/plugins/lda-sieve/lda-sieve-plugin.c --- a/src/plugins/lda-sieve/lda-sieve-plugin.c Sat Mar 02 22:36:55 2013 +0100 +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c Sun Mar 03 16:52:39 2013 +0100 @@ -219,7 +219,7 @@ (svinst, files[i], NULL, ehandler, &error); if ( script == NULL ) { - switch ( errno ) { + switch ( error ) { case SIEVE_ERROR_NOT_FOUND: /* Shouldn't normally happen, but the script could have disappeared */ sieve_sys_warning From pigeonhole at rename-it.nl Sun Mar 3 17:55:11 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 03 Mar 2013 16:55:11 +0100 Subject: dovecot-2.2-pigeonhole: LDA Sieve plugin: adjusted script compil... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/5a440010d1cf changeset: 1719:5a440010d1cf user: Stephan Bosch date: Sat Mar 02 22:36:55 2013 +0100 description: LDA Sieve plugin: adjusted script compile/load error reporting. Made normal compile error an info log item in the administrator log. diffstat: src/plugins/lda-sieve/lda-sieve-plugin.c | 55 ++++++++++++++++++++----------- 1 files changed, 35 insertions(+), 20 deletions(-) diffs (84 lines): diff -r 994b45b58e91 -r 5a440010d1cf src/plugins/lda-sieve/lda-sieve-plugin.c --- a/src/plugins/lda-sieve/lda-sieve-plugin.c Thu Feb 28 23:37:31 2013 +0100 +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c Sat Mar 02 22:36:55 2013 +0100 @@ -275,25 +275,34 @@ ehandler = srctx->master_ehandler; if ( debug ) - sieve_sys_debug(svinst, "opening script %s", sieve_script_location(script)); + sieve_sys_debug(svinst, "loading script %s", sieve_script_location(script)); sieve_error_handler_reset(ehandler); - /* Open the sieve script */ + /* Load or compile the sieve script */ if ( (sbin=sieve_open_script(script, ehandler, cpflags, error_r)) == NULL ) { - if ( *error_r == SIEVE_ERROR_NOT_FOUND ) { + switch ( *error_r ) { + /* Script not found */ + case SIEVE_ERROR_NOT_FOUND: if ( debug ) { sieve_sys_debug(svinst, "script file %s is missing", sieve_script_location(script)); } - } else if ( *error_r == SIEVE_ERROR_NOT_VALID && - script == srctx->user_script && srctx->userlog != NULL ) { - sieve_sys_error(svinst, "failed to open script %s " - "(view user logfile %s for more information)", - sieve_script_location(script), srctx->userlog); - } else { + break; + /* Compile failed */ + case SIEVE_ERROR_NOT_VALID: + if (script == srctx->user_script && srctx->userlog != NULL ) { + sieve_sys_info(svinst, "failed to compile script %s " + "(view user logfile %s for more information)", + sieve_script_location(script), srctx->userlog); + break; + } + /* Fall through */ + /* Something else */ + default: sieve_sys_error(svinst, "failed to open script %s", sieve_script_location(script)); + break; } return NULL; @@ -328,19 +337,25 @@ if ( (sbin=sieve_compile_script(script, ehandler, cpflags, error_r)) == NULL ) { - if ( *error_r == SIEVE_ERROR_NOT_FOUND ) { - if ( debug ) + switch ( *error_r ) { + case SIEVE_ERROR_NOT_FOUND: + if ( debug ) { sieve_sys_debug(svinst, "script file %s is missing for re-compile", sieve_script_location(script)); - } else if ( *error_r == SIEVE_ERROR_NOT_VALID && - script == srctx->user_script && srctx->userlog != NULL ) { - sieve_sys_error(svinst, - "failed to re-compile script %s " - "(view user logfile %s for more information)", - sieve_script_location(script), srctx->userlog); - } else { - sieve_sys_error(svinst, - "failed to re-compile script %s", sieve_script_location(script)); + } + break; + case SIEVE_ERROR_NOT_VALID: + if ( script == srctx->user_script && srctx->userlog != NULL ) { + sieve_sys_info(svinst, + "failed to re-compile script %s " + "(view user logfile %s for more information)", + sieve_script_location(script), srctx->userlog); + break; + } + /* Fall through */ + default: + sieve_sys_error(svinst, "failed to open script %s for re-compile", + sieve_script_location(script)); } return NULL; From pigeonhole at rename-it.nl Sun Mar 3 17:55:11 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 03 Mar 2013 16:55:11 +0100 Subject: dovecot-2.2-pigeonhole: Sieve: editheader: fixed bug in full hea... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/13d41cc284fc changeset: 1717:13d41cc284fc user: Stephan Bosch date: Thu Feb 28 23:06:47 2013 +0100 description: Sieve: editheader: fixed bug in full header parsing when addheader :last is used. diffstat: src/lib-sieve/edit-mail.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (16 lines): diff -r 32d178f5e1a2 -r 13d41cc284fc src/lib-sieve/edit-mail.c --- a/src/lib-sieve/edit-mail.c Wed Feb 06 21:24:30 2013 +0100 +++ b/src/lib-sieve/edit-mail.c Thu Feb 28 23:06:47 2013 +0100 @@ -659,9 +659,11 @@ /* Insert header field index items in main list */ if ( head != NULL && tail != NULL ) { if ( edmail->header_fields_appended != NULL ) { - if ( edmail->header_fields_appended->prev != NULL ) { + if ( edmail->header_fields_head != edmail->header_fields_appended ) { edmail->header_fields_appended->prev->next = head; head->prev = edmail->header_fields_appended->prev; + } else { + edmail->header_fields_head = head; } tail->next = edmail->header_fields_appended; From pigeonhole at rename-it.nl Sun Mar 3 17:55:11 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 03 Mar 2013 16:55:11 +0100 Subject: dovecot-2.2-pigeonhole: Sieve: editheader: fixed bug in header c... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/994b45b58e91 changeset: 1718:994b45b58e91 user: Stephan Bosch date: Thu Feb 28 23:37:31 2013 +0100 description: Sieve: editheader: fixed bug in header cloning for snapshot. Forgot to increment count for the clone. diffstat: src/lib-sieve/edit-mail.c | 1 + tests/extensions/editheader/alternating.svtest | 59 ++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 0 deletions(-) diffs (77 lines): diff -r 13d41cc284fc -r 994b45b58e91 src/lib-sieve/edit-mail.c --- a/src/lib-sieve/edit-mail.c Thu Feb 28 23:06:47 2013 +0100 +++ b/src/lib-sieve/edit-mail.c Thu Feb 28 23:37:31 2013 +0100 @@ -321,6 +321,7 @@ (&edmail_new->header_fields_head, &edmail_new->header_fields_tail, field_idx_new); + field_idx_new->header->count++; if ( field_idx->header->first == field_idx ) field_idx_new->header->first = field_idx_new; if ( field_idx->header->last == field_idx ) diff -r 13d41cc284fc -r 994b45b58e91 tests/extensions/editheader/alternating.svtest --- a/tests/extensions/editheader/alternating.svtest Thu Feb 28 23:06:47 2013 +0100 +++ b/tests/extensions/editheader/alternating.svtest Thu Feb 28 23:37:31 2013 +0100 @@ -120,3 +120,62 @@ test_fail "wrong content in redirected mail "; } } + +test_result_reset; + +test_set "message" "${message}"; +test "Alternating - add :last; delete any" { + addheader :last "X-Some-Header" "Header content"; + + if not exists "x-some-header" { + test_fail "header not added"; + } + + if not header :is "x-some-header" "Header content" { + test_fail "wrong content added"; + } + + redirect "frop at example.com"; + + deleteheader "X-Some-Other-Header"; + + if not exists "x-some-header" { + test_fail "header somehow deleted"; + } + + fileinto :create "folder3"; + + if not test_result_execute { + test_fail "failed to execute result"; + } + + /* redirected message */ + + if not test_message :smtp 0 { + test_fail "message not redirected"; + } + + if not exists "x-some-header" { + test_fail "added header not in redirected mail"; + } + + if not header :is "x-some-header" "Header content" { + test_fail "wrong content in redirected mail "; + } + + /* stored message message */ + + if not test_message :folder "folder3" 0 { + test_fail "message not stored"; + } + + if not exists "x-some-header" { + test_fail "added header lost in stored mail"; + } + + if not header :is "x-some-header" "Header content" { + test_fail "wrong content in stored mail "; + } + +} + From pigeonhole at rename-it.nl Sun Mar 3 17:55:11 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 03 Mar 2013 16:55:11 +0100 Subject: dovecot-2.2-pigeonhole: Changed behavior of redirect in case of ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/ab15c5eabc09 changeset: 1714:ab15c5eabc09 user: Stephan Bosch date: Sat Jan 26 08:52:27 2013 +0100 description: Changed behavior of redirect in case of a duplicate message delivery or a mail loop. If a duplicate is detected the implicit keep is canceled, as though the redirect was successful. This prevents getting local deliveries. The original SMTP recipient is used when it is available to augment the entry in the LDA duplicate database. This way, duplicates are only detected when (initially) addressed to the same recipient. The main goal of the duplicate detection is mail loop prevention, but this also has the effect that mere duplicate deliveries are handled specially whithout a good reason. We should fix this in a future version. diffstat: src/lib-sieve/cmd-redirect.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (24 lines): diff -r fe5f2738d538 -r ab15c5eabc09 src/lib-sieve/cmd-redirect.c --- a/src/lib-sieve/cmd-redirect.c Wed Dec 26 11:52:03 2012 +0100 +++ b/src/lib-sieve/cmd-redirect.c Sat Jan 26 08:52:27 2013 +0100 @@ -385,16 +385,18 @@ action->mail : sieve_message_get_mail(aenv->msgctx) ); const struct sieve_message_data *msgdata = aenv->msgdata; const struct sieve_script_env *senv = aenv->scriptenv; + const char *orig_recipient = sieve_message_get_orig_recipient(aenv->msgctx); const char *dupeid; /* Prevent mail loops if possible */ - dupeid = msgdata->id == NULL ? - NULL : t_strdup_printf("%s-%s", msgdata->id, ctx->to_address); + dupeid = msgdata->id == NULL ? NULL : t_strdup_printf + ("%s-%s-%s", msgdata->id, orig_recipient, ctx->to_address); if (dupeid != NULL) { /* Check whether we've seen this message before */ if (sieve_action_duplicate_check(senv, dupeid, strlen(dupeid))) { sieve_result_global_log(aenv, "discarded duplicate forward to <%s>", str_sanitize(ctx->to_address, 128)); + *keep = FALSE; return TRUE; } } From pigeonhole at rename-it.nl Sun Mar 3 18:35:43 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 03 Mar 2013 17:35:43 +0100 Subject: dovecot-2.2-pigeonhole: LDA Sieve plugin: fixed bug in opening s... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/f43c7609497c changeset: 1722:f43c7609497c user: Stephan Bosch date: Sun Mar 03 17:35:37 2013 +0100 description: LDA Sieve plugin: fixed bug in opening script files for multiscript. Used sieve_script_create instead of sieve_script_create_open. Changed plugin debug output a bit as well. diffstat: src/lib-sieve/sieve-script.c | 2 ++ src/plugins/lda-sieve/lda-sieve-plugin.c | 11 +++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diffs (54 lines): diff -r feb8fca97a0e -r f43c7609497c src/lib-sieve/sieve-script.c --- a/src/lib-sieve/sieve-script.c Sun Mar 03 16:55:05 2013 +0100 +++ b/src/lib-sieve/sieve-script.c Sun Mar 03 17:35:37 2013 +0100 @@ -240,6 +240,7 @@ script = script_class->v.alloc(); sieve_script_init(script, svinst, script_class, data, name, ehandler); + script->location = p_strdup(script->pool, location); return script; } @@ -268,6 +269,7 @@ return -1; } + script->location = NULL; if ( script->v.open(script, location, options, &error) < 0 ) { if ( error_r == NULL ) { if ( error == SIEVE_ERROR_NOT_FOUND ) diff -r feb8fca97a0e -r f43c7609497c src/plugins/lda-sieve/lda-sieve-plugin.c --- a/src/plugins/lda-sieve/lda-sieve-plugin.c Sun Mar 03 16:55:05 2013 +0100 +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c Sun Mar 03 17:35:37 2013 +0100 @@ -217,7 +217,7 @@ files = array_get(&script_files, &count); for ( i = 0; i < count; i++ ) { - struct sieve_script *script = sieve_script_create + struct sieve_script *script = sieve_script_create_open (svinst, files[i], NULL, ehandler, &error); if ( script == NULL ) { @@ -529,14 +529,21 @@ /* Open */ + if ( debug ) { + sieve_sys_debug + (svinst, "opening script %d of %d from %s", i+1, count, + sieve_script_location(script)); + } + if ( (sbin=lda_sieve_open(srctx, script, cpflags, &error)) == NULL ) break; /* Execute */ - if ( debug ) + if ( debug ) { sieve_sys_debug (svinst, "executing script from %s", sieve_get_source(sbin)); + } more = sieve_multiscript_run(mscript, sbin, ehandler, rtflags, final); From pigeonhole at rename-it.nl Sun Mar 3 19:04:36 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 03 Mar 2013 18:04:36 +0100 Subject: dovecot-2.1-pigeonhole: LDA Sieve plugin: further reduced useles... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/06c89405bdc6 changeset: 1677:06c89405bdc6 user: Stephan Bosch date: Sun Mar 03 18:03:33 2013 +0100 description: LDA Sieve plugin: further reduced useless error messages in administrator log. diffstat: src/plugins/lda-sieve/lda-sieve-plugin.c | 25 +++++++++++++++++++------ 1 files changed, 19 insertions(+), 6 deletions(-) diffs (77 lines): diff -r 9e8392895ab7 -r 06c89405bdc6 src/plugins/lda-sieve/lda-sieve-plugin.c --- a/src/plugins/lda-sieve/lda-sieve-plugin.c Sun Mar 03 16:52:39 2013 +0100 +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c Sun Mar 03 18:03:33 2013 +0100 @@ -370,27 +370,32 @@ struct sieve_instance *svinst = srctx->svinst; struct sieve_exec_status *estatus = srctx->scriptenv->exec_status; const char *userlog_notice = ""; - sieve_sys_error_func_t error_func = sieve_sys_error; + sieve_sys_error_func_t error_func, user_error_func; int ret; + error_func = user_error_func = sieve_sys_error; + if ( estatus != NULL && estatus->last_storage != NULL ) { enum mail_error mail_error; mail_storage_get_last_error(estatus->last_storage, &mail_error); /* Don't bother administrator too much with benign errors */ - if ( mail_error == MAIL_ERROR_NOSPACE ) + if ( mail_error == MAIL_ERROR_NOSPACE ) { error_func = sieve_sys_info; + user_error_func = sieve_sys_info; + } } if ( script == srctx->user_script && srctx->userlog != NULL ) { userlog_notice = t_strdup_printf (" (user logfile %s should reveal additional details)", srctx->userlog); + user_error_func = sieve_sys_info; } switch ( status ) { case SIEVE_EXEC_FAILURE: - error_func(svinst, + user_error_func(svinst, "execution of script %s failed, but implicit keep was successful%s", sieve_script_location(script), userlog_notice); ret = 1; @@ -494,10 +499,9 @@ struct sieve_error_handler *ehandler = srctx->master_ehandler; bool debug = srctx->mdctx->dest_user->mail_debug; struct sieve_script *last_script = NULL; - bool user_script = FALSE; + bool user_script = FALSE, more = TRUE, compile_error = FALSE; unsigned int i; int ret = 1; - bool more = TRUE; enum sieve_error error; /* Start execution */ @@ -527,8 +531,10 @@ /* Open */ - if ( (sbin=lda_sieve_open(srctx, script, cpflags, &error)) == NULL ) + if ( (sbin=lda_sieve_open(srctx, script, cpflags, &error)) == NULL ) { + compile_error = TRUE; break; + } /* Execute */ @@ -571,6 +577,13 @@ ret = sieve_multiscript_finish(&mscript, ehandler, NULL); + /* Don't log additional messages about compile failure */ + if ( compile_error && ret == SIEVE_EXEC_FAILURE ) { + sieve_sys_info(svinst, + "aborted script execution sequence with successful implicit keep"); + return 1; + } + return lda_sieve_handle_exec_status(srctx, last_script, ret); } From pigeonhole at rename-it.nl Sun Mar 3 19:07:35 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 03 Mar 2013 18:07:35 +0100 Subject: dovecot-2.2-pigeonhole: LDA Sieve plugin: further reduced useles... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/06c89405bdc6 changeset: 1723:06c89405bdc6 user: Stephan Bosch date: Sun Mar 03 18:03:33 2013 +0100 description: LDA Sieve plugin: further reduced useless error messages in administrator log. diffstat: src/plugins/lda-sieve/lda-sieve-plugin.c | 25 +++++++++++++++++++------ 1 files changed, 19 insertions(+), 6 deletions(-) diffs (77 lines): diff -r 9e8392895ab7 -r 06c89405bdc6 src/plugins/lda-sieve/lda-sieve-plugin.c --- a/src/plugins/lda-sieve/lda-sieve-plugin.c Sun Mar 03 16:52:39 2013 +0100 +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c Sun Mar 03 18:03:33 2013 +0100 @@ -370,27 +370,32 @@ struct sieve_instance *svinst = srctx->svinst; struct sieve_exec_status *estatus = srctx->scriptenv->exec_status; const char *userlog_notice = ""; - sieve_sys_error_func_t error_func = sieve_sys_error; + sieve_sys_error_func_t error_func, user_error_func; int ret; + error_func = user_error_func = sieve_sys_error; + if ( estatus != NULL && estatus->last_storage != NULL ) { enum mail_error mail_error; mail_storage_get_last_error(estatus->last_storage, &mail_error); /* Don't bother administrator too much with benign errors */ - if ( mail_error == MAIL_ERROR_NOSPACE ) + if ( mail_error == MAIL_ERROR_NOSPACE ) { error_func = sieve_sys_info; + user_error_func = sieve_sys_info; + } } if ( script == srctx->user_script && srctx->userlog != NULL ) { userlog_notice = t_strdup_printf (" (user logfile %s should reveal additional details)", srctx->userlog); + user_error_func = sieve_sys_info; } switch ( status ) { case SIEVE_EXEC_FAILURE: - error_func(svinst, + user_error_func(svinst, "execution of script %s failed, but implicit keep was successful%s", sieve_script_location(script), userlog_notice); ret = 1; @@ -494,10 +499,9 @@ struct sieve_error_handler *ehandler = srctx->master_ehandler; bool debug = srctx->mdctx->dest_user->mail_debug; struct sieve_script *last_script = NULL; - bool user_script = FALSE; + bool user_script = FALSE, more = TRUE, compile_error = FALSE; unsigned int i; int ret = 1; - bool more = TRUE; enum sieve_error error; /* Start execution */ @@ -527,8 +531,10 @@ /* Open */ - if ( (sbin=lda_sieve_open(srctx, script, cpflags, &error)) == NULL ) + if ( (sbin=lda_sieve_open(srctx, script, cpflags, &error)) == NULL ) { + compile_error = TRUE; break; + } /* Execute */ @@ -571,6 +577,13 @@ ret = sieve_multiscript_finish(&mscript, ehandler, NULL); + /* Don't log additional messages about compile failure */ + if ( compile_error && ret == SIEVE_EXEC_FAILURE ) { + sieve_sys_info(svinst, + "aborted script execution sequence with successful implicit keep"); + return 1; + } + return lda_sieve_handle_exec_status(srctx, last_script, ret); } From pigeonhole at rename-it.nl Sun Mar 3 19:07:35 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 03 Mar 2013 18:07:35 +0100 Subject: dovecot-2.2-pigeonhole: Merged changes from Pigeonhole v0.3. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/07983d15ad19 changeset: 1724:07983d15ad19 user: Stephan Bosch date: Sun Mar 03 18:07:30 2013 +0100 description: Merged changes from Pigeonhole v0.3. diffstat: src/plugins/lda-sieve/lda-sieve-plugin.c | 25 +++++++++++++++++++------ 1 files changed, 19 insertions(+), 6 deletions(-) diffs (77 lines): diff -r f43c7609497c -r 07983d15ad19 src/plugins/lda-sieve/lda-sieve-plugin.c --- a/src/plugins/lda-sieve/lda-sieve-plugin.c Sun Mar 03 17:35:37 2013 +0100 +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c Sun Mar 03 18:07:30 2013 +0100 @@ -372,27 +372,32 @@ struct sieve_instance *svinst = srctx->svinst; struct sieve_exec_status *estatus = srctx->scriptenv->exec_status; const char *userlog_notice = ""; - sieve_sys_error_func_t error_func = sieve_sys_error; + sieve_sys_error_func_t error_func, user_error_func; int ret; + error_func = user_error_func = sieve_sys_error; + if ( estatus != NULL && estatus->last_storage != NULL ) { enum mail_error mail_error; mail_storage_get_last_error(estatus->last_storage, &mail_error); /* Don't bother administrator too much with benign errors */ - if ( mail_error == MAIL_ERROR_NOSPACE ) + if ( mail_error == MAIL_ERROR_NOSPACE ) { error_func = sieve_sys_info; + user_error_func = sieve_sys_info; + } } if ( script == srctx->user_script && srctx->userlog != NULL ) { userlog_notice = t_strdup_printf (" (user logfile %s should reveal additional details)", srctx->userlog); + user_error_func = sieve_sys_info; } switch ( status ) { case SIEVE_EXEC_FAILURE: - error_func(svinst, + user_error_func(svinst, "execution of script %s failed, but implicit keep was successful%s", sieve_script_location(script), userlog_notice); ret = 1; @@ -496,10 +501,9 @@ struct sieve_error_handler *ehandler = srctx->master_ehandler; bool debug = srctx->mdctx->dest_user->mail_debug; struct sieve_script *last_script = NULL; - bool user_script = FALSE; + bool user_script = FALSE, more = TRUE, compile_error = FALSE; unsigned int i; int ret = 1; - bool more = TRUE; enum sieve_error error; /* Start execution */ @@ -535,8 +539,10 @@ sieve_script_location(script)); } - if ( (sbin=lda_sieve_open(srctx, script, cpflags, &error)) == NULL ) + if ( (sbin=lda_sieve_open(srctx, script, cpflags, &error)) == NULL ) { + compile_error = TRUE; break; + } /* Execute */ @@ -580,6 +586,13 @@ ret = sieve_multiscript_finish(&mscript, ehandler, NULL); + /* Don't log additional messages about compile failure */ + if ( compile_error && ret == SIEVE_EXEC_FAILURE ) { + sieve_sys_info(svinst, + "aborted script execution sequence with successful implicit keep"); + return 1; + } + return lda_sieve_handle_exec_status(srctx, last_script, ret); } From dovecot at dovecot.org Mon Mar 4 14:59:25 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 04 Mar 2013 14:59:25 +0200 Subject: dovecot-2.2: Fixed compiling without zlib. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/65705d9d94f1 changeset: 15990:65705d9d94f1 user: Timo Sirainen date: Mon Mar 04 14:59:13 2013 +0200 description: Fixed compiling without zlib. diffstat: src/doveadm/doveadm-zlib.c | 64 ++++++++++++++++++++++---------------- src/lib-compression/compression.c | 2 + 2 files changed, 39 insertions(+), 27 deletions(-) diffs (101 lines): diff -r 976bf9e69367 -r 65705d9d94f1 src/doveadm/doveadm-zlib.c --- a/src/doveadm/doveadm-zlib.c Wed Feb 27 18:00:29 2013 +0200 +++ b/src/doveadm/doveadm-zlib.c Mon Mar 04 14:59:13 2013 +0200 @@ -14,8 +14,33 @@ #include #include -const char *doveadm_zlib_plugin_version = DOVECOT_ABI_VERSION; +static bool test_dump_imapzlib(const char *path) +{ + const char *p; + char buf[4096]; + int fd, ret; + bool match = FALSE; + p = strrchr(path, '.'); + if (p == NULL || (strcmp(p, ".in") != 0 && strcmp(p, ".out") != 0)) + return FALSE; + + fd = open(path, O_RDONLY); + if (fd == -1) + return FALSE; + + ret = read(fd, buf, sizeof(buf)-1); + if (ret > 0) { + buf[ret] = '\0'; + (void)str_lcase(buf); + match = strstr(buf, " ok begin compression.") != NULL || + strstr(buf, " compress deflate") != NULL; + } + i_close_fd(&fd); + return match; +} + +#ifdef HAVE_ZLIB static void cmd_dump_imapzlib(int argc ATTR_UNUSED, char *argv[]) { struct istream *input, *input2; @@ -52,32 +77,6 @@ fflush(stdout); } -static bool test_dump_imapzlib(const char *path) -{ - const char *p; - char buf[4096]; - int fd, ret; - bool match = FALSE; - - p = strrchr(path, '.'); - if (p == NULL || (strcmp(p, ".in") != 0 && strcmp(p, ".out") != 0)) - return FALSE; - - fd = open(path, O_RDONLY); - if (fd == -1) - return FALSE; - - ret = read(fd, buf, sizeof(buf)-1); - if (ret > 0) { - buf[ret] = '\0'; - (void)str_lcase(buf); - match = strstr(buf, " ok begin compression.") != NULL || - strstr(buf, " compress deflate") != NULL; - } - i_close_fd(&fd); - return match; -} - struct client { int fd; struct io *io_client, *io_server; @@ -176,6 +175,17 @@ if (close(fd) < 0) i_fatal("close() failed: %m"); } +#else +static void cmd_dump_imapzlib(int argc ATTR_UNUSED, char *argv[] ATTR_UNUSED) +{ + i_fatal("Dovecot compiled without zlib support"); +} + +static void cmd_zlibconnect(int argc ATTR_UNUSED, char *argv[] ATTR_UNUSED) +{ + i_fatal("Dovecot compiled without zlib support"); +} +#endif struct doveadm_cmd_dump doveadm_cmd_dump_zlib = { "imapzlib", diff -r 976bf9e69367 -r 65705d9d94f1 src/lib-compression/compression.c --- a/src/lib-compression/compression.c Wed Feb 27 18:00:29 2013 +0200 +++ b/src/lib-compression/compression.c Mon Mar 04 14:59:13 2013 +0200 @@ -9,6 +9,8 @@ #ifndef HAVE_ZLIB # define i_stream_create_gz NULL # define o_stream_create_gz NULL +# define i_stream_create_deflate NULL +# define o_stream_create_deflate NULL #endif #ifndef HAVE_BZLIB # define i_stream_create_bz2 NULL From dovecot at dovecot.org Mon Mar 4 15:12:29 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 04 Mar 2013 15:12:29 +0200 Subject: dovecot-2.2: lib-storage: raw storage allows opening mails with ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cda5cb307619 changeset: 15991:cda5cb307619 user: Timo Sirainen date: Mon Mar 04 15:12:17 2013 +0200 description: lib-storage: raw storage allows opening mails with absolute paths again. Fixed dovecot-lda -p parameter. diffstat: src/lib-storage/index/raw/raw-storage.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diffs (24 lines): diff -r 65705d9d94f1 -r cda5cb307619 src/lib-storage/index/raw/raw-storage.c --- a/src/lib-storage/index/raw/raw-storage.c Mon Mar 04 14:59:13 2013 +0200 +++ b/src/lib-storage/index/raw/raw-storage.c Mon Mar 04 15:12:17 2013 +0200 @@ -19,6 +19,7 @@ struct mail_user *user; struct mail_namespace *ns; struct mail_namespace_settings *ns_set; + struct mail_storage_settings *mail_set; const char *error; user = mail_user_alloc("raw mail user", set_info, set); @@ -38,6 +39,12 @@ ns->flags &= ~NAMESPACE_FLAG_INBOX_USER; ns->flags |= NAMESPACE_FLAG_NOQUOTA | NAMESPACE_FLAG_NOACL; ns->set = ns_set; + /* absolute paths are ok with raw storage */ + mail_set = p_new(user->pool, struct mail_storage_settings, 1); + *mail_set = *ns->mail_set; + mail_set->mail_full_filesystem_access = TRUE; + ns->mail_set = mail_set; + if (mail_storage_create(ns, "raw", 0, &error) < 0) i_fatal("Couldn't create internal raw storage: %s", error); return user; From dovecot at dovecot.org Mon Mar 4 15:18:17 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 04 Mar 2013 15:18:17 +0200 Subject: dovecot-2.1: lib-settings: Improved error messages when config s... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/09fcb43c47a4 changeset: 14930:09fcb43c47a4 user: Timo Sirainen date: Mon Mar 04 15:18:08 2013 +0200 description: lib-settings: Improved error messages when config server disconnects too early. diffstat: src/lib-settings/settings-parser.c | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletions(-) diffs (36 lines): diff -r 311371856dcf -r 09fcb43c47a4 src/lib-settings/settings-parser.c --- a/src/lib-settings/settings-parser.c Wed Feb 27 13:07:35 2013 +0200 +++ b/src/lib-settings/settings-parser.c Mon Mar 04 15:18:08 2013 +0200 @@ -950,8 +950,15 @@ if (input->stream_errno != 0) { ctx->error = p_strdup_printf(ctx->parser_pool, "read() failed: %m"); + } else if (input->v_offset == 0) { + ctx->error = p_strdup_printf(ctx->parser_pool, + "read(%s) disconnected before receiving any data", + i_stream_get_name(input)); } else { - ctx->error = "input is missing end-of-settings line"; + ctx->error = p_strdup_printf(ctx->parser_pool, + "read(%s) disconnected before receiving " + "end-of-settings line", + i_stream_get_name(input)); } break; case -2: @@ -982,6 +989,7 @@ } input = i_stream_create_fd(fd, max_line_length, TRUE); + i_stream_set_name(input, path); ret = settings_parse_stream_read(ctx, input); i_stream_unref(&input); @@ -1071,6 +1079,7 @@ (void)close(fd[1]); input = i_stream_create_fd(fd[0], (size_t)-1, TRUE); + i_stream_set_name(input, bin_path); ret = settings_parse_stream_read(ctx, input); i_stream_destroy(&input); From dovecot at dovecot.org Mon Mar 4 15:53:55 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 04 Mar 2013 15:53:55 +0200 Subject: dovecot-2.1: dbox: Crashfix on some failed save error conditions. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/a7928075f0fd changeset: 14931:a7928075f0fd user: Timo Sirainen date: Mon Mar 04 15:53:42 2013 +0200 description: dbox: Crashfix on some failed save error conditions. diffstat: src/lib-storage/index/dbox-common/dbox-save.c | 12 ++++++++---- 1 files changed, 8 insertions(+), 4 deletions(-) diffs (22 lines): diff -r 09fcb43c47a4 -r a7928075f0fd src/lib-storage/index/dbox-common/dbox-save.c --- a/src/lib-storage/index/dbox-common/dbox-save.c Mon Mar 04 15:18:08 2013 +0200 +++ b/src/lib-storage/index/dbox-common/dbox-save.c Mon Mar 04 15:53:42 2013 +0200 @@ -106,10 +106,14 @@ ctx->failed = TRUE; } if (ctx->ctx.output != dbox_output) { - /* e.g. zlib plugin had changed this */ - o_stream_ref(dbox_output); - o_stream_destroy(&ctx->ctx.output); - ctx->ctx.output = dbox_output; + if (ctx->ctx.output != NULL) { + /* e.g. zlib plugin had changed this */ + o_stream_ref(dbox_output); + o_stream_destroy(&ctx->ctx.output); + ctx->ctx.output = dbox_output; + } else { + i_assert(ctx->failed); + } } index_mail_cache_parse_deinit(ctx->ctx.dest_mail, ctx->ctx.received_date, !ctx->failed); From dovecot at dovecot.org Mon Mar 4 16:27:26 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 04 Mar 2013 16:27:26 +0200 Subject: dovecot-2.2: tcpwrap: Fixed crash at startup. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b5a1a40348b8 changeset: 15992:b5a1a40348b8 user: Timo Sirainen date: Mon Mar 04 16:27:16 2013 +0200 description: tcpwrap: Fixed crash at startup. diffstat: src/util/tcpwrap.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r cda5cb307619 -r b5a1a40348b8 src/util/tcpwrap.c --- a/src/util/tcpwrap.c Mon Mar 04 15:12:17 2013 +0200 +++ b/src/util/tcpwrap.c Mon Mar 04 16:27:16 2013 +0200 @@ -113,7 +113,7 @@ int main(int argc, char *argv[]) { master_service = master_service_init("tcpwrap", 0, - &argc, &argv, NULL); + &argc, &argv, ""); if (master_getopt(master_service) > 0) return FATAL_DEFAULT; From pigeonhole at rename-it.nl Mon Mar 4 23:26:24 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Mon, 04 Mar 2013 22:26:24 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: Fixed segfault bug in reject. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/b75b00760b86 changeset: 1725:b75b00760b86 user: Stephan Bosch date: Mon Mar 04 22:26:15 2013 +0100 description: lib-sieve: Fixed segfault bug in reject. Passed senv->script_context rather than senv itself. Somehow the compiler fails to warn about this. diffstat: src/lib-sieve/sieve-actions.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 07983d15ad19 -r b75b00760b86 src/lib-sieve/sieve-actions.c --- a/src/lib-sieve/sieve-actions.c Sun Mar 03 18:07:30 2013 +0100 +++ b/src/lib-sieve/sieve-actions.c Mon Mar 04 22:26:15 2013 +0100 @@ -863,7 +863,7 @@ T_BEGIN { if ( senv->reject_mail != NULL ) { result = - ( senv->reject_mail(senv->script_context, recipient, reason) >= 0 ); + ( senv->reject_mail(senv, recipient, reason) >= 0 ); } else { result = sieve_action_do_reject_mail(aenv, sender, recipient, reason); } From dovecot at dovecot.org Tue Mar 5 11:24:57 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 05 Mar 2013 11:24:57 +0200 Subject: dovecot-2.2: lib-http: If connection was refused to a host, retr... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a2d59816565d changeset: 15993:a2d59816565d user: Timo Sirainen date: Tue Mar 05 11:24:46 2013 +0200 description: lib-http: If connection was refused to a host, retry again on next request. Instead of never retrying again for the host. diffstat: src/lib-http/http-client-host.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r b5a1a40348b8 -r a2d59816565d src/lib-http/http-client-host.c --- a/src/lib-http/http-client-host.c Mon Mar 04 16:27:16 2013 +0200 +++ b/src/lib-http/http-client-host.c Tue Mar 05 11:24:46 2013 +0200 @@ -142,6 +142,9 @@ } if (peer == NULL) { + /* all IPs failed, but retry all of them again on the + next request. */ + hport->ips_connect_idx = 0; http_client_host_port_error (hport, HTTP_CLIENT_REQUEST_ERROR_CONNECT_FAILED, "Connection failed"); if (host->client->ioloop != NULL) From dovecot at dovecot.org Tue Mar 5 11:45:44 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 05 Mar 2013 11:45:44 +0200 Subject: dovecot-2.2: Added io_loop_have_immediate_timeouts() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6daf58f568a0 changeset: 15994:6daf58f568a0 user: Timo Sirainen date: Tue Mar 05 11:45:10 2013 +0200 description: Added io_loop_have_immediate_timeouts() diffstat: src/lib/ioloop.c | 7 +++++++ src/lib/ioloop.h | 3 +++ 2 files changed, 10 insertions(+), 0 deletions(-) diffs (26 lines): diff -r a2d59816565d -r 6daf58f568a0 src/lib/ioloop.c --- a/src/lib/ioloop.c Tue Mar 05 11:24:46 2013 +0200 +++ b/src/lib/ioloop.c Tue Mar 05 11:45:10 2013 +0200 @@ -665,3 +665,10 @@ { return ioloop->io_files; } + +bool io_loop_have_immediate_timeouts(struct ioloop *ioloop) +{ + struct timeval tv; + + return io_loop_get_wait_time(ioloop, &tv) == 0; +} diff -r a2d59816565d -r 6daf58f568a0 src/lib/ioloop.h --- a/src/lib/ioloop.h Tue Mar 05 11:24:46 2013 +0200 +++ b/src/lib/ioloop.h Tue Mar 05 11:45:10 2013 +0200 @@ -139,5 +139,8 @@ struct timeout *io_loop_move_timeout(struct timeout **timeout); /* Returns TRUE if any IOs have been added to the ioloop. */ bool io_loop_have_ios(struct ioloop *ioloop); +/* Returns TRUE if there is a pending timeout that is going to be run + immediately. */ +bool io_loop_have_immediate_timeouts(struct ioloop *ioloop); #endif From dovecot at dovecot.org Tue Mar 5 11:45:44 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 05 Mar 2013 11:45:44 +0200 Subject: dovecot-2.2: lib-http: Fixed http_client_wait() assert. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/bdca6ecb5bb4 changeset: 15995:bdca6ecb5bb4 user: Timo Sirainen date: Tue Mar 05 11:45:26 2013 +0200 description: lib-http: Fixed http_client_wait() assert. diffstat: src/lib-http/http-client.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (15 lines): diff -r 6daf58f568a0 -r bdca6ecb5bb4 src/lib-http/http-client.c --- a/src/lib-http/http-client.c Tue Mar 05 11:45:10 2013 +0200 +++ b/src/lib-http/http-client.c Tue Mar 05 11:45:26 2013 +0200 @@ -160,7 +160,10 @@ client->ioloop = io_loop_create(); http_client_switch_ioloop(client); - i_assert(io_loop_have_ios(client->ioloop)); + /* either we're waiting for network I/O or we're getting out of a + callback using timeout_add_short(0) */ + i_assert(io_loop_have_ios(client->ioloop) || + io_loop_have_immediate_timeouts(client->ioloop)); do { http_client_debug(client, From dovecot at dovecot.org Tue Mar 5 12:20:52 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 05 Mar 2013 12:20:52 +0200 Subject: dovecot-2.2: lib-fs: istream-metawrap supports now seeking befor... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3dcdbab51347 changeset: 15996:3dcdbab51347 user: Timo Sirainen date: Tue Mar 05 12:20:41 2013 +0200 description: lib-fs: istream-metawrap supports now seeking before reading the metadata. diffstat: src/lib-fs/istream-metawrap.c | 20 ++++++++++++++------ 1 files changed, 14 insertions(+), 6 deletions(-) diffs (44 lines): diff -r bdca6ecb5bb4 -r 3dcdbab51347 src/lib-fs/istream-metawrap.c --- a/src/lib-fs/istream-metawrap.c Tue Mar 05 11:45:26 2013 +0200 +++ b/src/lib-fs/istream-metawrap.c Tue Mar 05 12:20:41 2013 +0200 @@ -9,7 +9,7 @@ metawrap_callback_t *callback; void *context; - uoff_t start_offset; + uoff_t start_offset, pending_seek; bool in_metadata; }; @@ -57,6 +57,10 @@ /* this stream is kind of silently skipping over the metadata */ stream->abs_start_offset += mstream->start_offset; mstream->in_metadata = FALSE; + if (mstream->pending_seek != 0) { + i_stream_seek(&stream->istream, mstream->pending_seek); + return i_stream_read(&stream->istream); + } } /* after metadata header it's all just passthrough */ return i_stream_read_copy_from_parent(&stream->istream); @@ -68,11 +72,15 @@ { struct metawrap_istream *mstream = (struct metawrap_istream *)stream; - /* support seeking only after reading the metadata */ - i_assert(!mstream->in_metadata || - (mstream->start_offset == 0 && v_offset == 0)); - - stream->istream.v_offset = v_offset; + if (!mstream->in_metadata) { + /* already read through metadata. we can skip directly. */ + stream->istream.v_offset = v_offset; + mstream->pending_seek = 0; + } else { + /* we need to read through the metadata first */ + mstream->pending_seek = v_offset; + stream->istream.v_offset = 0; + } stream->skip = stream->pos = 0; } From dovecot at dovecot.org Tue Mar 5 14:32:14 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 05 Mar 2013 14:32:14 +0200 Subject: dovecot-2.2: connection_list_deinit(): Set disconnect_reason cor... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/310c5ce38ef3 changeset: 15997:310c5ce38ef3 user: Timo Sirainen date: Tue Mar 05 14:31:29 2013 +0200 description: connection_list_deinit(): Set disconnect_reason correctly to CONNECTION_DISCONNECT_DEINIT diffstat: src/lib/connection.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 3dcdbab51347 -r 310c5ce38ef3 src/lib/connection.c --- a/src/lib/connection.c Tue Mar 05 12:20:41 2013 +0200 +++ b/src/lib/connection.c Tue Mar 05 14:31:29 2013 +0200 @@ -354,6 +354,7 @@ while (list->connections != NULL) { conn = list->connections; + conn->disconnect_reason = CONNECTION_DISCONNECT_DEINIT; list->v.destroy(conn); i_assert(conn != list->connections); } From dovecot at dovecot.org Tue Mar 5 14:32:14 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 05 Mar 2013 14:32:14 +0200 Subject: dovecot-2.2: connection: Give input/output streams a name. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/194ec0e10f3a changeset: 15998:194ec0e10f3a user: Timo Sirainen date: Tue Mar 05 14:31:43 2013 +0200 description: connection: Give input/output streams a name. diffstat: src/lib/connection.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (17 lines): diff -r 310c5ce38ef3 -r 194ec0e10f3a src/lib/connection.c --- a/src/lib/connection.c Tue Mar 05 14:31:29 2013 +0200 +++ b/src/lib/connection.c Tue Mar 05 14:31:43 2013 +0200 @@ -116,11 +116,13 @@ if (set->input_max_size != 0) { conn->input = i_stream_create_fd(conn->fd_in, set->input_max_size, FALSE); + i_stream_set_name(conn->input, conn->name); } if (set->output_max_size != 0) { conn->output = o_stream_create_fd(conn->fd_out, set->output_max_size, FALSE); o_stream_set_no_error_handling(conn->output, TRUE); + o_stream_set_name(conn->output, conn->name); } conn->io = io_add(conn->fd_in, IO_READ, *conn->list->v.input, conn); if (set->input_idle_timeout_secs != 0) { From dovecot at dovecot.org Tue Mar 5 14:32:14 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 05 Mar 2013 14:32:14 +0200 Subject: dovecot-2.2: lib-http: If we get disconnected, say exactly what ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f89ebdc1625d changeset: 15999:f89ebdc1625d user: Timo Sirainen date: Tue Mar 05 14:32:03 2013 +0200 description: lib-http: If we get disconnected, say exactly what the error was. diffstat: src/lib-http/http-client-connection.c | 41 +++++++++++++++++++++------------- src/lib-http/http-client-private.h | 6 +++- src/lib-http/http-client-request.c | 33 +++++++++++++++++++++------ 3 files changed, 54 insertions(+), 26 deletions(-) diffs (220 lines): diff -r 194ec0e10f3a -r f89ebdc1625d src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Tue Mar 05 14:31:43 2013 +0200 +++ b/src/lib-http/http-client-connection.c Tue Mar 05 14:32:03 2013 +0200 @@ -200,6 +200,7 @@ { struct http_client_request *const *req_idx; struct http_client_request *req; + const char *error; if (conn->to_response != NULL) timeout_remove(&conn->to_response); @@ -212,18 +213,19 @@ req = req_idx[0]; conn->payload_continue = TRUE; - if (http_client_request_send_more(req) < 0) { + if (http_client_request_send_more(req, &error) < 0) { http_client_connection_abort_temp_error(&conn, - HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, "Failed to send request"); + HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, + t_strdup_printf("Failed to send request: %s", error)); } } bool http_client_connection_next_request(struct http_client_connection *conn) { struct http_client_request *req = NULL; + const char *error; if (!http_client_connection_is_ready(conn)) { - http_client_connection_debug(conn, "Not ready for next request"); return FALSE; } @@ -250,10 +252,10 @@ http_client_connection_debug(conn, "Claimed request %s", http_client_request_label(req)); - if (http_client_request_send(req) < 0) { + if (http_client_request_send(req, &error) < 0) { http_client_connection_abort_temp_error(&conn, HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, - "Failed to send request"); + t_strdup_printf("Failed to send request: %s", error)); return FALSE; } @@ -292,8 +294,10 @@ break; case CONNECTION_DISCONNECT_CONN_CLOSED: /* retry pending requests if possible */ + errno = _conn->input->stream_errno; http_client_connection_retry_requests(conn, - HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, "Connection lost"); + HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, + t_strdup_printf("Connection lost: %m")); default: break; } @@ -459,10 +463,10 @@ conn->payload_continue = TRUE; http_client_connection_debug(conn, "Got expected 100-continue response"); - if (http_client_request_send_more(req) < 0) { + if (http_client_request_send_more(req, &error) < 0) { http_client_connection_abort_temp_error(&conn, HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, - "Failed to send request"); + t_strdup_printf("Failed to send request: %s", error)); } return; } else if (response->status / 100 == 1) { @@ -523,13 +527,14 @@ } if (ret <= 0 && - (conn->conn.input->eof || conn->conn.input->stream_errno != 0)) { + (conn->conn.input->eof || conn->conn.input->stream_errno != 0)) { int stream_errno = conn->conn.input->stream_errno; - http_client_connection_debug(conn, - "Lost connection to server (error=%s)", - stream_errno != 0 ? strerror(stream_errno) : "EOF"); http_client_connection_abort_temp_error(&conn, - HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, "Connection lost"); + 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 ? + strerror(stream_errno) : "EOF")); return; } @@ -550,12 +555,15 @@ { struct http_client_request *const *req_idx, *req; struct ostream *output = conn->conn.output; + const char *error; int ret; if ((ret = o_stream_flush(output)) <= 0) { if (ret < 0) { http_client_connection_abort_temp_error(&conn, - HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, "Connection lost"); + HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, + t_strdup_printf("Connection lost: write(%s) failed: %m", + o_stream_get_name(output))); } return ret; } @@ -565,9 +573,10 @@ req = req_idx[0]; if (!req->payload_sync || conn->payload_continue) { - if (http_client_request_send_more(req) < 0) { + if (http_client_request_send_more(req, &error) < 0) { http_client_connection_abort_temp_error(&conn, - HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, "Connection lost"); + HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, + t_strdup_printf("Connection lost: %s", error)); return -1; } if (!conn->output_locked) { diff -r 194ec0e10f3a -r f89ebdc1625d src/lib-http/http-client-private.h --- a/src/lib-http/http-client-private.h Tue Mar 05 14:31:43 2013 +0200 +++ b/src/lib-http/http-client-private.h Tue Mar 05 14:32:03 2013 +0200 @@ -200,8 +200,10 @@ void http_client_request_ref(struct http_client_request *req); void http_client_request_unref(struct http_client_request **_req); -int http_client_request_send(struct http_client_request *req); -int http_client_request_send_more(struct http_client_request *req); +int http_client_request_send(struct http_client_request *req, + const char **error_r); +int http_client_request_send_more(struct http_client_request *req, + const char **error_r); void http_client_request_callback(struct http_client_request *req, struct http_response *response); void http_client_request_resubmit(struct http_client_request *req); diff -r 194ec0e10f3a -r f89ebdc1625d src/lib-http/http-client-request.c --- a/src/lib-http/http-client-request.c Tue Mar 05 14:31:43 2013 +0200 +++ b/src/lib-http/http-client-request.c Tue Mar 05 14:32:03 2013 +0200 @@ -215,6 +215,7 @@ http_client_request_finish_payload_out(req); } else { req->payload_input = i_stream_create_from_data(data, size); + i_stream_set_name(req->payload_input, ""); } req->payload_size = 0; req->payload_chunked = TRUE; @@ -275,20 +276,32 @@ return http_client_request_continue_payload(_req, NULL, 0); } -int http_client_request_send_more(struct http_client_request *req) +int http_client_request_send_more(struct http_client_request *req, + const char **error_r) { struct http_client_connection *conn = req->conn; struct ostream *output = req->payload_output; - int ret = 0; + off_t ret; i_assert(req->payload_input != NULL); /* chunked ostream needs to write to the parent stream's buffer */ o_stream_set_max_buffer_size(output, IO_BLOCK_SIZE); - if (o_stream_send_istream(output, req->payload_input) < 0) - ret = -1; + ret = o_stream_send_istream(output, req->payload_input); o_stream_set_max_buffer_size(output, (size_t)-1); + if (req->payload_input->stream_errno != 0) { + errno = req->payload_input->stream_errno; + *error_r = t_strdup_printf("read(%s) failed: %m", + i_stream_get_name(req->payload_input)); + } else if (output->stream_errno != 0) { + errno = output->stream_errno; + *error_r = t_strdup_printf("write(%s) failed: %m", + o_stream_get_name(output)); + } else { + i_assert(ret >= 0); + } + if (!i_stream_have_bytes_left(req->payload_input)) { if (!req->payload_chunked && req->payload_input->v_offset - req->payload_offset != req->payload_size) { @@ -309,10 +322,11 @@ o_stream_set_flush_pending(output, TRUE); http_client_request_debug(req, "Partially sent payload"); } - return ret; + return ret < 0 ? -1 : 0; } -int http_client_request_send(struct http_client_request *req) +int http_client_request_send(struct http_client_request *req, + const char **error_r) { struct http_client_connection *conn = req->conn; struct ostream *output = conn->conn.output; @@ -356,14 +370,17 @@ req->state = HTTP_REQUEST_STATE_PAYLOAD_OUT; o_stream_cork(output); - if (o_stream_sendv(output, iov, N_ELEMENTS(iov)) < 0) + if (o_stream_sendv(output, iov, N_ELEMENTS(iov)) < 0) { + *error_r = t_strdup_printf("write(%s) failed: %m", + o_stream_get_name(output)); ret = -1; + } 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) < 0) + if (http_client_request_send_more(req, error_r) < 0) ret = -1; } else { http_client_request_debug(req, "Waiting for 100-continue"); From dovecot at dovecot.org Tue Mar 5 16:32:17 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 05 Mar 2013 16:32:17 +0200 Subject: dovecot-2.2: lib-http: Fixed crash caused by previous change. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/00ee7a8306c7 changeset: 16000:00ee7a8306c7 user: Timo Sirainen date: Tue Mar 05 16:32:12 2013 +0200 description: lib-http: Fixed crash caused by previous change. diffstat: src/lib-http/http-client-connection.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-) diffs (26 lines): diff -r f89ebdc1625d -r 00ee7a8306c7 src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Tue Mar 05 14:32:03 2013 +0200 +++ b/src/lib-http/http-client-connection.c Tue Mar 05 16:32:12 2013 +0200 @@ -284,6 +284,7 @@ { struct http_client_connection *conn = (struct http_client_connection *)_conn; + const char *error; conn->closing = TRUE; conn->connected = FALSE; @@ -294,10 +295,11 @@ break; case CONNECTION_DISCONNECT_CONN_CLOSED: /* retry pending requests if possible */ - errno = _conn->input->stream_errno; + error = _conn->input == NULL ? "Connection lost" : + t_strdup_printf("Connection lost: %s", + strerror(_conn->input->stream_errno)); http_client_connection_retry_requests(conn, - HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, - t_strdup_printf("Connection lost: %m")); + HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, error); default: break; } From dovecot at dovecot.org Tue Mar 5 21:44:22 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 05 Mar 2013 21:44:22 +0200 Subject: dovecot-2.2: lib-http: Avoid hanging on urgent requests. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/52e5d4186006 changeset: 16001:52e5d4186006 user: Timo Sirainen date: Tue Mar 05 21:44:07 2013 +0200 description: lib-http: Avoid hanging on urgent requests. Patch by Timo & Stephan. There are still some problems though, all urgent requests don't seem to get a new connection. diffstat: src/lib-http/http-client-connection.c | 1 + src/lib-http/http-client-host.c | 60 +++++++++++----------- src/lib-http/http-client-peer.c | 90 +++++++++++++++++++--------------- src/lib-http/http-client-private.h | 7 +- 4 files changed, 82 insertions(+), 76 deletions(-) diffs (truncated from 352 to 300 lines): diff -r 00ee7a8306c7 -r 52e5d4186006 src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Tue Mar 05 16:32:12 2013 +0200 +++ b/src/lib-http/http-client-connection.c Tue Mar 05 21:44:07 2013 +0200 @@ -787,6 +787,7 @@ http_client_connection_debug(conn, "Connection destroy"); + conn->closing = TRUE; conn->connected = FALSE; #ifdef HTTP_BUILD_SSL diff -r 00ee7a8306c7 -r 52e5d4186006 src/lib-http/http-client-host.c --- a/src/lib-http/http-client-host.c Tue Mar 05 16:32:12 2013 +0200 +++ b/src/lib-http/http-client-host.c Tue Mar 05 21:44:07 2013 +0200 @@ -68,7 +68,6 @@ hport->ssl = ssl; hport->ips_connect_idx = 0; i_array_init(&hport->request_queue, 16); - i_array_init(&hport->urgent_request_queue, 4); } return hport; @@ -83,11 +82,7 @@ array_foreach_modifiable(&hport->request_queue, req) { http_client_request_error(*req, status, error); } - array_foreach_modifiable(&hport->urgent_request_queue, req) { - http_client_request_error(*req, status, error); - } array_clear(&hport->request_queue); - array_clear(&hport->urgent_request_queue); } static void http_client_host_port_deinit(struct http_client_host_port *hport) @@ -95,7 +90,6 @@ http_client_host_port_error (hport, HTTP_CLIENT_REQUEST_ERROR_ABORTED, "Aborted"); array_free(&hport->request_queue); - array_free(&hport->urgent_request_queue); } static void @@ -103,14 +97,12 @@ struct http_client_request *req) { struct http_client_request **req_idx; - ARRAY_TYPE(http_client_request) *queue = - (req->urgent ? &hport->urgent_request_queue : &hport->request_queue); unsigned int idx; - array_foreach_modifiable(queue, req_idx) { + array_foreach_modifiable(&hport->request_queue, req_idx) { if (*req_idx == req) { - idx = array_foreach_idx(queue, req_idx); - array_delete(queue, idx, 1); + idx = array_foreach_idx(&hport->request_queue, req_idx); + array_delete(&hport->request_queue, idx, 1); break; } } @@ -297,7 +289,7 @@ /* add request to host (grouped by tcp port) */ hport = http_client_host_port_init(host, req->port, req->ssl); if (req->urgent) - array_append(&hport->urgent_request_queue, &req, 1); + array_insert(&hport->request_queue, 0, &req, 1); else array_append(&hport->request_queue, &req, 1); @@ -316,23 +308,26 @@ const struct http_client_peer_addr *addr, bool no_urgent) { struct http_client_host_port *hport; - struct http_client_request *const *req_idx; + struct http_client_request *const *requests; struct http_client_request *req; + unsigned int i, count; hport = http_client_host_port_find(host, addr->port, addr->ssl); if (hport == NULL) return NULL; - if (!no_urgent && array_count(&hport->urgent_request_queue) > 0) { - req_idx = array_idx(&hport->urgent_request_queue, 0); - req = *req_idx; - array_delete(&hport->urgent_request_queue, 0, 1); - } else if (array_count(&hport->request_queue) > 0) { - req_idx = array_idx(&hport->request_queue, 0); - req = *req_idx; - array_delete(&hport->request_queue, 0, 1); - } else { + + requests = array_get(&hport->request_queue, &count); + if (count == 0) return NULL; + i = 0; + if (requests[0]->urgent && no_urgent) { + for (; requests[i]->urgent; i++) { + if (i == count) + return NULL; + } } + req = requests[i]; + array_delete(&hport->request_queue, i, 1); http_client_host_debug(host, "Connection to peer %s:%u claimed request %s %s", @@ -342,18 +337,23 @@ return req; } -bool http_client_host_have_requests(struct http_client_host *host, - const struct http_client_peer_addr *addr, bool urgent) +unsigned int http_client_host_requests_pending(struct http_client_host *host, + const struct http_client_peer_addr *addr, unsigned int *num_urgent_r) { struct http_client_host_port *hport; + struct http_client_request *const *requests; + unsigned int count, i; + + *num_urgent_r = 0; hport = http_client_host_port_find(host, addr->port, addr->ssl); if (hport == NULL) - return FALSE; - - if (urgent) - return (array_count(&hport->urgent_request_queue) > 0); - return (array_count(&hport->request_queue) > 0); + return 0; + + requests = array_get(&hport->request_queue, &count); + for (i = 0; i < count && requests[i]->urgent; i++) + (*num_urgent_r)++; + return count; } void http_client_host_drop_request(struct http_client_host *host, @@ -364,7 +364,7 @@ hport = http_client_host_port_find(host, req->port, req->ssl); if (hport == NULL) return; - + http_client_host_port_drop_request(hport, req); } diff -r 00ee7a8306c7 -r 52e5d4186006 src/lib-http/http-client-peer.c --- a/src/lib-http/http-client-peer.c Tue Mar 05 16:32:12 2013 +0200 +++ b/src/lib-http/http-client-peer.c Tue Mar 05 21:44:07 2013 +0200 @@ -91,42 +91,51 @@ } static int -http_client_peer_connect(struct http_client_peer *peer) +http_client_peer_connect(struct http_client_peer *peer, unsigned int count) { struct http_client_connection *conn; + unsigned int i; - conn = http_client_connection_create(peer); - if (conn == NULL) { - http_client_peer_debug(peer, "Failed to make new connection"); - return -1; + for (i = 0; i < count; i++) { + http_client_peer_debug(peer, "Making new connection %u of %u", i+1, count); + + conn = http_client_connection_create(peer); + if (conn == NULL) { + http_client_peer_debug(peer, "Failed to make new connection"); + return -1; + } } return 0; } -static bool -http_client_peer_requests_pending(struct http_client_peer *peer, bool urgent) +static unsigned int +http_client_peer_requests_pending(struct http_client_peer *peer, unsigned int *num_urgent_r) { struct http_client_host *const *host; + unsigned int num_requests = 0, num_urgent = 0, requests, urgent; array_foreach(&peer->hosts, host) { - if (http_client_host_have_requests(*host, &peer->addr, urgent)) - return TRUE; + requests = http_client_host_requests_pending(*host, &peer->addr, &urgent); + + num_requests += requests; + num_urgent += urgent; } - - return FALSE; + *num_urgent_r = num_urgent; + return num_requests; } static bool -http_client_peer_next_request(struct http_client_peer *peer, - bool urgent) +http_client_peer_next_request(struct http_client_peer *peer) { struct http_client_connection *const *conn_idx; struct http_client_connection *conn = NULL; - unsigned int closing = 0, min_waiting = UINT_MAX; - + unsigned int connecting = 0, closing = 0, min_waiting = UINT_MAX; + unsigned int num_urgent, new_connections; + /* at this point we already know that a request for this peer is pending */ + (void)http_client_peer_requests_pending(peer, &num_urgent); /* find the least busy connection */ array_foreach(&peer->conns, conn_idx) { @@ -135,23 +144,27 @@ if (waiting < min_waiting) { min_waiting = waiting; conn = *conn_idx; - if (min_waiting == 0) + if (min_waiting == 0) { + /* found idle connection, use it now */ break; + } } } - /* count the number of closing connections */ + /* count the number of connecting and closing connections */ if ((*conn_idx)->closing) closing++; + else if (!(*conn_idx)->connected) + connecting++; } - /* do we have an idle connection? */ + /* did we find an idle connection? */ if (conn != NULL && min_waiting == 0) { - /* yes */ + /* yes, use it */ return http_client_connection_next_request(conn); } /* no, but can we create a new connection? */ - if (!urgent && (array_count(&peer->conns) - closing) >= + if (num_urgent == 0 && (array_count(&peer->conns) - closing) >= peer->client->set.max_parallel_connections) { /* no */ if (conn == NULL) @@ -160,8 +173,13 @@ return http_client_connection_next_request(conn); } - /* yes */ - if (http_client_peer_connect(peer) < 0) { + /* yes, determine how many connections to set up */ + if (num_urgent == 0) { + new_connections = 1; + } else { + new_connections = (num_urgent > connecting ? num_urgent - connecting : 0); + } + if (http_client_peer_connect(peer, new_connections) < 0) { /* connection failed */ if (conn == NULL) return FALSE; @@ -175,17 +193,7 @@ void http_client_peer_handle_requests(struct http_client_peer *peer) { - /* check urgent requests first */ - while (http_client_peer_requests_pending(peer, TRUE)) { - if (!http_client_peer_next_request(peer, TRUE)) - break; - } - - /* check normal requests once we're done */ - while (http_client_peer_requests_pending(peer, FALSE)) { - if (!http_client_peer_next_request(peer, FALSE)) - break; - } + while (http_client_peer_next_request(peer)) ; } static struct http_client_peer * @@ -234,7 +242,7 @@ } #endif - if (http_client_peer_connect(peer) < 0) { + if (http_client_peer_connect(peer, 1) < 0) { http_client_peer_free(&peer); return NULL; } @@ -308,7 +316,7 @@ if (!exists) array_append(&peer->hosts, &host, 1); if (exists || array_count(&peer->hosts) > 1) - (void)http_client_peer_next_request(peer, FALSE); + (void)http_client_peer_next_request(peer); } From dovecot at dovecot.org Wed Mar 6 11:40:11 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 06 Mar 2013 11:40:11 +0200 Subject: dovecot-2.2: Added ostream-hash for calculating a hash from data... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7a08461c5559 changeset: 16002:7a08461c5559 user: Timo Sirainen date: Wed Mar 06 11:39:43 2013 +0200 description: Added ostream-hash for calculating a hash from data going through ostream. diffstat: src/lib/Makefile.am | 4 ++- src/lib/ostream-hash.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/ostream-hash.h | 10 +++++++++ 3 files changed, 68 insertions(+), 1 deletions(-) diffs (95 lines): diff -r 52e5d4186006 -r 7a08461c5559 src/lib/Makefile.am --- a/src/lib/Makefile.am Tue Mar 05 21:44:07 2013 +0200 +++ b/src/lib/Makefile.am Wed Mar 06 11:39:43 2013 +0200 @@ -99,8 +99,9 @@ nfs-workarounds.c \ numpack.c \ ostream.c \ + ostream-buffer.c \ ostream-file.c \ - ostream-buffer.c \ + ostream-hash.c \ ostream-rawlog.c \ primes.c \ printf-format-fix.c \ @@ -215,6 +216,7 @@ nfs-workarounds.h \ numpack.h \ ostream.h \ + ostream-hash.h \ ostream-private.h \ ostream-rawlog.h \ primes.h \ diff -r 52e5d4186006 -r 7a08461c5559 src/lib/ostream-hash.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/ostream-hash.c Wed Mar 06 11:39:43 2013 +0200 @@ -0,0 +1,55 @@ +/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "hash-method.h" +#include "ostream-private.h" +#include "ostream-hash.h" + +struct hash_ostream { + struct ostream_private ostream; + const struct hash_method *method; + void *hash_context; +}; + +static ssize_t +o_stream_hash_sendv(struct ostream_private *stream, + const struct const_iovec *iov, unsigned int iov_count) +{ + struct hash_ostream *hstream = (struct hash_ostream *)stream; + unsigned int i; + size_t bytes_left, block_len; + ssize_t ret; + + if ((ret = o_stream_sendv(stream->parent, iov, iov_count)) < 0) { + o_stream_copy_error_from_parent(stream); + return -1; + } + if (ret > 0) { + bytes_left = ret; + for (i = 0; i < iov_count && bytes_left > 0; i++) { + block_len = iov[i].iov_len <= bytes_left ? + iov[i].iov_len : bytes_left; + hstream->method->loop(hstream->hash_context, + iov[i].iov_base, block_len); + bytes_left -= block_len; + } + } + + stream->ostream.offset += ret; + return ret; +} + +struct ostream * +o_stream_create_hash(struct ostream *output, const struct hash_method *method, + void *hash_context) +{ + struct hash_ostream *hstream; + + hstream = i_new(struct hash_ostream, 1); + hstream->ostream.sendv = o_stream_hash_sendv; + hstream->method = method; + hstream->hash_context = hash_context; + + return o_stream_create(&hstream->ostream, output, + o_stream_get_fd(output)); +} diff -r 52e5d4186006 -r 7a08461c5559 src/lib/ostream-hash.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/ostream-hash.h Wed Mar 06 11:39:43 2013 +0200 @@ -0,0 +1,10 @@ +#ifndef OSTREAM_HASH_H +#define OSTREAM_HASH_H + +/* hash_context must be allocated and initialized by caller. This ostream will + simply call method->loop() for all the data going through the ostream. */ +struct ostream * +o_stream_create_hash(struct ostream *output, const struct hash_method *method, + void *hash_context); + +#endif From dovecot at dovecot.org Fri Mar 8 20:25:32 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 08 Mar 2013 20:25:32 +0200 Subject: dovecot-2.2: lib-http: Send Content-Length whenever payload is s... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0aea43f87c0b changeset: 16003:0aea43f87c0b user: Timo Sirainen date: Fri Mar 08 20:25:12 2013 +0200 description: lib-http: Send Content-Length whenever payload is specified, even if its size is 0. diffstat: src/lib-http/http-client-request.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (14 lines): diff -r 7a08461c5559 -r 0aea43f87c0b src/lib-http/http-client-request.c --- a/src/lib-http/http-client-request.c Wed Mar 06 11:39:43 2013 +0200 +++ b/src/lib-http/http-client-request.c Fri Mar 08 20:25:12 2013 +0200 @@ -354,7 +354,9 @@ str_append(rtext, "Transfer-Encoding: chunked\r\n"); req->payload_output = http_transfer_chunked_ostream_create(output); - } else if (req->payload_size != 0) { + } else if (req->payload_input != NULL) { + /* send Content-Length if we have specified a payload, + even if it's 0 bytes. */ str_printfa(rtext, "Content-Length: %"PRIuUOFF_T"\r\n", req->payload_size); req->payload_output = output; From dovecot at dovecot.org Sun Mar 10 17:19:29 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 10 Mar 2013 17:19:29 +0200 Subject: dovecot-2.2: lib-http: Allow caller to find out what state a req... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5e63f628e3ca changeset: 16004:5e63f628e3ca user: Timo Sirainen date: Sun Mar 10 17:17:47 2013 +0200 description: lib-http: Allow caller to find out what state a request is in. diffstat: src/lib-http/http-client-private.h | 11 ----------- src/lib-http/http-client-request.c | 17 +++++++++++++++++ src/lib-http/http-client.h | 14 ++++++++++++++ 3 files changed, 31 insertions(+), 11 deletions(-) diffs (86 lines): diff -r 0aea43f87c0b -r 5e63f628e3ca src/lib-http/http-client-private.h --- a/src/lib-http/http-client-private.h Fri Mar 08 20:25:12 2013 +0200 +++ b/src/lib-http/http-client-private.h Sun Mar 10 17:17:47 2013 +0200 @@ -30,17 +30,6 @@ HASH_TABLE_DEFINE_TYPE(http_client_peer, const struct http_client_peer_addr *, struct http_client_peer *); -enum http_request_state { - HTTP_REQUEST_STATE_NEW = 0, - HTTP_REQUEST_STATE_QUEUED, - HTTP_REQUEST_STATE_PAYLOAD_OUT, - HTTP_REQUEST_STATE_WAITING, - HTTP_REQUEST_STATE_GOT_RESPONSE, - HTTP_REQUEST_STATE_PAYLOAD_IN, - HTTP_REQUEST_STATE_FINISHED, - HTTP_REQUEST_STATE_ABORTED -}; - struct http_client_request { pool_t pool; unsigned int refcount; diff -r 0aea43f87c0b -r 5e63f628e3ca src/lib-http/http-client-request.c --- a/src/lib-http/http-client-request.c Fri Mar 08 20:25:12 2013 +0200 +++ b/src/lib-http/http-client-request.c Sun Mar 10 17:17:47 2013 +0200 @@ -13,6 +13,17 @@ #include "http-client-private.h" +const char *http_request_state_names[] = { + "new", + "queued", + "payload_out", + "waiting", + "got_response", + "payload_in", + "finished", + "aborted" +}; + /* * Logging */ @@ -158,6 +169,12 @@ req->payload_sync = TRUE; } +enum http_request_state +http_client_request_get_state(struct http_client_request *req) +{ + return req->state; +} + static void http_client_request_do_submit(struct http_client_request *req) { struct http_client_host *host; diff -r 0aea43f87c0b -r 5e63f628e3ca src/lib-http/http-client.h --- a/src/lib-http/http-client.h Fri Mar 08 20:25:12 2013 +0200 +++ b/src/lib-http/http-client.h Sun Mar 10 17:17:47 2013 +0200 @@ -18,6 +18,18 @@ HTTP_CLIENT_REQUEST_ERROR_TIMED_OUT, }; +enum http_request_state { + HTTP_REQUEST_STATE_NEW = 0, + HTTP_REQUEST_STATE_QUEUED, + HTTP_REQUEST_STATE_PAYLOAD_OUT, + HTTP_REQUEST_STATE_WAITING, + HTTP_REQUEST_STATE_GOT_RESPONSE, + HTTP_REQUEST_STATE_PAYLOAD_IN, + HTTP_REQUEST_STATE_FINISHED, + HTTP_REQUEST_STATE_ABORTED +}; +extern const char *http_request_state_names[]; + struct http_client_settings { const char *dns_client_socket_path; @@ -75,6 +87,8 @@ void http_client_request_set_payload(struct http_client_request *req, struct istream *input, bool sync); +enum http_request_state +http_client_request_get_state(struct http_client_request *req); void http_client_request_submit(struct http_client_request *req); void http_client_request_abort(struct http_client_request **req); From dovecot at dovecot.org Sun Mar 10 17:19:29 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 10 Mar 2013 17:19:29 +0200 Subject: dovecot-2.2: lib-http: Fixed hangs with urgent requests. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d3e3edf8f7eb changeset: 16005:d3e3edf8f7eb user: Timo Sirainen date: Sun Mar 10 17:19:14 2013 +0200 description: lib-http: Fixed hangs with urgent requests. diffstat: src/lib-http/http-client-connection.c | 24 ++++++++++++++++-------- src/lib-http/http-client-peer.c | 26 +++++++++++++++----------- 2 files changed, 31 insertions(+), 19 deletions(-) diffs (137 lines): diff -r 5e63f628e3ca -r d3e3edf8f7eb src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Sun Mar 10 17:17:47 2013 +0200 +++ b/src/lib-http/http-client-connection.c Sun Mar 10 17:19:14 2013 +0200 @@ -61,9 +61,13 @@ bool http_client_connection_is_ready(struct http_client_connection *conn) { + unsigned int pending_count = array_count(&conn->request_wait_list); + + if (conn->pending_request != NULL) + pending_count++; return (conn->connected && !conn->output_locked && - !conn->close_indicated && array_count(&conn->request_wait_list) < - conn->client->set.max_pipelined_requests); + !conn->close_indicated && + pending_count < conn->client->set.max_pipelined_requests); } bool http_client_connection_is_idle(struct http_client_connection *conn) @@ -224,6 +228,7 @@ { struct http_client_request *req = NULL; const char *error; + bool have_pending_requests; if (!http_client_connection_is_ready(conn)) { http_client_connection_debug(conn, "Not ready for next request"); @@ -231,8 +236,9 @@ } /* claim request, but no urgent request can be second in line */ - req = http_client_peer_claim_request(conn->peer, - array_count(&conn->request_wait_list) > 0); + have_pending_requests = array_count(&conn->request_wait_list) > 0 || + conn->pending_request != NULL; + req = http_client_peer_claim_request(conn->peer, have_pending_requests); if (req == NULL) { http_client_connection_check_idle(conn); return FALSE; @@ -324,10 +330,12 @@ http_client_connection_input(&conn->conn); } -static void http_client_payload_destroyed(struct http_client_connection *conn) +static void http_client_payload_destroyed(struct http_client_request *req) { + struct http_client_connection *conn = req->conn; + + i_assert(conn->pending_request == req); i_assert(conn->incoming_payload != NULL); - i_assert(conn->pending_request != NULL); i_assert(conn->conn.io == NULL); http_client_connection_debug(conn, "Response payload stream destroyed"); @@ -338,7 +346,7 @@ conn->incoming_payload = NULL; - http_client_request_finish(&conn->pending_request); + http_client_request_finish(&req); conn->pending_request = NULL; /* input stream may have pending input. make sure input handler @@ -368,7 +376,7 @@ i_stream_create_limit(response->payload, (uoff_t)-1); i_stream_set_destroy_callback(response->payload, http_client_payload_destroyed, - conn); + req); /* the callback may add its own I/O, so we need to remove our one before calling it */ io_remove(&conn->conn.io); diff -r 5e63f628e3ca -r d3e3edf8f7eb src/lib-http/http-client-peer.c --- a/src/lib-http/http-client-peer.c Sun Mar 10 17:17:47 2013 +0200 +++ b/src/lib-http/http-client-peer.c Sun Mar 10 17:19:14 2013 +0200 @@ -133,14 +133,15 @@ unsigned int connecting = 0, closing = 0, min_waiting = UINT_MAX; unsigned int num_urgent, new_connections; - /* at this point we already know that a request for this peer is pending - */ - (void)http_client_peer_requests_pending(peer, &num_urgent); + if (http_client_peer_requests_pending(peer, &num_urgent) == 0) + return FALSE; /* find the least busy connection */ array_foreach(&peer->conns, conn_idx) { if (http_client_connection_is_ready(*conn_idx)) { unsigned int waiting = array_count(&(*conn_idx)->request_wait_list); + if ((*conn_idx)->pending_request != NULL) + waiting++; if (waiting < min_waiting) { min_waiting = waiting; conn = *conn_idx; @@ -315,8 +316,7 @@ if (!exists) array_append(&peer->hosts, &host, 1); - if (exists || array_count(&peer->hosts) > 1) - (void)http_client_peer_next_request(peer); + http_client_peer_handle_requests(peer); } struct http_client_request * @@ -340,9 +340,14 @@ { struct http_client_host *const *host; + i_assert(array_count(&peer->conns) > 0); + http_client_peer_debug(peer, "Failed to make connection"); if (array_count(&peer->conns) == 1) { + /* this was the only/last connection and connecting to it + failed. a second connect will probably also fail, so just + abort all requests. */ array_foreach(&peer->hosts, host) { http_client_host_connection_failure(*host, &peer->addr); } @@ -359,12 +364,11 @@ http_client_peer_debug(peer, "Lost a connection (%d connections left)", array_count(&peer->conns)); - if (array_count(&peer->conns) == 0) { - if (!http_client_peer_next_request(peer)) { - if (http_client_peer_requests_pending(peer, &num_urgent) == 0) - http_client_peer_free(&peer); - } - } + /* if there are pending requests, create a new connection for them. */ + http_client_peer_handle_requests(peer); + if (array_count(&peer->conns) == 0 && + http_client_peer_requests_pending(peer, &num_urgent) == 0) + http_client_peer_free(&peer); } unsigned int http_client_peer_idle_connections(struct http_client_peer *peer) From dovecot at dovecot.org Sun Mar 10 18:37:58 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 10 Mar 2013 18:37:58 +0200 Subject: dovecot-2.2: iostream-rawlog: Pass through close() to parent inp... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/01cfcf2b1c3c changeset: 16006:01cfcf2b1c3c user: Timo Sirainen date: Sun Mar 10 18:16:28 2013 +0200 description: iostream-rawlog: Pass through close() to parent input/output stream. diffstat: src/lib/istream-rawlog.c | 1 + src/lib/ostream-rawlog.c | 2 ++ 2 files changed, 3 insertions(+), 0 deletions(-) diffs (23 lines): diff -r d3e3edf8f7eb -r 01cfcf2b1c3c src/lib/istream-rawlog.c --- a/src/lib/istream-rawlog.c Sun Mar 10 17:19:14 2013 +0200 +++ b/src/lib/istream-rawlog.c Sun Mar 10 18:16:28 2013 +0200 @@ -15,6 +15,7 @@ struct rawlog_istream *rstream = (struct rawlog_istream *)stream; iostream_rawlog_close(&rstream->riostream); + i_stream_close(rstream->istream.parent); } static void i_stream_rawlog_destroy(struct iostream_private *stream) diff -r d3e3edf8f7eb -r 01cfcf2b1c3c src/lib/ostream-rawlog.c --- a/src/lib/ostream-rawlog.c Sun Mar 10 17:19:14 2013 +0200 +++ b/src/lib/ostream-rawlog.c Sun Mar 10 18:16:28 2013 +0200 @@ -16,6 +16,8 @@ (void)o_stream_flush(rstream->ostream.parent); iostream_rawlog_close(&rstream->riostream); + + o_stream_close(rstream->ostream.parent); } static ssize_t From dovecot at dovecot.org Sun Mar 10 18:37:58 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 10 Mar 2013 18:37:58 +0200 Subject: dovecot-2.2: lib-ssl-iostream: Enable SSL_MODE_ENABLE_PARTIAL_WRITE Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1a5414423958 changeset: 16008:1a5414423958 user: Timo Sirainen date: Sun Mar 10 18:37:10 2013 +0200 description: lib-ssl-iostream: Enable SSL_MODE_ENABLE_PARTIAL_WRITE diffstat: src/lib-ssl-iostream/iostream-openssl-context.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 09037e62447b -r 1a5414423958 src/lib-ssl-iostream/iostream-openssl-context.c --- a/src/lib-ssl-iostream/iostream-openssl-context.c Sun Mar 10 18:36:40 2013 +0200 +++ b/src/lib-ssl-iostream/iostream-openssl-context.c Sun Mar 10 18:37:10 2013 +0200 @@ -384,6 +384,7 @@ i_error("SSL_CTX_new() failed: %s", openssl_iostream_error()); return -1; } + SSL_CTX_set_mode(ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); ctx = i_new(struct ssl_iostream_context, 1); ctx->ssl_ctx = ssl_ctx; From dovecot at dovecot.org Sun Mar 10 18:37:58 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 10 Mar 2013 18:37:58 +0200 Subject: dovecot-2.2: lib-ssl-iostream: Fixed "bad write retry" errors wh... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/09037e62447b changeset: 16007:09037e62447b user: Timo Sirainen date: Sun Mar 10 18:36:40 2013 +0200 description: lib-ssl-iostream: Fixed "bad write retry" errors when output had to be buffered. diffstat: src/lib-ssl-iostream/ostream-openssl.c | 54 +++++---------------------------- 1 files changed, 8 insertions(+), 46 deletions(-) diffs (71 lines): diff -r 01cfcf2b1c3c -r 09037e62447b src/lib-ssl-iostream/ostream-openssl.c --- a/src/lib-ssl-iostream/ostream-openssl.c Sun Mar 10 18:16:28 2013 +0200 +++ b/src/lib-ssl-iostream/ostream-openssl.c Sun Mar 10 18:36:40 2013 +0200 @@ -129,59 +129,21 @@ } static ssize_t -o_stream_ssl_sendv_try(struct ssl_ostream *sstream, - const struct const_iovec *iov, unsigned int iov_count, - size_t *bytes_sent_r) -{ - unsigned int i; - size_t pos; - ssize_t ret = 0; - - *bytes_sent_r = 0; - for (i = 0, pos = 0; i < iov_count; ) { - ret = SSL_write(sstream->ssl_io->ssl, - CONST_PTR_OFFSET(iov[i].iov_base, pos), - iov[i].iov_len - pos); - if (ret <= 0) { - ret = openssl_iostream_handle_write_error(sstream->ssl_io, - ret, "SSL_write"); - if (ret < 0) { - sstream->ostream.ostream.stream_errno = errno; - break; - } - if (ret == 0) - break; - } else { - *bytes_sent_r += ret; - if ((size_t)ret < iov[i].iov_len) - pos += ret; - else { - i++; - pos = 0; - } - (void)openssl_iostream_bio_sync(sstream->ssl_io); - } - } - return ret < 0 ? -1 : 0; -} - -static ssize_t o_stream_ssl_sendv(struct ostream_private *stream, const struct const_iovec *iov, unsigned int iov_count) { struct ssl_ostream *sstream = (struct ssl_ostream *)stream; size_t bytes_sent = 0; - int ret; - - if (!sstream->ssl_io->handshaked) - ret = 0; - else { - ret = o_stream_ssl_sendv_try(sstream, iov, iov_count, - &bytes_sent); - } bytes_sent = o_stream_ssl_buffer(sstream, iov, iov_count, bytes_sent); - return bytes_sent != 0 ? (ssize_t)bytes_sent : ret; + if (sstream->ssl_io->handshaked && + sstream->buffer->used == bytes_sent) { + /* buffer was empty before calling this. try to write it + immediately. */ + if (o_stream_ssl_flush_buffer(sstream) < 0) + return -1; + } + return bytes_sent; } static void o_stream_ssl_switch_ioloop(struct ostream_private *stream) From dovecot at dovecot.org Sun Mar 10 18:37:58 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 10 Mar 2013 18:37:58 +0200 Subject: dovecot-2.2: lib-http: If SSL connection gets lost, log the last... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0eaa4fddd61d changeset: 16009:0eaa4fddd61d user: Timo Sirainen date: Sun Mar 10 18:37:46 2013 +0200 description: lib-http: If SSL connection gets lost, log the last SSL error. diffstat: src/lib-http/http-client-connection.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-) diffs (20 lines): diff -r 1a5414423958 -r 0eaa4fddd61d src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Sun Mar 10 18:37:10 2013 +0200 +++ b/src/lib-http/http-client-connection.c Sun Mar 10 18:37:46 2013 +0200 @@ -117,6 +117,16 @@ unsigned int status, const char *error) { struct http_client_connection *conn = *_conn; + const char *sslerr; + + if (status == HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST && + conn->ssl_iostream != NULL) { + sslerr = ssl_iostream_get_last_error(conn->ssl_iostream); + if (sslerr != NULL) { + error = t_strdup_printf("%s (last SSL error: %s)", + error, sslerr); + } + } conn->connected = FALSE; conn->closing = TRUE; From dovecot at dovecot.org Sun Mar 10 19:54:57 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 10 Mar 2013 19:54:57 +0200 Subject: dovecot-2.2: lib-http: If host can't be connected to, don't keep... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/69407b54a557 changeset: 16010:69407b54a557 user: Timo Sirainen date: Sun Mar 10 19:54:51 2013 +0200 description: lib-http: If host can't be connected to, don't keep retrying with more than one connection. This also fixes infinitely trying to reconnect to host and retry. diffstat: src/lib-http/http-client-connection.c | 1 + src/lib-http/http-client-peer.c | 16 ++++++++++++++-- src/lib-http/http-client-private.h | 1 + 3 files changed, 16 insertions(+), 2 deletions(-) diffs (60 lines): diff -r 0eaa4fddd61d -r 69407b54a557 src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Sun Mar 10 18:37:46 2013 +0200 +++ b/src/lib-http/http-client-connection.c Sun Mar 10 19:54:51 2013 +0200 @@ -615,6 +615,7 @@ struct stat st; conn->connected = TRUE; + conn->peer->last_connect_failed = FALSE; if (conn->client->set.rawlog_dir != NULL && stat(conn->client->set.rawlog_dir, &st) == 0) { diff -r 0eaa4fddd61d -r 69407b54a557 src/lib-http/http-client-peer.c --- a/src/lib-http/http-client-peer.c Sun Mar 10 18:37:46 2013 +0200 +++ b/src/lib-http/http-client-peer.c Sun Mar 10 19:54:51 2013 +0200 @@ -175,7 +175,12 @@ } /* yes, determine how many connections to set up */ - if (num_urgent == 0) { + if (peer->last_connect_failed && array_count(&peer->conns) > 0 && + array_count(&peer->conns) == connecting+closing) { + /* don't create new connections until the existing ones have + finished connecting successfully. */ + new_connections = 0; + } else if (num_urgent == 0) { new_connections = 1; } else { new_connections = (num_urgent > connecting ? num_urgent - connecting : 0); @@ -339,12 +344,19 @@ void http_client_peer_connection_failure(struct http_client_peer *peer) { struct http_client_host *const *host; + unsigned int num_urgent; i_assert(array_count(&peer->conns) > 0); http_client_peer_debug(peer, "Failed to make connection"); - if (array_count(&peer->conns) == 1) { + if (array_count(&peer->conns) > 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 + more than one connection until connects work again. */ + peer->last_connect_failed = TRUE; + } else { /* this was the only/last connection and connecting to it failed. a second connect will probably also fail, so just abort all requests. */ diff -r 0eaa4fddd61d -r 69407b54a557 src/lib-http/http-client-private.h --- a/src/lib-http/http-client-private.h Sun Mar 10 18:37:46 2013 +0200 +++ b/src/lib-http/http-client-private.h Sun Mar 10 19:54:51 2013 +0200 @@ -120,6 +120,7 @@ unsigned int destroyed:1; /* peer is being destroyed */ unsigned int no_payload_sync:1; /* expect: 100-continue failed before */ + unsigned int last_connect_failed:1; }; struct http_client_connection { From dovecot at dovecot.org Sun Mar 10 19:55:51 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 10 Mar 2013 19:55:51 +0200 Subject: dovecot-2.2: lib-http: Free peer if it can't be connected to and... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/904f78e80fa5 changeset: 16011:904f78e80fa5 user: Timo Sirainen date: Sun Mar 10 19:55:45 2013 +0200 description: lib-http: Free peer if it can't be connected to and it has no pending requests. diffstat: src/lib-http/http-client-peer.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r 69407b54a557 -r 904f78e80fa5 src/lib-http/http-client-peer.c --- a/src/lib-http/http-client-peer.c Sun Mar 10 19:54:51 2013 +0200 +++ b/src/lib-http/http-client-peer.c Sun Mar 10 19:55:45 2013 +0200 @@ -364,6 +364,9 @@ http_client_host_connection_failure(*host, &peer->addr); } } + 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) From dovecot at dovecot.org Sun Mar 10 20:38:40 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 10 Mar 2013 20:38:40 +0200 Subject: dovecot-2.2: lib-http: Removed unnecessary code from test-http-c... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7db226db28df changeset: 16012:7db226db28df user: Timo Sirainen date: Sun Mar 10 20:34:49 2013 +0200 description: lib-http: Removed unnecessary code from test-http-client diffstat: src/lib-http/test-http-client.c | 7 ------- 1 files changed, 0 insertions(+), 7 deletions(-) diffs (17 lines): diff -r 904f78e80fa5 -r 7db226db28df src/lib-http/test-http-client.c --- a/src/lib-http/test-http-client.c Sun Mar 10 19:55:45 2013 +0200 +++ b/src/lib-http/test-http-client.c Sun Mar 10 20:34:49 2013 +0200 @@ -45,13 +45,6 @@ got_request_response(const struct http_response *response, struct http_test_request *req) { - if (response == NULL) { - /* request failed */ - i_free(req); - i_error("HTTP REQUEST FAILED"); - return; - } - if (response->status / 100 != 2) { i_error("HTTP Request failed: %s", response->reason); i_free(req); From dovecot at dovecot.org Sun Mar 10 20:38:40 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 10 Mar 2013 20:38:40 +0200 Subject: dovecot-2.2: lib-http: Callback can now request a retry with htt... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/59572bce44fe changeset: 16013:59572bce44fe user: Timo Sirainen date: Sun Mar 10 20:37:41 2013 +0200 description: lib-http: Callback can now request a retry with http_client_request_try_retry() This can be useful for handling "try again" errors from HTTP servers. diffstat: src/lib-http/http-client-connection.c | 13 ++++++++++++- src/lib-http/http-client-private.h | 2 +- src/lib-http/http-client-request.c | 33 +++++++++++++++++++++++---------- src/lib-http/http-client.h | 1 + 4 files changed, 37 insertions(+), 12 deletions(-) diffs (114 lines): diff -r 7db226db28df -r 59572bce44fe src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Sun Mar 10 20:34:49 2013 +0200 +++ b/src/lib-http/http-client-connection.c Sun Mar 10 20:37:41 2013 +0200 @@ -392,7 +392,17 @@ io_remove(&conn->conn.io); } - http_client_request_callback(req, response); + if (!http_client_request_callback(req, response)) { + /* retrying, don't destroy the request */ + if (response->payload != NULL) { + i_stream_unset_destroy_callback(conn->incoming_payload); + i_stream_unref(&conn->incoming_payload); + conn->conn.io = io_add(conn->conn.fd_in, IO_READ, + http_client_connection_input, + &conn->conn); + } + return TRUE; + } // FIXME: conn may be freed at this point.. @@ -506,6 +516,7 @@ /* remove request from queue */ array_delete(&conn->request_wait_list, 0, 1); aborted = (req->state == HTTP_REQUEST_STATE_ABORTED); + i_assert(req->refcount > 1 || aborted); http_client_request_unref(&req); conn->close_indicated = response->connection_close; diff -r 7db226db28df -r 59572bce44fe src/lib-http/http-client-private.h --- a/src/lib-http/http-client-private.h Sun Mar 10 20:34:49 2013 +0200 +++ b/src/lib-http/http-client-private.h Sun Mar 10 20:37:41 2013 +0200 @@ -191,7 +191,7 @@ const char **error_r); int http_client_request_send_more(struct http_client_request *req, const char **error_r); -void http_client_request_callback(struct http_client_request *req, +bool http_client_request_callback(struct http_client_request *req, struct http_response *response); void http_client_request_resubmit(struct http_client_request *req); void http_client_request_retry(struct http_client_request *req, diff -r 7db226db28df -r 59572bce44fe src/lib-http/http-client-request.c --- a/src/lib-http/http-client-request.c Sun Mar 10 20:34:49 2013 +0200 +++ b/src/lib-http/http-client-request.c Sun Mar 10 20:37:41 2013 +0200 @@ -412,16 +412,25 @@ return ret; } -void http_client_request_callback(struct http_client_request *req, +bool http_client_request_callback(struct http_client_request *req, struct http_response *response) { http_client_request_callback_t *callback = req->callback; + unsigned int orig_attempts = req->attempts; req->state = HTTP_REQUEST_STATE_GOT_RESPONSE; req->callback = NULL; - if (callback != NULL) + if (callback != NULL) { callback(response, req->context); + if (req->attempts != orig_attempts) { + /* retrying */ + req->callback = callback; + http_client_request_resubmit(req); + return FALSE; + } + } + return TRUE; } static void @@ -636,17 +645,21 @@ void http_client_request_retry(struct http_client_request *req, unsigned int status, const char *error) { + if (!http_client_request_try_retry(req)) + http_client_request_error(req, status, error); +} + +bool http_client_request_try_retry(struct http_client_request *req) +{ /* limit the number of attempts for each request */ - if (++req->attempts >= req->client->set.max_attempts) { - /* return error */ - http_client_request_error(req, status, error); - return; - } + if (req->attempts+1 >= req->client->set.max_attempts) + return FALSE; + req->attempts++; http_client_request_debug(req, "Retrying (attempts=%d)", req->attempts); - - /* resubmit */ - http_client_request_resubmit(req); + if (req->callback != NULL) + http_client_request_resubmit(req); + return TRUE; } void http_client_request_set_destroy_callback(struct http_client_request *req, diff -r 7db226db28df -r 59572bce44fe src/lib-http/http-client.h --- a/src/lib-http/http-client.h Sun Mar 10 20:34:49 2013 +0200 +++ b/src/lib-http/http-client.h Sun Mar 10 20:37:41 2013 +0200 @@ -90,6 +90,7 @@ enum http_request_state http_client_request_get_state(struct http_client_request *req); void http_client_request_submit(struct http_client_request *req); +bool http_client_request_try_retry(struct http_client_request *req); void http_client_request_abort(struct http_client_request **req); /* Call the specified callback when HTTP request is destroyed. */ From dovecot at dovecot.org Sun Mar 10 20:38:40 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 10 Mar 2013 20:38:40 +0200 Subject: dovecot-2.2: lib-http: Added assert. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/81172305f1b2 changeset: 16014:81172305f1b2 user: Timo Sirainen date: Sun Mar 10 20:38:35 2013 +0200 description: lib-http: Added assert. diffstat: src/lib-http/http-client-request.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 59572bce44fe -r 81172305f1b2 src/lib-http/http-client-request.c --- a/src/lib-http/http-client-request.c Sun Mar 10 20:37:41 2013 +0200 +++ b/src/lib-http/http-client-request.c Sun Mar 10 20:38:35 2013 +0200 @@ -301,6 +301,7 @@ off_t ret; i_assert(req->payload_input != NULL); + i_assert(req->payload_output != NULL); /* chunked ostream needs to write to the parent stream's buffer */ o_stream_set_max_buffer_size(output, IO_BLOCK_SIZE); From dovecot at dovecot.org Sun Mar 10 20:50:06 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 10 Mar 2013 20:50:06 +0200 Subject: dovecot-2.2: lib-http: Don't crash if request callback manages t... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5606f1a6cbc6 changeset: 16015:5606f1a6cbc6 user: Timo Sirainen date: Sun Mar 10 20:49:51 2013 +0200 description: lib-http: Don't crash if request callback manages to get the connection destroyed. diffstat: src/lib-http/http-client-connection.c | 15 ++++++++++++--- 1 files changed, 12 insertions(+), 3 deletions(-) diffs (39 lines): diff -r 81172305f1b2 -r 5606f1a6cbc6 src/lib-http/http-client-connection.c --- a/src/lib-http/http-client-connection.c Sun Mar 10 20:38:35 2013 +0200 +++ b/src/lib-http/http-client-connection.c Sun Mar 10 20:49:51 2013 +0200 @@ -373,6 +373,7 @@ struct http_client_request *req, struct http_response *response) { struct istream *payload; + bool retrying; i_assert(conn->incoming_payload == NULL); i_assert(conn->pending_request == NULL); @@ -392,7 +393,17 @@ io_remove(&conn->conn.io); } - if (!http_client_request_callback(req, response)) { + http_client_connection_ref(conn); + retrying = !http_client_request_callback(req, response); + http_client_connection_unref(&conn); + if (conn == NULL) { + /* the callback managed to get this connection destroyed */ + if (!retrying) + http_client_request_finish(&req); + return FALSE; + } + + if (retrying) { /* retrying, don't destroy the request */ if (response->payload != NULL) { i_stream_unset_destroy_callback(conn->incoming_payload); @@ -404,8 +415,6 @@ return TRUE; } - // FIXME: conn may be freed at this point.. - if (response->payload != NULL) { req->state = HTTP_REQUEST_STATE_PAYLOAD_IN; payload = response->payload; From dovecot at dovecot.org Sun Mar 10 20:52:19 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 10 Mar 2013 20:52:19 +0200 Subject: dovecot-2.2: fts-solr: Removed unnecessary code. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/30baa62d8e72 changeset: 16016:30baa62d8e72 user: Timo Sirainen date: Sun Mar 10 20:52:10 2013 +0200 description: fts-solr: Removed unnecessary code. diffstat: src/plugins/fts-solr/solr-connection.c | 7 ------- 1 files changed, 0 insertions(+), 7 deletions(-) diffs (17 lines): diff -r 5606f1a6cbc6 -r 30baa62d8e72 src/plugins/fts-solr/solr-connection.c --- a/src/plugins/fts-solr/solr-connection.c Sun Mar 10 20:49:51 2013 +0200 +++ b/src/plugins/fts-solr/solr-connection.c Sun Mar 10 20:52:10 2013 +0200 @@ -378,13 +378,6 @@ solr_connection_select_response(const struct http_response *response, struct solr_connection *conn) { - if (response == NULL) { - /* request failed */ - i_error("fts_solr: HTTP GET request failed"); - conn->request_status = -1; - return; - } - if (response->status / 100 != 2) { i_error("fts_solr: Lookup failed: %s", response->reason); conn->request_status = -1; From dovecot at dovecot.org Mon Mar 11 14:44:58 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 11 Mar 2013 14:44:58 +0200 Subject: dovecot-2.2: acl: Delay initializing default backend ACLs. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/20955c64bde3 changeset: 16017:20955c64bde3 user: Timo Sirainen date: Mon Mar 11 14:44:48 2013 +0200 description: acl: Delay initializing default backend ACLs. This fixes a crash with LAYOUT=index. diffstat: src/plugins/acl/acl-backend.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) diffs (33 lines): diff -r 30baa62d8e72 -r 20955c64bde3 src/plugins/acl/acl-backend.c --- a/src/plugins/acl/acl-backend.c Sun Mar 10 20:52:10 2013 +0200 +++ b/src/plugins/acl/acl-backend.c Mon Mar 11 14:44:48 2013 +0200 @@ -82,8 +82,6 @@ backend->default_aclmask = acl_cache_mask_init(backend->cache, backend->pool, backend->default_rights); - - backend->default_aclobj = acl_object_init_from_name(backend, ""); return backend; } @@ -93,7 +91,8 @@ *_backend = NULL; - acl_object_deinit(&backend->default_aclobj); + if (backend->default_aclobj != NULL) + acl_object_deinit(&backend->default_aclobj); acl_cache_deinit(&backend->cache); backend->v.deinit(backend); } @@ -161,6 +160,10 @@ int acl_backend_get_default_rights(struct acl_backend *backend, const struct acl_mask **mask_r) { + if (backend->default_aclobj == NULL) { + backend->default_aclobj = + acl_object_init_from_name(backend, ""); + } if (backend->v.object_refresh_cache(backend->default_aclobj) < 0) return -1; From dovecot at dovecot.org Mon Mar 11 17:25:56 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 11 Mar 2013 17:25:56 +0200 Subject: dovecot-2.2: lib-fs: Fixed fs_delete() API description. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/dc4be035a038 changeset: 16018:dc4be035a038 user: Timo Sirainen date: Mon Mar 11 17:25:46 2013 +0200 description: lib-fs: Fixed fs_delete() API description. diffstat: src/lib-fs/fs-api.h | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diffs (13 lines): diff -r 20955c64bde3 -r dc4be035a038 src/lib-fs/fs-api.h --- a/src/lib-fs/fs-api.h Mon Mar 11 14:44:48 2013 +0200 +++ b/src/lib-fs/fs-api.h Mon Mar 11 17:25:46 2013 +0200 @@ -152,8 +152,7 @@ /* Returns 1 if file exists, 0 if not, -1 if error occurred. */ int fs_exists(struct fs_file *file); -/* Delete a file. Returns 1 if file was actually deleted by us, - 0 if file didn't exist, -1 if error. */ +/* Delete a file. Returns 0 if file was actually deleted by us, -1 if error. */ int fs_delete(struct fs_file *file); /* Returns 0 if ok, -1 if error occurred (e.g. errno=ENOENT). From dovecot at dovecot.org Wed Mar 13 15:05:16 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 13 Mar 2013 15:05:16 +0200 Subject: dovecot-2.2: lda, lmtp: postmaster_address = postmaster@%d works... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/34d61f447433 changeset: 16019:34d61f447433 user: Timo Sirainen date: Wed Mar 13 15:05:05 2013 +0200 description: lda, lmtp: postmaster_address = postmaster@%d works now. diffstat: doc/example-config/conf.d/15-lda.conf | 2 +- src/lda/main.c | 7 ++++++- src/lib-lda/lda-settings.c | 2 +- src/lmtp/commands.c | 6 +++++- 4 files changed, 13 insertions(+), 4 deletions(-) diffs (75 lines): diff -r dc4be035a038 -r 34d61f447433 doc/example-config/conf.d/15-lda.conf --- a/doc/example-config/conf.d/15-lda.conf Mon Mar 11 17:25:46 2013 +0200 +++ b/doc/example-config/conf.d/15-lda.conf Wed Mar 13 15:05:05 2013 +0200 @@ -3,7 +3,7 @@ ## # Address to use when sending rejection mails. -# Default is postmaster@. +# Default is postmaster@. %d expands to recipient domain. #postmaster_address = # Hostname to use in various parts of sent mails (e.g. in Message-Id) and diff -r dc4be035a038 -r 34d61f447433 src/lda/main.c --- a/src/lda/main.c Mon Mar 11 17:25:46 2013 +0200 +++ b/src/lda/main.c Wed Mar 13 15:05:05 2013 +0200 @@ -276,6 +276,7 @@ struct mail_deliver_context ctx; enum mail_storage_service_flags service_flags = 0; const char *user, *errstr, *path; + struct lda_settings *lda_set; struct mail_storage_service_ctx *storage_service; struct mail_storage_service_user *service_user; struct mail_storage_service_input service_input; @@ -420,7 +421,11 @@ #ifdef SIGXFSZ lib_signals_ignore(SIGXFSZ, TRUE); #endif - ctx.set = mail_storage_service_user_get_set(service_user)[1]; + lda_set = mail_storage_service_user_get_set(service_user)[1]; + settings_var_expand(&lda_setting_parser_info, lda_set, + ctx.dest_user->pool, + mail_user_var_expand_table(ctx.dest_user)); + ctx.set = lda_set; if (ctx.dest_user->mail_debug && *user_source != '\0') { i_debug("userdb lookup skipped, username taken from %s", diff -r dc4be035a038 -r 34d61f447433 src/lib-lda/lda-settings.c --- a/src/lib-lda/lda-settings.c Mon Mar 11 17:25:46 2013 +0200 +++ b/src/lib-lda/lda-settings.c Wed Mar 13 15:05:05 2013 +0200 @@ -18,7 +18,7 @@ { SET_DEFLIST, name, offsetof(struct lda_settings, field), defines } static const struct setting_define lda_setting_defines[] = { - DEF(SET_STR, postmaster_address), + DEF(SET_STR_VARS, postmaster_address), DEF(SET_STR, hostname), DEF(SET_STR, submission_host), DEF(SET_STR, sendmail_path), diff -r dc4be035a038 -r 34d61f447433 src/lmtp/commands.c --- a/src/lmtp/commands.c Mon Mar 11 17:25:46 2013 +0200 +++ b/src/lmtp/commands.c Wed Mar 13 15:05:05 2013 +0200 @@ -620,6 +620,7 @@ struct mail_storage *storage; const struct mail_storage_service_input *input; const struct mail_storage_settings *mail_set; + struct lda_settings *lda_set; struct mail_namespace *ns; struct setting_parser_context *set_parser; void **sets; @@ -654,11 +655,14 @@ return -1; } 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, + mail_user_var_expand_table(client->state.dest_user)); memset(&dctx, 0, sizeof(dctx)); dctx.session = session; dctx.pool = session->pool; - dctx.set = sets[1]; + dctx.set = lda_set; dctx.session_id = client->state.session_id; dctx.src_mail = src_mail; dctx.src_envelope_sender = client->state.mail_from; From dovecot at dovecot.org Wed Mar 13 22:14:01 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 13 Mar 2013 22:14:01 +0200 Subject: dovecot-2.2: iostreams: Added close_parent flag to close() handl... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6cabb95d32ec changeset: 16020:6cabb95d32ec user: Timo Sirainen date: Wed Mar 13 22:11:39 2013 +0200 description: iostreams: Added close_parent flag to close() handler and clarified close/destroy APIs. This makes it unambiguous how things work: Unless you explicitly call [io]_stream_close(), the parent streams won't be closed. This is what most (hopefully all!) of the existing code expects. I was wondering a bit if [io]_stream_destroy() should simply have been removed and replaced with [io]_stream_unref() calls, since they would have worked basically everywhere, but there might be some places where it's better to have explicitly closed the stream (and where closing the parent stream doesn't matter). diffstat: src/lib-compression/istream-bzlib.c | 5 ++++- src/lib-compression/istream-zlib.c | 5 ++++- src/lib-compression/ostream-bzlib.c | 5 ++++- src/lib-compression/ostream-zlib.c | 5 ++++- src/lib-fs/ostream-cmp.c | 5 ++++- src/lib-http/http-transfer-chunked.c | 5 ++++- src/lib-mail/istream-attachment-extractor.c | 5 ++++- src/lib-mail/istream-binary-converter.c | 5 ++++- src/lib-ssl-iostream/istream-openssl.c | 6 ++++-- src/lib-ssl-iostream/ostream-openssl.c | 6 ++++-- src/lib/iostream-private.h | 4 ++-- src/lib/iostream-temp.c | 4 +++- src/lib/iostream.c | 18 ++++++++++++------ src/lib/istream-concat.c | 9 ++++++--- src/lib/istream-file.c | 3 ++- src/lib/istream-mmap.c | 3 ++- src/lib/istream-rawlog.c | 6 ++++-- src/lib/istream-seekable.c | 3 ++- src/lib/istream-tee.c | 3 ++- src/lib/istream.c | 28 ++++++++++++++++++++++------ src/lib/istream.h | 6 +++--- src/lib/ostream-file.c | 3 ++- src/lib/ostream-rawlog.c | 6 ++++-- src/lib/ostream.c | 22 +++++++++++++++------- src/lib/ostream.h | 5 +++-- 25 files changed, 124 insertions(+), 51 deletions(-) diffs (truncated from 582 to 300 lines): diff -r 34d61f447433 -r 6cabb95d32ec src/lib-compression/istream-bzlib.c --- a/src/lib-compression/istream-bzlib.c Wed Mar 13 15:05:05 2013 +0200 +++ b/src/lib-compression/istream-bzlib.c Wed Mar 13 22:11:39 2013 +0200 @@ -23,7 +23,8 @@ unsigned int zs_closed:1; }; -static void i_stream_bzlib_close(struct iostream_private *stream) +static void i_stream_bzlib_close(struct iostream_private *stream, + bool close_parent) { struct bzlib_istream *zstream = (struct bzlib_istream *)stream; @@ -31,6 +32,8 @@ (void)BZ2_bzDecompressEnd(&zstream->zs); zstream->zs_closed = TRUE; } + if (close_parent) + i_stream_close(zstream->istream.parent); } static void bzlib_read_error(struct bzlib_istream *zstream, const char *error) diff -r 34d61f447433 -r 6cabb95d32ec src/lib-compression/istream-zlib.c --- a/src/lib-compression/istream-zlib.c Wed Mar 13 15:05:05 2013 +0200 +++ b/src/lib-compression/istream-zlib.c Wed Mar 13 22:11:39 2013 +0200 @@ -40,7 +40,8 @@ static void i_stream_zlib_init(struct zlib_istream *zstream); -static void i_stream_zlib_close(struct iostream_private *stream) +static void i_stream_zlib_close(struct iostream_private *stream, + bool close_parent) { struct zlib_istream *zstream = (struct zlib_istream *)stream; @@ -48,6 +49,8 @@ (void)inflateEnd(&zstream->zs); zstream->zs_closed = TRUE; } + if (close_parent) + i_stream_close(zstream->istream.parent); } static void zlib_read_error(struct zlib_istream *zstream, const char *error) diff -r 34d61f447433 -r 6cabb95d32ec src/lib-compression/ostream-bzlib.c --- a/src/lib-compression/ostream-bzlib.c Wed Mar 13 15:05:05 2013 +0200 +++ b/src/lib-compression/ostream-bzlib.c Wed Mar 13 22:11:39 2013 +0200 @@ -20,12 +20,15 @@ unsigned int flushed:1; }; -static void o_stream_bzlib_close(struct iostream_private *stream) +static void o_stream_bzlib_close(struct iostream_private *stream, + bool close_parent) { struct bzlib_ostream *zstream = (struct bzlib_ostream *)stream; (void)o_stream_flush(&zstream->ostream.ostream); (void)BZ2_bzCompressEnd(&zstream->zs); + if (close_parent) + o_stream_close(zstream->ostream.parent); } static int o_stream_zlib_send_outbuf(struct bzlib_ostream *zstream) diff -r 34d61f447433 -r 6cabb95d32ec src/lib-compression/ostream-zlib.c --- a/src/lib-compression/ostream-zlib.c Wed Mar 13 15:05:05 2013 +0200 +++ b/src/lib-compression/ostream-zlib.c Wed Mar 13 22:11:39 2013 +0200 @@ -27,12 +27,15 @@ unsigned int flushed:1; }; -static void o_stream_zlib_close(struct iostream_private *stream) +static void o_stream_zlib_close(struct iostream_private *stream, + bool close_parent) { struct zlib_ostream *zstream = (struct zlib_ostream *)stream; (void)o_stream_flush(&zstream->ostream.ostream); (void)deflateEnd(&zstream->zs); + if (close_parent) + o_stream_close(zstream->ostream.parent); } static int o_stream_zlib_send_gz_header(struct zlib_ostream *zstream) diff -r 34d61f447433 -r 6cabb95d32ec src/lib-fs/ostream-cmp.c --- a/src/lib-fs/ostream-cmp.c Wed Mar 13 15:05:05 2013 +0200 +++ b/src/lib-fs/ostream-cmp.c Wed Mar 13 22:11:39 2013 +0200 @@ -12,7 +12,8 @@ bool equals; }; -static void o_stream_cmp_close(struct iostream_private *stream) +static void o_stream_cmp_close(struct iostream_private *stream, + bool close_parent) { struct cmp_ostream *cstream = (struct cmp_ostream *)stream; @@ -21,6 +22,8 @@ i_stream_unref(&cstream->input); (void)o_stream_flush(&cstream->ostream.ostream); + if (close_parent) + o_stream_close(cstream->ostream.parent); } bool stream_cmp_block(struct istream *input, diff -r 34d61f447433 -r 6cabb95d32ec src/lib-http/http-transfer-chunked.c --- a/src/lib-http/http-transfer-chunked.c Wed Mar 13 15:05:05 2013 +0200 +++ b/src/lib-http/http-transfer-chunked.c Wed Mar 13 22:11:39 2013 +0200 @@ -556,13 +556,16 @@ } static void -http_transfer_chunked_ostream_close(struct iostream_private *stream) +http_transfer_chunked_ostream_close(struct iostream_private *stream, + bool close_parent) { struct http_transfer_chunked_ostream *tcstream = (struct http_transfer_chunked_ostream *)stream; (void)o_stream_send(tcstream->ostream.parent, "0\r\n\r\n", 5); (void)o_stream_flush(&tcstream->ostream.ostream); + if (close_parent) + o_stream_close(tcstream->ostream.parent); } static ssize_t diff -r 34d61f447433 -r 6cabb95d32ec src/lib-mail/istream-attachment-extractor.c --- a/src/lib-mail/istream-attachment-extractor.c Wed Mar 13 15:05:05 2013 +0200 +++ b/src/lib-mail/istream-attachment-extractor.c Wed Mar 13 22:11:39 2013 +0200 @@ -627,7 +627,8 @@ return ret; } -static void i_stream_attachment_extractor_close(struct iostream_private *stream) +static void i_stream_attachment_extractor_close(struct iostream_private *stream, + bool close_parent) { struct attachment_istream *astream = (struct attachment_istream *)stream; @@ -641,6 +642,8 @@ hash_format_deinit_free(&astream->set.hash_format); if (astream->pool != NULL) pool_unref(&astream->pool); + if (close_parent) + i_stream_close(astream->istream.parent); } struct istream * diff -r 34d61f447433 -r 6cabb95d32ec src/lib-mail/istream-binary-converter.c --- a/src/lib-mail/istream-binary-converter.c Wed Mar 13 15:05:05 2013 +0200 +++ b/src/lib-mail/istream-binary-converter.c Wed Mar 13 22:11:39 2013 +0200 @@ -260,7 +260,8 @@ return new_size - old_size; } -static void i_stream_binary_converter_close(struct iostream_private *stream) +static void i_stream_binary_converter_close(struct iostream_private *stream, + bool close_parent) { struct binary_converter_istream *bstream = (struct binary_converter_istream *)stream; @@ -270,6 +271,8 @@ (void)message_parser_deinit(&bstream->parser, &parts); if (bstream->pool != NULL) pool_unref(&bstream->pool); + if (close_parent) + i_stream_close(bstream->istream.parent); } struct istream *i_stream_create_binary_converter(struct istream *input) diff -r 34d61f447433 -r 6cabb95d32ec src/lib-ssl-iostream/istream-openssl.c --- a/src/lib-ssl-iostream/istream-openssl.c Wed Mar 13 15:05:05 2013 +0200 +++ b/src/lib-ssl-iostream/istream-openssl.c Wed Mar 13 22:11:39 2013 +0200 @@ -10,11 +10,13 @@ bool seen_eof; }; -static void i_stream_ssl_close(struct iostream_private *stream) +static void i_stream_ssl_close(struct iostream_private *stream, + bool close_parent) { struct ssl_istream *sstream = (struct ssl_istream *)stream; - i_stream_close(sstream->ssl_io->plain_input); + if (close_parent) + i_stream_close(sstream->ssl_io->plain_input); } static void i_stream_ssl_destroy(struct iostream_private *stream) diff -r 34d61f447433 -r 6cabb95d32ec src/lib-ssl-iostream/ostream-openssl.c --- a/src/lib-ssl-iostream/ostream-openssl.c Wed Mar 13 15:05:05 2013 +0200 +++ b/src/lib-ssl-iostream/ostream-openssl.c Wed Mar 13 22:11:39 2013 +0200 @@ -11,11 +11,13 @@ buffer_t *buffer; }; -static void o_stream_ssl_close(struct iostream_private *stream) +static void +o_stream_ssl_close(struct iostream_private *stream, bool close_parent) { struct ssl_ostream *sstream = (struct ssl_ostream *)stream; - o_stream_close(sstream->ssl_io->plain_output); + if (close_parent) + o_stream_close(sstream->ssl_io->plain_output); } static void o_stream_ssl_destroy(struct iostream_private *stream) diff -r 34d61f447433 -r 6cabb95d32ec src/lib/iostream-private.h --- a/src/lib/iostream-private.h Wed Mar 13 15:05:05 2013 +0200 +++ b/src/lib/iostream-private.h Wed Mar 13 22:11:39 2013 +0200 @@ -7,7 +7,7 @@ int refcount; char *name; - void (*close)(struct iostream_private *stream); + void (*close)(struct iostream_private *streami, bool close_parent); void (*destroy)(struct iostream_private *stream); void (*set_max_buffer_size)(struct iostream_private *stream, size_t max_size); @@ -19,7 +19,7 @@ void io_stream_init(struct iostream_private *stream); void io_stream_ref(struct iostream_private *stream); void io_stream_unref(struct iostream_private *stream); -void io_stream_close(struct iostream_private *stream); +void io_stream_close(struct iostream_private *stream, bool close_parent); void io_stream_set_max_buffer_size(struct iostream_private *stream, size_t max_size); diff -r 34d61f447433 -r 6cabb95d32ec src/lib/iostream-temp.c --- a/src/lib/iostream-temp.c Wed Mar 13 15:05:05 2013 +0200 +++ b/src/lib/iostream-temp.c Wed Mar 13 22:11:39 2013 +0200 @@ -27,7 +27,9 @@ bool fd_tried; }; -static void o_stream_temp_close(struct iostream_private *stream) +static void +o_stream_temp_close(struct iostream_private *stream, + bool close_parent ATTR_UNUSED) { struct temp_ostream *tstream = (struct temp_ostream *)stream; diff -r 34d61f447433 -r 6cabb95d32ec src/lib/iostream.c --- a/src/lib/iostream.c Wed Mar 13 15:05:05 2013 +0200 +++ b/src/lib/iostream.c Wed Mar 13 22:11:39 2013 +0200 @@ -4,16 +4,22 @@ #include "iostream-private.h" static void -io_stream_default_close_destroy(struct iostream_private *stream ATTR_UNUSED) +io_stream_default_close(struct iostream_private *stream ATTR_UNUSED, + bool close_parent ATTR_UNUSED) +{ +} + +static void +io_stream_default_destroy(struct iostream_private *stream ATTR_UNUSED) { } void io_stream_init(struct iostream_private *stream) { if (stream->close == NULL) - stream->close = io_stream_default_close_destroy; + stream->close = io_stream_default_close; if (stream->destroy == NULL) - stream->destroy = io_stream_default_close_destroy; + stream->destroy = io_stream_default_destroy; stream->refcount = 1; } @@ -29,7 +35,7 @@ if (--stream->refcount != 0) return; - stream->close(stream); + stream->close(stream, FALSE); stream->destroy(stream); if (stream->destroy_callback != NULL) stream->destroy_callback(stream->destroy_context); @@ -38,9 +44,9 @@ i_free(stream); } -void io_stream_close(struct iostream_private *stream) +void io_stream_close(struct iostream_private *stream, bool close_parent) { - stream->close(stream); + stream->close(stream, close_parent); } void io_stream_set_max_buffer_size(struct iostream_private *stream, diff -r 34d61f447433 -r 6cabb95d32ec src/lib/istream-concat.c --- a/src/lib/istream-concat.c Wed Mar 13 15:05:05 2013 +0200 +++ b/src/lib/istream-concat.c Wed Mar 13 22:11:39 2013 +0200 @@ -15,13 +15,16 @@ size_t prev_stream_left, prev_skip; }; From dovecot at dovecot.org Thu Mar 14 15:41:49 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 14 Mar 2013 15:41:49 +0200 Subject: dovecot-2.2: istream-dot unit test updated. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e5b5e2ce7578 changeset: 16021:e5b5e2ce7578 user: Timo Sirainen date: Thu Mar 14 15:25:07 2013 +0200 description: istream-dot unit test updated. diffstat: src/lib-mail/test-istream-dot.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 6cabb95d32ec -r e5b5e2ce7578 src/lib-mail/test-istream-dot.c --- a/src/lib-mail/test-istream-dot.c Wed Mar 13 22:11:39 2013 +0200 +++ b/src/lib-mail/test-istream-dot.c Thu Mar 14 15:25:07 2013 +0200 @@ -106,6 +106,8 @@ static struct dot_test tests[] = { { "..foo\n..\n.foo\n.\nfoo", ".foo\n.\nfoo\n", "foo" }, { "..foo\r\n..\r\n.foo\r\n.\r\nfoo", ".foo\r\n.\r\nfoo\r\n", "foo" }, + { "\r.\r\n.\r\n", "\r.\r\n", "" }, + { "\n\r.\r\r\n.\r\n", "\n\r.\r\r\n", "" }, { "\r\n.\r\n", "\r\n", "" }, { "\n.\r\n", "\n", "" }, { "\n.\n", "\n", "" }, From dovecot at dovecot.org Thu Mar 14 15:41:49 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 14 Mar 2013 15:41:49 +0200 Subject: dovecot-2.2: lib-master: Added version_string_verify_full() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9a8eaf97559d changeset: 16022:9a8eaf97559d user: Timo Sirainen date: Thu Mar 14 15:24:48 2013 +0200 description: lib-master: Added version_string_verify_full() diffstat: src/lib-master/master-service.c | 21 ++++++++++++++++++++- src/lib-master/master-service.h | 4 ++++ 2 files changed, 24 insertions(+), 1 deletions(-) diffs (51 lines): diff -r e5b5e2ce7578 -r 9a8eaf97559d src/lib-master/master-service.c --- a/src/lib-master/master-service.c Thu Mar 14 15:25:07 2013 +0200 +++ b/src/lib-master/master-service.c Thu Mar 14 15:24:48 2013 +0200 @@ -1002,6 +1002,16 @@ bool version_string_verify(const char *line, const char *service_name, unsigned major_version) { + unsigned int minor_version; + + return version_string_verify_full(line, service_name, + major_version, &minor_version); +} + +bool version_string_verify_full(const char *line, const char *service_name, + unsigned major_version, + unsigned int *minor_version_r) +{ unsigned int service_name_len = strlen(service_name); bool ret; @@ -1015,7 +1025,16 @@ line += service_name_len + 1; T_BEGIN { - ret = str_uint_equals(t_strcut(line, '\t'), major_version); + const char *p = strchr(line, '\t'); + + if (p == NULL) + ret = FALSE; + else { + ret = str_uint_equals(t_strdup_until(line, p), + major_version); + if (str_to_uint(p+1, minor_version_r) < 0) + ret = FALSE; + } } T_END; return ret; } diff -r e5b5e2ce7578 -r 9a8eaf97559d src/lib-master/master-service.h --- a/src/lib-master/master-service.h Thu Mar 14 15:25:07 2013 +0200 +++ b/src/lib-master/master-service.h Thu Mar 14 15:24:48 2013 +0200 @@ -155,5 +155,9 @@ VERSION service_name major version minor version */ bool version_string_verify(const char *line, const char *service_name, unsigned major_version); +/* Same as version_string_verify(), but return the minor version. */ +bool version_string_verify_full(const char *line, const char *service_name, + unsigned major_version, + unsigned int *minor_version_r); #endif From dovecot at dovecot.org Thu Mar 14 15:41:49 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 14 Mar 2013 15:41:49 +0200 Subject: dovecot-2.2: lib-index: mail_index_attribute_[un]set() adds chan... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/db0136374bb0 changeset: 16023:db0136374bb0 user: Timo Sirainen date: Thu Mar 14 15:29:18 2013 +0200 description: lib-index: mail_index_attribute_[un]set() adds changed attributes' keys to transaction log. This provides them both a modseq (so their changes become visible) as well as an efficient way to see what attributes have changed by reading the transaction log. The values themselves aren't written to the log, because they could be large. diffstat: src/doveadm/doveadm-dump-log.c | 14 ++++++++++ src/lib-index/mail-index-modseq.c | 10 ++++++- src/lib-index/mail-index-sync-update.c | 5 +++ src/lib-index/mail-index-transaction-export.c | 9 ++++++ src/lib-index/mail-index-transaction-private.h | 1 + src/lib-index/mail-index-transaction-update.c | 27 ++++++++++++++++++++ src/lib-index/mail-index.h | 8 ++++++ src/lib-index/mail-transaction-log-file.c | 1 + src/lib-index/mail-transaction-log-view.c | 34 ++++++++++++++++++++++++++ src/lib-index/mail-transaction-log.h | 3 +- 10 files changed, 110 insertions(+), 2 deletions(-) diffs (260 lines): diff -r 9a8eaf97559d -r db0136374bb0 src/doveadm/doveadm-dump-log.c --- a/src/doveadm/doveadm-dump-log.c Thu Mar 14 15:24:48 2013 +0200 +++ b/src/doveadm/doveadm-dump-log.c Thu Mar 14 15:29:18 2013 +0200 @@ -52,6 +52,7 @@ case MAIL_TRANSACTION_FLAG_UPDATE: case MAIL_TRANSACTION_KEYWORD_UPDATE: case MAIL_TRANSACTION_KEYWORD_RESET: + case MAIL_TRANSACTION_ATTRIBUTE_UPDATE: /* these changes increase modseq */ return TRUE; } @@ -114,6 +115,9 @@ case MAIL_TRANSACTION_BOUNDARY: name = "boundary"; break; + case MAIL_TRANSACTION_ATTRIBUTE_UPDATE: + name = "attribute-update"; + break; default: name = t_strdup_printf("unknown: %x", type); break; @@ -415,6 +419,16 @@ printf(" - size=%u\n", rec->size); break; } + case MAIL_TRANSACTION_ATTRIBUTE_UPDATE: { + const char *keys = data; + unsigned int i; + + for (i = 0; i < size && keys[i] != '\0'; ) { + printf(" - %s\n", keys+i); + i += strlen(keys+i) + 1; + } + break; + } default: break; } diff -r 9a8eaf97559d -r db0136374bb0 src/lib-index/mail-index-modseq.c --- a/src/lib-index/mail-index-modseq.c Thu Mar 14 15:24:48 2013 +0200 +++ b/src/lib-index/mail-index-modseq.c Thu Mar 14 15:29:18 2013 +0200 @@ -335,6 +335,7 @@ buffer_t uid_buf; unsigned int i, count; uint32_t seq1, seq2; + uint64_t modseq; switch (thdr->type & MAIL_TRANSACTION_TYPE_MASK) { case MAIL_TRANSACTION_APPEND: { @@ -374,12 +375,19 @@ array_create_from_buffer(&uids, &uid_buf, sizeof(struct mail_transaction_keyword_reset)); break; + case MAIL_TRANSACTION_ATTRIBUTE_UPDATE: + break; default: return; } + /* update highestmodseq regardless of whether any mails were updated */ + modseq = mail_transaction_log_view_get_prev_modseq(ctx->log_view); + if (modseq > ctx->highest_modseq) + ctx->highest_modseq = modseq; + /* update modseqs */ - count = array_count(&uids); + count = array_is_created(&uids) ? array_count(&uids) : 0; for (i = 0; i < count; i++) { rec = array_idx(&uids, i); if (mail_index_lookup_seq_range(ctx->view, rec->seq1, rec->seq2, diff -r 9a8eaf97559d -r db0136374bb0 src/lib-index/mail-index-sync-update.c --- a/src/lib-index/mail-index-sync-update.c Thu Mar 14 15:24:48 2013 +0200 +++ b/src/lib-index/mail-index-sync-update.c Thu Mar 14 15:29:18 2013 +0200 @@ -495,6 +495,7 @@ const struct mail_transaction_header *hdr, const void *data) { + uint64_t modseq; int ret = 0; switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) { @@ -767,6 +768,10 @@ break; case MAIL_TRANSACTION_BOUNDARY: break; + case MAIL_TRANSACTION_ATTRIBUTE_UPDATE: + modseq = mail_transaction_log_view_get_prev_modseq(ctx->view->log_view); + mail_index_modseq_update_highest(ctx->modseq_ctx, modseq); + break; default: mail_index_sync_set_corrupted(ctx, "Unknown transaction record type 0x%x", diff -r 9a8eaf97559d -r db0136374bb0 src/lib-index/mail-index-transaction-export.c --- a/src/lib-index/mail-index-transaction-export.c Thu Mar 14 15:24:48 2013 +0200 +++ b/src/lib-index/mail-index-transaction-export.c Thu Mar 14 15:29:18 2013 +0200 @@ -393,6 +393,15 @@ log_append_buffer(&ctx, log_get_hdr_update_buffer(t, TRUE), MAIL_TRANSACTION_HEADER_UPDATE); } + if (t->attribute_updates != NULL) { + /* need to have 32bit alignment */ + if (t->attribute_updates->used % 4 != 0) { + buffer_append_zero(t->attribute_updates, + 4 - t->attribute_updates->used % 4); + } + log_append_buffer(&ctx, t->attribute_updates, + MAIL_TRANSACTION_ATTRIBUTE_UPDATE); + } if (array_is_created(&t->appends)) { change_mask |= MAIL_INDEX_FSYNC_MASK_APPENDS; log_append_buffer(&ctx, t->appends.arr.buffer, diff -r 9a8eaf97559d -r db0136374bb0 src/lib-index/mail-index-transaction-private.h --- a/src/lib-index/mail-index-transaction-private.h Thu Mar 14 15:24:48 2013 +0200 +++ b/src/lib-index/mail-index-transaction-private.h Thu Mar 14 15:29:18 2013 +0200 @@ -70,6 +70,7 @@ ARRAY(uint32_t) ext_reset_atomic; ARRAY(struct mail_index_transaction_keyword_update) keyword_updates; + buffer_t *attribute_updates; /* [+-][ps]key\0.. */ uint64_t min_highest_modseq; uint64_t max_modseq; diff -r 9a8eaf97559d -r db0136374bb0 src/lib-index/mail-index-transaction-update.c --- a/src/lib-index/mail-index-transaction-update.c Thu Mar 14 15:24:48 2013 +0200 +++ b/src/lib-index/mail-index-transaction-update.c Thu Mar 14 15:29:18 2013 +0200 @@ -76,6 +76,8 @@ array_free(&t->ext_reset_ids); if (array_is_created(&t->ext_reset_atomic)) array_free(&t->ext_reset_atomic); + if (t->attribute_updates != NULL) + buffer_free(&t->attribute_updates); t->first_new_seq = mail_index_view_get_messages_count(t->view)+1; t->last_new_seq = 0; @@ -106,6 +108,7 @@ array_is_created(&t->modseq_updates) || array_is_created(&t->expunges) || array_is_created(&t->keyword_updates) || + t->attribute_updates != NULL || t->pre_hdr_changed || t->post_hdr_changed || t->min_highest_modseq != 0; } @@ -647,6 +650,30 @@ mail_index_update_flags_range(t, seq, seq, modify_type, flags); } +static void +mail_index_attribute_set_full(struct mail_index_transaction *t, + const char *key, bool pvt, char prefix) +{ + if (t->attribute_updates == NULL) + t->attribute_updates = buffer_create_dynamic(default_pool, 64); + buffer_append_c(t->attribute_updates, prefix); + buffer_append_c(t->attribute_updates, pvt ? 'p' : 's'); + buffer_append(t->attribute_updates, key, strlen(key)+1); + t->log_updates = TRUE; +} + +void mail_index_attribute_set(struct mail_index_transaction *t, + bool pvt, const char *key) +{ + mail_index_attribute_set_full(t, key, pvt, '+'); +} + +void mail_index_attribute_unset(struct mail_index_transaction *t, + bool pvt, const char *key) +{ + mail_index_attribute_set_full(t, key, pvt, '-'); +} + void mail_index_update_header(struct mail_index_transaction *t, size_t offset, const void *data, size_t size, bool prepend) diff -r 9a8eaf97559d -r db0136374bb0 src/lib-index/mail-index.h --- a/src/lib-index/mail-index.h Thu Mar 14 15:24:48 2013 +0200 +++ b/src/lib-index/mail-index.h Thu Mar 14 15:29:18 2013 +0200 @@ -464,6 +464,14 @@ uint32_t seq1, uint32_t seq2, enum modify_type modify_type, enum mail_flags flags); +/* Specified attribute's value was changed. This is just a notification so the + change gets assigned its own modseq and any log readers can find out about + this change. */ +void mail_index_attribute_set(struct mail_index_transaction *t, + bool pvt, const char *key); +/* Attribute was deleted. */ +void mail_index_attribute_unset(struct mail_index_transaction *t, + bool pvt, const char *key); /* Update message's modseq to be at least min_modseq. */ void mail_index_update_modseq(struct mail_index_transaction *t, uint32_t seq, uint64_t min_modseq); diff -r 9a8eaf97559d -r db0136374bb0 src/lib-index/mail-transaction-log-file.c --- a/src/lib-index/mail-transaction-log-file.c Thu Mar 14 15:24:48 2013 +0200 +++ b/src/lib-index/mail-transaction-log-file.c Thu Mar 14 15:29:18 2013 +0200 @@ -1022,6 +1022,7 @@ case MAIL_TRANSACTION_FLAG_UPDATE: case MAIL_TRANSACTION_KEYWORD_UPDATE: case MAIL_TRANSACTION_KEYWORD_RESET: + case MAIL_TRANSACTION_ATTRIBUTE_UPDATE: /* these changes increase modseq */ *cur_modseq += 1; break; diff -r 9a8eaf97559d -r db0136374bb0 src/lib-index/mail-transaction-log-view.c --- a/src/lib-index/mail-transaction-log-view.c Thu Mar 14 15:24:48 2013 +0200 +++ b/src/lib-index/mail-transaction-log-view.c Thu Mar 14 15:29:18 2013 +0200 @@ -608,6 +608,40 @@ if ((i % 4) != 0) i += 4 - (i % 4); } + break; + } + case MAIL_TRANSACTION_ATTRIBUTE_UPDATE: { + const char *attr_changes = data; + unsigned int i; + + for (i = 0; i+2 < rec_size && attr_changes[i] != '\0'; ) { + if (attr_changes[i] != '+' && attr_changes[i] != '-') { + mail_transaction_log_file_set_corrupted(file, + "attribute update: Invalid prefix 0x%02x", + attr_changes[i]); + return FALSE; + } + i++; + if (attr_changes[i] != 'p' && attr_changes[i] != 's') { + mail_transaction_log_file_set_corrupted(file, + "attribute update: Invalid type 0x%02x", + attr_changes[i]); + return FALSE; + } + i++; + if (attr_changes[i] == '\0') { + mail_transaction_log_file_set_corrupted(file, + "attribute update: Empty key"); + return FALSE; + } + i += strlen(attr_changes+i) + 1; + } + if (i == 0 || (i < rec_size && attr_changes[i] != '\0')) { + mail_transaction_log_file_set_corrupted(file, + "attribute update doesn't end with NUL"); + return FALSE; + } + break; } default: break; diff -r 9a8eaf97559d -r db0136374bb0 src/lib-index/mail-transaction-log.h --- a/src/lib-index/mail-transaction-log.h Thu Mar 14 15:24:48 2013 +0200 +++ b/src/lib-index/mail-transaction-log.h Thu Mar 14 15:29:18 2013 +0200 @@ -44,8 +44,9 @@ MAIL_TRANSACTION_INDEX_DELETED = 0x00020000, MAIL_TRANSACTION_INDEX_UNDELETED = 0x00040000, MAIL_TRANSACTION_BOUNDARY = 0x00080000, + MAIL_TRANSACTION_ATTRIBUTE_UPDATE = 0x00100000, - MAIL_TRANSACTION_TYPE_MASK = 0x000fffff, + MAIL_TRANSACTION_TYPE_MASK = 0x0fffffff, #define MAIL_TRANSACTION_EXT_MASK \ (MAIL_TRANSACTION_EXT_INTRO | MAIL_TRANSACTION_EXT_RESET | \ From dovecot at dovecot.org Thu Mar 14 15:41:49 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 14 Mar 2013 15:41:49 +0200 Subject: dovecot-2.2: lib-storage: Changed mailbox_attribute_get/set() AP... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f3cd9e5cbe99 changeset: 16024:f3cd9e5cbe99 user: Timo Sirainen date: Thu Mar 14 15:32:14 2013 +0200 description: lib-storage: Changed mailbox_attribute_get/set() APIs to have a transaction and update index. The _get() doesn't currently actually use the transaction. It was mainly put there for future use where it could be useful. It's also possible that _iter() will need a transaction also. For now these decisions seem good enough. diffstat: src/lib-imap-urlauth/imap-urlauth-backend.c | 60 +++++++++++++++++++++---- src/lib-storage/index/index-attribute.c | 69 ++++++++++++++++++++++------ src/lib-storage/index/index-storage.c | 49 ++++++++++--------- src/lib-storage/index/index-storage.h | 4 +- src/lib-storage/index/index-transaction.c | 19 +++++++- src/lib-storage/mail-storage-private.h | 9 ++- src/lib-storage/mail-storage.c | 18 ++++--- src/lib-storage/mail-storage.h | 20 ++++++-- 8 files changed, 180 insertions(+), 68 deletions(-) diffs (truncated from 447 to 300 lines): diff -r db0136374bb0 -r f3cd9e5cbe99 src/lib-imap-urlauth/imap-urlauth-backend.c --- a/src/lib-imap-urlauth/imap-urlauth-backend.c Thu Mar 14 15:29:18 2013 +0200 +++ b/src/lib-imap-urlauth/imap-urlauth-backend.c Thu Mar 14 15:32:14 2013 +0200 @@ -12,11 +12,14 @@ #define IMAP_URLAUTH_KEY MAILBOX_ATTRIBUTE_PREFIX_DOVECOT"imap-urlauth" -int imap_urlauth_backend_get_mailbox_key(struct mailbox *box, bool create, - unsigned char mailbox_key_r[IMAP_URLAUTH_KEY_LEN], - const char **error_r, - enum mail_error *error_code_r) +static int +imap_urlauth_backend_trans_get_mailbox_key(struct mailbox_transaction_context *trans, + bool create, + unsigned char mailbox_key_r[IMAP_URLAUTH_KEY_LEN], + const char **error_r, + enum mail_error *error_code_r) { + struct mailbox *box = mailbox_transaction_get_mailbox(trans); struct mail_user *user = mail_storage_get_user(mailbox_get_storage(box)); struct mail_attribute_value urlauth_key; const char *mailbox_key_hex = NULL; @@ -26,7 +29,7 @@ *error_r = "Internal server error"; *error_code_r = MAIL_ERROR_TEMP; - ret = mailbox_attribute_get(box, MAIL_ATTRIBUTE_TYPE_PRIVATE, + ret = mailbox_attribute_get(trans, MAIL_ATTRIBUTE_TYPE_PRIVATE, IMAP_URLAUTH_KEY, &urlauth_key); if (ret < 0) return -1; @@ -44,7 +47,7 @@ random_fill(mailbox_key_r, IMAP_URLAUTH_KEY_LEN); mailbox_key_hex = binary_to_hex(mailbox_key_r, IMAP_URLAUTH_KEY_LEN); - ret = mailbox_attribute_set(box, MAIL_ATTRIBUTE_TYPE_PRIVATE, + ret = mailbox_attribute_set(trans, MAIL_ATTRIBUTE_TYPE_PRIVATE, IMAP_URLAUTH_KEY, mailbox_key_hex); if (ret < 0) return -1; @@ -69,10 +72,48 @@ return 1; } +int imap_urlauth_backend_get_mailbox_key(struct mailbox *box, bool create, + unsigned char mailbox_key_r[IMAP_URLAUTH_KEY_LEN], + const char **error_r, + enum mail_error *error_code_r) +{ + struct mailbox_transaction_context *t; + int ret; + + t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL); + ret = imap_urlauth_backend_trans_get_mailbox_key(t, create, mailbox_key_r, error_r, error_code_r); + if (mailbox_transaction_commit(&t) < 0) + ret = -1; + return ret; +} + int imap_urlauth_backend_reset_mailbox_key(struct mailbox *box) { - return mailbox_attribute_unset(box, MAIL_ATTRIBUTE_TYPE_PRIVATE, - IMAP_URLAUTH_KEY) < 0 ? -1 : 1; + struct mailbox_transaction_context *t; + int ret; + + t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL); + ret = mailbox_attribute_unset(t, MAIL_ATTRIBUTE_TYPE_PRIVATE, + IMAP_URLAUTH_KEY) < 0 ? -1 : 1; + if (mailbox_transaction_commit(&t) < 0) + ret = -1; + return ret; +} + +static int imap_urlauth_backend_mailbox_reset_key(struct mailbox *box) +{ + const char *errstr; + enum mail_error error; + + if (mailbox_open(box) < 0) { + errstr = mailbox_get_last_error(box, &error); + if (error == MAIL_ERROR_NOTFOUND || error == MAIL_ERROR_PERM) + return 0; + i_error("urlauth key reset: Couldn't open mailbox %s: %s", + mailbox_get_vname(box), errstr); + return -1; + } + return imap_urlauth_backend_reset_mailbox_key(box) < 0 ? -1 : 0; } int imap_urlauth_backend_reset_all_keys(struct mail_user *user) @@ -90,8 +131,7 @@ MAILBOX_LIST_ITER_RETURN_NO_FLAGS); while ((info = mailbox_list_iter_next(iter)) != NULL) { box = mailbox_alloc(info->ns->list, info->vname, 0); - if (mailbox_attribute_unset(box, MAIL_ATTRIBUTE_TYPE_PRIVATE, - IMAP_URLAUTH_KEY) < 0) + if (imap_urlauth_backend_mailbox_reset_key(box) < 0) ret = -1; mailbox_free(&box); } diff -r db0136374bb0 -r f3cd9e5cbe99 src/lib-storage/index/index-attribute.c --- a/src/lib-storage/index/index-attribute.c Thu Mar 14 15:29:18 2013 +0200 +++ b/src/lib-storage/index/index-attribute.c Thu Mar 14 15:32:14 2013 +0200 @@ -147,33 +147,66 @@ i_unreached(); } -int index_storage_attribute_set(struct mailbox *box, +static int +index_storage_attribute_get_dict_trans(struct mailbox_transaction_context *t, + enum mail_attribute_type type, + struct dict_transaction_context **dtrans_r, + const char **mailbox_prefix_r) +{ + struct dict_transaction_context **dtransp = NULL; + struct dict *dict; + + switch (type) { + case MAIL_ATTRIBUTE_TYPE_PRIVATE: + dtransp = &t->attr_pvt_trans; + break; + case MAIL_ATTRIBUTE_TYPE_SHARED: + dtransp = &t->attr_shared_trans; + break; + } + i_assert(dtransp != NULL); + + if (index_storage_get_dict(t->box, type, &dict, mailbox_prefix_r) < 0) + return -1; + *dtransp = *dtrans_r = dict_transaction_begin(dict); + return 0; +} + +int index_storage_attribute_set(struct mailbox_transaction_context *t, enum mail_attribute_type type, const char *key, const char *value) { struct dict_transaction_context *dtrans; - struct dict *dict; const char *mailbox_prefix; + bool pvt = type == MAIL_ATTRIBUTE_TYPE_PRIVATE; - if (index_storage_get_dict(box, type, &dict, &mailbox_prefix) < 0) + if (strncmp(key, MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT, + strlen(MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT)) == 0) { + mail_storage_set_error(t->box->storage, MAIL_ERROR_PARAMS, + "Internal attributes cannot be changed directly"); + return -1; + } + + if (index_storage_attribute_get_dict_trans(t, type, &dtrans, + &mailbox_prefix) < 0) return -1; T_BEGIN { - key = key_get_prefixed(type, mailbox_prefix, key); - dtrans = dict_transaction_begin(dict); - if (value != NULL) - dict_set(dtrans, key, value); - else - dict_unset(dtrans, key); + const char *prefixed_key = + key_get_prefixed(type, mailbox_prefix, key); + + if (value != NULL) { + dict_set(dtrans, prefixed_key, value); + mail_index_attribute_set(t->itrans, pvt, key); + } else { + dict_unset(dtrans, prefixed_key); + mail_index_attribute_unset(t->itrans, pvt, key); + } } T_END; - if (dict_transaction_commit(&dtrans) < 0) { - mail_storage_set_internal_error(box->storage); - return -1; - } return 0; } -int index_storage_attribute_get(struct mailbox *box, +int index_storage_attribute_get(struct mailbox_transaction_context *t, enum mail_attribute_type type, const char *key, struct mail_attribute_value *value_r) { @@ -183,14 +216,18 @@ memset(value_r, 0, sizeof(*value_r)); - if (index_storage_get_dict(box, type, &dict, &mailbox_prefix) < 0) + if (strncmp(key, MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT, + strlen(MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT)) == 0) + return 0; + + if (index_storage_get_dict(t->box, type, &dict, &mailbox_prefix) < 0) return -1; ret = dict_lookup(dict, pool_datastack_create(), key_get_prefixed(type, mailbox_prefix, key), &value_r->value); if (ret < 0) { - mail_storage_set_internal_error(box->storage); + mail_storage_set_internal_error(t->box->storage); return -1; } return ret; diff -r db0136374bb0 -r f3cd9e5cbe99 src/lib-storage/index/index-storage.c --- a/src/lib-storage/index/index-storage.c Thu Mar 14 15:29:18 2013 +0200 +++ b/src/lib-storage/index/index-storage.c Thu Mar 14 15:32:14 2013 +0200 @@ -601,7 +601,25 @@ return 0; } -static int mailbox_expunge_all_mails(struct mailbox *box) +static int +mailbox_delete_all_attributes(struct mailbox_transaction_context *t, + enum mail_attribute_type type) +{ + struct mailbox_attribute_iter *iter; + const char *key; + int ret = 0; + + iter = mailbox_attribute_iter_init(t->box, type, ""); + while ((key = mailbox_attribute_iter_next(iter)) != NULL) { + if (mailbox_attribute_unset(t, type, key) < 0) + ret = -1; + } + if (mailbox_attribute_iter_deinit(&iter) < 0) + ret = -1; + return ret; +} + +static int mailbox_expunge_all_data(struct mailbox *box) { struct mail_search_context *ctx; struct mailbox_transaction_context *t; @@ -624,26 +642,15 @@ mailbox_transaction_rollback(&t); return -1; } + + if (mailbox_delete_all_attributes(t, MAIL_ATTRIBUTE_TYPE_PRIVATE) < 0 || + mailbox_delete_all_attributes(t, MAIL_ATTRIBUTE_TYPE_SHARED) < 0) { + mailbox_transaction_rollback(&t); + return -1; + } return mailbox_transaction_commit(&t); } -static int -mailbox_delete_all_attributes(struct mailbox *box, enum mail_attribute_type type) -{ - struct mailbox_attribute_iter *iter; - const char *key; - int ret = 0; - - iter = mailbox_attribute_iter_init(box, type, ""); - while ((key = mailbox_attribute_iter_next(iter)) != NULL) { - if (mailbox_attribute_unset(box, type, key) < 0) - ret = -1; - } - if (mailbox_attribute_iter_deinit(&iter) < 0) - ret = -1; - return ret; -} - int index_storage_mailbox_delete(struct mailbox *box) { struct mailbox_metadata metadata; @@ -672,11 +679,7 @@ */ if (!box->deleting_must_be_empty) { - if (mailbox_expunge_all_mails(box) < 0) - return -1; - if (mailbox_delete_all_attributes(box, MAIL_ATTRIBUTE_TYPE_PRIVATE) < 0) - return -1; - if (mailbox_delete_all_attributes(box, MAIL_ATTRIBUTE_TYPE_SHARED) < 0) + if (mailbox_expunge_all_data(box) < 0) return -1; } if (mailbox_mark_index_deleted(box, TRUE) < 0) diff -r db0136374bb0 -r f3cd9e5cbe99 src/lib-storage/index/index-storage.h --- a/src/lib-storage/index/index-storage.h Thu Mar 14 15:29:18 2013 +0200 +++ b/src/lib-storage/index/index-storage.h Thu Mar 14 15:32:14 2013 +0200 @@ -116,10 +116,10 @@ enum mailbox_metadata_items items, struct mailbox_metadata *metadata_r); -int index_storage_attribute_set(struct mailbox *box, +int index_storage_attribute_set(struct mailbox_transaction_context *t, enum mail_attribute_type type, const char *key, const char *value); -int index_storage_attribute_get(struct mailbox *box, +int index_storage_attribute_get(struct mailbox_transaction_context *t, enum mail_attribute_type type, const char *key, struct mail_attribute_value *value_r); struct mailbox_attribute_iter * diff -r db0136374bb0 -r f3cd9e5cbe99 src/lib-storage/index/index-transaction.c --- a/src/lib-storage/index/index-transaction.c Thu Mar 14 15:29:18 2013 +0200 From dovecot at dovecot.org Thu Mar 14 15:41:49 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 14 Mar 2013 15:41:49 +0200 Subject: dovecot-2.2: dsync: Added support for syncing mailbox attributes. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c6082de4bf5b changeset: 16025:c6082de4bf5b user: Timo Sirainen date: Thu Mar 14 15:41:09 2013 +0200 description: dsync: Added support for syncing mailbox attributes. diffstat: src/doveadm/dsync/Makefile.am | 1 + src/doveadm/dsync/dsync-brain-mailbox.c | 8 +- src/doveadm/dsync/dsync-brain-mails.c | 36 ++++++ src/doveadm/dsync/dsync-brain-private.h | 1 + src/doveadm/dsync/dsync-ibc-pipe.c | 34 ++++++ src/doveadm/dsync/dsync-ibc-private.h | 6 + src/doveadm/dsync/dsync-ibc-stream.c | 136 ++++++++++++++++++++++-- src/doveadm/dsync/dsync-ibc.c | 17 +++ src/doveadm/dsync/dsync-ibc.h | 8 + src/doveadm/dsync/dsync-mailbox-export.c | 120 +++++++++++++++++++++- src/doveadm/dsync/dsync-mailbox-export.h | 3 +- src/doveadm/dsync/dsync-mailbox-import.c | 115 +++++++++++++++++++++ src/doveadm/dsync/dsync-mailbox-import.h | 3 + src/doveadm/dsync/dsync-mailbox.c | 17 +++ src/doveadm/dsync/dsync-mailbox.h | 16 ++ src/doveadm/dsync/dsync-transaction-log-scan.c | 72 +++++++++++++ src/doveadm/dsync/dsync-transaction-log-scan.h | 5 + 17 files changed, 578 insertions(+), 20 deletions(-) diffs (truncated from 1002 to 300 lines): diff -r f3cd9e5cbe99 -r c6082de4bf5b src/doveadm/dsync/Makefile.am --- a/src/doveadm/dsync/Makefile.am Thu Mar 14 15:32:14 2013 +0200 +++ b/src/doveadm/dsync/Makefile.am Thu Mar 14 15:41:09 2013 +0200 @@ -21,6 +21,7 @@ dsync-brain-mails.c \ dsync-deserializer.c \ dsync-mail.c \ + dsync-mailbox.c \ dsync-mailbox-import.c \ dsync-mailbox-export.c \ dsync-mailbox-state.c \ diff -r f3cd9e5cbe99 -r c6082de4bf5b src/doveadm/dsync/dsync-brain-mailbox.c --- a/src/doveadm/dsync/dsync-brain-mailbox.c Thu Mar 14 15:32:14 2013 +0200 +++ b/src/doveadm/dsync/dsync-brain-mailbox.c Thu Mar 14 15:41:09 2013 +0200 @@ -84,7 +84,7 @@ { if (brain->backup_send) { /* we have an exporter, but no importer. */ - brain->box_send_state = DSYNC_BOX_STATE_CHANGES; + brain->box_send_state = DSYNC_BOX_STATE_ATTRIBUTES; brain->box_recv_state = brain->mail_requests ? DSYNC_BOX_STATE_MAIL_REQUESTS : DSYNC_BOX_STATE_RECV_LAST_COMMON; @@ -93,10 +93,10 @@ brain->box_send_state = brain->mail_requests ? DSYNC_BOX_STATE_MAIL_REQUESTS : DSYNC_BOX_STATE_DONE; - brain->box_recv_state = DSYNC_BOX_STATE_CHANGES; + brain->box_recv_state = DSYNC_BOX_STATE_ATTRIBUTES; } else { - brain->box_send_state = DSYNC_BOX_STATE_CHANGES; - brain->box_recv_state = DSYNC_BOX_STATE_CHANGES; + brain->box_send_state = DSYNC_BOX_STATE_ATTRIBUTES; + brain->box_recv_state = DSYNC_BOX_STATE_ATTRIBUTES; } } diff -r f3cd9e5cbe99 -r c6082de4bf5b src/doveadm/dsync/dsync-brain-mails.c --- a/src/doveadm/dsync/dsync-brain-mails.c Thu Mar 14 15:32:14 2013 +0200 +++ b/src/doveadm/dsync/dsync-brain-mails.c Thu Mar 14 15:41:09 2013 +0200 @@ -11,6 +11,7 @@ const char *dsync_box_state_names[DSYNC_BOX_STATE_DONE+1] = { "mailbox", "changes", + "attributes", "mail_requests", "mails", "recv_last_common", @@ -59,6 +60,34 @@ return TRUE; } +static bool dsync_brain_recv_mailbox_attribute(struct dsync_brain *brain) +{ + const struct dsync_mailbox_attribute *attr; + enum dsync_ibc_recv_ret ret; + + if ((ret = dsync_ibc_recv_mailbox_attribute(brain->ibc, &attr)) == 0) + return FALSE; + if (ret == DSYNC_IBC_RECV_RET_FINISHED) { + brain->box_recv_state = DSYNC_BOX_STATE_CHANGES; + return TRUE; + } + if (dsync_mailbox_import_attribute(brain->box_importer, attr) < 0) + brain->failed = TRUE; + return TRUE; +} + +static void dsync_brain_send_mailbox_attribute(struct dsync_brain *brain) +{ + const struct dsync_mailbox_attribute *attr; + + while ((attr = dsync_mailbox_export_next_attr(brain->box_exporter)) != NULL) { + if (dsync_ibc_send_mailbox_attribute(brain->ibc, attr) == 0) + return; + } + dsync_ibc_send_end_of_list(brain->ibc); + brain->box_send_state = DSYNC_BOX_STATE_CHANGES; +} + static bool dsync_brain_recv_mail_change(struct dsync_brain *brain) { const struct dsync_mail_change *change; @@ -278,6 +307,9 @@ case DSYNC_BOX_STATE_MAILBOX: changed = dsync_brain_master_sync_recv_mailbox(brain); break; + case DSYNC_BOX_STATE_ATTRIBUTES: + changed = dsync_brain_recv_mailbox_attribute(brain); + break; case DSYNC_BOX_STATE_CHANGES: changed = dsync_brain_recv_mail_change(brain); break; @@ -299,6 +331,10 @@ case DSYNC_BOX_STATE_MAILBOX: /* wait for mailbox to be received first */ break; + case DSYNC_BOX_STATE_ATTRIBUTES: + dsync_brain_send_mailbox_attribute(brain); + changed = TRUE; + break; case DSYNC_BOX_STATE_CHANGES: dsync_brain_send_mail_change(brain); changed = TRUE; diff -r f3cd9e5cbe99 -r c6082de4bf5b src/doveadm/dsync/dsync-brain-private.h --- a/src/doveadm/dsync/dsync-brain-private.h Thu Mar 14 15:32:14 2013 +0200 +++ b/src/doveadm/dsync/dsync-brain-private.h Thu Mar 14 15:41:09 2013 +0200 @@ -38,6 +38,7 @@ enum dsync_box_state { DSYNC_BOX_STATE_MAILBOX, DSYNC_BOX_STATE_CHANGES, + DSYNC_BOX_STATE_ATTRIBUTES, DSYNC_BOX_STATE_MAIL_REQUESTS, DSYNC_BOX_STATE_MAILS, DSYNC_BOX_STATE_RECV_LAST_COMMON, diff -r f3cd9e5cbe99 -r c6082de4bf5b src/doveadm/dsync/dsync-ibc-pipe.c --- a/src/doveadm/dsync/dsync-ibc-pipe.c Thu Mar 14 15:32:14 2013 +0200 +++ b/src/doveadm/dsync/dsync-ibc-pipe.c Thu Mar 14 15:41:09 2013 +0200 @@ -16,6 +16,7 @@ ITEM_MAILBOX_TREE_NODE, ITEM_MAILBOX_DELETE, ITEM_MAILBOX, + ITEM_MAILBOX_ATTRIBUTE, ITEM_MAIL_CHANGE, ITEM_MAIL_REQUEST, ITEM_MAIL @@ -31,6 +32,7 @@ struct dsync_mailbox_node node; guid_128_t mailbox_guid; struct dsync_mailbox dsync_box; + struct dsync_mailbox_attribute attr; struct dsync_mail_change change; struct dsync_mail_request request; struct dsync_mail mail; @@ -84,6 +86,7 @@ case ITEM_HANDSHAKE: case ITEM_MAILBOX: case ITEM_MAILBOX_TREE_NODE: + case ITEM_MAILBOX_ATTRIBUTE: case ITEM_MAIL_CHANGE: case ITEM_MAIL_REQUEST: case ITEM_MAIL: @@ -342,6 +345,35 @@ } static void +dsync_ibc_pipe_send_mailbox_attribute(struct dsync_ibc *ibc, + const struct dsync_mailbox_attribute *attr) +{ + struct dsync_ibc_pipe *pipe = (struct dsync_ibc_pipe *)ibc; + struct item *item; + + item = dsync_ibc_pipe_push_item(pipe->remote, ITEM_MAILBOX_ATTRIBUTE); + dsync_mailbox_attribute_dup(item->pool, attr, &item->u.attr); +} + +static enum dsync_ibc_recv_ret +dsync_ibc_pipe_recv_mailbox_attribute(struct dsync_ibc *ibc, + const struct dsync_mailbox_attribute **attr_r) +{ + struct dsync_ibc_pipe *pipe = (struct dsync_ibc_pipe *)ibc; + struct item *item; + + if (dsync_ibc_pipe_try_pop_eol(pipe)) + return DSYNC_IBC_RECV_RET_FINISHED; + + item = dsync_ibc_pipe_pop_item(pipe, ITEM_MAILBOX_ATTRIBUTE); + if (item == NULL) + return DSYNC_IBC_RECV_RET_TRYAGAIN; + + *attr_r = &item->u.attr; + return DSYNC_IBC_RECV_RET_OK; +} + +static void dsync_ibc_pipe_send_change(struct dsync_ibc *ibc, const struct dsync_mail_change *change) { @@ -470,6 +502,8 @@ dsync_ibc_pipe_recv_mailbox_deletes, dsync_ibc_pipe_send_mailbox, dsync_ibc_pipe_recv_mailbox, + dsync_ibc_pipe_send_mailbox_attribute, + dsync_ibc_pipe_recv_mailbox_attribute, dsync_ibc_pipe_send_change, dsync_ibc_pipe_recv_change, dsync_ibc_pipe_send_mail_request, diff -r f3cd9e5cbe99 -r c6082de4bf5b src/doveadm/dsync/dsync-ibc-private.h --- a/src/doveadm/dsync/dsync-ibc-private.h Thu Mar 14 15:32:14 2013 +0200 +++ b/src/doveadm/dsync/dsync-ibc-private.h Thu Mar 14 15:41:09 2013 +0200 @@ -43,6 +43,12 @@ (*recv_mailbox)(struct dsync_ibc *ibc, const struct dsync_mailbox **dsync_box_r); + void (*send_mailbox_attribute)(struct dsync_ibc *ibc, + const struct dsync_mailbox_attribute *attr); + enum dsync_ibc_recv_ret + (*recv_mailbox_attribute)(struct dsync_ibc *ibc, + const struct dsync_mailbox_attribute **attr_r); + void (*send_change)(struct dsync_ibc *ibc, const struct dsync_mail_change *change); enum dsync_ibc_recv_ret diff -r f3cd9e5cbe99 -r c6082de4bf5b src/doveadm/dsync/dsync-ibc-stream.c --- a/src/doveadm/dsync/dsync-ibc-stream.c Thu Mar 14 15:32:14 2013 +0200 +++ b/src/doveadm/dsync/dsync-ibc-stream.c Thu Mar 14 15:41:09 2013 +0200 @@ -28,7 +28,10 @@ #define DSYNC_IBC_STREAM_OUTBUF_THROTTLE_SIZE (1024*128) #define DSYNC_PROTOCOL_VERSION_MAJOR 3 -#define DSYNC_HANDSHAKE_VERSION "VERSION\tdsync\t3\t0\n" +#define DSYNC_PROTOCOL_VERSION_MINOR 1 +#define DSYNC_HANDSHAKE_VERSION "VERSION\tdsync\t3\t1\n" + +#define DSYNC_PROTOCOL_MINOR_HAVE_ATTRIBUTES 1 enum item_type { ITEM_NONE, @@ -40,6 +43,7 @@ ITEM_MAILBOX_DELETE, ITEM_MAILBOX, + ITEM_MAILBOX_ATTRIBUTE, ITEM_MAIL_CHANGE, ITEM_MAIL_REQUEST, ITEM_MAIL, @@ -92,6 +96,11 @@ "first_recent_uid highest_modseq highest_pvt_modseq", .optional_keys = "mailbox_lost cache_fields have_guids" }, + { .name = "mailbox_attribute", + .chr = 'A', + .required_keys = "type key", + .optional_keys = "value deleted last_change modseq" + }, { .name = "mail_change", .chr = 'C', .required_keys = "type uid", @@ -126,6 +135,7 @@ struct io *io; struct timeout *to; + unsigned int minor_version; struct dsync_serializer *serializers[ITEM_END_OF_LIST]; struct dsync_deserializer *deserializers[ITEM_END_OF_LIST]; @@ -195,16 +205,9 @@ &data, &size, 0)) > 0) { add = '\0'; for (i = 0; i < size; i++) { - if (data[i] == '\n') { - if ((i == 0 && ibc->mail_output_last != '\r') || - (i > 0 && data[i-1] != '\r')) { - /* missing CR */ - add = '\r'; - break; - } - } else if (data[i] == '.' && - ((i == 0 && ibc->mail_output_last == '\n') || - (i > 0 && data[i-1] == '\n'))) { + if (data[i] == '.' && + ((i == 0 && ibc->mail_output_last == '\n') || + (i > 0 && data[i-1] == '\n'))) { /* escape the dot */ add = '.'; break; @@ -243,7 +246,8 @@ return -1; } - /* finished sending the stream */ + /* finished sending the stream. use "CRLF." instead of "LF." just in + case we're sending binary data that ends with CR. */ o_stream_nsend_str(ibc->output, "\r\n.\r\n"); i_stream_unref(&ibc->mail_output); return 1; @@ -429,8 +433,9 @@ return TRUE; if (!ibc->version_received) { - if (!version_string_verify(line, "dsync", - DSYNC_PROTOCOL_VERSION_MAJOR)) { + if (!version_string_verify_full(line, "dsync", + DSYNC_PROTOCOL_VERSION_MAJOR, + &ibc->minor_version)) { dsync_ibc_input_error(ibc, NULL, "Remote dsync doesn't use compatible protocol"); return DSYNC_IBC_RECV_RET_TRYAGAIN; @@ -1185,6 +1190,107 @@ } static void +dsync_ibc_stream_send_mailbox_attribute(struct dsync_ibc *_ibc, + const struct dsync_mailbox_attribute *attr) +{ + struct dsync_ibc_stream *ibc = (struct dsync_ibc_stream *)_ibc; + struct dsync_serializer_encoder *encoder; + string_t *str = t_str_new(128); + char type[2]; + From dovecot at dovecot.org Thu Mar 14 15:41:49 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 14 Mar 2013 15:41:49 +0200 Subject: dovecot-2.2: acl: Added ACL checks for attributes. Added ACL <->... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3ba8fa6d3cc2 changeset: 16026:3ba8fa6d3cc2 user: Timo Sirainen date: Thu Mar 14 15:41:39 2013 +0200 description: acl: Added ACL checks for attributes. Added ACL <-> mailbox attribute mapping. The ACL checks will be useful once IMAP METADATA extension is finished. The mapping is used by dsync to sync ACLs via generic attribute syncing. diffstat: src/plugins/acl/Makefile.am | 1 + src/plugins/acl/acl-api-private.h | 5 + src/plugins/acl/acl-api.c | 100 ++++++++++++++ src/plugins/acl/acl-api.h | 9 + src/plugins/acl/acl-attributes.c | 234 +++++++++++++++++++++++++++++++++ src/plugins/acl/acl-backend-vfile.c | 22 +++ src/plugins/acl/acl-mailbox.c | 60 +++++++- src/plugins/acl/acl-plugin.h | 8 + src/plugins/acl/acl-storage.h | 19 ++ src/plugins/acl/doveadm-acl.c | 121 +++------------- src/plugins/imap-acl/imap-acl-plugin.c | 29 +++- 11 files changed, 499 insertions(+), 109 deletions(-) diffs (truncated from 820 to 300 lines): diff -r c6082de4bf5b -r 3ba8fa6d3cc2 src/plugins/acl/Makefile.am --- a/src/plugins/acl/Makefile.am Thu Mar 14 15:41:09 2013 +0200 +++ b/src/plugins/acl/Makefile.am Thu Mar 14 15:41:39 2013 +0200 @@ -18,6 +18,7 @@ lib01_acl_plugin_la_SOURCES = \ acl-api.c \ + acl-attributes.c \ acl-backend.c \ acl-backend-vfile.c \ acl-backend-vfile-acllist.c \ diff -r c6082de4bf5b -r 3ba8fa6d3cc2 src/plugins/acl/acl-api-private.h --- a/src/plugins/acl/acl-api-private.h Thu Mar 14 15:41:09 2013 +0200 +++ b/src/plugins/acl/acl-api-private.h Thu Mar 14 15:41:39 2013 +0200 @@ -32,6 +32,7 @@ int (*object_refresh_cache)(struct acl_object *aclobj); int (*object_update)(struct acl_object *aclobj, const struct acl_rights_update *update); + int (*last_changed)(struct acl_object *aclobj, time_t *last_changed_r); struct acl_object_list_iter * (*object_list_init)(struct acl_object *aclobj); @@ -86,5 +87,9 @@ bool acl_rights_has_nonowner_lookup_changes(const struct acl_rights *rights); int acl_identifier_parse(const char *line, struct acl_rights *rights); +int acl_rights_update_import(struct acl_rights_update *update, + const char *id, const char *const *rights, + const char **error_r); +const char *acl_rights_export(const struct acl_rights *rights); #endif diff -r c6082de4bf5b -r 3ba8fa6d3cc2 src/plugins/acl/acl-api.c --- a/src/plugins/acl/acl-api.c Thu Mar 14 15:41:09 2013 +0200 +++ b/src/plugins/acl/acl-api.c Thu Mar 14 15:41:39 2013 +0200 @@ -1,6 +1,7 @@ /* Copyright (c) 2006-2013 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "array.h" #include "str.h" #include "hash.h" #include "mail-user.h" @@ -122,6 +123,11 @@ pool_datastack_create()); } +int acl_object_last_changed(struct acl_object *aclobj, time_t *last_changed_r) +{ + return aclobj->backend->v.last_changed(aclobj, last_changed_r); +} + int acl_object_update(struct acl_object *aclobj, const struct acl_rights_update *update) { @@ -205,6 +211,100 @@ } } +const char *acl_rights_get_id(const struct acl_rights *right) +{ + string_t *str = t_str_new(32); + + acl_rights_write_id(str, right); + return str_c(str); +} + +static bool is_standard_right(const char *name) +{ + unsigned int i; + + for (i = 0; all_mailbox_rights[i] != NULL; i++) { + if (strcmp(all_mailbox_rights[i], name) == 0) + return TRUE; + } + return FALSE; +} + +int acl_rights_update_import(struct acl_rights_update *update, + const char *id, const char *const *rights, + const char **error_r) +{ + ARRAY_TYPE(const_string) dest_rights, dest_neg_rights, *dest; + unsigned int i, j; + + if (acl_identifier_parse(id, &update->rights) < 0) { + *error_r = t_strdup_printf("Invalid ID: %s", id); + return -1; + } + if (rights == NULL) { + update->modify_mode = ACL_MODIFY_MODE_CLEAR; + update->neg_modify_mode = ACL_MODIFY_MODE_CLEAR; + return 0; + } + + t_array_init(&dest_rights, 8); + t_array_init(&dest_neg_rights, 8); + for (i = 0; rights[i] != NULL; i++) { + const char *right = rights[i]; + + if (right[0] != '-') + dest = &dest_rights; + else { + right++; + dest = &dest_neg_rights; + } + if (strcmp(right, "all") != 0) { + if (*right == ':') { + /* non-standard right */ + right++; + array_append(dest, &right, 1); + } else if (is_standard_right(right)) { + array_append(dest, &right, 1); + } else { + *error_r = t_strdup_printf("Invalid right '%s'", + right); + return -1; + } + } else { + for (j = 0; all_mailbox_rights[j] != NULL; j++) + array_append(dest, &all_mailbox_rights[j], 1); + } + } + if (array_count(&dest_rights) > 0) { + array_append_zero(&dest_rights); + update->rights.rights = array_idx(&dest_rights, 0); + } else if (update->modify_mode == ACL_MODIFY_MODE_REPLACE) { + update->modify_mode = ACL_MODIFY_MODE_CLEAR; + } + if (array_count(&dest_neg_rights) > 0) { + array_append_zero(&dest_neg_rights); + update->rights.neg_rights = array_idx(&dest_neg_rights, 0); + } else if (update->neg_modify_mode == ACL_MODIFY_MODE_REPLACE) { + update->neg_modify_mode = ACL_MODIFY_MODE_CLEAR; + } + return 0; +} + +const char *acl_rights_export(const struct acl_rights *rights) +{ + string_t *str = t_str_new(128); + + if (rights->rights != NULL) + str_append(str, t_strarray_join(rights->rights, " ")); + if (rights->neg_rights != NULL) { + if (str_len(str) > 0) + str_append_c(str, ' '); + str_append_c(str, '-'); + str_append(str, t_strarray_join(rights->neg_rights, " -")); + } + return str_c(str); +} + bool acl_rights_has_nonowner_lookup_changes(const struct acl_rights *rights) { const char *const *p; diff -r c6082de4bf5b -r 3ba8fa6d3cc2 src/plugins/acl/acl-api.h --- a/src/plugins/acl/acl-api.h Thu Mar 14 15:41:09 2013 +0200 +++ b/src/plugins/acl/acl-api.h Thu Mar 14 15:41:39 2013 +0200 @@ -30,6 +30,9 @@ /* Allow changing ACL state in this mailbox */ #define MAIL_ACL_ADMIN "admin" +#define MAILBOX_ATTRIBUTE_PREFIX_ACL \ + MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT"acl/" + /* ACL identifiers in override order */ enum acl_id_type { /* Anyone's rights, including anonymous's. @@ -138,6 +141,9 @@ const char *const **rights_r); /* Returns the default rights for the object. */ const char *const *acl_object_get_default_rights(struct acl_object *aclobj); +/* Returns timestamp of when the ACLs were last changed for this object, + or 0 = never. */ +int acl_object_last_changed(struct acl_object *aclobj, time_t *last_changed_r); /* Update ACL of given object. */ int acl_object_update(struct acl_object *aclobj, @@ -149,4 +155,7 @@ struct acl_rights *rights_r); void acl_object_list_deinit(struct acl_object_list_iter **iter); +/* Returns the canonical ID for the right. */ +const char *acl_rights_get_id(const struct acl_rights *right); + #endif diff -r c6082de4bf5b -r 3ba8fa6d3cc2 src/plugins/acl/acl-attributes.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plugins/acl/acl-attributes.c Thu Mar 14 15:41:39 2013 +0200 @@ -0,0 +1,234 @@ +/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "str.h" +#include "mail-storage-private.h" +#include "acl-api-private.h" +#include "acl-plugin.h" +#include "acl-storage.h" + +struct acl_mailbox_attribute_iter { + struct mailbox_attribute_iter iter; + struct mailbox_attribute_iter *super; + + struct acl_object_list_iter *acl_iter; + string_t *acl_name; + + bool failed; +}; + +static int acl_attribute_update_acl(struct mailbox_transaction_context *t, + const char *key, const char *value) +{ + const char *id, *const *rights, *error; + struct acl_rights_update update; + + /* for now allow only admin (=dsync) to update ACLs this way. + if this check is removed, it should be replaced by a setting, since + some admins may still have configured Dovecot using dovecot-acl + files directly that they don't want users to update. and in any case + ACL_STORAGE_RIGHT_ADMIN must be checked then. */ + if (!t->box->storage->user->admin) { + mail_storage_set_error(t->box->storage, MAIL_ERROR_PERM, + MAIL_ERRSTR_NO_PERMISSION); + return -1; + } + + memset(&update, 0, sizeof(update)); + update.modify_mode = ACL_MODIFY_MODE_REPLACE; + update.neg_modify_mode = ACL_MODIFY_MODE_REPLACE; + id = key + strlen(MAILBOX_ATTRIBUTE_PREFIX_ACL); + rights = value == NULL ? NULL : t_strsplit(value, " "); + if (acl_rights_update_import(&update, id, rights, &error) < 0) { + mail_storage_set_error(t->box->storage, MAIL_ERROR_PARAMS, error); + return -1; + } + /* FIXME: this should actually be done only at commit().. */ + return acl_mailbox_update_acl(t, &update); +} + +static int acl_attribute_get_acl(struct mailbox *box, const char *key, + struct mail_attribute_value *value_r) +{ + struct acl_object *aclobj = acl_mailbox_get_aclobj(box); + struct acl_object_list_iter *iter; + struct acl_rights rights, wanted_rights; + const char *id; + int ret; + + memset(value_r, 0, sizeof(*value_r)); + + if (!box->storage->user->admin) { + mail_storage_set_error(box->storage, MAIL_ERROR_PERM, + MAIL_ERRSTR_NO_PERMISSION); + return -1; + } + /* set last_change for all ACL objects, even if they don't exist + (because they could have been removed by the last change, and dsync + can use this information) */ + (void)acl_object_last_changed(aclobj, &value_r->last_change); + + memset(&wanted_rights, 0, sizeof(wanted_rights)); + id = key + strlen(MAILBOX_ATTRIBUTE_PREFIX_ACL); + if (acl_identifier_parse(id, &wanted_rights) < 0) { + mail_storage_set_error(box->storage, MAIL_ERROR_PARAMS, + t_strdup_printf("Invalid ID: %s", id)); + return -1; + } + + iter = acl_object_list_init(aclobj); + while ((ret = acl_object_list_next(iter, &rights)) > 0) { + if (!rights.global && + rights.id_type == wanted_rights.id_type && + null_strcmp(rights.identifier, wanted_rights.identifier) == 0) { + value_r->value = acl_rights_export(&rights); + break; + } + } + if (ret < 0) + mail_storage_set_internal_error(box->storage); + acl_object_list_deinit(&iter); + return ret; +} + +static int acl_have_attribute_rights(struct mailbox *box) +{ + int ret; + + /* RFC 5464: + + When the ACL extension [RFC4314] is present, users can only set and + retrieve private or shared mailbox annotations on a mailbox on which + they have the "l" right and any one of the "r", "s", "w", "i", or "p" + rights. + */ + ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_LOOKUP); + if (ret <= 0) { + if (ret < 0) + return -1; + mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND, From dovecot at dovecot.org Fri Mar 15 21:49:51 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 15 Mar 2013 21:49:51 +0200 Subject: dovecot-2.2: Compile fix on non-gcc/clang. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/afdad7fbe8a6 changeset: 16027:afdad7fbe8a6 user: Timo Sirainen date: Fri Mar 15 20:49:39 2013 +0100 description: Compile fix on non-gcc/clang. diffstat: src/lib/istream-chain.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (18 lines): diff -r 3ba8fa6d3cc2 -r afdad7fbe8a6 src/lib/istream-chain.c --- a/src/lib/istream-chain.c Thu Mar 14 15:41:39 2013 +0200 +++ b/src/lib/istream-chain.c Fri Mar 15 20:49:39 2013 +0100 @@ -58,12 +58,12 @@ void i_stream_chain_append(struct istream_chain *chain, struct istream *stream) { - return i_stream_chain_append_internal(chain, stream); + i_stream_chain_append_internal(chain, stream); } void i_stream_chain_append_eof(struct istream_chain *chain) { - return i_stream_chain_append_internal(chain, NULL); + i_stream_chain_append_internal(chain, NULL); } static void From dovecot at dovecot.org Fri Mar 15 22:56:46 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 15 Mar 2013 22:56:46 +0200 Subject: dovecot-2.2: Compile fix on non-gcc/clang. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5f14a12a1700 changeset: 16028:5f14a12a1700 user: Timo Sirainen date: Fri Mar 15 21:55:40 2013 +0100 description: Compile fix on non-gcc/clang. diffstat: src/lib-storage/index/maildir/maildir-uidlist.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (19 lines): diff -r afdad7fbe8a6 -r 5f14a12a1700 src/lib-storage/index/maildir/maildir-uidlist.c --- a/src/lib-storage/index/maildir/maildir-uidlist.c Fri Mar 15 20:49:39 2013 +0100 +++ b/src/lib-storage/index/maildir/maildir-uidlist.c Fri Mar 15 21:55:40 2013 +0100 @@ -1213,13 +1213,13 @@ enum maildir_uidlist_rec_ext_key key, const char *value) { - return maildir_uidlist_set_ext_internal(uidlist, uid, key, value); + maildir_uidlist_set_ext_internal(uidlist, uid, key, value); } void maildir_uidlist_unset_ext(struct maildir_uidlist *uidlist, uint32_t uid, enum maildir_uidlist_rec_ext_key key) { - return maildir_uidlist_set_ext_internal(uidlist, uid, key, NULL); + maildir_uidlist_set_ext_internal(uidlist, uid, key, NULL); } static void From dovecot at dovecot.org Fri Mar 15 22:59:00 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 15 Mar 2013 22:59:00 +0200 Subject: dovecot-2.2: lib-master: include unistd.h for master_getopt() us... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/69c26a9e3be5 changeset: 16029:69c26a9e3be5 user: Timo Sirainen date: Fri Mar 15 21:58:51 2013 +0100 description: lib-master: include unistd.h for master_getopt() users. diffstat: src/lib-master/master-service.h | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 5f14a12a1700 -r 69c26a9e3be5 src/lib-master/master-service.h --- a/src/lib-master/master-service.h Fri Mar 15 21:55:40 2013 +0100 +++ b/src/lib-master/master-service.h Fri Mar 15 21:58:51 2013 +0100 @@ -3,6 +3,8 @@ #include "net.h" +#include /* for getopt() opt* variables */ + enum master_service_flags { /* stdin/stdout already contains a client which we want to serve */ MASTER_SERVICE_FLAG_STD_CLIENT = 0x01, From dovecot at dovecot.org Mon Mar 18 15:47:25 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 18 Mar 2013 15:47:25 +0200 Subject: dovecot-2.2: istream-qp-decoder: Fixed assert-crashing with buff... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ee7352f46d1e changeset: 16031:ee7352f46d1e user: Timo Sirainen date: Mon Mar 18 15:47:14 2013 +0200 description: istream-qp-decoder: Fixed assert-crashing with buffer size allocations. The original implementation was copy&pasted from istream-base64-decoder without enough thinking.. diffstat: src/lib-mail/istream-qp-decoder.c | 20 ++++++++++---------- 1 files changed, 10 insertions(+), 10 deletions(-) diffs (66 lines): diff -r 689dbeadf168 -r ee7352f46d1e src/lib-mail/istream-qp-decoder.c --- a/src/lib-mail/istream-qp-decoder.c Mon Mar 18 15:46:16 2013 +0200 +++ b/src/lib-mail/istream-qp-decoder.c Mon Mar 18 15:47:14 2013 +0200 @@ -22,8 +22,6 @@ return 1; } - /* we have less than one qp block. - see if there is more data available. */ ret = i_stream_read(stream->parent); if (ret <= 0) { stream->istream.stream_errno = stream->parent->stream_errno; @@ -35,7 +33,7 @@ } static int -i_stream_qp_try_decode_block(struct qp_decoder_istream *bstream, bool eof) +i_stream_qp_try_decode_input(struct qp_decoder_istream *bstream, bool eof) { struct istream_private *stream = &bstream->istream; const unsigned char *data; @@ -47,13 +45,15 @@ if (size == 0) return 0; - i_stream_try_alloc(stream, (size+3)/4*3, &avail); + /* the decoded quoted-printable content can never be larger than the + encoded content. at worst they are equal. */ + i_stream_try_alloc(stream, size, &avail); buffer_avail = stream->buffer_size - stream->pos; - if ((size + 3) / 4 * 3 > buffer_avail) { + if (size > buffer_avail) { /* can't fit everything to destination buffer. write as much as we can. */ - size = (buffer_avail / 3) * 4; + size = buffer_avail; if (size == 0) return -2; } @@ -86,21 +86,21 @@ if (ret != -1 || stream->istream.stream_errno != 0) return 0; - ret = i_stream_qp_try_decode_block(bstream, TRUE); + ret = i_stream_qp_try_decode_input(bstream, TRUE); if (ret == 0) { /* ended with =[whitespace] but without LF */ stream->istream.eof = TRUE; return -1; } - /* qp input with a partial block */ + /* partial qp input */ i_assert(ret < 0); stream->istream.stream_errno = EINVAL; return -1; } - /* encode as many blocks as fits into destination buffer */ + /* encode as much data as fits into destination buffer */ pre_count = stream->pos - stream->skip; - while ((ret = i_stream_qp_try_decode_block(bstream, FALSE)) > 0) ; + while ((ret = i_stream_qp_try_decode_input(bstream, FALSE)) > 0) ; post_count = stream->pos - stream->skip; } while (ret == 0 && pre_count == post_count); From dovecot at dovecot.org Mon Mar 18 15:47:25 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 18 Mar 2013 15:47:25 +0200 Subject: dovecot-2.2: quoted-printable decoding: Don't add CR if it wasn'... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/689dbeadf168 changeset: 16030:689dbeadf168 user: Timo Sirainen date: Mon Mar 18 15:46:16 2013 +0200 description: quoted-printable decoding: Don't add CR if it wasn't in input. This guarantees that the decoded Q-P won't be larger than its input. diffstat: src/lib-mail/quoted-printable.c | 12 +++++++++--- src/lib-mail/test-quoted-printable.c | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diffs (46 lines): diff -r 69c26a9e3be5 -r 689dbeadf168 src/lib-mail/quoted-printable.c --- a/src/lib-mail/quoted-printable.c Fri Mar 15 21:58:51 2013 +0100 +++ b/src/lib-mail/quoted-printable.c Mon Mar 18 15:46:16 2013 +0200 @@ -33,7 +33,7 @@ { char hexbuf[3]; size_t src_pos, pos, next; - bool errors = FALSE; + bool have_cr, errors = FALSE; int ret; hexbuf[2] = '\0'; @@ -46,13 +46,19 @@ if (src[src_pos] == '\n') { /* drop trailing whitespace */ pos = src_pos; - if (pos > 0 && src[pos-1] == '\r') + if (pos > 0 && src[pos-1] == '\r') { pos--; + have_cr = TRUE; + } else { + have_cr = FALSE; + } while (pos > 0 && QP_IS_TRAILING_SPACE(src[pos-1])) pos--; buffer_append(dest, src + next, pos - next); next = src_pos+1; - buffer_append(dest, "\r\n", 2); + if (have_cr) + buffer_append_c(dest, '\r'); + buffer_append_c(dest, '\n'); continue; } diff -r 69c26a9e3be5 -r 689dbeadf168 src/lib-mail/test-quoted-printable.c --- a/src/lib-mail/test-quoted-printable.c Fri Mar 15 21:58:51 2013 +0100 +++ b/src/lib-mail/test-quoted-printable.c Mon Mar 18 15:46:16 2013 +0200 @@ -21,7 +21,7 @@ { "foo = \n=01", "foo \001", 0, 0 }, { "foo =\t\r\nbar", "foo bar", 0, 0 }, { "foo =\r\n=01", "foo \001", 0, 0 }, - { "foo \nbar=", "foo\r\nbar", 1, 0 }, + { "foo \nbar=", "foo\nbar", 1, 0 }, { "=0A=0D ", "\n\r", 2, 0 }, { "foo_bar", "foo_bar", 0, 0 }, { "foo=", "foo", 1, 0 }, From dovecot at dovecot.org Mon Mar 18 15:59:47 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 18 Mar 2013 15:59:47 +0200 Subject: dovecot-2.2: Compiling fix for Solaris Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1728871f6d21 changeset: 16032:1728871f6d21 user: Timo Sirainen date: Mon Mar 18 15:59:40 2013 +0200 description: Compiling fix for Solaris diffstat: src/lib-master/master-service.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r ee7352f46d1e -r 1728871f6d21 src/lib-master/master-service.h --- a/src/lib-master/master-service.h Mon Mar 18 15:47:14 2013 +0200 +++ b/src/lib-master/master-service.h Mon Mar 18 15:59:40 2013 +0200 @@ -4,6 +4,7 @@ #include "net.h" #include /* for getopt() opt* variables */ +#include /* for getopt() opt* variables in Solaris */ enum master_service_flags { /* stdin/stdout already contains a client which we want to serve */ From dovecot at dovecot.org Mon Mar 18 16:52:10 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 18 Mar 2013 16:52:10 +0200 Subject: dovecot-2.2: auth: Return "nologin" and "proxy" fields to login ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d7d7cbcc2b67 changeset: 16033:d7d7cbcc2b67 user: Timo Sirainen date: Mon Mar 18 16:51:58 2013 +0200 description: auth: Return "nologin" and "proxy" fields to login process without "=value". diffstat: src/auth/auth-fields.c | 11 +++++++++++ src/auth/auth-fields.h | 3 +++ src/auth/auth-request-handler.c | 5 +++++ 3 files changed, 19 insertions(+), 0 deletions(-) diffs (49 lines): diff -r 1728871f6d21 -r d7d7cbcc2b67 src/auth/auth-fields.c --- a/src/auth/auth-fields.c Mon Mar 18 15:59:40 2013 +0200 +++ b/src/auth/auth-fields.c Mon Mar 18 16:51:58 2013 +0200 @@ -175,6 +175,17 @@ array_count(&fields->fields) == 0; } +void auth_fields_booleanize(struct auth_fields *fields, const char *key) +{ + struct auth_field *field; + unsigned int idx; + + if (auth_fields_find_idx(fields, key, &idx)) { + field = array_idx_modifiable(&fields->fields, idx); + field->value = NULL; + } +} + void auth_fields_snapshot(struct auth_fields *fields) { struct auth_field *field; diff -r 1728871f6d21 -r d7d7cbcc2b67 src/auth/auth-fields.h --- a/src/auth/auth-fields.h Mon Mar 18 15:59:40 2013 +0200 +++ b/src/auth/auth-fields.h Mon Mar 18 16:51:58 2013 +0200 @@ -34,6 +34,9 @@ enum auth_field_flags flags_mask, enum auth_field_flags flags_result); bool auth_fields_is_empty(struct auth_fields *fields); +/* If the field exists, clear its value (so the exported string will be "key" + instead of e.g. "key=y"). */ +void auth_fields_booleanize(struct auth_fields *fields, const char *key); /* Remember the current fields. */ void auth_fields_snapshot(struct auth_fields *fields); diff -r 1728871f6d21 -r d7d7cbcc2b67 src/auth/auth-request-handler.c --- a/src/auth/auth-request-handler.c Mon Mar 18 15:59:40 2013 +0200 +++ b/src/auth/auth-request-handler.c Mon Mar 18 16:51:58 2013 +0200 @@ -244,6 +244,11 @@ auth_penalty_update(auth_penalty, request, 0); } + /* sanitize these fields, since the login code currently assumes they + are exactly in this format. */ + auth_fields_booleanize(request->extra_fields, "nologin"); + auth_fields_booleanize(request->extra_fields, "proxy"); + str_printfa(str, "OK\t%u\tuser=", request->id); str_append_tabescaped(str, request->user); auth_str_append_extra_fields(request, str); From dovecot at dovecot.org Mon Mar 18 20:57:27 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 18 Mar 2013 20:57:27 +0200 Subject: dovecot-2.2: ldap auth: Support field values containing DNs to o... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/07a52d0edd46 changeset: 16034:07a52d0edd46 user: Timo Sirainen date: Mon Mar 18 20:51:33 2013 +0200 description: ldap auth: Support field values containing DNs to other LDAP records and getting them. For example: user_attrs = \ =user=%{ldap:uid}, \ @mail=base(%{ldap:mailDN}), \ =uid=%{ldap:uidNumber at mail}, \ =gid=%{ldap:gidNumber at mail}, \ =home=%{ldap:rootPath at mail}/%d/%n This first does the regular lookup, and then does another lookup using mailDN's value as the new lookup's base. The other lookup's filter is currently hardcoded to "no filter". diffstat: src/auth/db-ldap.c | 322 +++++++++++++++++++++++++++++++++++++++++++----- src/auth/db-ldap.h | 44 +++-- src/auth/passdb-ldap.c | 14 +- src/auth/userdb-ldap.c | 16 +- 4 files changed, 329 insertions(+), 67 deletions(-) diffs (truncated from 659 to 300 lines): diff -r d7d7cbcc2b67 -r 07a52d0edd46 src/auth/db-ldap.c --- a/src/auth/db-ldap.c Mon Mar 18 16:51:58 2013 +0200 +++ b/src/auth/db-ldap.c Mon Mar 18 20:51:33 2013 +0200 @@ -66,6 +66,8 @@ const char *val_1_arr[2]; string_t *var, *debug; + + bool iter_dn_values; }; struct db_ldap_sasl_bind_context { @@ -153,6 +155,10 @@ static int db_ldap_bind(struct ldap_connection *conn); static void db_ldap_conn_close(struct ldap_connection *conn); +struct db_ldap_result_iterate_context * +db_ldap_result_iterate_init_full(struct ldap_connection *conn, + struct ldap_request_search *ldap_request, + bool iter_dn_values); static int deref2str(const char *str) { @@ -540,26 +546,178 @@ return NULL; } -static void -db_ldap_handle_result(struct ldap_connection *conn, LDAPMessage *res) +static int db_ldap_dn_parse(struct auth_request *auth_request, + struct ldap_request_named_result *named_res, + const char *name, const char *value) { - struct ldap_request *request; - unsigned int idx; - int msgid, ret; + unsigned int len = strlen(value); - msgid = ldap_msgid(res); - if (msgid == conn->default_bind_msgid) { - db_ldap_default_bind_finished(conn, res); - return; + /* in future we could also have a filter() in here and maybe some + options.. of course, in future the whole ldap configuration will + probably be redesigned to become simpler.. */ + if (strncmp(value, "base(", 5) != 0 || value[len-1] != ')') { + auth_request_log_error(auth_request, "ldap", + "Invalid @%s value '%s'", name, value); + return -1; } + named_res->dn = p_strndup(auth_request->pool, value+5, len-5-1); + return 0; +} - request = db_ldap_find_request(conn, msgid, &idx); - if (request == NULL) { - i_error("LDAP: Reply with unknown msgid %d", msgid); - return; +static int db_ldap_fields_get_dn(struct ldap_connection *conn, + struct ldap_request_search *request) +{ + struct auth_request *auth_request = request->request.auth_request; + struct ldap_request_named_result *named_res; + struct db_ldap_result_iterate_context *ldap_iter; + const char *name, *const *values; + + ldap_iter = db_ldap_result_iterate_init_full(conn, request, TRUE); + while (db_ldap_result_iterate_next(ldap_iter, &name, &values)) { + if (values[1] != NULL) { + auth_request_log_warning(auth_request, "ldap", + "Multiple values found for '%s', " + "using value '%s'", name, values[0]); + } + array_foreach_modifiable(&request->named_results, named_res) { + if (strcmp(named_res->field->name, name) != 0) + continue; + if (db_ldap_dn_parse(auth_request, named_res, + name, values[0]) < 0) + return -1; + } } + db_ldap_result_iterate_deinit(&ldap_iter); + return 0; +} + +struct ldap_field_find_subquery_context { + ARRAY_TYPE(string) attr_names; + const char *name; +}; + +static const char * +db_ldap_field_subquery_find(const char *data, void *context) +{ + struct ldap_field_find_subquery_context *ctx = context; + char *ldap_attr; + const char *p; + + if (*data != '\0') { + data = t_strcut(data, ':'); + p = strchr(data, '@'); + if (p != NULL && strcmp(p+1, ctx->name) == 0) { + ldap_attr = p_strdup_until(unsafe_data_stack_pool, + data, p); + array_append(&ctx->attr_names, &ldap_attr, 1); + } + } + return NULL; +} + + +static int +ldap_request_send_subquery(struct ldap_connection *conn, + struct ldap_request_search *request, + struct ldap_request_named_result *named_res) +{ + static struct var_expand_func_table var_funcs_table[] = { + { "ldap", db_ldap_field_subquery_find }, + { NULL, NULL } + }; + const struct ldap_field *field; + const char *p; + char *name; + struct ldap_field_find_subquery_context ctx; + string_t *tmp_str = t_str_new(64); + + memset(&ctx, 0, sizeof(ctx)); + t_array_init(&ctx.attr_names, 8); + ctx.name = named_res->field->name; + + /* get the attributes names into array (ldapAttr at name -> ldapAttr) */ + array_foreach(request->attr_map, field) { + if (field->ldap_attr_name[0] == '\0') { + str_truncate(tmp_str, 0); + var_expand_with_funcs(tmp_str, field->value, NULL, + var_funcs_table, &ctx); + } else { + p = strchr(field->ldap_attr_name, '@'); + if (p != NULL && + strcmp(p+1, named_res->field->name) == 0) { + name = p_strdup_until(unsafe_data_stack_pool, + field->ldap_attr_name, p); + array_append(&ctx.attr_names, &name, 1); + } + } + } + array_append_zero(&ctx.attr_names); + + request->request.msgid = + ldap_search(conn->ld, named_res->dn, LDAP_SCOPE_BASE, + NULL, array_idx_modifiable(&ctx.attr_names, 0), 0); + if (request->request.msgid == -1) { + auth_request_log_error(request->request.auth_request, "ldap", + "ldap_search(dn=%s) failed: %s", + named_res->dn, ldap_get_error(conn)); + return -1; + } + return 0; +} + +static int db_ldap_search_next_subsearch(struct ldap_connection *conn, + struct ldap_request *_request, + LDAPMessage *res) +{ + struct ldap_request_search *request = + (struct ldap_request_search *)_request; + struct ldap_request_named_result *named_res; + const struct ldap_field *field; + + if (request->result == NULL) { + request->result = res; + /* see if we need to do more LDAP queries */ + p_array_init(&request->named_results, + _request->auth_request->pool, 2); + array_foreach(request->attr_map, field) { + if (!field->value_is_dn) + continue; + named_res = array_append_space(&request->named_results); + named_res->field = field; + } + if (db_ldap_fields_get_dn(conn, request) < 0) + return -1; + } else { + named_res = array_idx_modifiable(&request->named_results, + request->name_idx++); + named_res->result = res; + } + while (request->name_idx < array_count(&request->named_results)) { + /* send the next LDAP query */ + named_res = array_idx_modifiable(&request->named_results, + request->name_idx); + if (named_res->dn != NULL) { + if (ldap_request_send_subquery(conn, request, + named_res) < 0) + return -1; + return 1; + } + /* dn field wasn't returned, skip this */ + request->name_idx++; + } + return 0; +} + +static bool +db_ldap_handle_request_result(struct ldap_connection *conn, + struct ldap_request *request, unsigned int idx, + LDAPMessage *res) +{ + int ret; + bool final_result; i_assert(conn->pending_count > 0); + if (request->type == LDAP_REQUEST_TYPE_BIND) { i_assert(conn->conn_state == LDAP_CONN_STATE_BINDING); i_assert(conn->pending_count == 1); @@ -571,18 +729,18 @@ break; case LDAP_RES_SEARCH_REFERENCE: /* we're going to ignore this */ - return; + return FALSE; default: i_error("LDAP: Reply with unexpected type %d", ldap_msgtype(res)); - return; + return TRUE; } } - if (ldap_msgtype(res) == LDAP_RES_SEARCH_ENTRY) + if (ldap_msgtype(res) == LDAP_RES_SEARCH_ENTRY) { ret = LDAP_SUCCESS; - else { - conn->pending_count--; - aqueue_delete(conn->request_queue, idx); + final_result = FALSE; + } else { + final_result = TRUE; ret = ldap_result2error(conn->ld, res, 0); } if (ret != LDAP_SUCCESS && request->type == LDAP_REQUEST_TYPE_SEARCH) { @@ -596,6 +754,20 @@ ldap_err2string(ret)); res = NULL; } + if (ret == LDAP_SUCCESS && request->type == LDAP_REQUEST_TYPE_SEARCH) { + /* expand any @results */ + ret = db_ldap_search_next_subsearch(conn, request, res); + if (ret > 0) { + /* wait for finish, don't free the result yet */ + return FALSE; + } + if (ret < 0) + res = NULL; + } + if (final_result) { + conn->pending_count--; + aqueue_delete(conn->request_queue, idx); + } T_BEGIN { request->callback(conn, request, res); @@ -607,6 +779,54 @@ DB_LDAP_REQUEST_LOST_TIMEOUT_SECS, TRUE, "Request lost"); } + return TRUE; +} + +static void db_ldap_request_free(struct ldap_request *request, LDAPMessage *res) +{ + if (request->type == LDAP_REQUEST_TYPE_SEARCH) { + struct ldap_request_search *srequest = + (struct ldap_request_search *)request; + const struct ldap_request_named_result *named_res; + + if (srequest->result == res) + res = NULL; + if (srequest->result != NULL) + ldap_msgfree(srequest->result); + + array_foreach(&srequest->named_results, named_res) { + if (named_res->result == res) + res = NULL; + if (named_res->result != NULL) + ldap_msgfree(named_res->result); + } + } + if (res != NULL) + ldap_msgfree(res); +} + +static void +db_ldap_handle_result(struct ldap_connection *conn, LDAPMessage *res) +{ + struct ldap_request *request; + unsigned int idx; + int msgid; + + msgid = ldap_msgid(res); + if (msgid == conn->default_bind_msgid) { From dovecot at dovecot.org Mon Mar 18 21:24:10 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 18 Mar 2013 21:24:10 +0200 Subject: dovecot-2.2: ldap auth: Fix to previous change. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0b33047566a9 changeset: 16035:0b33047566a9 user: Timo Sirainen date: Mon Mar 18 21:20:54 2013 +0200 description: ldap auth: Fix to previous change. diffstat: src/auth/db-ldap.c | 63 +++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 46 insertions(+), 17 deletions(-) diffs (117 lines): diff -r 07a52d0edd46 -r 0b33047566a9 src/auth/db-ldap.c --- a/src/auth/db-ldap.c Mon Mar 18 20:51:33 2013 +0200 +++ b/src/auth/db-ldap.c Mon Mar 18 21:20:54 2013 +0200 @@ -665,20 +665,35 @@ return 0; } +static int db_ldap_search_save_result(struct ldap_request_search *request, + LDAPMessage *res) +{ + struct ldap_request_named_result *named_res; + + if (!array_is_created(&request->named_results)) { + if (request->result != NULL) + return -1; + request->result = res; + } else { + named_res = array_idx_modifiable(&request->named_results, + request->name_idx); + if (named_res->result != NULL) + return -1; + named_res->result = res; + } + return 0; +} + static int db_ldap_search_next_subsearch(struct ldap_connection *conn, - struct ldap_request *_request, - LDAPMessage *res) + struct ldap_request_search *request) { - struct ldap_request_search *request = - (struct ldap_request_search *)_request; struct ldap_request_named_result *named_res; const struct ldap_field *field; - if (request->result == NULL) { - request->result = res; + if (!array_is_created(&request->named_results)) { /* see if we need to do more LDAP queries */ p_array_init(&request->named_results, - _request->auth_request->pool, 2); + request->request.auth_request->pool, 2); array_foreach(request->attr_map, field) { if (!field->value_is_dn) continue; @@ -688,9 +703,7 @@ if (db_ldap_fields_get_dn(conn, request) < 0) return -1; } else { - named_res = array_idx_modifiable(&request->named_results, - request->name_idx++); - named_res->result = res; + request->name_idx++; } while (request->name_idx < array_count(&request->named_results)) { /* send the next LDAP query */ @@ -713,6 +726,7 @@ struct ldap_request *request, unsigned int idx, LDAPMessage *res) { + struct ldap_request_search *srequest = NULL; int ret; bool final_result; @@ -723,6 +737,7 @@ i_assert(conn->pending_count == 1); conn->conn_state = LDAP_CONN_STATE_BOUND_AUTH; } else { + srequest = (struct ldap_request_search *)request; switch (ldap_msgtype(res)) { case LDAP_RES_SEARCH_ENTRY: case LDAP_RES_SEARCH_RESULT: @@ -754,15 +769,27 @@ ldap_err2string(ret)); res = NULL; } - if (ret == LDAP_SUCCESS && request->type == LDAP_REQUEST_TYPE_SEARCH) { + if (ret == LDAP_SUCCESS && srequest != NULL) { /* expand any @results */ - ret = db_ldap_search_next_subsearch(conn, request, res); - if (ret > 0) { - /* wait for finish, don't free the result yet */ - return FALSE; + if (!final_result) { + if (db_ldap_search_save_result(srequest, res) < 0) { + auth_request_log_error(request->auth_request, "ldap", + "LDAP search returned multiple entries"); + res = NULL; + } else { + /* wait for finish, don't free the result yet */ + return FALSE; + } + } else { + ret = db_ldap_search_next_subsearch(conn, srequest); + if (ret > 0) { + /* free this result, but not the others */ + ldap_msgfree(res); + return FALSE; + } + if (ret < 0) + res = NULL; } - if (ret < 0) - res = NULL; } if (final_result) { conn->pending_count--; @@ -770,6 +797,8 @@ } T_BEGIN { + if (res != NULL && srequest != NULL && srequest->result != NULL) + request->callback(conn, request, srequest->result); request->callback(conn, request, res); } T_END; From dovecot at dovecot.org Mon Mar 18 21:24:10 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 18 Mar 2013 21:24:10 +0200 Subject: dovecot-2.2: ldap auth: Added %{ldap_ptr:realAttr} to get the va... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b6986edec17f changeset: 16036:b6986edec17f user: Timo Sirainen date: Mon Mar 18 21:23:54 2013 +0200 description: ldap auth: Added %{ldap_ptr:realAttr} to get the value from the realAttr. For example: password_attrs = \ =proxy=y, \ =host=%{ldap_ptr:activeHost}, \ primaryHost, secondaryHost Where activeHost's value is either "primaryHost" or "secondaryHost". diffstat: src/auth/db-ldap.c | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) diffs (47 lines): diff -r 0b33047566a9 -r b6986edec17f src/auth/db-ldap.c --- a/src/auth/db-ldap.c Mon Mar 18 21:20:54 2013 +0200 +++ b/src/auth/db-ldap.c Mon Mar 18 21:23:54 2013 +0200 @@ -623,6 +623,7 @@ { static struct var_expand_func_table var_funcs_table[] = { { "ldap", db_ldap_field_subquery_find }, + { "ldap_ptr", db_ldap_field_subquery_find }, { NULL, NULL } }; const struct ldap_field *field; @@ -1251,6 +1252,7 @@ { static struct var_expand_func_table var_funcs_table[] = { { "ldap", db_ldap_field_find }, + { "ldap_ptr", db_ldap_field_find }, { NULL, NULL } }; struct ldap_field_find_context ctx; @@ -1515,6 +1517,19 @@ return ldap_value->values[0]; } +static const char *db_ldap_field_ptr_expand(const char *data, void *context) +{ + struct db_ldap_result_iterate_context *ctx = context; + const char *field_name, *suffix; + + suffix = strchr(t_strcut(data, ':'), '@'); + field_name = db_ldap_field_expand(data, ctx); + if (field_name[0] == '\0') + return ""; + field_name = t_strconcat(field_name, suffix, NULL); + return db_ldap_field_expand(field_name, ctx); +} + static const char *const * db_ldap_result_return_value(struct db_ldap_result_iterate_context *ctx, const struct ldap_field *field, @@ -1522,6 +1537,7 @@ { static struct var_expand_func_table var_funcs_table[] = { { "ldap", db_ldap_field_expand }, + { "ldap_ptr", db_ldap_field_ptr_expand }, { NULL, NULL } }; const struct var_expand_table *var_table; From dovecot at dovecot.org Mon Mar 18 21:31:45 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 18 Mar 2013 21:31:45 +0200 Subject: dovecot-2.2: ldap auth: "!ldapField" now requests the given fiel... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/16a410a546de changeset: 16037:16a410a546de user: Timo Sirainen date: Mon Mar 18 21:31:34 2013 +0200 description: ldap auth: "!ldapField" now requests the given field, but doesn't return it directly. It's only useful for listing fields that %{ldap_ptr} can potentially access. diffstat: src/auth/db-ldap.c | 8 +++++++- src/auth/db-ldap.h | 3 +++ 2 files changed, 10 insertions(+), 1 deletions(-) diffs (38 lines): diff -r b6986edec17f -r 16a410a546de src/auth/db-ldap.c --- a/src/auth/db-ldap.c Mon Mar 18 21:23:54 2013 +0200 +++ b/src/auth/db-ldap.c Mon Mar 18 21:31:34 2013 +0200 @@ -1314,6 +1314,11 @@ /* @name=ldapField */ name++; field->value_is_dn = TRUE; + } else if (name[0] == '!' && name == ldap_attr) { + /* !ldapAttr */ + name = ""; + ldap_attr++; + field->skip = TRUE; } field->name = name; field->value = templ; @@ -1596,7 +1601,8 @@ if (ctx->attr_idx == array_count(ctx->attr_map)) return FALSE; field = array_idx(ctx->attr_map, ctx->attr_idx++); - } while (field->value_is_dn != ctx->iter_dn_values); + } while (field->value_is_dn != ctx->iter_dn_values || + field->skip); ldap_value = *field->ldap_attr_name == '\0' ? NULL : hash_table_lookup(ctx->ldap_attrs, field->ldap_attr_name); diff -r b6986edec17f -r 16a410a546de src/auth/db-ldap.h --- a/src/auth/db-ldap.h Mon Mar 18 21:23:54 2013 +0200 +++ b/src/auth/db-ldap.h Mon Mar 18 21:31:34 2013 +0200 @@ -87,6 +87,9 @@ /* LDAP value contains a DN, which is looked up and used for @name attributes. */ bool value_is_dn; + /* This attribute is used internally only via %{ldap_ptr}, + it shouldn't be returned in iteration. */ + bool skip; }; ARRAY_DEFINE_TYPE(ldap_field, struct ldap_field); From dovecot at dovecot.org Tue Mar 19 11:43:04 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 19 Mar 2013 11:43:04 +0200 Subject: dovecot-2.2: lib-fs: Allow passing through SSL client settings v... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/aa255de644d0 changeset: 16038:aa255de644d0 user: Timo Sirainen date: Tue Mar 19 11:39:07 2013 +0200 description: lib-fs: Allow passing through SSL client settings via struct fs_settings. diffstat: src/lib-fs/fs-api.h | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 16a410a546de -r aa255de644d0 src/lib-fs/fs-api.h --- a/src/lib-fs/fs-api.h Mon Mar 18 21:31:34 2013 +0200 +++ b/src/lib-fs/fs-api.h Tue Mar 19 11:39:07 2013 +0200 @@ -65,6 +65,8 @@ /* Directory where temporary files can be created at any time (e.g. /tmp or mail_temp_dir) */ const char *temp_dir; + /* SSL client settings. */ + const struct ssl_iostream_settings *ssl_client_set; /* Automatically try to rmdir() directories up to this path when deleting files. */ From dovecot at dovecot.org Tue Mar 19 11:43:04 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 19 Mar 2013 11:43:04 +0200 Subject: dovecot-2.2: Moved ssl_client_ca_dir and ssl_crypto_device to ma... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cf9f36e8ada0 changeset: 16039:cf9f36e8ada0 user: Timo Sirainen date: Tue Mar 19 11:42:51 2013 +0200 description: Moved ssl_client_ca_dir and ssl_crypto_device to mail_storage_settings. Probably could also be moved to master_service_settings, but that makes accessing them a bit more tricky with the current code. diffstat: src/doveadm/doveadm-settings.c | 6 ----- src/doveadm/doveadm-settings.h | 3 -- src/doveadm/dsync/doveadm-dsync.c | 31 ++++++++++++++++++--------- src/lib-storage/index/imapc/imapc-settings.c | 17 +-------------- src/lib-storage/index/imapc/imapc-settings.h | 3 -- src/lib-storage/index/imapc/imapc-storage.c | 4 +- src/lib-storage/index/pop3c/pop3c-settings.c | 15 +------------ src/lib-storage/index/pop3c/pop3c-settings.h | 2 - src/lib-storage/index/pop3c/pop3c-storage.c | 16 +++++++------- src/lib-storage/mail-storage-settings.c | 17 ++++++++++++++- src/lib-storage/mail-storage-settings.h | 3 ++ 11 files changed, 51 insertions(+), 66 deletions(-) diffs (truncated from 362 to 300 lines): diff -r aa255de644d0 -r cf9f36e8ada0 src/doveadm/doveadm-settings.c --- a/src/doveadm/doveadm-settings.c Tue Mar 19 11:39:07 2013 +0200 +++ b/src/doveadm/doveadm-settings.c Tue Mar 19 11:42:51 2013 +0200 @@ -65,9 +65,6 @@ DEF(SET_STR, dsync_alt_char), DEF(SET_STR, dsync_remote_cmd), - DEF(SET_STR, ssl_client_ca_dir), - DEF(SET_STR, ssl_crypto_device), - { SET_STRLIST, "plugin", offsetof(struct doveadm_settings, plugin_envs), NULL }, SETTING_DEFINE_LIST_END @@ -86,9 +83,6 @@ .dsync_alt_char = "_", .dsync_remote_cmd = "ssh -l%{login} %{host} doveadm dsync-server -u%u", - .ssl_client_ca_dir = "", - .ssl_crypto_device = "", - .plugin_envs = ARRAY_INIT }; diff -r aa255de644d0 -r cf9f36e8ada0 src/doveadm/doveadm-settings.h --- a/src/doveadm/doveadm-settings.h Tue Mar 19 11:39:07 2013 +0200 +++ b/src/doveadm/doveadm-settings.h Tue Mar 19 11:42:51 2013 +0200 @@ -14,9 +14,6 @@ const char *dsync_alt_char; const char *dsync_remote_cmd; - const char *ssl_client_ca_dir; - const char *ssl_crypto_device; - ARRAY(const char *) plugin_envs; }; diff -r aa255de644d0 -r cf9f36e8ada0 src/doveadm/dsync/doveadm-dsync.c --- a/src/doveadm/dsync/doveadm-dsync.c Tue Mar 19 11:39:07 2013 +0200 +++ b/src/doveadm/dsync/doveadm-dsync.c Tue Mar 19 11:42:51 2013 +0200 @@ -551,7 +551,8 @@ io_loop_stop(current_ioloop); } -static int dsync_init_ssl_ctx(struct dsync_cmd_context *ctx) +static int dsync_init_ssl_ctx(struct dsync_cmd_context *ctx, + const struct mail_storage_settings *mail_set) { struct ssl_iostream_settings ssl_set; @@ -559,16 +560,18 @@ return 0; memset(&ssl_set, 0, sizeof(ssl_set)); - ssl_set.ca_dir = doveadm_settings->ssl_client_ca_dir; + ssl_set.ca_dir = mail_set->ssl_client_ca_dir; ssl_set.verify_remote_cert = TRUE; - ssl_set.crypto_device = doveadm_settings->ssl_crypto_device; + ssl_set.crypto_device = mail_set->ssl_crypto_device; return ssl_iostream_context_init_client("doveadm", &ssl_set, &ctx->ssl_ctx); } -static int dsync_connect_tcp(struct dsync_cmd_context *ctx, const char *target, - bool ssl, const char **error_r) +static int +dsync_connect_tcp(struct dsync_cmd_context *ctx, + const struct mail_storage_settings *mail_set, + const char *target, bool ssl, const char **error_r) { struct doveadm_server *server; struct server_connection *conn; @@ -578,7 +581,7 @@ server = p_new(ctx->ctx.pool, struct doveadm_server, 1); server->name = p_strdup(ctx->ctx.pool, target); if (ssl) { - if (dsync_init_ssl_ctx(ctx) < 0) { + if (dsync_init_ssl_ctx(ctx, mail_set) < 0) { *error_r = "Couldn't initialize SSL context"; return -1; } @@ -624,18 +627,22 @@ } static int -parse_location(struct dsync_cmd_context *ctx, const char *location, +parse_location(struct dsync_cmd_context *ctx, + const struct mail_storage_settings *mail_set, + const char *location, const char *const **remote_cmd_args_r, const char **error_r) { if (strncmp(location, "tcp:", 4) == 0) { /* TCP connection to remote dsync */ ctx->remote_name = location+4; - return dsync_connect_tcp(ctx, ctx->remote_name, FALSE, error_r); + return dsync_connect_tcp(ctx, mail_set, ctx->remote_name, + FALSE, error_r); } if (strncmp(location, "tcps:", 5) == 0) { /* TCP+SSL connection to remote dsync */ ctx->remote_name = location+5; - return dsync_connect_tcp(ctx, ctx->remote_name, TRUE, error_r); + return dsync_connect_tcp(ctx, mail_set, ctx->remote_name, + TRUE, error_r); } if (strncmp(location, "remote:", 7) == 0) { @@ -663,9 +670,11 @@ struct dsync_cmd_context *ctx = (struct dsync_cmd_context *)_ctx; const char *const *remote_cmd_args = NULL; const struct mail_user_settings *user_set; + const struct mail_storage_settings *mail_set; const char *username = ""; user_set = mail_storage_service_user_get_set(service_user)[0]; + mail_set = mail_storage_service_user_get_mail_set(service_user); ctx->fd_in = -1; ctx->fd_out = -1; @@ -697,8 +706,8 @@ } if (remote_cmd_args == NULL && ctx->local_location != NULL) { - if (parse_location(ctx, ctx->local_location, &remote_cmd_args, - error_r) < 0) + if (parse_location(ctx, mail_set, ctx->local_location, + &remote_cmd_args, error_r) < 0) return -1; } diff -r aa255de644d0 -r cf9f36e8ada0 src/lib-storage/index/imapc/imapc-settings.c --- a/src/lib-storage/index/imapc/imapc-settings.c Tue Mar 19 11:39:07 2013 +0200 +++ b/src/lib-storage/index/imapc/imapc-settings.c Tue Mar 19 11:42:51 2013 +0200 @@ -29,9 +29,6 @@ DEF(SET_STR, imapc_list_prefix), DEF(SET_TIME, imapc_max_idle_time), - DEF(SET_STR, ssl_client_ca_dir), - DEF(SET_STR, ssl_crypto_device), - SETTING_DEFINE_LIST_END }; @@ -49,10 +46,7 @@ .imapc_features = "", .imapc_rawlog_dir = "", .imapc_list_prefix = "", - .imapc_max_idle_time = 60*29, - - .ssl_client_ca_dir = "", - .ssl_crypto_device = "" + .imapc_max_idle_time = 60*29 }; static const struct setting_parser_info imapc_setting_parser_info = { @@ -122,15 +116,6 @@ *error_r = "invalid imapc_port"; return FALSE; } -#ifndef CONFIG_BINARY - if (*set->ssl_client_ca_dir != '\0' && - access(set->ssl_client_ca_dir, X_OK) < 0) { - *error_r = t_strdup_printf( - "ssl_client_ca_dir: access(%s) failed: %m", - set->ssl_client_ca_dir); - return FALSE; - } -#endif if (set->imapc_max_idle_time == 0) { *error_r = "imapc_max_idle_time must not be 0"; return FALSE; diff -r aa255de644d0 -r cf9f36e8ada0 src/lib-storage/index/imapc/imapc-settings.h --- a/src/lib-storage/index/imapc/imapc-settings.h Tue Mar 19 11:39:07 2013 +0200 +++ b/src/lib-storage/index/imapc/imapc-settings.h Tue Mar 19 11:42:51 2013 +0200 @@ -24,9 +24,6 @@ const char *imapc_list_prefix; unsigned int imapc_max_idle_time; - const char *ssl_client_ca_dir; - const char *ssl_crypto_device; - enum imapc_features parsed_features; }; diff -r aa255de644d0 -r cf9f36e8ada0 src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Tue Mar 19 11:39:07 2013 +0200 +++ b/src/lib-storage/index/imapc/imapc-storage.c Tue Mar 19 11:42:51 2013 +0200 @@ -243,7 +243,7 @@ mail_user_set_get_temp_prefix(str, _storage->user->set); set.temp_path_prefix = str_c(str); - set.ssl_ca_dir = storage->set->ssl_client_ca_dir; + set.ssl_ca_dir = _storage->set->ssl_client_ca_dir; set.ssl_verify = storage->set->imapc_ssl_verify; if (strcmp(storage->set->imapc_ssl, "imaps") == 0) set.ssl_mode = IMAPC_CLIENT_SSL_MODE_IMMEDIATE; @@ -251,7 +251,7 @@ set.ssl_mode = IMAPC_CLIENT_SSL_MODE_STARTTLS; else set.ssl_mode = IMAPC_CLIENT_SSL_MODE_NONE; - set.ssl_crypto_device = storage->set->ssl_crypto_device; + set.ssl_crypto_device = _storage->set->ssl_crypto_device; storage->list = (struct imapc_mailbox_list *)ns->list; storage->list->storage = storage; diff -r aa255de644d0 -r cf9f36e8ada0 src/lib-storage/index/pop3c/pop3c-settings.c --- a/src/lib-storage/index/pop3c/pop3c-settings.c Tue Mar 19 11:39:07 2013 +0200 +++ b/src/lib-storage/index/pop3c/pop3c-settings.c Tue Mar 19 11:42:51 2013 +0200 @@ -25,8 +25,6 @@ DEF(SET_BOOL, pop3c_ssl_verify), DEF(SET_STR, pop3c_rawlog_dir), - DEF(SET_STR, ssl_client_ca_dir), - DEF(SET_STR, ssl_crypto_device), SETTING_DEFINE_LIST_END }; @@ -42,9 +40,7 @@ .pop3c_ssl = "no:pop3s:starttls", .pop3c_ssl_verify = TRUE, - .pop3c_rawlog_dir = "", - .ssl_client_ca_dir = "", - .ssl_crypto_device = "" + .pop3c_rawlog_dir = "" }; static const struct setting_parser_info pop3c_setting_parser_info = { @@ -76,14 +72,5 @@ *error_r = "invalid pop3c_port"; return FALSE; } -#ifndef CONFIG_BINARY - if (*set->ssl_client_ca_dir != '\0' && - access(set->ssl_client_ca_dir, X_OK) < 0) { - *error_r = t_strdup_printf( - "ssl_client_ca_dir: access(%s) failed: %m", - set->ssl_client_ca_dir); - return FALSE; - } -#endif return TRUE; } diff -r aa255de644d0 -r cf9f36e8ada0 src/lib-storage/index/pop3c/pop3c-settings.h --- a/src/lib-storage/index/pop3c/pop3c-settings.h Tue Mar 19 11:39:07 2013 +0200 +++ b/src/lib-storage/index/pop3c/pop3c-settings.h Tue Mar 19 11:42:51 2013 +0200 @@ -13,8 +13,6 @@ bool pop3c_ssl_verify; const char *pop3c_rawlog_dir; - const char *ssl_client_ca_dir; - const char *ssl_crypto_device; }; const struct setting_parser_info *pop3c_get_setting_parser_info(void); diff -r aa255de644d0 -r cf9f36e8ada0 src/lib-storage/index/pop3c/pop3c-storage.c --- a/src/lib-storage/index/pop3c/pop3c-storage.c Tue Mar 19 11:39:07 2013 +0200 +++ b/src/lib-storage/index/pop3c/pop3c-storage.c Tue Mar 19 11:42:51 2013 +0200 @@ -50,7 +50,7 @@ } static struct pop3c_client * -pop3c_client_create_from_set(struct mail_user *user, +pop3c_client_create_from_set(struct mail_storage *storage, const struct pop3c_settings *set) { struct pop3c_client_settings client_set; @@ -63,17 +63,17 @@ client_set.master_user = set->pop3c_master_user; client_set.password = set->pop3c_password; client_set.dns_client_socket_path = - t_strconcat(user->set->base_dir, "/", + t_strconcat(storage->user->set->base_dir, "/", DNS_CLIENT_SOCKET_NAME, NULL); str = t_str_new(128); - mail_user_set_get_temp_prefix(str, user->set); + mail_user_set_get_temp_prefix(str, storage->user->set); client_set.temp_path_prefix = str_c(str); - client_set.debug = user->mail_debug; + client_set.debug = storage->user->mail_debug; client_set.rawlog_dir = - mail_user_home_expand(user, set->pop3c_rawlog_dir); + mail_user_home_expand(storage->user, set->pop3c_rawlog_dir); - client_set.ssl_ca_dir = set->ssl_client_ca_dir; + client_set.ssl_ca_dir = storage->set->ssl_client_ca_dir; client_set.ssl_verify = set->pop3c_ssl_verify; if (strcmp(set->pop3c_ssl, "pop3s") == 0) client_set.ssl_mode = POP3C_CLIENT_SSL_MODE_IMMEDIATE; @@ -81,7 +81,7 @@ client_set.ssl_mode = POP3C_CLIENT_SSL_MODE_STARTTLS; else client_set.ssl_mode = POP3C_CLIENT_SSL_MODE_NONE; - client_set.ssl_crypto_device = set->ssl_crypto_device; + client_set.ssl_crypto_device = storage->set->ssl_crypto_device; return pop3c_client_init(&client_set); } @@ -171,7 +171,7 @@ From dovecot at dovecot.org Tue Mar 19 11:52:22 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 19 Mar 2013 11:52:22 +0200 Subject: dovecot-2.2: lib-fs: fs-test now sets the ssl_client_set.ca_dir Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/70dd78cd89ab changeset: 16040:70dd78cd89ab user: Timo Sirainen date: Tue Mar 19 11:52:15 2013 +0200 description: lib-fs: fs-test now sets the ssl_client_set.ca_dir diffstat: src/lib-fs/Makefile.am | 1 + src/lib-fs/fs-test.c | 6 ++++++ 2 files changed, 7 insertions(+), 0 deletions(-) diffs (32 lines): diff -r cf9f36e8ada0 -r 70dd78cd89ab src/lib-fs/Makefile.am --- a/src/lib-fs/Makefile.am Tue Mar 19 11:42:51 2013 +0200 +++ b/src/lib-fs/Makefile.am Tue Mar 19 11:52:15 2013 +0200 @@ -4,6 +4,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-ssl-iostream \ -DMODULE_DIR=\""$(moduledir)"\" libfs_la_SOURCES = \ diff -r cf9f36e8ada0 -r 70dd78cd89ab src/lib-fs/fs-test.c --- a/src/lib-fs/fs-test.c Tue Mar 19 11:42:51 2013 +0200 +++ b/src/lib-fs/fs-test.c Tue Mar 19 11:52:15 2013 +0200 @@ -4,11 +4,17 @@ #include "ioloop.h" #include "istream.h" #include "ostream.h" +#include "iostream-ssl.h" #include "fs-api.h" #include +static const struct ssl_iostream_settings ssl_set = { + .ca_dir = "/etc/ssl/certs" /* FIXME: some parameter to change this? */ +}; + static const struct fs_settings fs_set = { + .ssl_client_set = &ssl_set, .temp_dir = "/tmp" }; From dovecot at dovecot.org Tue Mar 19 12:13:41 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 19 Mar 2013 12:13:41 +0200 Subject: dovecot-2.2: ldap auth: Removed base() wrapper around @dn values. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5b975ddc1c9a changeset: 16041:5b975ddc1c9a user: Timo Sirainen date: Tue Mar 19 12:13:33 2013 +0200 description: ldap auth: Removed base() wrapper around @dn values. The idea was to provide extensibility, but it can better be done with LDAP URLs. diffstat: src/auth/db-ldap.c | 24 +++--------------------- 1 files changed, 3 insertions(+), 21 deletions(-) diffs (41 lines): diff -r 70dd78cd89ab -r 5b975ddc1c9a src/auth/db-ldap.c --- a/src/auth/db-ldap.c Tue Mar 19 11:52:15 2013 +0200 +++ b/src/auth/db-ldap.c Tue Mar 19 12:13:33 2013 +0200 @@ -546,24 +546,6 @@ return NULL; } -static int db_ldap_dn_parse(struct auth_request *auth_request, - struct ldap_request_named_result *named_res, - const char *name, const char *value) -{ - unsigned int len = strlen(value); - - /* in future we could also have a filter() in here and maybe some - options.. of course, in future the whole ldap configuration will - probably be redesigned to become simpler.. */ - if (strncmp(value, "base(", 5) != 0 || value[len-1] != ')') { - auth_request_log_error(auth_request, "ldap", - "Invalid @%s value '%s'", name, value); - return -1; - } - named_res->dn = p_strndup(auth_request->pool, value+5, len-5-1); - return 0; -} - static int db_ldap_fields_get_dn(struct ldap_connection *conn, struct ldap_request_search *request) { @@ -582,9 +564,9 @@ array_foreach_modifiable(&request->named_results, named_res) { if (strcmp(named_res->field->name, name) != 0) continue; - if (db_ldap_dn_parse(auth_request, named_res, - name, values[0]) < 0) - return -1; + /* In future we could also support LDAP URLs here */ + named_res->dn = p_strdup(auth_request->pool, + values[0]); } } db_ldap_result_iterate_deinit(&ldap_iter); From dovecot at dovecot.org Tue Mar 19 12:18:41 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 19 Mar 2013 12:18:41 +0200 Subject: dovecot-2.2: test-json-parser: Fixed failing test with some non-... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ea6636b36b1c changeset: 16042:ea6636b36b1c user: Timo Sirainen date: Tue Mar 19 12:18:25 2013 +0200 description: test-json-parser: Fixed failing test with some non-gcc/clang compilers. diffstat: src/lib/test-json-parser.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r 5b975ddc1c9a -r ea6636b36b1c src/lib/test-json-parser.c --- a/src/lib/test-json-parser.c Tue Mar 19 12:13:33 2013 +0200 +++ b/src/lib/test-json-parser.c Tue Mar 19 12:18:25 2013 +0200 @@ -26,8 +26,8 @@ " \"sub3\":12.456e9,\n" " \"sub4\":0.456e-789" "}," - "\"key9\": \"foo\\\\\\\"\\b\\f\\n\\r\\t\\u0001\uffff\"," - "\"key10\": \"foo\\\\\\\"\\b\\f\\n\\r\\t\\u0001\uffff\"," + "\"key9\": \"foo\\\\\\\"\\b\\f\\n\\r\\t\\u0001\\uffff\"," + "\"key10\": \"foo\\\\\\\"\\b\\f\\n\\r\\t\\u0001\\uffff\"," "\"key11\": []," "\"key12\": [ \"foo\" , 5.24,[true],{\"aobj\":[]}]" "}\n"; From dovecot at dovecot.org Tue Mar 19 12:39:59 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 19 Mar 2013 12:39:59 +0200 Subject: dovecot-2.2: net_is_in_network(): Don't assert-crash with invali... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/790bb5dfadc6 changeset: 16043:790bb5dfadc6 user: Timo Sirainen date: Tue Mar 19 12:39:43 2013 +0200 description: net_is_in_network(): Don't assert-crash with invalid IP. It's probably better to do the check here instead of remembering for caller to do the check. diffstat: src/lib/net.c | 5 +++++ src/lib/net.h | 3 ++- 2 files changed, 7 insertions(+), 1 deletions(-) diffs (28 lines): diff -r ea6636b36b1c -r 790bb5dfadc6 src/lib/net.c --- a/src/lib/net.c Tue Mar 19 12:18:25 2013 +0200 +++ b/src/lib/net.c Tue Mar 19 12:39:43 2013 +0200 @@ -984,6 +984,11 @@ ip = &tmp_ip; } + if (ip->family == 0) { + /* non-IPv4/IPv6 address (e.g. UNIX socket) never matches + anything */ + return FALSE; + } if (IPADDR_IS_V4(ip) != IPADDR_IS_V4(net_ip)) { /* one is IPv6 and one is IPv4 */ return FALSE; diff -r ea6636b36b1c -r 790bb5dfadc6 src/lib/net.h --- a/src/lib/net.h Tue Mar 19 12:18:25 2013 +0200 +++ b/src/lib/net.h Tue Mar 19 12:39:43 2013 +0200 @@ -145,7 +145,8 @@ int net_parse_range(const char *network, struct ip_addr *ip_r, unsigned int *bits_r); /* Returns TRUE if ip is in net_ip/bits network. IPv6 mapped IPv4 addresses - are converted to plain IPv4 addresses before matching. */ + are converted to plain IPv4 addresses before matching. Invalid IPs + (family=0) never match anything. */ bool net_is_in_network(const struct ip_addr *ip, const struct ip_addr *net_ip, unsigned int bits) ATTR_PURE; From dovecot at dovecot.org Tue Mar 19 13:34:27 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 19 Mar 2013 13:34:27 +0200 Subject: dovecot-2.2: lib-storage: mailbox_attribute_set() now uses struc... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2396eb0a3e3f changeset: 16044:2396eb0a3e3f user: Timo Sirainen date: Tue Mar 19 13:34:12 2013 +0200 description: lib-storage: mailbox_attribute_set() now uses struct mail_attribute_value. This allows settig the last_change value, as well as using streams and setting other flags in future. diffstat: src/doveadm/dsync/dsync-mailbox-import.c | 7 ++++++- src/lib-imap-urlauth/imap-urlauth-backend.c | 4 +++- src/lib-storage/index/index-attribute.c | 8 ++++---- src/lib-storage/index/index-storage.h | 4 ++-- src/lib-storage/mail-storage-private.h | 4 ++-- src/lib-storage/mail-storage.c | 11 ++++++++--- src/lib-storage/mail-storage.h | 4 ++-- src/plugins/acl/acl-attributes.c | 11 ++++++----- src/plugins/acl/acl-storage.h | 4 ++-- 9 files changed, 35 insertions(+), 22 deletions(-) diffs (177 lines): diff -r 790bb5dfadc6 -r 2396eb0a3e3f src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Tue Mar 19 12:39:43 2013 +0200 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Tue Mar 19 13:34:12 2013 +0200 @@ -299,8 +299,13 @@ } } if (attr->value != NULL) { + struct mail_attribute_value value; + + memset(&value, 0, sizeof(value)); + value.value = attr->value; + value.last_change = attr->last_change; ret = mailbox_attribute_set(importer->trans, attr->type, - attr->key, attr->value); + attr->key, &value); } else { ret = mailbox_attribute_unset(importer->trans, attr->type, attr->key); diff -r 790bb5dfadc6 -r 2396eb0a3e3f src/lib-imap-urlauth/imap-urlauth-backend.c --- a/src/lib-imap-urlauth/imap-urlauth-backend.c Tue Mar 19 12:39:43 2013 +0200 +++ b/src/lib-imap-urlauth/imap-urlauth-backend.c Tue Mar 19 13:34:12 2013 +0200 @@ -47,8 +47,10 @@ random_fill(mailbox_key_r, IMAP_URLAUTH_KEY_LEN); mailbox_key_hex = binary_to_hex(mailbox_key_r, IMAP_URLAUTH_KEY_LEN); + memset(&urlauth_key, 0, sizeof(urlauth_key)); + urlauth_key.value = mailbox_key_hex; ret = mailbox_attribute_set(trans, MAIL_ATTRIBUTE_TYPE_PRIVATE, - IMAP_URLAUTH_KEY, mailbox_key_hex); + IMAP_URLAUTH_KEY, &urlauth_key); if (ret < 0) return -1; if (user->mail_debug) { diff -r 790bb5dfadc6 -r 2396eb0a3e3f src/lib-storage/index/index-attribute.c --- a/src/lib-storage/index/index-attribute.c Tue Mar 19 12:39:43 2013 +0200 +++ b/src/lib-storage/index/index-attribute.c Tue Mar 19 13:34:12 2013 +0200 @@ -173,8 +173,8 @@ } int index_storage_attribute_set(struct mailbox_transaction_context *t, - enum mail_attribute_type type, - const char *key, const char *value) + enum mail_attribute_type type, const char *key, + const struct mail_attribute_value *value) { struct dict_transaction_context *dtrans; const char *mailbox_prefix; @@ -195,8 +195,8 @@ const char *prefixed_key = key_get_prefixed(type, mailbox_prefix, key); - if (value != NULL) { - dict_set(dtrans, prefixed_key, value); + if (value->value != NULL) { + dict_set(dtrans, prefixed_key, value->value); mail_index_attribute_set(t->itrans, pvt, key); } else { dict_unset(dtrans, prefixed_key); diff -r 790bb5dfadc6 -r 2396eb0a3e3f src/lib-storage/index/index-storage.h --- a/src/lib-storage/index/index-storage.h Tue Mar 19 12:39:43 2013 +0200 +++ b/src/lib-storage/index/index-storage.h Tue Mar 19 13:34:12 2013 +0200 @@ -117,8 +117,8 @@ struct mailbox_metadata *metadata_r); int index_storage_attribute_set(struct mailbox_transaction_context *t, - enum mail_attribute_type type, - const char *key, const char *value); + enum mail_attribute_type type, const char *key, + const struct mail_attribute_value *value); int index_storage_attribute_get(struct mailbox_transaction_context *t, enum mail_attribute_type type, const char *key, struct mail_attribute_value *value_r); diff -r 790bb5dfadc6 -r 2396eb0a3e3f src/lib-storage/mail-storage-private.h --- a/src/lib-storage/mail-storage-private.h Tue Mar 19 12:39:43 2013 +0200 +++ b/src/lib-storage/mail-storage-private.h Tue Mar 19 13:34:12 2013 +0200 @@ -154,8 +154,8 @@ int (*set_subscribed)(struct mailbox *box, bool set); int (*attribute_set)(struct mailbox_transaction_context *t, - enum mail_attribute_type type, - const char *key, const char *value); + enum mail_attribute_type type, const char *key, + const struct mail_attribute_value *value); int (*attribute_get)(struct mailbox_transaction_context *t, enum mail_attribute_type type, const char *key, struct mail_attribute_value *value_r); diff -r 790bb5dfadc6 -r 2396eb0a3e3f src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Tue Mar 19 12:39:43 2013 +0200 +++ b/src/lib-storage/mail-storage.c Tue Mar 19 13:34:12 2013 +0200 @@ -1522,16 +1522,21 @@ } int mailbox_attribute_set(struct mailbox_transaction_context *t, - enum mail_attribute_type type, - const char *key, const char *value) + enum mail_attribute_type type, const char *key, + const struct mail_attribute_value *value) { + i_assert(value->value != NULL); + return t->box->v.attribute_set(t, type, key, value); } int mailbox_attribute_unset(struct mailbox_transaction_context *t, enum mail_attribute_type type, const char *key) { - return t->box->v.attribute_set(t, type, key, NULL); + struct mail_attribute_value value; + + memset(&value, 0, sizeof(value)); + return t->box->v.attribute_set(t, type, key, &value); } int mailbox_attribute_get(struct mailbox_transaction_context *t, diff -r 790bb5dfadc6 -r 2396eb0a3e3f src/lib-storage/mail-storage.h --- a/src/lib-storage/mail-storage.h Tue Mar 19 12:39:43 2013 +0200 +++ b/src/lib-storage/mail-storage.h Tue Mar 19 13:34:12 2013 +0200 @@ -553,8 +553,8 @@ IMAP METADATA, so for Dovecot-specific keys use MAILBOX_ATTRIBUTE_PREFIX_DOVECOT. */ int mailbox_attribute_set(struct mailbox_transaction_context *t, - enum mail_attribute_type type, - const char *key, const char *value); + enum mail_attribute_type type, const char *key, + const struct mail_attribute_value *value); /* Delete mailbox attribute key. */ int mailbox_attribute_unset(struct mailbox_transaction_context *t, enum mail_attribute_type type, const char *key); diff -r 790bb5dfadc6 -r 2396eb0a3e3f src/plugins/acl/acl-attributes.c --- a/src/plugins/acl/acl-attributes.c Tue Mar 19 12:39:43 2013 +0200 +++ b/src/plugins/acl/acl-attributes.c Tue Mar 19 13:34:12 2013 +0200 @@ -17,8 +17,9 @@ bool failed; }; -static int acl_attribute_update_acl(struct mailbox_transaction_context *t, - const char *key, const char *value) +static int +acl_attribute_update_acl(struct mailbox_transaction_context *t, const char *key, + const struct mail_attribute_value *value) { const char *id, *const *rights, *error; struct acl_rights_update update; @@ -38,7 +39,7 @@ update.modify_mode = ACL_MODIFY_MODE_REPLACE; update.neg_modify_mode = ACL_MODIFY_MODE_REPLACE; id = key + strlen(MAILBOX_ATTRIBUTE_PREFIX_ACL); - rights = value == NULL ? NULL : t_strsplit(value, " "); + rights = value->value == NULL ? NULL : t_strsplit(value->value, " "); if (acl_rights_update_import(&update, id, rights, &error) < 0) { mail_storage_set_error(t->box->storage, MAIL_ERROR_PARAMS, error); return -1; @@ -125,8 +126,8 @@ } int acl_attribute_set(struct mailbox_transaction_context *t, - enum mail_attribute_type type, - const char *key, const char *value) + enum mail_attribute_type type, const char *key, + const struct mail_attribute_value *value) { struct acl_mailbox *abox = ACL_CONTEXT(t->box); diff -r 790bb5dfadc6 -r 2396eb0a3e3f src/plugins/acl/acl-storage.h --- a/src/plugins/acl/acl-storage.h Tue Mar 19 12:39:43 2013 +0200 +++ b/src/plugins/acl/acl-storage.h Tue Mar 19 13:34:12 2013 +0200 @@ -32,8 +32,8 @@ const struct acl_rights_update *update); int acl_attribute_set(struct mailbox_transaction_context *t, - enum mail_attribute_type type, - const char *key, const char *value); + enum mail_attribute_type type, const char *key, + const struct mail_attribute_value *value); int acl_attribute_get(struct mailbox_transaction_context *t, enum mail_attribute_type type, const char *key, struct mail_attribute_value *value_r); From dovecot at dovecot.org Tue Mar 19 14:00:59 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 19 Mar 2013 14:00:59 +0200 Subject: dovecot-2.2: lib-storage: Allow mailbox_attribute_set() to also ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cdfc9f30b482 changeset: 16045:cdfc9f30b482 user: Timo Sirainen date: Tue Mar 19 13:59:02 2013 +0200 description: lib-storage: Allow mailbox_attribute_set() to also unset values. This allows giving the last_change timestamp also when unsetting. diffstat: src/lib-storage/mail-storage.c | 2 -- src/lib-storage/mail-storage.h | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diffs (25 lines): diff -r 2396eb0a3e3f -r cdfc9f30b482 src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Tue Mar 19 13:34:12 2013 +0200 +++ b/src/lib-storage/mail-storage.c Tue Mar 19 13:59:02 2013 +0200 @@ -1525,8 +1525,6 @@ enum mail_attribute_type type, const char *key, const struct mail_attribute_value *value) { - i_assert(value->value != NULL); - return t->box->v.attribute_set(t, type, key, value); } diff -r 2396eb0a3e3f -r cdfc9f30b482 src/lib-storage/mail-storage.h --- a/src/lib-storage/mail-storage.h Tue Mar 19 13:34:12 2013 +0200 +++ b/src/lib-storage/mail-storage.h Tue Mar 19 13:59:02 2013 +0200 @@ -555,7 +555,8 @@ int mailbox_attribute_set(struct mailbox_transaction_context *t, enum mail_attribute_type type, const char *key, const struct mail_attribute_value *value); -/* Delete mailbox attribute key. */ +/* Delete mailbox attribute key. This is just a wrapper to + mailbox_attribute_set() with value->value=NULL. */ int mailbox_attribute_unset(struct mailbox_transaction_context *t, enum mail_attribute_type type, const char *key); /* Returns value for mailbox attribute key. Returns 1 if value was returned, From dovecot at dovecot.org Tue Mar 19 14:00:59 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 19 Mar 2013 14:00:59 +0200 Subject: dovecot-2.2: dsync: Set last_change timestamp for unset attributes. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3e4c4f9c230b changeset: 16046:3e4c4f9c230b user: Timo Sirainen date: Tue Mar 19 13:59:22 2013 +0200 description: dsync: Set last_change timestamp for unset attributes. diffstat: src/doveadm/dsync/dsync-mailbox-import.c | 17 ++++++----------- 1 files changed, 6 insertions(+), 11 deletions(-) diffs (35 lines): diff -r cdfc9f30b482 -r 3e4c4f9c230b src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Tue Mar 19 13:59:02 2013 +0200 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Tue Mar 19 13:59:22 2013 +0200 @@ -247,6 +247,7 @@ const struct dsync_mailbox_attribute *attr) { const struct dsync_mailbox_attribute *local_attr; + struct mail_attribute_value value; int ret; i_assert(attr->value != NULL || attr->deleted); @@ -298,18 +299,12 @@ return 0; } } - if (attr->value != NULL) { - struct mail_attribute_value value; - memset(&value, 0, sizeof(value)); - value.value = attr->value; - value.last_change = attr->last_change; - ret = mailbox_attribute_set(importer->trans, attr->type, - attr->key, &value); - } else { - ret = mailbox_attribute_unset(importer->trans, attr->type, - attr->key); - } + memset(&value, 0, sizeof(value)); + value.value = attr->value; + value.last_change = attr->last_change; + ret = mailbox_attribute_set(importer->trans, attr->type, + attr->key, &value); if (ret < 0) { i_error("Mailbox %s: Failed to set attribute %s: %s", mailbox_get_vname(importer->box), attr->key, From dovecot at dovecot.org Tue Mar 19 14:00:59 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 19 Mar 2013 14:00:59 +0200 Subject: dovecot-2.2: acl: Don't unnecessarily rewrite dovecot-acl file w... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/45999b94692c changeset: 16047:45999b94692c user: Timo Sirainen date: Tue Mar 19 14:00:21 2013 +0200 description: acl: Don't unnecessarily rewrite dovecot-acl file when re-adding the same ACL. diffstat: src/plugins/acl/acl-backend-vfile.c | 14 ++++++++++++-- 1 files changed, 12 insertions(+), 2 deletions(-) diffs (31 lines): diff -r 3e4c4f9c230b -r 45999b94692c src/plugins/acl/acl-backend-vfile.c --- a/src/plugins/acl/acl-backend-vfile.c Tue Mar 19 13:59:22 2013 +0200 +++ b/src/plugins/acl/acl-backend-vfile.c Tue Mar 19 14:00:21 2013 +0200 @@ -992,6 +992,7 @@ const struct acl_rights_update *update) { struct acl_rights right; + bool c1, c2; if (update->modify_mode == ACL_MODIFY_MODE_REMOVE && update->neg_modify_mode == ACL_MODIFY_MODE_REMOVE) { @@ -1003,8 +1004,17 @@ right.id_type = update->rights.id_type; right.identifier = p_strdup(aclobj->rights_pool, update->rights.identifier); - array_insert(&aclobj->rights, idx, &right, 1); - return vfile_object_modify_right(aclobj, idx, update); + + c1 = modify_right_list(aclobj->rights_pool, &right.rights, + update->rights.rights, update->modify_mode); + c2 = modify_right_list(aclobj->rights_pool, &right.neg_rights, + update->rights.neg_rights, + update->neg_modify_mode); + if (c1 || c2) { + array_insert(&aclobj->rights, idx, &right, 1); + return TRUE; + } + return FALSE; } static void vfile_write_rights_list(string_t *dest, const char *const *rights) From dovecot at dovecot.org Tue Mar 19 14:00:59 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 19 Mar 2013 14:00:59 +0200 Subject: dovecot-2.2: acl: Preserve dovecot-acl file's mtime when dsyncing. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/394e1c6f0aaf changeset: 16048:394e1c6f0aaf user: Timo Sirainen date: Tue Mar 19 14:00:49 2013 +0200 description: acl: Preserve dovecot-acl file's mtime when dsyncing. diffstat: src/plugins/acl/acl-api.h | 2 ++ src/plugins/acl/acl-attributes.c | 1 + src/plugins/acl/acl-backend-vfile.c | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+), 0 deletions(-) diffs (73 lines): diff -r 45999b94692c -r 394e1c6f0aaf src/plugins/acl/acl-api.h --- a/src/plugins/acl/acl-api.h Tue Mar 19 14:00:21 2013 +0200 +++ b/src/plugins/acl/acl-api.h Tue Mar 19 14:00:49 2013 +0200 @@ -85,6 +85,8 @@ enum acl_modify_mode modify_mode; enum acl_modify_mode neg_modify_mode; + /* These changes' "last changed" timestamp */ + time_t last_change; }; /* data contains the information needed to initialize ACL backend. If username diff -r 45999b94692c -r 394e1c6f0aaf src/plugins/acl/acl-attributes.c --- a/src/plugins/acl/acl-attributes.c Tue Mar 19 14:00:21 2013 +0200 +++ b/src/plugins/acl/acl-attributes.c Tue Mar 19 14:00:49 2013 +0200 @@ -38,6 +38,7 @@ memset(&update, 0, sizeof(update)); update.modify_mode = ACL_MODIFY_MODE_REPLACE; update.neg_modify_mode = ACL_MODIFY_MODE_REPLACE; + update.last_change = value->last_change; id = key + strlen(MAILBOX_ATTRIBUTE_PREFIX_ACL); rights = value->value == NULL ? NULL : t_strsplit(value->value, " "); if (acl_rights_update_import(&update, id, rights, &error) < 0) { diff -r 45999b94692c -r 394e1c6f0aaf src/plugins/acl/acl-backend-vfile.c --- a/src/plugins/acl/acl-backend-vfile.c Tue Mar 19 14:00:21 2013 +0200 +++ b/src/plugins/acl/acl-backend-vfile.c Tue Mar 19 14:00:49 2013 +0200 @@ -19,6 +19,7 @@ #include #include #include +#include #include #define ACL_ESTALE_RETRY_COUNT NFS_ESTALE_RETRY_COUNT @@ -1136,7 +1137,10 @@ struct acl_object_vfile *aclobj = (struct acl_object_vfile *)_aclobj; struct acl_backend_vfile *backend = (struct acl_backend_vfile *)_aclobj->backend; + struct acl_backend_vfile_validity *validity; struct dotlock *dotlock; + struct utimbuf ut; + time_t orig_mtime; const char *path; unsigned int i; int fd; @@ -1159,6 +1163,10 @@ return 0; } + validity = acl_cache_get_validity(_aclobj->backend->cache, + _aclobj->name); + orig_mtime = validity->local_validity.last_mtime; + /* ACLs were really changed, write the new ones */ path = file_dotlock_get_lock_path(dotlock); if (acl_backend_vfile_update_write(aclobj, fd, path) < 0) { @@ -1166,6 +1174,16 @@ acl_cache_flush(_aclobj->backend->cache, _aclobj->name); return -1; } + if (orig_mtime < update->last_change && update->last_change != 0) { + /* set mtime to last_change, if it's higher than the file's + original mtime. if original mtime is higher, then we're + merging some changes and it's better for the mtime to get + updated. */ + ut.actime = ioloop_time; + ut.modtime = update->last_change; + if (utime(path, &ut) < 0) + i_error("utime(%s) failed: %m", path); + } acl_backend_vfile_update_cache(_aclobj, fd); if (file_dotlock_replace(&dotlock, 0) < 0) { acl_cache_flush(_aclobj->backend->cache, _aclobj->name); From dovecot at dovecot.org Tue Mar 19 18:48:56 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 19 Mar 2013 18:48:56 +0200 Subject: dovecot-2.2: acl: Don't iterate ACL attributes if prefix has no ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/64c0449b8fec changeset: 16049:64c0449b8fec user: Timo Sirainen date: Tue Mar 19 18:48:47 2013 +0200 description: acl: Don't iterate ACL attributes if prefix has no chance of matching them. diffstat: src/plugins/acl/acl-attributes.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (14 lines): diff -r 394e1c6f0aaf -r 64c0449b8fec src/plugins/acl/acl-attributes.c --- a/src/plugins/acl/acl-attributes.c Tue Mar 19 14:00:49 2013 +0200 +++ b/src/plugins/acl/acl-attributes.c Tue Mar 19 18:48:47 2013 +0200 @@ -169,7 +169,9 @@ aiter->super = abox->module_ctx.super. attribute_iter_init(box, type, prefix); if (box->storage->user->admin && - type == MAIL_ATTRIBUTE_TYPE_SHARED) { + type == MAIL_ATTRIBUTE_TYPE_SHARED && + strncmp(prefix, MAILBOX_ATTRIBUTE_PREFIX_ACL, + strlen(prefix)) == 0) { aiter->acl_iter = acl_object_list_init(abox->aclobj); aiter->acl_name = str_new(default_pool, 128); str_append(aiter->acl_name, MAILBOX_ATTRIBUTE_PREFIX_ACL); From dovecot at dovecot.org Tue Mar 19 18:51:50 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 19 Mar 2013 18:51:50 +0200 Subject: dovecot-2.2: dsync: Mail requests were lost when attributes were... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ccba138bc1c6 changeset: 16050:ccba138bc1c6 user: Timo Sirainen date: Tue Mar 19 18:50:55 2013 +0200 description: dsync: Mail requests were lost when attributes were being synced. diffstat: src/doveadm/dsync/dsync-brain-mails.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 64c0449b8fec -r ccba138bc1c6 src/doveadm/dsync/dsync-brain-mails.c --- a/src/doveadm/dsync/dsync-brain-mails.c Tue Mar 19 18:48:47 2013 +0200 +++ b/src/doveadm/dsync/dsync-brain-mails.c Tue Mar 19 18:50:55 2013 +0200 @@ -153,7 +153,7 @@ if (dsync_ibc_send_mail_request(brain->ibc, request) == 0) return TRUE; } - if (brain->box_recv_state <= DSYNC_BOX_STATE_CHANGES) + if (brain->box_recv_state < DSYNC_BOX_STATE_MAIL_REQUESTS) return FALSE; dsync_ibc_send_end_of_list(brain->ibc); From dovecot at dovecot.org Tue Mar 19 18:52:47 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 19 Mar 2013 18:52:47 +0200 Subject: dovecot-2.2: dsync: Fixed sending mailbox attributes with stream... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/46b223892373 changeset: 16051:46b223892373 user: Timo Sirainen date: Tue Mar 19 18:52:39 2013 +0200 description: dsync: Fixed sending mailbox attributes with stream ibc. diffstat: src/doveadm/dsync/dsync-ibc-stream.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r ccba138bc1c6 -r 46b223892373 src/doveadm/dsync/dsync-ibc-stream.c --- a/src/doveadm/dsync/dsync-ibc-stream.c Tue Mar 19 18:50:55 2013 +0200 +++ b/src/doveadm/dsync/dsync-ibc-stream.c Tue Mar 19 18:52:39 2013 +0200 @@ -1251,7 +1251,7 @@ p_clear(pool); attr = p_new(pool, struct dsync_mailbox_attribute, 1); - ret = dsync_ibc_stream_input_next(ibc, ITEM_MAIL_CHANGE, &decoder); + ret = dsync_ibc_stream_input_next(ibc, ITEM_MAILBOX_ATTRIBUTE, &decoder); if (ret != DSYNC_IBC_RECV_RET_OK) return ret; From dovecot at dovecot.org Tue Mar 19 19:05:40 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 19 Mar 2013 19:05:40 +0200 Subject: dovecot-2.2: lib-storage: Mailbox attributes can now be accessed... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0e5a359b7b7f changeset: 16052:0e5a359b7b7f user: Timo Sirainen date: Tue Mar 19 19:05:27 2013 +0200 description: lib-storage: Mailbox attributes can now be accessed via istreams. The idea is to use istreams for larger values. diffstat: src/doveadm/dsync/dsync-brain-mails.c | 4 + src/doveadm/dsync/dsync-ibc-stream.c | 180 +++++++++++++--------- src/doveadm/dsync/dsync-mailbox-export.c | 250 ++++++++++++++++++------------ src/doveadm/dsync/dsync-mailbox-import.c | 147 +++++++++++++++--- src/doveadm/dsync/dsync-mailbox.c | 4 + src/doveadm/dsync/dsync-mailbox.h | 6 +- src/lib-storage/index/index-attribute.c | 11 +- src/lib-storage/mail-storage.c | 56 ++++++- src/lib-storage/mail-storage.h | 15 +- src/plugins/acl/acl-attributes.c | 8 +- 10 files changed, 469 insertions(+), 212 deletions(-) diffs (truncated from 1142 to 300 lines): diff -r 46b223892373 -r 0e5a359b7b7f src/doveadm/dsync/dsync-brain-mails.c --- a/src/doveadm/dsync/dsync-brain-mails.c Tue Mar 19 18:52:39 2013 +0200 +++ b/src/doveadm/dsync/dsync-brain-mails.c Tue Mar 19 19:05:27 2013 +0200 @@ -63,6 +63,7 @@ static bool dsync_brain_recv_mailbox_attribute(struct dsync_brain *brain) { const struct dsync_mailbox_attribute *attr; + struct istream *input; enum dsync_ibc_recv_ret ret; if ((ret = dsync_ibc_recv_mailbox_attribute(brain->ibc, &attr)) == 0) @@ -73,6 +74,9 @@ } if (dsync_mailbox_import_attribute(brain->box_importer, attr) < 0) brain->failed = TRUE; + input = attr->value_stream; + if (input != NULL) + i_stream_unref(&input); return TRUE; } diff -r 46b223892373 -r 0e5a359b7b7f src/doveadm/dsync/dsync-ibc-stream.c --- a/src/doveadm/dsync/dsync-ibc-stream.c Tue Mar 19 18:52:39 2013 +0200 +++ b/src/doveadm/dsync/dsync-ibc-stream.c Tue Mar 19 19:05:27 2013 +0200 @@ -99,7 +99,7 @@ { .name = "mailbox_attribute", .chr = 'A', .required_keys = "type key", - .optional_keys = "value deleted last_change modseq" + .optional_keys = "value stream deleted last_change modseq" }, { .name = "mail_change", .chr = 'C', @@ -142,9 +142,10 @@ pool_t ret_pool; struct dsync_deserializer_decoder *cur_decoder; - struct istream *mail_output, *mail_input; + struct istream *value_output, *value_input; struct dsync_mail *cur_mail; - char mail_output_last; + struct dsync_mailbox_attribute *cur_attr; + char value_output_last; unsigned int version_received:1; unsigned int handshake_received:1; @@ -163,21 +164,21 @@ static int dsync_ibc_stream_read_mail_stream(struct dsync_ibc_stream *ibc) { do { - i_stream_skip(ibc->mail_input, - i_stream_get_data_size(ibc->mail_input)); - } while (i_stream_read(ibc->mail_input) > 0); - if (ibc->mail_input->eof) { - if (ibc->mail_input->stream_errno != 0) { - errno = ibc->mail_input->stream_errno; + i_stream_skip(ibc->value_input, + i_stream_get_data_size(ibc->value_input)); + } while (i_stream_read(ibc->value_input) > 0); + if (ibc->value_input->eof) { + if (ibc->value_input->stream_errno != 0) { + errno = ibc->value_input->stream_errno; i_error("dsync(%s): read() failed: %m", ibc->name); dsync_ibc_stream_stop(ibc); return -1; } /* finished reading the mail stream */ - i_assert(ibc->mail_input->eof); - i_stream_seek(ibc->mail_input, 0); + i_assert(ibc->value_input->eof); + i_stream_seek(ibc->value_input, 0); ibc->has_pending_data = TRUE; - ibc->mail_input = NULL; + ibc->value_input = NULL; return 1; } return 0; @@ -185,7 +186,7 @@ static void dsync_ibc_stream_input(struct dsync_ibc_stream *ibc) { - if (ibc->mail_input != NULL) { + if (ibc->value_input != NULL) { if (dsync_ibc_stream_read_mail_stream(ibc) == 0) return; } @@ -194,19 +195,19 @@ o_stream_uncork(ibc->output); } -static int dsync_ibc_stream_send_mail_stream(struct dsync_ibc_stream *ibc) +static int dsync_ibc_stream_send_value_stream(struct dsync_ibc_stream *ibc) { const unsigned char *data; unsigned char add; size_t i, size; int ret; - while ((ret = i_stream_read_data(ibc->mail_output, + while ((ret = i_stream_read_data(ibc->value_output, &data, &size, 0)) > 0) { add = '\0'; for (i = 0; i < size; i++) { if (data[i] == '.' && - ((i == 0 && ibc->mail_output_last == '\n') || + ((i == 0 && ibc->value_output_last == '\n') || (i > 0 && data[i-1] == '\n'))) { /* escape the dot */ add = '.'; @@ -216,8 +217,8 @@ if (i > 0) { o_stream_nsend(ibc->output, data, i); - ibc->mail_output_last = data[i-1]; - i_stream_skip(ibc->mail_output, i); + ibc->value_output_last = data[i-1]; + i_stream_skip(ibc->value_output, i); } if (o_stream_get_buffer_used_size(ibc->output) >= 4096) { @@ -234,14 +235,14 @@ if (add != '\0') { o_stream_nsend(ibc->output, &add, 1); - ibc->mail_output_last = add; + ibc->value_output_last = add; } } i_assert(ret == -1); - if (ibc->mail_output->stream_errno != 0) { + if (ibc->value_output->stream_errno != 0) { i_error("dsync(%s): read(%s) failed: %m", - ibc->name, i_stream_get_name(ibc->mail_output)); + ibc->name, i_stream_get_name(ibc->value_output)); dsync_ibc_stream_stop(ibc); return -1; } @@ -249,7 +250,7 @@ /* finished sending the stream. use "CRLF." instead of "LF." just in case we're sending binary data that ends with CR. */ o_stream_nsend_str(ibc->output, "\r\n.\r\n"); - i_stream_unref(&ibc->mail_output); + i_stream_unref(&ibc->value_output); return 1; } @@ -261,8 +262,8 @@ o_stream_cork(ibc->output); if ((ret = o_stream_flush(output)) < 0) ret = 1; - else if (ibc->mail_output != NULL) { - if (dsync_ibc_stream_send_mail_stream(ibc) < 0) + else if (ibc->value_output != NULL) { + if (dsync_ibc_stream_send_value_stream(ibc) < 0) ret = 1; } timeout_reset(ibc->to); @@ -320,8 +321,8 @@ if (ibc->cur_decoder != NULL) dsync_deserializer_decode_finish(&ibc->cur_decoder); - if (ibc->mail_output != NULL) - i_stream_unref(&ibc->mail_output); + if (ibc->value_output != NULL) + i_stream_unref(&ibc->value_output); else { /* notify remote that we're closing. this is mainly to avoid "read() failed: EOF" errors on failing dsyncs */ @@ -399,10 +400,50 @@ dsync_ibc_stream_send_string(struct dsync_ibc_stream *ibc, const string_t *str) { - i_assert(ibc->mail_output == NULL); + i_assert(ibc->value_output == NULL); o_stream_nsend(ibc->output, str_data(str), str_len(str)); } +static int seekable_fd_callback(const char **path_r, void *context) +{ + struct dsync_ibc_stream *ibc = context; + string_t *path; + int fd; + + path = t_str_new(128); + str_append(path, ibc->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)); + 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_close_fd(&fd); + return -1; + } + + *path_r = str_c(path); + return fd; +} + +static struct istream * +dsync_ibc_stream_input_stream(struct dsync_ibc_stream *ibc) +{ + struct istream *inputs[2]; + + inputs[0] = i_stream_create_dot(ibc->input, FALSE); + inputs[1] = NULL; + ibc->value_input = i_stream_create_seekable(inputs, MAIL_READ_FULL_BLOCK_SIZE, + seekable_fd_callback, ibc); + i_stream_unref(&inputs[0]); + + return ibc->value_input; +} + static int dsync_ibc_check_missing_deserializers(struct dsync_ibc_stream *ibc) { @@ -483,7 +524,7 @@ const char *line, *error; unsigned int i; - i_assert(ibc->mail_input == NULL); + i_assert(ibc->value_input == NULL); timeout_reset(ibc->to); @@ -659,7 +700,7 @@ { struct dsync_ibc_stream *ibc = (struct dsync_ibc_stream *)_ibc; - i_assert(ibc->mail_output == NULL); + i_assert(ibc->value_output == NULL); o_stream_nsend_str(ibc->output, END_OF_LIST_LINE"\n"); } @@ -1218,6 +1259,8 @@ dsync_serializer_encode_add(encoder, "key", attr->key); if (attr->value != NULL) dsync_serializer_encode_add(encoder, "value", attr->value); + else if (attr->value_stream != NULL) + dsync_serializer_encode_add(encoder, "stream", ""); if (attr->deleted) dsync_serializer_encode_add(encoder, "deleted", ""); @@ -1232,6 +1275,13 @@ dsync_serializer_encode_finish(&encoder, str); dsync_ibc_stream_send_string(ibc, str); + + if (attr->value_stream != NULL) { + ibc->value_output_last = '\0'; + ibc->value_output = attr->value_stream; + i_stream_ref(ibc->value_output); + (void)dsync_ibc_stream_send_value_stream(ibc); + } } static enum dsync_ibc_recv_ret @@ -1248,6 +1298,13 @@ if (ibc->minor_version < DSYNC_PROTOCOL_MINOR_HAVE_ATTRIBUTES) return DSYNC_IBC_RECV_RET_FINISHED; + if (ibc->cur_attr != NULL) { + /* finished reading the stream, return the mail now */ + *attr_r = ibc->cur_attr; + ibc->cur_attr = NULL; + return DSYNC_IBC_RECV_RET_OK; + } + p_clear(pool); attr = p_new(pool, struct dsync_mailbox_attribute, 1); @@ -1271,7 +1328,15 @@ value = dsync_deserializer_decode_get(decoder, "key"); attr->key = p_strdup(pool, value); - if (dsync_deserializer_decode_try(decoder, "value", &value)) + if (dsync_deserializer_decode_try(decoder, "stream", &value)) { + attr->value_stream = dsync_ibc_stream_input_stream(ibc); + if (dsync_ibc_stream_read_mail_stream(ibc) <= 0) { + ibc->cur_attr = attr; + return DSYNC_IBC_RECV_RET_TRYAGAIN; + } + /* already finished reading the stream */ + i_assert(ibc->value_input == NULL); + } else if (dsync_deserializer_decode_try(decoder, "value", &value)) attr->value = p_strdup(pool, value); if (dsync_deserializer_decode_try(decoder, "deleted", &value)) attr->deleted = TRUE; @@ -1512,7 +1577,7 @@ struct dsync_serializer_encoder *encoder; string_t *str = t_str_new(128); - i_assert(ibc->mail_output == NULL); + i_assert(ibc->value_output == NULL); From dovecot at dovecot.org Tue Mar 19 23:30:04 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 19 Mar 2013 23:30:04 +0200 Subject: dovecot-2.2: lib-storage: Added a way to create plugins that for... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7a334ebc0145 changeset: 16053:7a334ebc0145 user: Timo Sirainen date: Tue Mar 19 19:08:17 2013 +0200 description: lib-storage: Added a way to create plugins that forcibly hook into mail storage. Mostly meant for doveadm_sieve plugin. diffstat: src/lib-storage/mail-storage-hooks.c | 20 ++++++++++++++++++-- src/lib-storage/mail-storage-hooks.h | 4 ++++ src/lib-storage/mail-storage-private.h | 3 +++ 3 files changed, 25 insertions(+), 2 deletions(-) diffs (81 lines): diff -r 0e5a359b7b7f -r 7a334ebc0145 src/lib-storage/mail-storage-hooks.c --- a/src/lib-storage/mail-storage-hooks.c Tue Mar 19 19:05:27 2013 +0200 +++ b/src/lib-storage/mail-storage-hooks.c Tue Mar 19 19:08:17 2013 +0200 @@ -12,6 +12,7 @@ struct mail_storage_module_hooks { struct module *module; const struct mail_storage_hooks *hooks; + bool forced; }; struct hook_stack { @@ -41,7 +42,8 @@ void mail_storage_hooks_init(void) { - i_array_init(&module_hooks, 32); + if (!array_is_created(&module_hooks)) + i_array_init(&module_hooks, 32); i_array_init(&internal_hooks, 8); } @@ -60,9 +62,23 @@ new_hook.module = module; new_hook.hooks = hooks; + /* allow adding hooks before mail_storage_hooks_init() */ + if (!array_is_created(&module_hooks)) + i_array_init(&module_hooks, 32); array_append(&module_hooks, &new_hook, 1); } +void mail_storage_hooks_add_forced(struct module *module, + const struct mail_storage_hooks *hooks) +{ + struct mail_storage_module_hooks *hook; + + mail_storage_hooks_add(module, hooks); + hook = array_idx_modifiable(&module_hooks, + array_count(&module_hooks)-1); + hook->forced = TRUE; +} + void mail_storage_hooks_remove(const struct mail_storage_hooks *hooks) { const struct mail_storage_module_hooks *module_hook; @@ -125,7 +141,7 @@ plugins = t_strsplit_spaces(user->set->mail_plugins, ", "); array_foreach(&module_hooks, module_hook) { name = module_get_plugin_name(module_hook->module); - if (str_array_find(plugins, name)) + if (str_array_find(plugins, name) || module_hook->forced) array_append(&tmp_hooks, module_hook, 1); } diff -r 0e5a359b7b7f -r 7a334ebc0145 src/lib-storage/mail-storage-hooks.h --- a/src/lib-storage/mail-storage-hooks.h Tue Mar 19 19:05:27 2013 +0200 +++ b/src/lib-storage/mail-storage-hooks.h Tue Mar 19 19:08:17 2013 +0200 @@ -25,6 +25,10 @@ void mail_storage_hooks_add(struct module *module, const struct mail_storage_hooks *hooks); +/* Add hooks to this plugin regardless of whether it exists in user's + mail_plugins setting. */ +void mail_storage_hooks_add_forced(struct module *module, + const struct mail_storage_hooks *hooks); void mail_storage_hooks_remove(const struct mail_storage_hooks *hooks); void mail_storage_hooks_add_internal(const struct mail_storage_hooks *hooks); diff -r 0e5a359b7b7f -r 7a334ebc0145 src/lib-storage/mail-storage-private.h --- a/src/lib-storage/mail-storage-private.h Tue Mar 19 19:05:27 2013 +0200 +++ b/src/lib-storage/mail-storage-private.h Tue Mar 19 19:08:17 2013 +0200 @@ -644,6 +644,9 @@ unsigned int mail_storage_get_lock_timeout(struct mail_storage *storage, unsigned int secs); void mail_storage_free_binary_cache(struct mail_storage *storage); +int mailbox_attribute_value_to_string(struct mail_storage *storage, + const struct mail_attribute_value *value, + const char **str_r); enum mail_index_open_flags mail_storage_settings_to_index_flags(const struct mail_storage_settings *set); From dovecot at dovecot.org Tue Mar 19 23:32:06 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 19 Mar 2013 23:32:06 +0200 Subject: dovecot-2.2: Compiler warning fix. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a4c01707feb7 changeset: 16054:a4c01707feb7 user: Timo Sirainen date: Tue Mar 19 23:31:41 2013 +0200 description: Compiler warning fix. diffstat: src/doveadm/dsync/dsync-mailbox.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 7a334ebc0145 -r a4c01707feb7 src/doveadm/dsync/dsync-mailbox.c --- a/src/doveadm/dsync/dsync-mailbox.c Tue Mar 19 19:08:17 2013 +0200 +++ b/src/doveadm/dsync/dsync-mailbox.c Tue Mar 19 23:31:41 2013 +0200 @@ -1,6 +1,7 @@ /* Copyright (c) 2013 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "istream.h" #include "dsync-mailbox.h" void dsync_mailbox_attribute_dup(pool_t pool, From dovecot at dovecot.org Wed Mar 20 09:59:43 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 09:59:43 +0200 Subject: dovecot-2.2: dsync: Fixed attribute value comparisons. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8b5c098cbd0f changeset: 16055:8b5c098cbd0f user: Timo Sirainen date: Wed Mar 20 09:59:27 2013 +0200 description: dsync: Fixed attribute value comparisons. diffstat: src/doveadm/dsync/dsync-mailbox-import.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (19 lines): diff -r a4c01707feb7 -r 8b5c098cbd0f src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Tue Mar 19 23:31:41 2013 +0200 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Wed Mar 20 09:59:27 2013 +0200 @@ -317,11 +317,13 @@ if (DSYNC_ATTR_HAS_VALUE(attr) && !DSYNC_ATTR_HAS_VALUE(local_attr)) { /* remote has a value and local doesn't -> use it */ - return 1; + *cmp_r = 1; + return 0; } else if (!DSYNC_ATTR_HAS_VALUE(attr) && DSYNC_ATTR_HAS_VALUE(local_attr)) { /* remote doesn't have a value, bt local does -> skip */ - return -1; + *cmp_r = -1; + return 0; } return dsync_attributes_cmp_values(attr, local_attr, cmp_r); From dovecot at dovecot.org Wed Mar 20 17:10:52 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 17:10:52 +0200 Subject: dovecot-2.2: lib-fs: Fixed fs_default_copy() to work with async ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/653d81709dd0 changeset: 16057:653d81709dd0 user: Timo Sirainen date: Wed Mar 20 17:10:47 2013 +0200 description: lib-fs: Fixed fs_default_copy() to work with async writes. diffstat: src/lib-fs/fs-api.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r fccd79d41d37 -r 653d81709dd0 src/lib-fs/fs-api.c --- a/src/lib-fs/fs-api.c Wed Mar 20 12:04:39 2013 +0200 +++ b/src/lib-fs/fs-api.c Wed Mar 20 17:10:47 2013 +0200 @@ -449,7 +449,7 @@ i_assert(src == NULL || src == dest->copy_src); if (dest->copy_output == NULL) { i_assert(dest->copy_input == NULL); - if (fs_write_stream_finish_async(dest) < 0) + if (fs_write_stream_finish_async(dest) <= 0) return -1; dest->copy_src = NULL; return 0; @@ -477,7 +477,7 @@ return -1; } i_stream_unref(&dest->copy_input); - if (fs_write_stream_finish(dest, &dest->copy_output) < 0) + if (fs_write_stream_finish(dest, &dest->copy_output) <= 0) return -1; dest->copy_src = NULL; return 0; From dovecot at dovecot.org Wed Mar 20 17:10:52 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 17:10:52 +0200 Subject: dovecot-2.2: replicator: Renamed doveadm-connection to dsync-cli... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fccd79d41d37 changeset: 16056:fccd79d41d37 user: Timo Sirainen date: Wed Mar 20 12:04:39 2013 +0200 description: replicator: Renamed doveadm-connection to dsync-client. diffstat: src/replication/replicator/Makefile.am | 4 +- src/replication/replicator/doveadm-connection.c | 223 ------------------------ src/replication/replicator/doveadm-connection.h | 21 -- src/replication/replicator/dsync-client.c | 223 ++++++++++++++++++++++++ src/replication/replicator/dsync-client.h | 21 ++ src/replication/replicator/replicator-brain.c | 49 ++-- 6 files changed, 270 insertions(+), 271 deletions(-) diffs (truncated from 658 to 300 lines): diff -r 8b5c098cbd0f -r fccd79d41d37 src/replication/replicator/Makefile.am --- a/src/replication/replicator/Makefile.am Wed Mar 20 09:59:27 2013 +0200 +++ b/src/replication/replicator/Makefile.am Wed Mar 20 12:04:39 2013 +0200 @@ -15,7 +15,7 @@ replicator_DEPENDENCIES = $(LIBDOVECOT_DEPS) replicator_SOURCES = \ - doveadm-connection.c \ + dsync-client.c \ replicator.c \ replicator-brain.c \ replicator-queue.c \ @@ -23,7 +23,7 @@ notify-connection.c noinst_HEADERS = \ - doveadm-connection.h \ + dsync-client.h \ replicator-brain.h \ replicator-queue.h \ replicator-settings.h \ diff -r 8b5c098cbd0f -r fccd79d41d37 src/replication/replicator/doveadm-connection.c --- a/src/replication/replicator/doveadm-connection.c Wed Mar 20 09:59:27 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,223 +0,0 @@ -/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */ - -#include "lib.h" -#include "ioloop.h" -#include "net.h" -#include "istream.h" -#include "ostream.h" -#include "str.h" -#include "strescape.h" -#include "doveadm-connection.h" - -#include - -#define DOVEADM_FAIL_TIMEOUT_MSECS (1000*5) -#define DOVEADM_HANDSHAKE "VERSION\tdoveadm-server\t1\t0\n" - -/* normally there shouldn't be any need for locking, since replicator doesn't - start dsync in parallel for the same user. we'll do locking just in case - anyway */ -#define DSYNC_LOCK_TIMEOUT_SECS 30 - -struct doveadm_connection { - char *path; - int fd; - struct io *io; - struct istream *input; - struct ostream *output; - struct timeout *to; - - char *state; - doveadm_callback_t *callback; - void *context; - - time_t last_connect_failure; - unsigned int handshaked:1; - unsigned int cmd_sent:1; -}; - -struct doveadm_connection *doveadm_connection_init(const char *path) -{ - struct doveadm_connection *conn; - - conn = i_new(struct doveadm_connection, 1); - conn->path = i_strdup(path); - conn->fd = -1; - return conn; -} - -static void doveadm_callback(struct doveadm_connection *conn, - const char *state, enum doveadm_reply reply) -{ - doveadm_callback_t *callback = conn->callback; - void *context = conn->context; - - if (conn->to != NULL) - timeout_remove(&conn->to); - - conn->callback = NULL; - conn->context = NULL; - - /* make sure callback doesn't try to reuse this connection, since - we can't currently handle it */ - i_assert(!conn->cmd_sent); - conn->cmd_sent = TRUE; - callback(reply, state, context); - conn->cmd_sent = FALSE; -} - -static void doveadm_close(struct doveadm_connection *conn) -{ - if (conn->fd == -1) - return; - - io_remove(&conn->io); - o_stream_destroy(&conn->output); - i_stream_destroy(&conn->input); - if (close(conn->fd) < 0) - i_error("close(doveadm) failed: %m"); - conn->fd = -1; - i_free_and_null(conn->state); - conn->cmd_sent = FALSE; - conn->handshaked = FALSE; -} - -static void doveadm_disconnect(struct doveadm_connection *conn) -{ - doveadm_close(conn); - if (conn->callback != NULL) - doveadm_callback(conn, "", DOVEADM_REPLY_FAIL); -} - -void doveadm_connection_deinit(struct doveadm_connection **_conn) -{ - struct doveadm_connection *conn = *_conn; - - *_conn = NULL; - - doveadm_disconnect(conn); - i_free(conn->path); - i_free(conn); -} - -static int doveadm_input_line(struct doveadm_connection *conn, const char *line) -{ - const char *state; - - if (!conn->handshaked) { - if (strcmp(line, "+") != 0) { - i_error("%s: Unexpected handshake: %s", - conn->path, line); - return -1; - } - conn->handshaked = TRUE; - return 0; - } - if (conn->callback == NULL) { - i_error("%s: Unexpected input: %s", conn->path, line); - return -1; - } - if (conn->state == NULL) { - conn->state = i_strdup(t_strcut(line, '\t')); - return 0; - } - state = t_strdup(conn->state); - line = t_strdup(line); - doveadm_close(conn); - - if (line[0] == '+') - doveadm_callback(conn, state, DOVEADM_REPLY_OK); - else if (line[0] == '-') { - if (strcmp(line+1, "NOUSER") == 0) - doveadm_callback(conn, "", DOVEADM_REPLY_NOUSER); - else - doveadm_callback(conn, "", DOVEADM_REPLY_FAIL); - } else { - i_error("%s: Invalid input: %s", conn->path, line); - return -1; - } - /* FIXME: disconnect after each request for now. - doveadm server's getopt() handling seems to break otherwise. - also with multiple UIDs doveadm-server fails because setid() fails */ - return -1; -} - -static void doveadm_input(struct doveadm_connection *conn) -{ - const char *line; - - while ((line = i_stream_read_next_line(conn->input)) != NULL) { - if (doveadm_input_line(conn, line) < 0) { - doveadm_disconnect(conn); - return; - } - } - if (conn->input->eof) - doveadm_disconnect(conn); -} - -static int doveadm_connect(struct doveadm_connection *conn) -{ - if (conn->fd != -1) - return 0; - - if (conn->last_connect_failure == ioloop_time) - return -1; - - conn->fd = net_connect_unix(conn->path); - if (conn->fd == -1) { - i_error("net_connect_unix(%s) failed: %m", conn->path); - conn->last_connect_failure = ioloop_time; - return -1; - } - conn->last_connect_failure = 0; - conn->io = io_add(conn->fd, IO_READ, doveadm_input, conn); - conn->input = i_stream_create_fd(conn->fd, (size_t)-1, FALSE); - conn->output = o_stream_create_fd(conn->fd, (size_t)-1, FALSE); - o_stream_set_no_error_handling(conn->output, TRUE); - o_stream_nsend_str(conn->output, DOVEADM_HANDSHAKE); - return 0; -} - -static void doveadm_fail_timeout(struct doveadm_connection *conn) -{ - doveadm_disconnect(conn); -} - -void doveadm_connection_sync(struct doveadm_connection *conn, - const char *username, const char *state, bool full, - doveadm_callback_t *callback, void *context) -{ - string_t *cmd; - - i_assert(callback != NULL); - i_assert(!doveadm_connection_is_busy(conn)); - - conn->cmd_sent = TRUE; - conn->callback = callback; - conn->context = context; - - if (doveadm_connect(conn) < 0) { - i_assert(conn->to == NULL); - conn->to = timeout_add(DOVEADM_FAIL_TIMEOUT_MSECS, - doveadm_fail_timeout, conn); - } else { - /* [] */ - cmd = t_str_new(256); - str_append_c(cmd, '\t'); - str_append_tabescaped(cmd, username); - str_printfa(cmd, "\tsync\t-d\t-N\t-l\t%u", DSYNC_LOCK_TIMEOUT_SECS); - if (full) - str_append(cmd, "\t-f"); - str_append(cmd, "\t-s\t"); - if (state != NULL) - str_append(cmd, state); - str_append_c(cmd, '\n'); - o_stream_nsend(conn->output, str_data(cmd), str_len(cmd)); - } -} - -bool doveadm_connection_is_busy(struct doveadm_connection *conn) -{ - return conn->cmd_sent; -} diff -r 8b5c098cbd0f -r fccd79d41d37 src/replication/replicator/doveadm-connection.h --- a/src/replication/replicator/doveadm-connection.h Wed Mar 20 09:59:27 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -#ifndef DOVEADM_CONNECTION_H -#define DOVEADM_CONNECTION_H - -enum doveadm_reply { - DOVEADM_REPLY_OK, - DOVEADM_REPLY_FAIL, - DOVEADM_REPLY_NOUSER -}; - -typedef void doveadm_callback_t(enum doveadm_reply reply, - const char *state, void *context); - -struct doveadm_connection *doveadm_connection_init(const char *path); -void doveadm_connection_deinit(struct doveadm_connection **conn); - -void doveadm_connection_sync(struct doveadm_connection *conn, - const char *username, const char *state, bool full, - doveadm_callback_t *callback, void *context); -bool doveadm_connection_is_busy(struct doveadm_connection *conn); - -#endif diff -r 8b5c098cbd0f -r fccd79d41d37 src/replication/replicator/dsync-client.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/replication/replicator/dsync-client.c Wed Mar 20 12:04:39 2013 +0200 @@ -0,0 +1,223 @@ +/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "ioloop.h" +#include "net.h" +#include "istream.h" +#include "ostream.h" +#include "str.h" +#include "strescape.h" +#include "dsync-client.h" + +#include + +#define DSYNC_FAIL_TIMEOUT_MSECS (1000*5) +#define DOVEADM_HANDSHAKE "VERSION\tdoveadm-server\t1\t0\n" + +/* normally there shouldn't be any need for locking, since replicator doesn't + start dsync in parallel for the same user. we'll do locking just in case + anyway */ +#define DSYNC_LOCK_TIMEOUT_SECS 30 + +struct dsync_client { + char *path; From dovecot at dovecot.org Wed Mar 20 17:44:16 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 17:44:16 +0200 Subject: dovecot-2.2: lib-storage: mailbox_rename() shouldn't require sou... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d44ae1527bc0 changeset: 16058:d44ae1527bc0 user: Timo Sirainen date: Wed Mar 20 17:43:32 2013 +0200 description: lib-storage: mailbox_rename() shouldn't require source mailbox to exist. \Noselect mailboxes may not exist. The nonexistence will be noticed eventually in the backend code. diffstat: src/lib-storage/mail-storage.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 653d81709dd0 -r d44ae1527bc0 src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Wed Mar 20 17:10:47 2013 +0200 +++ b/src/lib-storage/mail-storage.c Wed Mar 20 17:43:32 2013 +0200 @@ -1359,7 +1359,8 @@ { const char *error = NULL; - if (mailbox_verify_existing_name(src) < 0) + /* Check only name validity, \Noselect don't necessarily exist. */ + if (mailbox_verify_name(src) < 0) return -1; if (*src->name == '\0') { mail_storage_set_error(src->storage, MAIL_ERROR_PARAMS, From dovecot at dovecot.org Wed Mar 20 17:44:16 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 17:44:16 +0200 Subject: dovecot-2.2: layout=index: Don't return a path for \Noselect mai... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4649782a4213 changeset: 16059:4649782a4213 user: Timo Sirainen date: Wed Mar 20 17:44:07 2013 +0200 description: layout=index: Don't return a path for \Noselect mailboxes. diffstat: src/lib-storage/list/mailbox-list-index-backend.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r d44ae1527bc0 -r 4649782a4213 src/lib-storage/list/mailbox-list-index-backend.c --- a/src/lib-storage/list/mailbox-list-index-backend.c Wed Mar 20 17:43:32 2013 +0200 +++ b/src/lib-storage/list/mailbox-list-index-backend.c Wed Mar 20 17:44:07 2013 +0200 @@ -140,7 +140,8 @@ 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)) { + &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; From dovecot at dovecot.org Wed Mar 20 17:55:02 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 17:55:02 +0200 Subject: dovecot-2.2: imap: Fixed RESETKEY assert-crashing Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8bacc34cead9 changeset: 16060:8bacc34cead9 user: Timo Sirainen date: Wed Mar 20 17:54:52 2013 +0200 description: imap: Fixed RESETKEY assert-crashing diffstat: src/imap/cmd-resetkey.c | 15 +++------------ 1 files changed, 3 insertions(+), 12 deletions(-) diffs (33 lines): diff -r 4649782a4213 -r 8bacc34cead9 src/imap/cmd-resetkey.c --- a/src/imap/cmd-resetkey.c Wed Mar 20 17:44:07 2013 +0200 +++ b/src/imap/cmd-resetkey.c Wed Mar 20 17:54:52 2013 +0200 @@ -20,7 +20,6 @@ cmd_resetkey_mailbox(struct client_command_context *cmd, const char *mailbox, const struct imap_arg *mech_args) { - enum mailbox_existence existence; struct mail_namespace *ns; enum mailbox_flags flags = MAILBOX_FLAG_READONLY; struct mailbox *box; @@ -49,18 +48,10 @@ if (ns == NULL) return TRUE; - /* check mailbox */ + /* open mailbox */ box = mailbox_alloc(ns->list, mailbox, flags); - if (mailbox_exists(box, TRUE, &existence) < 0) { - client_send_internal_error(cmd); - mailbox_free(&box); - return TRUE; - } - - if (existence == MAILBOX_EXISTENCE_NONE) { - client_send_tagline(cmd, t_strdup_printf( - "NO ["IMAP_RESP_CODE_NONEXISTENT"] " - MAIL_ERRSTR_MAILBOX_NOT_FOUND, mailbox)); + if (mailbox_open(box) < 0) { + client_send_storage_error(cmd, mailbox_get_storage(box)); mailbox_free(&box); return TRUE; } From dovecot at dovecot.org Wed Mar 20 17:59:38 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 17:59:38 +0200 Subject: dovecot-2.2: layout=index: Fixed mailbox_exists() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c742a7bf48a6 changeset: 16061:c742a7bf48a6 user: Timo Sirainen date: Wed Mar 20 17:59:32 2013 +0200 description: layout=index: Fixed mailbox_exists() diffstat: src/lib-storage/list/mailbox-list-index-backend.c | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-) diffs (32 lines): diff -r 8bacc34cead9 -r c742a7bf48a6 src/lib-storage/list/mailbox-list-index-backend.c --- a/src/lib-storage/list/mailbox-list-index-backend.c Wed Mar 20 17:54:52 2013 +0200 +++ b/src/lib-storage/list/mailbox-list-index-backend.c Wed Mar 20 17:59:32 2013 +0200 @@ -363,6 +363,20 @@ return 0; } +static int +index_list_mailbox_exists(struct mailbox *box, bool auto_boxes ATTR_UNUSED, + enum mailbox_existence *existence_r) +{ + struct index_mailbox_list *list = + (struct index_mailbox_list *)box->list; + + if (index_list_node_exists(list, box->name, existence_r) < 0) { + mail_storage_copy_list_error(box->storage, box->list); + return -1; + } + return 0; +} + static void index_list_try_delete(struct index_mailbox_list *list, const char *name, enum mailbox_list_path_type type) @@ -663,6 +677,7 @@ return; box->v.create_box = index_list_mailbox_create; box->v.update_box = index_list_mailbox_update; + box->v.exists = index_list_mailbox_exists; box->v.list_index_has_changed = NULL; box->v.list_index_update_sync = NULL; From dovecot at dovecot.org Wed Mar 20 18:09:55 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 18:09:55 +0200 Subject: dovecot-2.2: acl: Put ACL files to control dir if storage doesn'... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/abd9763e91d1 changeset: 16062:abd9763e91d1 user: Timo Sirainen date: Wed Mar 20 18:09:46 2013 +0200 description: acl: Put ACL files to control dir if storage doesn't have a mail directory. diffstat: src/plugins/acl/acl-backend-vfile-acllist.c | 15 +++++++++------ src/plugins/acl/acl-backend-vfile.c | 6 +++++- 2 files changed, 14 insertions(+), 7 deletions(-) diffs (43 lines): diff -r c742a7bf48a6 -r abd9763e91d1 src/plugins/acl/acl-backend-vfile-acllist.c --- a/src/plugins/acl/acl-backend-vfile-acllist.c Wed Mar 20 17:59:32 2013 +0200 +++ b/src/plugins/acl/acl-backend-vfile-acllist.c Wed Mar 20 18:09:46 2013 +0200 @@ -44,14 +44,17 @@ { struct mail_storage *storage; const char *rootdir, *maildir; - - if (!mailbox_list_get_root_path(backend->backend.list, - MAILBOX_LIST_PATH_TYPE_DIR, &rootdir)) - return FALSE; - *type_r = MAILBOX_LIST_PATH_TYPE_DIR; + enum mailbox_list_path_type type; storage = mailbox_list_get_namespace(backend->backend.list)->storage; - if (mail_storage_is_mailbox_file(storage)) { + type = (storage->class_flags & MAIL_STORAGE_CLASS_FLAG_NO_ROOT) != 0 ? + MAILBOX_LIST_PATH_TYPE_CONTROL : MAILBOX_LIST_PATH_TYPE_DIR; + if (!mailbox_list_get_root_path(backend->backend.list, type, &rootdir)) + return FALSE; + *type_r = type; + + if (type == MAILBOX_LIST_PATH_TYPE_DIR && + mail_storage_is_mailbox_file(storage)) { maildir = mailbox_list_get_root_forced(backend->backend.list, MAILBOX_LIST_PATH_TYPE_MAILBOX); if (strcmp(maildir, rootdir) == 0) { diff -r c742a7bf48a6 -r abd9763e91d1 src/plugins/acl/acl-backend-vfile.c --- a/src/plugins/acl/acl-backend-vfile.c Wed Mar 20 17:59:32 2013 +0200 +++ b/src/plugins/acl/acl-backend-vfile.c Wed Mar 20 18:09:46 2013 +0200 @@ -138,7 +138,11 @@ else if (!mailbox_list_is_valid_name(ns->list, name, &error)) return NULL; - type = mail_storage_is_mailbox_file(ns->storage) ? + /* ACL files are very important. try to keep them among the main + mail files. that's not possible though with a) if the mailbox is + a file or b) if the mailbox path doesn't point to filesystem. */ + type = mail_storage_is_mailbox_file(ns->storage) || + (ns->storage->class_flags & MAIL_STORAGE_CLASS_FLAG_NO_ROOT) != 0 ? MAILBOX_LIST_PATH_TYPE_CONTROL : MAILBOX_LIST_PATH_TYPE_MAILBOX; if (name == NULL) { if (!mailbox_list_get_root_path(ns->list, type, &dir)) From dovecot at dovecot.org Wed Mar 20 18:24:33 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 18:24:33 +0200 Subject: dovecot-2.2: lib-lda: Send QUIT after DATA replies have been rec... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b61be8a47126 changeset: 16063:b61be8a47126 user: Timo Sirainen date: Wed Mar 20 18:24:21 2013 +0200 description: lib-lda: Send QUIT after DATA replies have been received. diffstat: src/lib-lda/lmtp-client.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (15 lines): diff -r abd9763e91d1 -r b61be8a47126 src/lib-lda/lmtp-client.c --- a/src/lib-lda/lmtp-client.c Wed Mar 20 18:09:46 2013 +0200 +++ b/src/lib-lda/lmtp-client.c Wed Mar 20 18:24:21 2013 +0200 @@ -277,9 +277,10 @@ if (client->protocol == LMTP_CLIENT_PROTOCOL_LMTP) break; } - if (i < count) + if (client->rcpt_next_data_idx < count) return 0; + o_stream_send_str(client->output, "QUIT\r\n"); lmtp_client_close(client); return -1; } From dovecot at dovecot.org Wed Mar 20 18:46:21 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 18:46:21 +0200 Subject: dovecot-2.1: fts: Fixed crash when searching virtual mailboxes a... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/87a9eec10145 changeset: 14932:87a9eec10145 user: Timo Sirainen date: Wed Mar 20 18:46:10 2013 +0200 description: fts: Fixed crash when searching virtual mailboxes and fts backend without lookup_multi(). Patch by Mike Abbott / Apple diffstat: src/plugins/fts/fts-api.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diffs (18 lines): diff -r a7928075f0fd -r 87a9eec10145 src/plugins/fts/fts-api.c --- a/src/plugins/fts/fts-api.c Mon Mar 04 15:53:42 2013 +0200 +++ b/src/plugins/fts/fts-api.c Wed Mar 20 18:46:10 2013 +0200 @@ -337,8 +337,13 @@ result->box_results = p_new(result->pool, struct fts_result, i+1); for (i = 0; boxes[i] != NULL; i++) { + struct fts_result *box_result = &result->box_results[i]; + + p_array_init(&box_result->definite_uids, result->pool, 32); + p_array_init(&box_result->maybe_uids, result->pool, 32); + p_array_init(&box_result->scores, result->pool, 32); if (backend->v.lookup(backend, boxes[i], args, - and_args, &result->box_results[i]) < 0) + and_args, box_result) < 0) return -1; } return 0; From dovecot at dovecot.org Wed Mar 20 18:53:01 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 18:53:01 +0200 Subject: dovecot-2.2: example-config: Removed a warning about mail_attach... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1ae6a51450f2 changeset: 16064:1ae6a51450f2 user: Timo Sirainen date: Wed Mar 20 18:52:51 2013 +0200 description: example-config: Removed a warning about mail_attachment_dir not being tested. diffstat: doc/example-config/conf.d/10-mail.conf | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diffs (12 lines): diff -r b61be8a47126 -r 1ae6a51450f2 doc/example-config/conf.d/10-mail.conf --- a/doc/example-config/conf.d/10-mail.conf Wed Mar 20 18:24:21 2013 +0200 +++ b/doc/example-config/conf.d/10-mail.conf Wed Mar 20 18:52:51 2013 +0200 @@ -345,8 +345,6 @@ # also allows single instance storage for them. Other backends don't support # this for now. -# WARNING: This feature hasn't been tested much yet. Use at your own risk. - # Directory root where to store mail attachments. Disabled, if empty. #mail_attachment_dir = From dovecot at dovecot.org Wed Mar 20 19:18:07 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 19:18:07 +0200 Subject: dovecot-2.2: imap: Don't crash with invalid FETCH BODY[sections] Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ab434891f2af changeset: 16065:ab434891f2af user: Timo Sirainen date: Wed Mar 20 19:18:01 2013 +0200 description: imap: Don't crash with invalid FETCH BODY[sections] diffstat: src/imap/imap-fetch-body.c | 2 +- src/lib-imap-storage/imap-msgpart.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diffs (25 lines): diff -r 1ae6a51450f2 -r ab434891f2af src/imap/imap-fetch-body.c --- a/src/imap/imap-fetch-body.c Wed Mar 20 18:52:51 2013 +0200 +++ b/src/imap/imap-fetch-body.c Wed Mar 20 19:18:01 2013 +0200 @@ -357,7 +357,7 @@ } if (imap_msgpart_parse(body->section, &body->msgpart) < 0) { ctx->error = "Invalid BODY[..] section"; - return -1; + return FALSE; } ctx->fetch_ctx->fetch_data |= imap_msgpart_get_fetch_data(body->msgpart); diff -r 1ae6a51450f2 -r ab434891f2af src/lib-imap-storage/imap-msgpart.c --- a/src/lib-imap-storage/imap-msgpart.c Wed Mar 20 18:52:51 2013 +0200 +++ b/src/lib-imap-storage/imap-msgpart.c Wed Mar 20 19:18:01 2013 +0200 @@ -288,7 +288,8 @@ else msgpart->wanted_fields |= MAIL_FETCH_STREAM_BODY; } else { - i_unreached(); + imap_msgpart_free(&msgpart); + return -1; } return 0; } From dovecot at dovecot.org Wed Mar 20 20:17:27 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 20:17:27 +0200 Subject: dovecot-2.2: layout=fs: Fixed assert-crash when mail root doesn'... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fb934cb4a37e changeset: 16066:fb934cb4a37e user: Timo Sirainen date: Wed Mar 20 20:17:15 2013 +0200 description: layout=fs: Fixed assert-crash when mail root doesn't exist (pop3c). diffstat: src/lib-storage/list/mailbox-list-fs-iter.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (16 lines): diff -r ab434891f2af -r fb934cb4a37e src/lib-storage/list/mailbox-list-fs-iter.c --- a/src/lib-storage/list/mailbox-list-fs-iter.c Wed Mar 20 19:18:01 2013 +0200 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Wed Mar 20 20:17:15 2013 +0200 @@ -237,8 +237,10 @@ } if (*path != '/') { /* non-absolute path. add the mailbox root dir as prefix. */ - root = mailbox_list_get_root_forced(ctx->ctx.list, - MAILBOX_LIST_PATH_TYPE_MAILBOX); + if (!mailbox_list_get_root_path(ctx->ctx.list, + MAILBOX_LIST_PATH_TYPE_MAILBOX, + &root)) + return FALSE; path = *path == '\0' ? root : t_strconcat(root, "/", path, NULL); } From dovecot at dovecot.org Wed Mar 20 20:24:42 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 20:24:42 +0200 Subject: dovecot-2.2: dsync: Don't crash when requested mail doesn't have... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/19ce7403114f changeset: 16067:19ce7403114f user: Timo Sirainen date: Wed Mar 20 20:24:31 2013 +0200 description: dsync: Don't crash when requested mail doesn't have a GUID. diffstat: src/doveadm/dsync/dsync-ibc.c | 2 +- src/doveadm/dsync/dsync-mail.h | 2 +- src/doveadm/dsync/dsync-mailbox-export.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diffs (36 lines): diff -r fb934cb4a37e -r 19ce7403114f src/doveadm/dsync/dsync-ibc.c --- a/src/doveadm/dsync/dsync-ibc.c Wed Mar 20 20:17:15 2013 +0200 +++ b/src/doveadm/dsync/dsync-ibc.c Wed Mar 20 20:24:31 2013 +0200 @@ -163,7 +163,7 @@ dsync_ibc_send_mail_request(struct dsync_ibc *ibc, const struct dsync_mail_request *request) { - i_assert(*request->guid != '\0' || request->uid != 0); + i_assert(request->guid != NULL || request->uid != 0); T_BEGIN { ibc->v.send_mail_request(ibc, request); diff -r fb934cb4a37e -r 19ce7403114f src/doveadm/dsync/dsync-mail.h --- a/src/doveadm/dsync/dsync-mail.h Wed Mar 20 20:17:15 2013 +0200 +++ b/src/doveadm/dsync/dsync-mail.h Wed Mar 20 20:24:31 2013 +0200 @@ -26,7 +26,7 @@ }; struct dsync_mail_request { - /* either GUID="" or uid=0 */ + /* either GUID=NULL or uid=0 */ const char *guid; uint32_t uid; }; diff -r fb934cb4a37e -r 19ce7403114f src/doveadm/dsync/dsync-mailbox-export.c --- a/src/doveadm/dsync/dsync-mailbox-export.c Wed Mar 20 20:17:15 2013 +0200 +++ b/src/doveadm/dsync/dsync-mailbox-export.c Wed Mar 20 20:24:31 2013 +0200 @@ -762,7 +762,7 @@ i_assert(!exporter->auto_export_mails); - if (*request->guid == '\0') { + if (request->guid == NULL) { i_assert(request->uid > 0); seq_range_array_add(&exporter->requested_uids, request->uid); return; From dovecot at dovecot.org Wed Mar 20 20:57:09 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 20:57:09 +0200 Subject: dovecot-2.2: dsync: Avoid a creating a lot of searches for each ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1a5a0b7cf37a changeset: 16068:1a5a0b7cf37a user: Timo Sirainen date: Wed Mar 20 20:47:14 2013 +0200 description: dsync: Avoid a creating a lot of searches for each synced mailbox. diffstat: src/doveadm/dsync/dsync-brain-mails.c | 16 +++++++++------- 1 files changed, 9 insertions(+), 7 deletions(-) diffs (31 lines): diff -r 19ce7403114f -r 1a5a0b7cf37a src/doveadm/dsync/dsync-brain-mails.c --- a/src/doveadm/dsync/dsync-brain-mails.c Wed Mar 20 20:24:31 2013 +0200 +++ b/src/doveadm/dsync/dsync-brain-mails.c Wed Mar 20 20:47:14 2013 +0200 @@ -242,18 +242,20 @@ static bool dsync_brain_send_mail(struct dsync_brain *brain) { const struct dsync_mail *mail; - bool changed = FALSE; + + if (brain->mail_requests && + brain->box_recv_state < DSYNC_BOX_STATE_MAILS) { + /* wait for mail requests to finish. we could already start + exporting, but then we're going to do quite a lot of + separate searches. especially with pipe backend we'd do + a separate search for each mail. */ + return FALSE; + } while ((mail = dsync_mailbox_export_next_mail(brain->box_exporter)) != NULL) { - changed = TRUE; if (dsync_ibc_send_mail(brain->ibc, mail) == 0) return TRUE; } - if (brain->mail_requests && - brain->box_recv_state < DSYNC_BOX_STATE_MAILS) { - /* wait for mail requests to finish */ - return changed; - } brain->box_send_state = DSYNC_BOX_STATE_DONE; dsync_ibc_send_end_of_list(brain->ibc); From dovecot at dovecot.org Wed Mar 20 20:57:09 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 20:57:09 +0200 Subject: dovecot-2.2: dsync: Fixed retrying a search when GUIDs aren't av... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3d5a065e18bb changeset: 16069:3d5a065e18bb user: Timo Sirainen date: Wed Mar 20 20:47:46 2013 +0200 description: dsync: Fixed retrying a search when GUIDs aren't available. diffstat: src/doveadm/dsync/dsync-mailbox-export.c | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-) diffs (48 lines): diff -r 1a5a0b7cf37a -r 3d5a065e18bb src/doveadm/dsync/dsync-mailbox-export.c --- a/src/doveadm/dsync/dsync-mailbox-export.c Wed Mar 20 20:47:14 2013 +0200 +++ b/src/doveadm/dsync/dsync-mailbox-export.c Wed Mar 20 20:47:46 2013 +0200 @@ -30,7 +30,7 @@ /* GUID => instances */ HASH_TABLE(char *, struct dsync_mail_guid_instances *) export_guids; ARRAY_TYPE(seq_range) requested_uids; - unsigned int requested_uid_search_idx; + ARRAY_TYPE(seq_range) search_uids; ARRAY_TYPE(seq_range) expunged_seqs; ARRAY_TYPE(const_string) expunged_guids; @@ -462,6 +462,7 @@ exporter->mails_have_guids = (flags & DSYNC_MAILBOX_EXPORTER_FLAG_MAILS_HAVE_GUIDS) != 0; p_array_init(&exporter->requested_uids, pool, 16); + p_array_init(&exporter->search_uids, pool, 16); hash_table_create(&exporter->export_guids, pool, 0, str_hash, strcmp); p_array_init(&exporter->expunged_seqs, pool, 16); p_array_init(&exporter->expunged_guids, pool, 16); @@ -688,14 +689,16 @@ /* add requested UIDs */ range = array_get(&exporter->requested_uids, &count); - for (i = exporter->requested_uid_search_idx; i < count; i++) { + for (i = 0; i < count; i++) { mailbox_get_seq_range(exporter->box, range->seq1, range->seq2, &seq1, &seq2); seq_range_array_add_range(&sarg->value.seqset, seq1, seq2); } - exporter->requested_uid_search_idx = count; + array_clear(&exporter->search_uids); + array_append_array(&exporter->search_uids, &exporter->requested_uids); + array_clear(&exporter->requested_uids); exporter->search_ctx = mailbox_search_init(exporter->trans, search_args, NULL, @@ -744,7 +747,7 @@ return -1; } - if (!seq_range_exists(&exporter->requested_uids, mail->uid)) + if (!seq_range_exists(&exporter->search_uids, mail->uid)) exporter->dsync_mail.uid = 0; else exporter->dsync_mail.guid = ""; From dovecot at dovecot.org Wed Mar 20 20:57:09 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 20:57:09 +0200 Subject: dovecot-2.2: layout=fs: Fixed crash with mbox when control dir w... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f39c649057ea changeset: 16070:f39c649057ea user: Timo Sirainen date: Wed Mar 20 20:56:58 2013 +0200 description: layout=fs: Fixed crash with mbox when control dir was enabled. diffstat: src/lib-storage/list/mailbox-list-fs.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diffs (19 lines): diff -r 3d5a065e18bb -r f39c649057ea src/lib-storage/list/mailbox-list-fs.c --- a/src/lib-storage/list/mailbox-list-fs.c Wed Mar 20 20:47:46 2013 +0200 +++ b/src/lib-storage/list/mailbox-list-fs.c Wed Mar 20 20:56:58 2013 +0200 @@ -167,10 +167,13 @@ const char *name, bool set) { struct fs_mailbox_list *list = (struct fs_mailbox_list *)_list; + enum mailbox_list_path_type type; const char *path; - path = t_strconcat(_list->set.control_dir != NULL ? - _list->set.control_dir : _list->set.root_dir, + type = _list->set.control_dir != NULL ? + MAILBOX_LIST_PATH_TYPE_CONTROL : MAILBOX_LIST_PATH_TYPE_DIR; + + path = t_strconcat(mailbox_list_get_root_forced(_list, type), "/", _list->set.subscription_fname, NULL); return subsfile_set_subscribed(_list, path, list->temp_prefix, name, set); From dovecot at dovecot.org Wed Mar 20 21:04:47 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 21:04:47 +0200 Subject: dovecot-2.2: mbox: Moved .subscriptions back to control_dir/ roo... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9a913c803608 changeset: 16071:9a913c803608 user: Timo Sirainen date: Wed Mar 20 21:04:29 2013 +0200 description: mbox: Moved .subscriptions back to control_dir/ root instead of control_dir/.imap/ diffstat: src/lib-storage/index/mbox/mbox-storage.c | 8 ++++++++ src/lib-storage/list/mailbox-list-subscriptions.c | 7 +++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diffs (42 lines): diff -r f39c649057ea -r 9a913c803608 src/lib-storage/index/mbox/mbox-storage.c --- a/src/lib-storage/index/mbox/mbox-storage.c Wed Mar 20 20:56:58 2013 +0200 +++ b/src/lib-storage/index/mbox/mbox-storage.c Wed Mar 20 21:04:29 2013 +0200 @@ -100,6 +100,14 @@ if (type == MAILBOX_LIST_PATH_TYPE_CONTROL || type == MAILBOX_LIST_PATH_TYPE_INDEX) { + if (name == NULL && type == MAILBOX_LIST_PATH_TYPE_CONTROL && + list->set.control_dir != NULL) { + /* kind of a kludge for backwards compatibility: + the subscriptions file is in the root control_dir + without .imap/ suffix */ + *path_r = path; + return 1; + } if (name == NULL) { *path_r = t_strconcat(path, "/"MBOX_INDEX_DIR_NAME, NULL); return 1; diff -r f39c649057ea -r 9a913c803608 src/lib-storage/list/mailbox-list-subscriptions.c --- a/src/lib-storage/list/mailbox-list-subscriptions.c Wed Mar 20 20:56:58 2013 +0200 +++ b/src/lib-storage/list/mailbox-list-subscriptions.c Wed Mar 20 21:04:29 2013 +0200 @@ -110,6 +110,7 @@ { struct subsfile_list_context *subsfile_ctx; struct stat st; + enum mailbox_list_path_type type; const char *path, *name; char sep; int ret; @@ -122,8 +123,10 @@ sep = mail_namespace_get_sep(src_list->ns); dest_list->subscriptions = mailbox_tree_init(sep); } - path = t_strconcat(src_list->set.control_dir != NULL ? - src_list->set.control_dir : src_list->set.root_dir, + + type = src_list->set.control_dir != NULL ? + MAILBOX_LIST_PATH_TYPE_CONTROL : MAILBOX_LIST_PATH_TYPE_DIR; + path = t_strconcat(mailbox_list_get_root_forced(src_list, type), "/", src_list->set.subscription_fname, NULL); if (stat(path, &st) < 0) { if (errno == ENOENT) { From dovecot at dovecot.org Wed Mar 20 21:14:03 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 21:14:03 +0200 Subject: dovecot-2.1: doveadm pw -t: Don't ask for password if -p is also... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/e511408bd991 changeset: 14933:e511408bd991 user: Timo Sirainen date: Wed Mar 20 21:13:20 2013 +0200 description: doveadm pw -t: Don't ask for password if -p is also specified. Patch by Paul Wallingford. diffstat: src/doveadm/doveadm-pw.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 87a9eec10145 -r e511408bd991 src/doveadm/doveadm-pw.c --- a/src/doveadm/doveadm-pw.c Wed Mar 20 18:46:10 2013 +0200 +++ b/src/doveadm/doveadm-pw.c Wed Mar 20 21:13:20 2013 +0200 @@ -78,7 +78,7 @@ if (rounds > 0) password_set_encryption_rounds(rounds); - if (test_hash != NULL) + if (test_hash != NULL && plaintext == NULL) plaintext = t_askpass("Enter password to verify: "); while (plaintext == NULL) { const char *check; From dovecot at dovecot.org Wed Mar 20 21:45:49 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 21:45:49 +0200 Subject: dovecot-2.2: lib-storage: If namespace has disabled=yes, don't v... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a46951762a27 changeset: 16073:a46951762a27 user: Timo Sirainen date: Tue Feb 26 10:37:19 2013 +0200 description: lib-storage: If namespace has disabled=yes, don't verify alias_for validity. diffstat: src/lib-storage/mail-storage-settings.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 0af0def22533 -r a46951762a27 src/lib-storage/mail-storage-settings.c --- a/src/lib-storage/mail-storage-settings.c Tue Feb 26 09:05:09 2013 +0200 +++ b/src/lib-storage/mail-storage-settings.c Tue Feb 26 10:37:19 2013 +0200 @@ -452,7 +452,7 @@ return FALSE; } - if (ns->alias_for != NULL) { + if (ns->alias_for != NULL && !ns->disabled) { if (array_is_created(&ns->user_set->namespaces)) { namespaces = array_get(&ns->user_set->namespaces, &count); From dovecot at dovecot.org Wed Mar 20 21:45:49 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 21:45:49 +0200 Subject: dovecot-2.2: scram-sha1: Support authzid field. Check fields' co... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0af0def22533 changeset: 16072:0af0def22533 user: Timo Sirainen date: Tue Feb 26 09:05:09 2013 +0200 description: scram-sha1: Support authzid field. Check fields' correctness better. diffstat: src/auth/mech-scram-sha1.c | 64 +++++++++++++++++++++++++++++++++++++-------- 1 files changed, 52 insertions(+), 12 deletions(-) diffs (106 lines): diff -r fa9387588430 -r 0af0def22533 src/auth/mech-scram-sha1.c --- a/src/auth/mech-scram-sha1.c Mon Feb 25 17:23:25 2013 +0200 +++ b/src/auth/mech-scram-sha1.c Tue Feb 26 09:05:09 2013 +0200 @@ -150,40 +150,75 @@ const unsigned char *data, size_t size, const char **error_r) { - const char *const *fields; + const char *const *fields, *login_username = NULL; + const char *gs2_cbind_flag, *authzid, *username, *nonce; fields = t_strsplit(t_strndup(data, size), ","); if (str_array_length(fields) < 4) { *error_r = "Invalid initial client message"; return FALSE; } + gs2_cbind_flag = fields[0]; + authzid = fields[1]; + username = fields[2]; + nonce = fields[3]; - switch (fields[0][0]) { + /* Order of fields is fixed: + + client-first-message = gs2-header client-first-message-bare + gs2-header = gs2-cbind-flag "," [ authzid ] "," + gs2-cbind-flag = ("p=" cb-name) / "n" / "y" + + client-first-message-bare = [reserved-mext ","] + username "," nonce ["," extensions] + reserved-mext = "m=" 1*(value-char) + + username = "n=" saslname + nonce = "r=" c-nonce [s-nonce] + + extensions = attr-val *("," attr-val) + ;; All extensions are optional, + ;; i.e., unrecognized attributes + ;; not defined in this document + ;; MUST be ignored. + attr-val = ALPHA "=" value + + */ + switch (gs2_cbind_flag[0]) { case 'p': *error_r = "Channel binding not supported"; return FALSE; case 'y': case 'n': - request->gs2_cbind_flag = p_strdup(request->pool, fields[0]); + request->gs2_cbind_flag = + p_strdup(request->pool, gs2_cbind_flag); break; default: *error_r = "Invalid GS2 header"; return FALSE; } - if (fields[1][0] != '\0') { - *error_r = "authzid not supported"; + if (authzid[0] == '\0') + ; + else if (authzid[0] == 'a' && authzid[1] == '=') { + /* Unescape authzid */ + login_username = scram_unescape_username(authzid + 2); + + if (login_username == NULL) { + *error_r = "authzid escaping is invalid"; + return FALSE; + } + } else { + *error_r = "Invalid authzid field"; return FALSE; } - if (fields[2][0] == 'm') { + if (username[0] == 'm') { *error_r = "Mandatory extension(s) not supported"; return FALSE; } - if (fields[2][0] == 'n') { + if (username[0] == 'n' && username[1] == '=') { /* Unescape username */ - const char *username = - scram_unescape_username(fields[2] + 2); - + username = scram_unescape_username(username + 2); if (username == NULL) { *error_r = "Username escaping is invalid"; return FALSE; @@ -195,9 +230,14 @@ *error_r = "Invalid username field"; return FALSE; } + if (login_username != NULL) { + if (!auth_request_set_login_username(&request->auth_request, + login_username, error_r)) + return FALSE; + } - if (fields[3][0] == 'r') - request->cnonce = p_strdup(request->pool, fields[3]+2); + if (nonce[0] == 'r' && nonce[1] == '=') + request->cnonce = p_strdup(request->pool, nonce+2); else { *error_r = "Invalid client nonce"; return FALSE; From dovecot at dovecot.org Wed Mar 20 21:45:49 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 21:45:49 +0200 Subject: dovecot-2.2: message-decode: Minor fix to previous change. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/311371856dcf changeset: 16075:311371856dcf user: Timo Sirainen date: Wed Feb 27 13:07:35 2013 +0200 description: message-decode: Minor fix to previous change. The == condition should probably never happen, but handle it anyway. diffstat: src/lib-mail/message-decoder.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r cf7b590d19f9 -r 311371856dcf src/lib-mail/message-decoder.c --- a/src/lib-mail/message-decoder.c Wed Feb 27 13:05:40 2013 +0200 +++ b/src/lib-mail/message-decoder.c Wed Feb 27 13:07:35 2013 +0200 @@ -222,7 +222,7 @@ (void)charset_to_utf8(ctx->charset_trans, trans_buf, &trans_size, ctx->buf2); - if (trans_size < ctx->translation_size) { + if (trans_size <= ctx->translation_size) { /* need more data to finish the translation. */ i_assert(orig_size < MAX_TRANSLATION_BUF_SIZE); memcpy(ctx->translation_buf, trans_buf, orig_size); From dovecot at dovecot.org Wed Mar 20 21:45:49 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 21:45:49 +0200 Subject: dovecot-2.2: message-decoder: Fixed assert-crash when trying to ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cf7b590d19f9 changeset: 16074:cf7b590d19f9 user: Timo Sirainen date: Wed Feb 27 13:05:40 2013 +0200 description: message-decoder: Fixed assert-crash when trying to decode partial character twice. diffstat: src/lib-mail/message-decoder.c | 14 +++++++++++--- 1 files changed, 11 insertions(+), 3 deletions(-) diffs (34 lines): diff -r a46951762a27 -r cf7b590d19f9 src/lib-mail/message-decoder.c --- a/src/lib-mail/message-decoder.c Tue Feb 26 10:37:19 2013 +0200 +++ b/src/lib-mail/message-decoder.c Wed Feb 27 13:05:40 2013 +0200 @@ -207,7 +207,7 @@ { unsigned char trans_buf[MAX_TRANSLATION_BUF_SIZE+1]; unsigned int data_wanted, skip; - size_t trans_size; + size_t trans_size, orig_size; /* @UNSAFE: move the previously untranslated bytes to trans_buf and see if we have now enough data to get the next character @@ -218,11 +218,19 @@ data_wanted = *size; memcpy(trans_buf + ctx->translation_size, *data, data_wanted); - trans_size = ctx->translation_size + data_wanted; + orig_size = trans_size = ctx->translation_size + data_wanted; (void)charset_to_utf8(ctx->charset_trans, trans_buf, &trans_size, ctx->buf2); - i_assert(trans_size > ctx->translation_size); + if (trans_size < ctx->translation_size) { + /* need more data to finish the translation. */ + i_assert(orig_size < MAX_TRANSLATION_BUF_SIZE); + memcpy(ctx->translation_buf, trans_buf, orig_size); + ctx->translation_size = orig_size; + *data += *size; + *size = 0; + return; + } skip = trans_size - ctx->translation_size; i_assert(*size >= skip); From dovecot at dovecot.org Wed Mar 20 21:45:49 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 21:45:49 +0200 Subject: dovecot-2.2: lib-settings: Improved error messages when config s... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/09fcb43c47a4 changeset: 16076:09fcb43c47a4 user: Timo Sirainen date: Mon Mar 04 15:18:08 2013 +0200 description: lib-settings: Improved error messages when config server disconnects too early. diffstat: src/lib-settings/settings-parser.c | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletions(-) diffs (36 lines): diff -r 311371856dcf -r 09fcb43c47a4 src/lib-settings/settings-parser.c --- a/src/lib-settings/settings-parser.c Wed Feb 27 13:07:35 2013 +0200 +++ b/src/lib-settings/settings-parser.c Mon Mar 04 15:18:08 2013 +0200 @@ -950,8 +950,15 @@ if (input->stream_errno != 0) { ctx->error = p_strdup_printf(ctx->parser_pool, "read() failed: %m"); + } else if (input->v_offset == 0) { + ctx->error = p_strdup_printf(ctx->parser_pool, + "read(%s) disconnected before receiving any data", + i_stream_get_name(input)); } else { - ctx->error = "input is missing end-of-settings line"; + ctx->error = p_strdup_printf(ctx->parser_pool, + "read(%s) disconnected before receiving " + "end-of-settings line", + i_stream_get_name(input)); } break; case -2: @@ -982,6 +989,7 @@ } input = i_stream_create_fd(fd, max_line_length, TRUE); + i_stream_set_name(input, path); ret = settings_parse_stream_read(ctx, input); i_stream_unref(&input); @@ -1071,6 +1079,7 @@ (void)close(fd[1]); input = i_stream_create_fd(fd[0], (size_t)-1, TRUE); + i_stream_set_name(input, bin_path); ret = settings_parse_stream_read(ctx, input); i_stream_destroy(&input); From dovecot at dovecot.org Wed Mar 20 21:45:49 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 21:45:49 +0200 Subject: dovecot-2.2: dbox: Crashfix on some failed save error conditions. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a7928075f0fd changeset: 16077:a7928075f0fd user: Timo Sirainen date: Mon Mar 04 15:53:42 2013 +0200 description: dbox: Crashfix on some failed save error conditions. diffstat: src/lib-storage/index/dbox-common/dbox-save.c | 12 ++++++++---- 1 files changed, 8 insertions(+), 4 deletions(-) diffs (22 lines): diff -r 09fcb43c47a4 -r a7928075f0fd src/lib-storage/index/dbox-common/dbox-save.c --- a/src/lib-storage/index/dbox-common/dbox-save.c Mon Mar 04 15:18:08 2013 +0200 +++ b/src/lib-storage/index/dbox-common/dbox-save.c Mon Mar 04 15:53:42 2013 +0200 @@ -106,10 +106,14 @@ ctx->failed = TRUE; } if (ctx->ctx.output != dbox_output) { - /* e.g. zlib plugin had changed this */ - o_stream_ref(dbox_output); - o_stream_destroy(&ctx->ctx.output); - ctx->ctx.output = dbox_output; + if (ctx->ctx.output != NULL) { + /* e.g. zlib plugin had changed this */ + o_stream_ref(dbox_output); + o_stream_destroy(&ctx->ctx.output); + ctx->ctx.output = dbox_output; + } else { + i_assert(ctx->failed); + } } index_mail_cache_parse_deinit(ctx->ctx.dest_mail, ctx->ctx.received_date, !ctx->failed); From dovecot at dovecot.org Wed Mar 20 21:45:49 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 21:45:49 +0200 Subject: dovecot-2.2: fts: Fixed crash when searching virtual mailboxes a... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/87a9eec10145 changeset: 16078:87a9eec10145 user: Timo Sirainen date: Wed Mar 20 18:46:10 2013 +0200 description: fts: Fixed crash when searching virtual mailboxes and fts backend without lookup_multi(). Patch by Mike Abbott / Apple diffstat: src/plugins/fts/fts-api.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diffs (18 lines): diff -r a7928075f0fd -r 87a9eec10145 src/plugins/fts/fts-api.c --- a/src/plugins/fts/fts-api.c Mon Mar 04 15:53:42 2013 +0200 +++ b/src/plugins/fts/fts-api.c Wed Mar 20 18:46:10 2013 +0200 @@ -337,8 +337,13 @@ result->box_results = p_new(result->pool, struct fts_result, i+1); for (i = 0; boxes[i] != NULL; i++) { + struct fts_result *box_result = &result->box_results[i]; + + p_array_init(&box_result->definite_uids, result->pool, 32); + p_array_init(&box_result->maybe_uids, result->pool, 32); + p_array_init(&box_result->scores, result->pool, 32); if (backend->v.lookup(backend, boxes[i], args, - and_args, &result->box_results[i]) < 0) + and_args, box_result) < 0) return -1; } return 0; From dovecot at dovecot.org Wed Mar 20 21:45:49 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 21:45:49 +0200 Subject: dovecot-2.2: Merged changes from v2.1 tree. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f874733b4029 changeset: 16080:f874733b4029 user: Timo Sirainen date: Wed Mar 20 21:44:48 2013 +0200 description: Merged changes from v2.1 tree. diffstat: src/doveadm/doveadm-pw.c | 2 +- src/lib-mail/message-decoder.c | 14 +++++++++++--- src/lib-settings/settings-parser.c | 11 ++++++++++- src/lib-storage/index/dbox-common/dbox-save.c | 12 ++++++++---- src/lib-storage/mail-storage-settings.c | 2 +- src/plugins/fts/fts-api.c | 7 ++++++- 6 files changed, 37 insertions(+), 11 deletions(-) diffs (134 lines): diff -r 9a913c803608 -r f874733b4029 src/doveadm/doveadm-pw.c --- a/src/doveadm/doveadm-pw.c Wed Mar 20 21:04:29 2013 +0200 +++ b/src/doveadm/doveadm-pw.c Wed Mar 20 21:44:48 2013 +0200 @@ -78,7 +78,7 @@ if (rounds > 0) password_set_encryption_rounds(rounds); - if (test_hash != NULL) + if (test_hash != NULL && plaintext == NULL) plaintext = t_askpass("Enter password to verify: "); while (plaintext == NULL) { const char *check; diff -r 9a913c803608 -r f874733b4029 src/lib-mail/message-decoder.c --- a/src/lib-mail/message-decoder.c Wed Mar 20 21:04:29 2013 +0200 +++ b/src/lib-mail/message-decoder.c Wed Mar 20 21:44:48 2013 +0200 @@ -201,7 +201,7 @@ { unsigned char trans_buf[MAX_TRANSLATION_BUF_SIZE+1]; unsigned int data_wanted, skip; - size_t trans_size; + size_t trans_size, orig_size; /* @UNSAFE: move the previously untranslated bytes to trans_buf and see if we have now enough data to get the next character @@ -212,11 +212,19 @@ data_wanted = *size; memcpy(trans_buf + ctx->translation_size, *data, data_wanted); - trans_size = ctx->translation_size + data_wanted; + orig_size = trans_size = ctx->translation_size + data_wanted; (void)charset_to_utf8(ctx->charset_trans, trans_buf, &trans_size, ctx->buf2); - i_assert(trans_size > ctx->translation_size); + if (trans_size <= ctx->translation_size) { + /* need more data to finish the translation. */ + i_assert(orig_size < MAX_TRANSLATION_BUF_SIZE); + memcpy(ctx->translation_buf, trans_buf, orig_size); + ctx->translation_size = orig_size; + *data += *size; + *size = 0; + return; + } skip = trans_size - ctx->translation_size; i_assert(*size >= skip); diff -r 9a913c803608 -r f874733b4029 src/lib-settings/settings-parser.c --- a/src/lib-settings/settings-parser.c Wed Mar 20 21:04:29 2013 +0200 +++ b/src/lib-settings/settings-parser.c Wed Mar 20 21:44:48 2013 +0200 @@ -959,8 +959,15 @@ if (input->stream_errno != 0) { ctx->error = p_strdup_printf(ctx->parser_pool, "read() failed: %m"); + } else if (input->v_offset == 0) { + ctx->error = p_strdup_printf(ctx->parser_pool, + "read(%s) disconnected before receiving any data", + i_stream_get_name(input)); } else { - ctx->error = "input is missing end-of-settings line"; + ctx->error = p_strdup_printf(ctx->parser_pool, + "read(%s) disconnected before receiving " + "end-of-settings line", + i_stream_get_name(input)); } break; case -2: @@ -991,6 +998,7 @@ } input = i_stream_create_fd(fd, max_line_length, TRUE); + i_stream_set_name(input, path); ret = settings_parse_stream_read(ctx, input); i_stream_unref(&input); @@ -1080,6 +1088,7 @@ i_close_fd(&fd[1]); input = i_stream_create_fd(fd[0], (size_t)-1, TRUE); + i_stream_set_name(input, bin_path); ret = settings_parse_stream_read(ctx, input); i_stream_destroy(&input); diff -r 9a913c803608 -r f874733b4029 src/lib-storage/index/dbox-common/dbox-save.c --- a/src/lib-storage/index/dbox-common/dbox-save.c Wed Mar 20 21:04:29 2013 +0200 +++ b/src/lib-storage/index/dbox-common/dbox-save.c Wed Mar 20 21:44:48 2013 +0200 @@ -113,10 +113,14 @@ ctx->failed = TRUE; } if (mdata->output != dbox_output) { - /* e.g. zlib plugin had changed this */ - o_stream_ref(dbox_output); - o_stream_destroy(&mdata->output); - mdata->output = dbox_output; + if (mdata->output != NULL) { + /* e.g. zlib plugin had changed this */ + o_stream_ref(dbox_output); + o_stream_destroy(&mdata->output); + mdata->output = dbox_output; + } else { + i_assert(ctx->failed); + } } index_mail_cache_parse_deinit(ctx->ctx.dest_mail, ctx->ctx.data.received_date, diff -r 9a913c803608 -r f874733b4029 src/lib-storage/mail-storage-settings.c --- a/src/lib-storage/mail-storage-settings.c Wed Mar 20 21:04:29 2013 +0200 +++ b/src/lib-storage/mail-storage-settings.c Wed Mar 20 21:44:48 2013 +0200 @@ -458,7 +458,7 @@ return FALSE; } - if (ns->alias_for != NULL) { + if (ns->alias_for != NULL && !ns->disabled) { if (array_is_created(&ns->user_set->namespaces)) { namespaces = array_get(&ns->user_set->namespaces, &count); diff -r 9a913c803608 -r f874733b4029 src/plugins/fts/fts-api.c --- a/src/plugins/fts/fts-api.c Wed Mar 20 21:04:29 2013 +0200 +++ b/src/plugins/fts/fts-api.c Wed Mar 20 21:44:48 2013 +0200 @@ -342,8 +342,13 @@ result->box_results = p_new(result->pool, struct fts_result, i+1); for (i = 0; boxes[i] != NULL; i++) { + struct fts_result *box_result = &result->box_results[i]; + + p_array_init(&box_result->definite_uids, result->pool, 32); + p_array_init(&box_result->maybe_uids, result->pool, 32); + p_array_init(&box_result->scores, result->pool, 32); if (backend->v.lookup(backend, boxes[i], args, - and_args, &result->box_results[i]) < 0) + and_args, box_result) < 0) return -1; } return 0; From dovecot at dovecot.org Wed Mar 20 21:45:49 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 21:45:49 +0200 Subject: dovecot-2.2: doveadm pw -t: Don't ask for password if -p is also... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e511408bd991 changeset: 16079:e511408bd991 user: Timo Sirainen date: Wed Mar 20 21:13:20 2013 +0200 description: doveadm pw -t: Don't ask for password if -p is also specified. Patch by Paul Wallingford. diffstat: src/doveadm/doveadm-pw.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 87a9eec10145 -r e511408bd991 src/doveadm/doveadm-pw.c --- a/src/doveadm/doveadm-pw.c Wed Mar 20 18:46:10 2013 +0200 +++ b/src/doveadm/doveadm-pw.c Wed Mar 20 21:13:20 2013 +0200 @@ -78,7 +78,7 @@ if (rounds > 0) password_set_encryption_rounds(rounds); - if (test_hash != NULL) + if (test_hash != NULL && plaintext == NULL) plaintext = t_askpass("Enter password to verify: "); while (plaintext == NULL) { const char *check; From dovecot at dovecot.org Wed Mar 20 22:09:45 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 22:09:45 +0200 Subject: dovecot-2.2: Added tag 2.2.rc3 for changeset 11bd79bf4866 Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fe8f92d44f56 changeset: 16082:fe8f92d44f56 user: Timo Sirainen date: Wed Mar 20 22:05:53 2013 +0200 description: Added tag 2.2.rc3 for changeset 11bd79bf4866 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 11bd79bf4866 -r fe8f92d44f56 .hgtags --- a/.hgtags Wed Mar 20 22:05:53 2013 +0200 +++ b/.hgtags Wed Mar 20 22:05:53 2013 +0200 @@ -97,3 +97,4 @@ 018de2aa893a040256cb8cd92b1fc9f3f2bbd09f 2.2.beta2 508d46f858153c85ae777e87e1c5143a534a51fe 2.2.rc1 e62fa121f4a2db3348fd79bb176dd363cc1224bf 2.2.rc2 +11bd79bf4866b0d728b25717134a6ba972505746 2.2.rc3 From dovecot at dovecot.org Wed Mar 20 22:09:45 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 22:09:45 +0200 Subject: dovecot-2.2: Released v2.2.rc3. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/11bd79bf4866 changeset: 16081:11bd79bf4866 user: Timo Sirainen date: Wed Mar 20 22:05:53 2013 +0200 description: Released v2.2.rc3. diffstat: NEWS | 9 +++++++++ configure.ac | 2 +- 2 files changed, 10 insertions(+), 1 deletions(-) diffs (28 lines): diff -r f874733b4029 -r 11bd79bf4866 NEWS --- a/NEWS Wed Mar 20 21:44:48 2013 +0200 +++ b/NEWS Wed Mar 20 22:05:53 2013 +0200 @@ -1,3 +1,12 @@ +v2.2.rc3 2013-03-20 Timo Sirainen + + + dsync: Support syncing ACLs (and Sieve scripts with Pigeonhole) + + ldap: Support subqueries and value pointers, see + http://wiki2.dovecot.org/AuthDatabase/LDAP/Userdb + + postmaster_address setting: Expand %d to recipient's domain + - Fixed a crash when decoding quoted-printable content. + - dsync: Various bugfixes + v2.2.rc2 2013-02-15 Timo Sirainen - rc1 wasn't actually usable in most configurations. diff -r f874733b4029 -r 11bd79bf4866 configure.ac --- a/configure.ac Wed Mar 20 21:44:48 2013 +0200 +++ b/configure.ac Wed Mar 20 22:05:53 2013 +0200 @@ -2,7 +2,7 @@ # Be sure to update ABI version also if anything changes that might require # recompiling plugins. Most importantly that means if any structs are changed. -AC_INIT([Dovecot],[2.2.rc2],[dovecot at dovecot.org]) +AC_INIT([Dovecot],[2.2.rc3],[dovecot at dovecot.org]) AC_DEFINE_UNQUOTED([DOVECOT_ABI_VERSION], "2.2.ABIv0($PACKAGE_VERSION)", [Dovecot ABI version]) AC_CONFIG_SRCDIR([src]) From dovecot at dovecot.org Wed Mar 20 22:09:45 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 20 Mar 2013 22:09:45 +0200 Subject: dovecot-2.2: Added signature for changeset 11bd79bf4866 Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f722e60f9811 changeset: 16083:f722e60f9811 user: Timo Sirainen date: Wed Mar 20 22:06:06 2013 +0200 description: Added signature for changeset 11bd79bf4866 diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r fe8f92d44f56 -r f722e60f9811 .hgsigs --- a/.hgsigs Wed Mar 20 22:05:53 2013 +0200 +++ b/.hgsigs Wed Mar 20 22:06:06 2013 +0200 @@ -60,3 +60,4 @@ 018de2aa893a040256cb8cd92b1fc9f3f2bbd09f 0 iEYEABECAAYFAlEmOJEACgkQyUhSUUBVismawgCfbfY6KuH+/AauPkRZs4ish20YeV8Ani5DMLh02DUyJvDIpVPJMmTn2Mu/ 508d46f858153c85ae777e87e1c5143a534a51fe 0 iEYEABECAAYFAlErhDkACgkQyUhSUUBViskRdwCeJ61F0qLZ/3xxIQruTujzo0AEWK0An3PH7nkTY7ouyBdUr0QCra5KLXEZ e62fa121f4a2db3348fd79bb176dd363cc1224bf 0 iEYEABECAAYFAlErsAwACgkQyUhSUUBVismarACbBffm3XY21sfkTsbmF8o8udtRZk4An0ofYy2VminZ3S8EFApHymk/UpNv +11bd79bf4866b0d728b25717134a6ba972505746 0 iEYEABECAAYFAlFKFqsACgkQyUhSUUBVismbSwCdHgMYWjcwcTM7fD4v6wTd/8/8ZEsAn2THId1zYspMTEMtDg0rlrvjlht4 From dovecot at dovecot.org Thu Mar 21 14:49:48 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 21 Mar 2013 14:49:48 +0200 Subject: dovecot-2.2: dsync: -m '' parameter now syncs mailbox list, but ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/38774adaddaf changeset: 16084:38774adaddaf user: Timo Sirainen date: Thu Mar 21 14:48:33 2013 +0200 description: dsync: -m '' parameter now syncs mailbox list, but no actual mails. diffstat: src/doveadm/dsync/doveadm-dsync.c | 4 ++++ src/doveadm/dsync/dsync-brain-mailbox.c | 10 +++++++--- src/doveadm/dsync/dsync-brain-mails.c | 3 +-- src/doveadm/dsync/dsync-brain-private.h | 4 +++- src/doveadm/dsync/dsync-brain.c | 1 + src/doveadm/dsync/dsync-brain.h | 5 ++++- 6 files changed, 20 insertions(+), 7 deletions(-) diffs (103 lines): diff -r f722e60f9811 -r 38774adaddaf src/doveadm/dsync/doveadm-dsync.c --- a/src/doveadm/dsync/doveadm-dsync.c Wed Mar 20 22:06:06 2013 +0200 +++ b/src/doveadm/dsync/doveadm-dsync.c Thu Mar 21 14:48:33 2013 +0200 @@ -470,6 +470,10 @@ if (doveadm_debug) brain_flags |= DSYNC_BRAIN_FLAG_DEBUG; + if (ctx->mailbox != NULL && *ctx->mailbox == '\0') { + brain_flags |= DSYNC_BRAIN_FLAG_NO_MAIL_SYNC; + ctx->mailbox = NULL; + } brain = dsync_brain_master_init(user, ibc, sync_ns, ctx->mailbox, ctx->sync_type, brain_flags, ctx->lock_timeout, diff -r f722e60f9811 -r 38774adaddaf src/doveadm/dsync/dsync-brain-mailbox.c --- a/src/doveadm/dsync/dsync-brain-mailbox.c Wed Mar 20 22:06:06 2013 +0200 +++ b/src/doveadm/dsync/dsync-brain-mailbox.c Thu Mar 21 14:48:33 2013 +0200 @@ -422,9 +422,14 @@ brain->state = DSYNC_STATE_SYNC_MAILS; } -bool dsync_boxes_need_sync(const struct dsync_mailbox *box1, +bool dsync_boxes_need_sync(struct dsync_brain *brain, + const struct dsync_mailbox *box1, const struct dsync_mailbox *box2) { + if (brain->no_mail_sync) + return FALSE; + if (brain->sync_type != DSYNC_BRAIN_SYNC_TYPE_CHANGED) + return TRUE; return box1->highest_modseq != box2->highest_modseq || box1->highest_pvt_modseq != box2->highest_pvt_modseq || box1->messages_count != box2->messages_count || @@ -631,8 +636,7 @@ dsync_brain_mailbox_update_pre(brain, box, &local_dsync_box, dsync_box); - if (brain->sync_type == DSYNC_BRAIN_SYNC_TYPE_CHANGED && - !dsync_boxes_need_sync(&local_dsync_box, dsync_box)) { + if (!dsync_boxes_need_sync(brain, &local_dsync_box, dsync_box)) { /* no fields appear to have changed, skip this mailbox */ mailbox_free(&box); return TRUE; diff -r f722e60f9811 -r 38774adaddaf src/doveadm/dsync/dsync-brain-mails.c --- a/src/doveadm/dsync/dsync-brain-mails.c Wed Mar 20 22:06:06 2013 +0200 +++ b/src/doveadm/dsync/dsync-brain-mails.c Thu Mar 21 14:48:33 2013 +0200 @@ -48,8 +48,7 @@ dsync_brain_mailbox_update_pre(brain, brain->box, &brain->local_dsync_box, dsync_box); - if (brain->sync_type == DSYNC_BRAIN_SYNC_TYPE_CHANGED && - !dsync_boxes_need_sync(&brain->local_dsync_box, dsync_box)) { + if (!dsync_boxes_need_sync(brain, &brain->local_dsync_box, dsync_box)) { /* no fields appear to have changed, skip this mailbox */ dsync_brain_sync_mailbox_deinit(brain); return TRUE; diff -r f722e60f9811 -r 38774adaddaf src/doveadm/dsync/dsync-brain-private.h --- a/src/doveadm/dsync/dsync-brain-private.h Wed Mar 20 22:06:06 2013 +0200 +++ b/src/doveadm/dsync/dsync-brain-private.h Thu Mar 21 14:48:33 2013 +0200 @@ -91,6 +91,7 @@ unsigned int backup_recv:1; unsigned int debug:1; unsigned int sync_visible_namespaces:1; + unsigned int no_mail_sync:1; unsigned int changes_during_sync:1; unsigned int failed:1; }; @@ -112,7 +113,8 @@ struct mailbox *box, const struct dsync_mailbox *local_box, const struct dsync_mailbox *remote_box); -bool dsync_boxes_need_sync(const struct dsync_mailbox *box1, +bool dsync_boxes_need_sync(struct dsync_brain *brain, + const struct dsync_mailbox *box1, const struct dsync_mailbox *box2); void dsync_brain_sync_init_box_states(struct dsync_brain *brain); diff -r f722e60f9811 -r 38774adaddaf src/doveadm/dsync/dsync-brain.c --- a/src/doveadm/dsync/dsync-brain.c Wed Mar 20 22:06:06 2013 +0200 +++ b/src/doveadm/dsync/dsync-brain.c Thu Mar 21 14:48:33 2013 +0200 @@ -81,6 +81,7 @@ brain->debug = (flags & DSYNC_BRAIN_FLAG_DEBUG) != 0; brain->sync_visible_namespaces = (flags & DSYNC_BRAIN_FLAG_SYNC_VISIBLE_NAMESPACES) != 0; + brain->no_mail_sync = (flags & DSYNC_BRAIN_FLAG_NO_MAIL_SYNC) != 0; } struct dsync_brain * diff -r f722e60f9811 -r 38774adaddaf src/doveadm/dsync/dsync-brain.h --- a/src/doveadm/dsync/dsync-brain.h Wed Mar 20 22:06:06 2013 +0200 +++ b/src/doveadm/dsync/dsync-brain.h Thu Mar 21 14:48:33 2013 +0200 @@ -10,7 +10,10 @@ DSYNC_BRAIN_FLAG_BACKUP_SEND = 0x02, DSYNC_BRAIN_FLAG_BACKUP_RECV = 0x04, DSYNC_BRAIN_FLAG_DEBUG = 0x08, - DSYNC_BRAIN_FLAG_SYNC_VISIBLE_NAMESPACES= 0x10 + DSYNC_BRAIN_FLAG_SYNC_VISIBLE_NAMESPACES= 0x10, + /* Sync everything but the actual mails (e.g. mailbox creates, + deletes) */ + DSYNC_BRAIN_FLAG_NO_MAIL_SYNC = 0x20 }; enum dsync_brain_sync_type { From dovecot at dovecot.org Thu Mar 21 23:51:27 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 21 Mar 2013 23:51:27 +0200 Subject: dovecot-2.2: login proxy: Set a default 30s timeout. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9439a43bd645 changeset: 16086:9439a43bd645 user: Timo Sirainen date: Thu Mar 21 23:51:16 2013 +0200 description: login proxy: Set a default 30s timeout. diffstat: src/login-common/client-common-auth.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (20 lines): diff -r a4ea6946c621 -r 9439a43bd645 src/login-common/client-common-auth.c --- a/src/login-common/client-common-auth.c Thu Mar 21 23:50:53 2013 +0200 +++ b/src/login-common/client-common-auth.c Thu Mar 21 23:51:16 2013 +0200 @@ -15,6 +15,7 @@ #include #define PROXY_FAILURE_MSG "Account is temporarily unavailable." +#define PROXY_DEFAULT_TIMEOUT_MSECS (1000*30) /* If we've been waiting auth server to respond for over this many milliseconds, send a "waiting" message. */ @@ -307,6 +308,8 @@ proxy_set.ip.family = 0; proxy_set.port = reply->port; proxy_set.connect_timeout_msecs = reply->proxy_timeout_msecs; + if (proxy_set.connect_timeout_msecs == 0) + proxy_set.connect_timeout_msecs = PROXY_DEFAULT_TIMEOUT_MSECS; proxy_set.notify_refresh_secs = reply->proxy_refresh_secs; proxy_set.ssl_flags = reply->ssl_flags; From dovecot at dovecot.org Thu Mar 21 23:51:27 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 21 Mar 2013 23:51:27 +0200 Subject: dovecot-2.2: login proxy: Stop proxy_timeout only after successf... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a4ea6946c621 changeset: 16085:a4ea6946c621 user: Timo Sirainen date: Thu Mar 21 23:50:53 2013 +0200 description: login proxy: Stop proxy_timeout only after successfully logged in (not after connected). diffstat: src/login-common/login-proxy.c | 20 ++++++++++++++------ 1 files changed, 14 insertions(+), 6 deletions(-) diffs (55 lines): diff -r 38774adaddaf -r a4ea6946c621 src/login-common/login-proxy.c --- a/src/login-common/login-proxy.c Thu Mar 21 14:48:33 2013 +0200 +++ b/src/login-common/login-proxy.c Thu Mar 21 23:50:53 2013 +0200 @@ -48,6 +48,7 @@ proxy_callback_t *callback; + unsigned int connected:1; unsigned int destroying:1; unsigned int disconnecting:1; }; @@ -202,9 +203,15 @@ struct ip_addr local_ip; unsigned int local_port; - str_printfa(str, "proxy(%s): connect(%s, %u) failed: %m (after %u secs", - proxy->client->virtual_user, - proxy->host, proxy->port, + str_printfa(str, "proxy(%s): ", proxy->client->virtual_user); + if (!proxy->connected) { + str_printfa(str, "connect(%s, %u) failed: %m", + proxy->host, proxy->port); + } else { + str_printfa(str, "Login for %s:%u timed out", + proxy->host, proxy->port); + } + str_printfa(str, " (after %u secs", (unsigned int)(ioloop_time - proxy->created.tv_sec)); if (proxy->server_fd != -1 && @@ -226,13 +233,11 @@ login_proxy_free(&proxy); return; } + proxy->connected = TRUE; proxy->state_rec->last_success = ioloop_timeval; proxy->state_rec->num_waiting_connections--; proxy->state_rec = NULL; - if (proxy->to != NULL) - timeout_remove(&proxy->to); - if ((proxy->ssl_flags & PROXY_SSL_FLAG_YES) != 0 && (proxy->ssl_flags & PROXY_SSL_FLAG_STARTTLS) == 0) { if (login_proxy_starttls(proxy) < 0) { @@ -464,6 +469,9 @@ i_assert(proxy->client_fd == -1); i_assert(proxy->server_output != NULL); + if (proxy->to != NULL) + timeout_remove(&proxy->to); + proxy->client_fd = i_stream_get_fd(client->input); proxy->client_output = client->output; From dovecot at dovecot.org Fri Mar 22 10:29:17 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 22 Mar 2013 10:29:17 +0200 Subject: dovecot-2.2: acl: Don't crash when rebuilding acl dict for "unus... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d211174a2392 changeset: 16087:d211174a2392 user: Timo Sirainen date: Fri Mar 22 10:29:12 2013 +0200 description: acl: Don't crash when rebuilding acl dict for "unusable" namespaces. diffstat: src/plugins/acl/acl-lookup-dict.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 9439a43bd645 -r d211174a2392 src/plugins/acl/acl-lookup-dict.c --- a/src/plugins/acl/acl-lookup-dict.c Thu Mar 21 23:51:16 2013 +0200 +++ b/src/plugins/acl/acl-lookup-dict.c Fri Mar 22 10:29:12 2013 +0200 @@ -110,7 +110,8 @@ string_t *id; int ret, ret2 = 0; - if ((ns->flags & NAMESPACE_FLAG_NOACL) != 0 || ns->owner == NULL) + if ((ns->flags & NAMESPACE_FLAG_NOACL) != 0 || ns->owner == NULL || + ACL_LIST_CONTEXT(ns->list) == NULL) return 0; id = t_str_new(128); From dovecot at dovecot.org Fri Mar 22 11:17:48 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 22 Mar 2013 11:17:48 +0200 Subject: dovecot-2.2: Compiler warning fix Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b839613c1573 changeset: 16088:b839613c1573 user: Timo Sirainen date: Fri Mar 22 11:17:14 2013 +0200 description: Compiler warning fix diffstat: src/doveadm/dsync/dsync-mailbox-import.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r d211174a2392 -r b839613c1573 src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Fri Mar 22 10:29:12 2013 +0200 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Fri Mar 22 11:17:14 2013 +0200 @@ -252,6 +252,8 @@ const unsigned char *data1, *data2; size_t size1, size2, size; + *cmp_r = -1; /* quiet gcc */ + for (;;) { (void)i_stream_read_data(input1, &data1, &size1, 0); (void)i_stream_read_data(input2, &data2, &size2, 0); From dovecot at dovecot.org Fri Mar 22 12:48:26 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 22 Mar 2013 12:48:26 +0200 Subject: dovecot-2.2: dsync: Use fcntl() locking instead of flock(). Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b436c1f6bd06 changeset: 16089:b436c1f6bd06 user: Timo Sirainen date: Fri Mar 22 12:48:21 2013 +0200 description: dsync: Use fcntl() locking instead of flock(). diffstat: src/doveadm/dsync/dsync-brain.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r b839613c1573 -r b436c1f6bd06 src/doveadm/dsync/dsync-brain.c --- a/src/doveadm/dsync/dsync-brain.c Fri Mar 22 11:17:14 2013 +0200 +++ b/src/doveadm/dsync/dsync-brain.c Fri Mar 22 12:48:21 2013 +0200 @@ -232,7 +232,7 @@ } if (file_wait_lock(brain->lock_fd, brain->lock_path, F_WRLCK, - FILE_LOCK_METHOD_FLOCK, brain->lock_timeout, + FILE_LOCK_METHOD_FCNTL, brain->lock_timeout, &brain->lock) <= 0) { i_error("Couldn't lock %s: %m", brain->lock_path); break; From dovecot at dovecot.org Fri Mar 22 17:30:40 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 22 Mar 2013 17:30:40 +0200 Subject: dovecot-2.2: lib-storage: Added mailbox_list_get_settings() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/304cd3067061 changeset: 16090:304cd3067061 user: Timo Sirainen date: Fri Mar 22 17:30:36 2013 +0200 description: lib-storage: Added mailbox_list_get_settings() diffstat: src/lib-storage/mailbox-list.c | 6 ++++++ src/lib-storage/mailbox-list.h | 2 ++ 2 files changed, 8 insertions(+), 0 deletions(-) diffs (28 lines): diff -r b436c1f6bd06 -r 304cd3067061 src/lib-storage/mailbox-list.c --- a/src/lib-storage/mailbox-list.c Fri Mar 22 12:48:21 2013 +0200 +++ b/src/lib-storage/mailbox-list.c Fri Mar 22 17:30:36 2013 +0200 @@ -738,6 +738,12 @@ return list->name; } +const struct mailbox_list_settings * +mailbox_list_get_settings(const struct mailbox_list *list) +{ + return list->set; +} + enum mailbox_list_flags mailbox_list_get_flags(const struct mailbox_list *list) { return list->flags; diff -r b436c1f6bd06 -r 304cd3067061 src/lib-storage/mailbox-list.h --- a/src/lib-storage/mailbox-list.h Fri Mar 22 12:48:21 2013 +0200 +++ b/src/lib-storage/mailbox-list.h Fri Mar 22 17:30:36 2013 +0200 @@ -150,6 +150,8 @@ const char * mailbox_list_get_driver_name(const struct mailbox_list *list) ATTR_PURE; +const struct mailbox_list_settings * +mailbox_list_get_settings(const struct mailbox_list *list) ATTR_PURE; enum mailbox_list_flags mailbox_list_get_flags(const struct mailbox_list *list) ATTR_PURE; struct mail_namespace * From dovecot at dovecot.org Fri Mar 22 17:44:06 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 22 Mar 2013 17:44:06 +0200 Subject: dovecot-2.2: lib-storage: Fixed crash if shared namespace had su... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6f5b14d4ad56 changeset: 16091:6f5b14d4ad56 user: Timo Sirainen date: Fri Mar 22 17:43:52 2013 +0200 description: lib-storage: Fixed crash if shared namespace had subscriptions=yes diffstat: src/lib-storage/index/shared/shared-list.c | 11 +++++++++-- 1 files changed, 9 insertions(+), 2 deletions(-) diffs (29 lines): diff -r 304cd3067061 -r 6f5b14d4ad56 src/lib-storage/index/shared/shared-list.c --- a/src/lib-storage/index/shared/shared-list.c Fri Mar 22 17:30:36 2013 +0200 +++ b/src/lib-storage/index/shared/shared-list.c Fri Mar 22 17:43:52 2013 +0200 @@ -2,6 +2,7 @@ #include "lib.h" #include "imap-match.h" +#include "mailbox-tree.h" #include "mailbox-list-private.h" #include "index-storage.h" #include "shared-storage.h" @@ -175,9 +176,15 @@ } static int -shared_list_subscriptions_refresh(struct mailbox_list *src_list ATTR_UNUSED, - struct mailbox_list *dest_list ATTR_UNUSED) +shared_list_subscriptions_refresh(struct mailbox_list *src_list, + struct mailbox_list *dest_list) { + char sep; + + if (dest_list->subscriptions == NULL) { + sep = mail_namespace_get_sep(src_list->ns); + dest_list->subscriptions = mailbox_tree_init(sep); + } return 0; } From dovecot at dovecot.org Fri Mar 22 19:46:04 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 22 Mar 2013 19:46:04 +0200 Subject: dovecot-2.2: lib-storage: Compiling fix Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fed3adf86ab5 changeset: 16092:fed3adf86ab5 user: Timo Sirainen date: Fri Mar 22 19:45:52 2013 +0200 description: lib-storage: Compiling fix diffstat: src/lib-storage/mailbox-list.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 6f5b14d4ad56 -r fed3adf86ab5 src/lib-storage/mailbox-list.c --- a/src/lib-storage/mailbox-list.c Fri Mar 22 17:43:52 2013 +0200 +++ b/src/lib-storage/mailbox-list.c Fri Mar 22 19:45:52 2013 +0200 @@ -741,7 +741,7 @@ const struct mailbox_list_settings * mailbox_list_get_settings(const struct mailbox_list *list) { - return list->set; + return &list->set; } enum mailbox_list_flags mailbox_list_get_flags(const struct mailbox_list *list) From pigeonhole at rename-it.nl Sat Mar 23 00:10:12 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 22 Mar 2013 23:10:12 +0100 Subject: dovecot-2.2-pigeonhole: Committed Timo's patch that adds a plugi... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/43b09b9a2f72 changeset: 1726:43b09b9a2f72 user: Stephan Bosch date: Fri Mar 22 23:09:57 2013 +0100 description: Committed Timo's patch that adds a plugin that provides Sieve dsync support. http://dovecot.org/patches/2.2/doveadm-sieve-plugin.diff Made some small modifications. This code should not interfere with normal ManageSieve operation, so I commit this right now without much testing. The actual doveadm sieve plugin has a few open issues that need to be resolved still. diffstat: configure.ac | 1 + src/lib-sievestorage/Makefile.am | 4 +- src/lib-sievestorage/sieve-storage.c | 17 + src/lib-sievestorage/sieve-storage.h | 3 + src/managesieve/Makefile.am | 2 +- src/plugins/Makefile.am | 2 +- src/plugins/doveadm-sieve/Makefile.am | 15 + src/plugins/doveadm-sieve/doveadm-sieve-plugin.c | 481 +++++++++++++++++++++++ 8 files changed, 521 insertions(+), 4 deletions(-) diffs (truncated from 586 to 300 lines): diff -r b75b00760b86 -r 43b09b9a2f72 configure.ac --- a/configure.ac Mon Mar 04 22:26:15 2013 +0100 +++ b/configure.ac Fri Mar 22 23:09:57 2013 +0100 @@ -127,6 +127,7 @@ src/lib-sievestorage/Makefile src/lib-managesieve/Makefile src/plugins/Makefile +src/plugins/doveadm-sieve/Makefile src/plugins/lda-sieve/Makefile src/sieve-tools/Makefile src/managesieve/Makefile diff -r b75b00760b86 -r 43b09b9a2f72 src/lib-sievestorage/Makefile.am --- a/src/lib-sievestorage/Makefile.am Mon Mar 04 22:26:15 2013 +0100 +++ b/src/lib-sievestorage/Makefile.am Fri Mar 22 23:09:57 2013 +0100 @@ -1,11 +1,11 @@ -noinst_LIBRARIES = libsievestorage.a +noinst_LTLIBRARIES = libsievestorage.la INCLUDES = \ $(LIBDOVECOT_INCLUDE) \ -I$(top_srcdir) \ -I$(top_srcdir)/src/lib-sieve -libsievestorage_a_SOURCES = \ +libsievestorage_la_SOURCES = \ sieve-storage-save.c \ sieve-storage-script.c \ sieve-storage-list.c \ diff -r b75b00760b86 -r 43b09b9a2f72 src/lib-sievestorage/sieve-storage.c --- a/src/lib-sievestorage/sieve-storage.c Mon Mar 04 22:26:15 2013 +0100 +++ b/src/lib-sievestorage/sieve-storage.c Fri Mar 22 23:09:57 2013 +0100 @@ -586,4 +586,21 @@ return storage->error != NULL ? storage->error : "Unknown error"; } +int sieve_storage_get_last_change +(struct sieve_storage *storage, time_t *last_change_r) +{ + struct stat st; + if (stat(storage->dir, &st) < 0) { + if (errno == ENOENT) { + *last_change_r = 0; + return 0; + } + sieve_storage_set_critical(storage, "stat(%s) failed: %m", + storage->dir); + return -1; + } + *last_change_r = st.st_mtime; + return 0; +} + diff -r b75b00760b86 -r 43b09b9a2f72 src/lib-sievestorage/sieve-storage.h --- a/src/lib-sievestorage/sieve-storage.h Mon Mar 04 22:26:15 2013 +0100 +++ b/src/lib-sievestorage/sieve-storage.h Fri Mar 22 23:09:57 2013 +0100 @@ -32,4 +32,7 @@ const char *sieve_storage_get_last_error (struct sieve_storage *storage, enum sieve_error *error_r); +int sieve_storage_get_last_change + (struct sieve_storage *storage, time_t *last_change_r); + #endif diff -r b75b00760b86 -r 43b09b9a2f72 src/managesieve/Makefile.am --- a/src/managesieve/Makefile.am Mon Mar 04 22:26:15 2013 +0100 +++ b/src/managesieve/Makefile.am Fri Mar 22 23:09:57 2013 +0100 @@ -24,7 +24,7 @@ libs = \ managesieve-settings.lo \ $(top_builddir)/src/lib-managesieve/libmanagesieve.a \ - $(top_builddir)/src/lib-sievestorage/libsievestorage.a \ + $(top_builddir)/src/lib-sievestorage/libsievestorage.la \ $(top_builddir)/src/lib-sieve/libdovecot-sieve.la managesieve_LDADD = $(libs) $(LIBDOVECOT_STORAGE) $(LIBDOVECOT_LDA) $(LIBDOVECOT) diff -r b75b00760b86 -r 43b09b9a2f72 src/plugins/Makefile.am --- a/src/plugins/Makefile.am Mon Mar 04 22:26:15 2013 +0100 +++ b/src/plugins/Makefile.am Fri Mar 22 23:09:57 2013 +0100 @@ -1,1 +1,1 @@ -SUBDIRS = lda-sieve +SUBDIRS = doveadm-sieve lda-sieve diff -r b75b00760b86 -r 43b09b9a2f72 src/plugins/doveadm-sieve/Makefile.am --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plugins/doveadm-sieve/Makefile.am Fri Mar 22 23:09:57 2013 +0100 @@ -0,0 +1,15 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/lib-sieve \ + -I$(top_srcdir)/src/lib-sievestorage \ + $(LIBDOVECOT_INCLUDE) + +doveadm_moduledir = $(dovecot_moduledir)/doveadm +lib10_doveadm_sieve_plugin_la_LDFLAGS = -module -avoid-version + +doveadm_module_LTLIBRARIES = lib10_doveadm_sieve_plugin.la + +lib10_doveadm_sieve_plugin_la_SOURCES = \ + doveadm-sieve-plugin.c +lib10_doveadm_sieve_plugin_la_LIBADD = \ + $(top_builddir)/src/lib-sieve/libdovecot-sieve.la \ + $(top_builddir)/src/lib-sievestorage/libsievestorage.la diff -r b75b00760b86 -r 43b09b9a2f72 src/plugins/doveadm-sieve/doveadm-sieve-plugin.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plugins/doveadm-sieve/doveadm-sieve-plugin.c Fri Mar 22 23:09:57 2013 +0100 @@ -0,0 +1,481 @@ +/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "istream.h" +#include "sieve-storage.h" +#include "sieve-storage-list.h" +#include "sieve-storage-save.h" +#include "sieve-storage-script.h" +#include "mail-storage-private.h" + +#define SIEVE_MAIL_CONTEXT(obj) \ + MODULE_CONTEXT(obj, sieve_storage_module) +#define SIEVE_USER_CONTEXT(obj) \ + MODULE_CONTEXT(obj, sieve_user_module) + +#define MAILBOX_ATTRIBUTE_PREFIX_SIEVE \ + MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT"sieve/" +#define MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES \ + MAILBOX_ATTRIBUTE_PREFIX_SIEVE"files/" +#define MAILBOX_ATTRIBUTE_SIEVE_ACTIVE \ + MAILBOX_ATTRIBUTE_PREFIX_SIEVE"active" + +struct sieve_mail_user { + union mail_user_module_context module_ctx; + + struct sieve_instance *svinst; + struct sieve_storage *sstorage; +}; + +struct sieve_mailbox_attribute_iter { + struct mailbox_attribute_iter iter; + struct mailbox_attribute_iter *super; + + struct sieve_list_context *sieve_list; + string_t *name; + + bool failed; + bool have_active; +}; + +void doveadm_sieve_plugin_init(struct module *module); +void doveadm_sieve_plugin_deinit(void); + +static MODULE_CONTEXT_DEFINE_INIT(sieve_storage_module, + &mail_storage_module_register); +static MODULE_CONTEXT_DEFINE_INIT(sieve_user_module, + &mail_user_module_register); + +const char *doveadm_sieve_plugin_version = DOVECOT_ABI_VERSION; + +static const char * +mail_sieve_get_setting(void *context, const char *identifier) +{ + struct mail_user *mail_user = context; + + return mail_user_plugin_getenv(mail_user, identifier); +} + +static const struct sieve_callbacks mail_sieve_callbacks = { + NULL, + mail_sieve_get_setting +}; + +static void mail_sieve_user_deinit(struct mail_user *user) +{ + struct sieve_mail_user *suser = SIEVE_USER_CONTEXT(user); + + sieve_storage_free(suser->sstorage); + sieve_deinit(&suser->svinst); + + suser->module_ctx.super.deinit(user); +} + +static int +mail_sieve_user_init(struct mail_user *user, struct sieve_storage **sstorage_r) +{ + /* delayed initialization of sieve storage until it's actually needed */ + struct mail_user_vfuncs *v = user->vlast; + struct sieve_environment svenv; + struct sieve_mail_user *suser; + + memset(&svenv, 0, sizeof(svenv)); + svenv.username = user->username; + (void)mail_user_get_home(user, &svenv.home_dir); + svenv.base_dir = user->set->base_dir; + svenv.flags = SIEVE_FLAG_HOME_RELATIVE; + + suser = p_new(user->pool, struct sieve_mail_user, 1); + suser->module_ctx.super = *v; + user->vlast = &suser->module_ctx.super; + v->deinit = mail_sieve_user_deinit; + + suser->svinst = sieve_init(&svenv, &mail_sieve_callbacks, + user, user->mail_debug); + suser->sstorage = sieve_storage_create(suser->svinst, user->username, + svenv.home_dir, user->mail_debug); + + MODULE_CONTEXT_SET(user, sieve_user_module, suser); + *sstorage_r = suser->sstorage; + return 0; +} + +static int sieve_attribute_unset_script(struct mail_storage *storage, + struct sieve_storage *sstorage, + const char *scriptname) +{ + struct sieve_script *script; + const char *errstr; + enum sieve_error error; + int ret = 0; + + script = sieve_storage_script_init(sstorage, scriptname); + ret = script == NULL ? -1 : + sieve_storage_script_delete(&script); + if (ret < 0) { + errstr = sieve_storage_get_last_error(sstorage, &error); + if (error == SIEVE_ERROR_NOT_FOUND) { + /* already deleted, ignore */ + return 0; + } + mail_storage_set_critical(storage, + "Failed to delete sieve script '%s': %s", scriptname, + errstr); + return -1; + } + return 0; +} + +static int +sieve_attribute_set_active(struct mail_storage *storage, + struct sieve_storage *sstorage, + const struct mail_attribute_value *value) +{ + const char *scriptname; + struct sieve_script *script; + int ret; + + if (mailbox_attribute_value_to_string(storage, value, &scriptname) < 0) + return -1; + if (scriptname == NULL) { + /* deactivate current script */ + if (sieve_storage_deactivate(sstorage) < 0) { + mail_storage_set_critical(storage, + "Failed to deactivate sieve: %s", + sieve_storage_get_last_error(sstorage, NULL)); + return -1; + } + return 0; + } + + /* activate specified script */ + script = sieve_storage_script_init(sstorage, scriptname); + ret = script == NULL ? -1 : + sieve_storage_script_activate(script); + if (ret < 0) { + mail_storage_set_critical(storage, + "Failed to activate sieve script '%s': %s", scriptname, + sieve_storage_get_last_error(sstorage, NULL)); + } + if (script != NULL) + sieve_script_unref(&script); + return ret; +} + +static int +sieve_attribute_set_sieve(struct mail_storage *storage, + const char *key, + const struct mail_attribute_value *value) +{ + struct sieve_storage *sstorage; + struct sieve_save_context *save_ctx; + struct istream *input; + const char *scriptname; + int ret = 0; + + if (mail_sieve_user_init(storage->user, &sstorage) < 0) + return -1; + + if (strcmp(key, MAILBOX_ATTRIBUTE_SIEVE_ACTIVE) == 0) + return sieve_attribute_set_active(storage, sstorage, value); + if (strncmp(key, MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, + strlen(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES)) != 0) { + mail_storage_set_error(storage, MAIL_ERROR_NOTFOUND, + "Nonexistent sieve attribute"); + return -1; + } + scriptname = key + strlen(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES); + + if (value->value != NULL) { + input = i_stream_create_from_data(value->value, + strlen(value->value)); + save_ctx = sieve_storage_save_init(sstorage, scriptname, input); + i_stream_unref(&input); + } else if (value->value_stream != NULL) { + input = value->value_stream; From pigeonhole at rename-it.nl Sat Mar 23 13:14:21 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 23 Mar 2013 12:14:21 +0100 Subject: dovecot-2.2-pigeonhole: Fixed compile order for previous change. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/cb910570ad88 changeset: 1727:cb910570ad88 user: Stephan Bosch date: Sat Mar 23 12:14:14 2013 +0100 description: Fixed compile order for previous change. diffstat: src/Makefile.am | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (20 lines): diff -r 43b09b9a2f72 -r cb910570ad88 src/Makefile.am --- a/src/Makefile.am Fri Mar 22 23:09:57 2013 +0100 +++ b/src/Makefile.am Sat Mar 23 12:14:14 2013 +0100 @@ -1,6 +1,8 @@ + sieve_subdirs = \ lib-sieve \ + lib-sievestorage \ plugins \ lib-sieve-tool \ sieve-tools \ @@ -9,7 +11,6 @@ if BUILD_MANAGESIEVE managesieve_subdirs = \ lib-managesieve \ - lib-sievestorage \ managesieve \ managesieve-login else From dovecot at dovecot.org Sun Mar 24 11:37:00 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 24 Mar 2013 11:37:00 +0200 Subject: dovecot-2.1: Add DOVECOT_PREREQ to src/lib/macros.h - convenienc... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/a588b743d695 changeset: 14935:a588b743d695 user: Dennis Schridde date: Sun Oct 30 12:39:53 2011 +0100 description: Add DOVECOT_PREREQ to src/lib/macros.h - convenience macro to test the version of dovecot diffstat: src/lib/macros.h | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diffs (16 lines): diff -r e294e416f5ba -r a588b743d695 src/lib/macros.h --- a/src/lib/macros.h Sun Oct 30 12:23:28 2011 +0100 +++ b/src/lib/macros.h Sun Oct 30 12:39:53 2011 +0100 @@ -196,4 +196,12 @@ #define i_unreached() \ i_panic("file %s: line %d: unreached", __FILE__, __LINE__) +/* Convenience macros to test the versions of dovecot. */ +#if defined DOVECOT_VERSION_MAJOR && defined DOVECOT_VERSION_MINOR +# define DOVECOT_PREREQ(maj, min) \ + ((DOVECOT_VERSION_MAJOR << 16) + DOVECOT_VERSION_MINOR >= ((maj) << 16) + (min)) +#else +# define DOVECOT_PREREQ(maj, min) 0 #endif + +#endif From dovecot at dovecot.org Sun Mar 24 11:36:59 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 24 Mar 2013 11:36:59 +0200 Subject: dovecot-2.1: Add macros DOVECOT_VERSION_{MAJOR,MINOR} to config.... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/e294e416f5ba changeset: 14934:e294e416f5ba user: Dennis Schridde date: Sun Oct 30 12:23:28 2011 +0100 description: Add macros DOVECOT_VERSION_{MAJOR,MINOR} to config.h to allow version checks in the preprocessor Version number set as PACKAGE_VERSION is assumed to be D.D* with D=digits diffstat: configure.in | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r e511408bd991 -r e294e416f5ba configure.in --- a/configure.in Wed Mar 20 21:13:20 2013 +0200 +++ b/configure.in Sun Oct 30 12:23:28 2011 +0100 @@ -287,6 +287,9 @@ AC_DEFINE_UNQUOTED(DOVECOT_STRING, "$PACKAGE_STRING", Dovecot string) AC_DEFINE_UNQUOTED(DOVECOT_VERSION, "$PACKAGE_VERSION", Dovecot version) +AC_DEFINE([DOVECOT_VERSION_MAJOR], regexp(AC_PACKAGE_VERSION, [^\([0-9]+\)\.\([0-9]+\)], [\1]), [Dovecot major version]) +AC_DEFINE([DOVECOT_VERSION_MINOR], regexp(AC_PACKAGE_VERSION, [^\([0-9]+\)\.\([0-9]+\)], [\2]), [Dovecot minor version]) + AC_CHECK_HEADERS(strings.h stdint.h unistd.h dirent.h malloc.h inttypes.h \ sys/uio.h sys/sysmacros.h sys/resource.h sys/select.h libgen.h \ sys/quota.h sys/fs/ufs_quota.h ufs/ufs/quota.h jfs/quota.h sys/fs/quota_common.h \ From dovecot at dovecot.org Sun Mar 24 12:09:45 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 24 Mar 2013 12:09:45 +0200 Subject: dovecot-2.1: "Mailbox doesn't exist" error mixed up using storag... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/eece943c7521 changeset: 14936:eece943c7521 user: Timo Sirainen date: Sun Mar 24 12:09:39 2013 +0200 description: "Mailbox doesn't exist" error mixed up using storage and virtual mailbox names. This could have allowed a user to figure out existence of a mailbox without having lookup ACL. diffstat: src/lib-storage/index/cydir/cydir-storage.c | 2 +- src/lib-storage/index/dbox-common/dbox-storage.c | 2 +- src/lib-storage/index/maildir/maildir-storage.c | 2 +- src/lib-storage/index/mbox/mbox-storage.c | 2 +- src/lib-storage/index/pop3c/pop3c-storage.c | 2 +- src/lib-storage/index/raw/raw-storage.c | 2 +- src/lib-storage/list/mailbox-list-delete.c | 8 ++++---- src/lib-storage/list/mailbox-list-fs.c | 4 ++-- src/lib-storage/list/mailbox-list-maildir.c | 4 ++-- src/lib-storage/mailbox-list-private.h | 4 ++++ src/plugins/acl/acl-mailbox.c | 2 +- src/plugins/virtual/virtual-config.c | 2 +- 12 files changed, 20 insertions(+), 16 deletions(-) diffs (191 lines): diff -r a588b743d695 -r eece943c7521 src/lib-storage/index/cydir/cydir-storage.c --- a/src/lib-storage/index/cydir/cydir-storage.c Sun Oct 30 12:39:53 2011 +0100 +++ b/src/lib-storage/index/cydir/cydir-storage.c Sun Mar 24 12:09:39 2013 +0200 @@ -68,7 +68,7 @@ /* exists, open it */ } else if (errno == ENOENT) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name)); + T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname)); return -1; } else if (errno == EACCES) { mail_storage_set_critical(box->storage, "%s", diff -r a588b743d695 -r eece943c7521 src/lib-storage/index/dbox-common/dbox-storage.c --- a/src/lib-storage/index/dbox-common/dbox-storage.c Sun Oct 30 12:39:53 2011 +0100 +++ b/src/lib-storage/index/dbox-common/dbox-storage.c Sun Mar 24 12:09:39 2013 +0200 @@ -184,7 +184,7 @@ ; else if (errno == ENOENT || errno == ENAMETOOLONG) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name)); + T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname)); return -1; } else if (errno == EACCES) { mail_storage_set_critical(box->storage, "%s", diff -r a588b743d695 -r eece943c7521 src/lib-storage/index/maildir/maildir-storage.c --- a/src/lib-storage/index/maildir/maildir-storage.c Sun Oct 30 12:39:53 2011 +0100 +++ b/src/lib-storage/index/maildir/maildir-storage.c Sun Mar 24 12:09:39 2013 +0200 @@ -367,7 +367,7 @@ if (errno == ENOENT || errno == ENAMETOOLONG) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name)); + T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname)); return -1; } else { mail_storage_set_critical(box->storage, diff -r a588b743d695 -r eece943c7521 src/lib-storage/index/mbox/mbox-storage.c --- a/src/lib-storage/index/mbox/mbox-storage.c Sun Oct 30 12:39:53 2011 +0100 +++ b/src/lib-storage/index/mbox/mbox-storage.c Sun Mar 24 12:09:39 2013 +0200 @@ -470,7 +470,7 @@ return -1; } else if (ENOTFOUND(errno)) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name)); + T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname)); return -1; } else if (mail_storage_set_error_from_errno(box->storage)) { return -1; diff -r a588b743d695 -r eece943c7521 src/lib-storage/index/pop3c/pop3c-storage.c --- a/src/lib-storage/index/pop3c/pop3c-storage.c Sun Oct 30 12:39:53 2011 +0100 +++ b/src/lib-storage/index/pop3c/pop3c-storage.c Sun Mar 24 12:09:39 2013 +0200 @@ -165,7 +165,7 @@ if (strcmp(box->name, "INBOX") != 0) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name)); + T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname)); return -1; } diff -r a588b743d695 -r eece943c7521 src/lib-storage/index/raw/raw-storage.c --- a/src/lib-storage/index/raw/raw-storage.c Sun Oct 30 12:39:53 2011 +0100 +++ b/src/lib-storage/index/raw/raw-storage.c Sun Mar 24 12:09:39 2013 +0200 @@ -151,7 +151,7 @@ if (ENOTFOUND(errno)) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name)); + T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname)); } else if (!mail_storage_set_error_from_errno(box->storage)) { mail_storage_set_critical(box->storage, "open(%s) failed: %m", path); diff -r a588b743d695 -r eece943c7521 src/lib-storage/list/mailbox-list-delete.c --- a/src/lib-storage/list/mailbox-list-delete.c Sun Oct 30 12:39:53 2011 +0100 +++ b/src/lib-storage/list/mailbox-list-delete.c Sun Mar 24 12:09:39 2013 +0200 @@ -68,7 +68,7 @@ continue; } mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + T_MAILBOX_LIST_ERR_NOT_FOUND(list, name)); return -1; } if (errno == EXDEV) { @@ -130,7 +130,7 @@ return 0; else if (ENOTFOUND(errno)) { mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + T_MAILBOX_LIST_ERR_NOT_FOUND(list, name)); return -1; } else { if (!mailbox_list_set_error_from_errno(list)) { @@ -158,7 +158,7 @@ if (dir == NULL) { if (errno == ENOENT) { mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + T_MAILBOX_LIST_ERR_NOT_FOUND(list, name)); } else { if (!mailbox_list_set_error_from_errno(list)) { mailbox_list_set_critical(list, @@ -340,7 +340,7 @@ if (errno == ENOENT) { mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + T_MAILBOX_LIST_ERR_NOT_FOUND(list, name)); } else if (errno == EISDIR || errno == EPERM) { /* Solaris */ mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, diff -r a588b743d695 -r eece943c7521 src/lib-storage/list/mailbox-list-fs.c --- a/src/lib-storage/list/mailbox-list-fs.c Sun Oct 30 12:39:53 2011 +0100 +++ b/src/lib-storage/list/mailbox-list-fs.c Sun Mar 24 12:09:39 2013 +0200 @@ -393,7 +393,7 @@ if (errno == ENOENT || errno == ENOTDIR) { mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + T_MAILBOX_LIST_ERR_NOT_FOUND(list, name)); } else if (errno == ENOTEMPTY || errno == EEXIST) { /* mbox workaround: if only .imap/ directory is preventing the deletion, remove it */ @@ -586,7 +586,7 @@ if (rename(oldpath, newpath) < 0) { if (ENOTFOUND(errno)) { mailbox_list_set_error(oldlist, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(oldname)); + T_MAILBOX_LIST_ERR_NOT_FOUND(oldlist, oldname)); } else if (!mailbox_list_set_error_from_errno(oldlist)) { mailbox_list_set_critical(oldlist, "rename(%s, %s) failed: %m", oldpath, newpath); diff -r a588b743d695 -r eece943c7521 src/lib-storage/list/mailbox-list-maildir.c --- a/src/lib-storage/list/mailbox-list-maildir.c Sun Oct 30 12:39:53 2011 +0100 +++ b/src/lib-storage/list/mailbox-list-maildir.c Sun Mar 24 12:09:39 2013 +0200 @@ -428,7 +428,7 @@ "Mailbox exists"); } else if (errno == ENOENT || errno == ENOTDIR) { mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + T_MAILBOX_LIST_ERR_NOT_FOUND(list, name)); } else { mailbox_list_set_critical(list, "stat(%s) failed: %m", path); } @@ -613,7 +613,7 @@ return -1; if (!found && ret == 0) { mailbox_list_set_error(oldlist, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(oldname)); + T_MAILBOX_LIST_ERR_NOT_FOUND(oldlist, oldname)); return -1; } diff -r a588b743d695 -r eece943c7521 src/lib-storage/mailbox-list-private.h --- a/src/lib-storage/mailbox-list-private.h Sun Oct 30 12:39:53 2011 +0100 +++ b/src/lib-storage/mailbox-list-private.h Sun Mar 24 12:09:39 2013 +0200 @@ -11,6 +11,10 @@ #define MAILBOX_LOG_FILE_NAME "dovecot.mailbox.log" +#define T_MAILBOX_LIST_ERR_NOT_FOUND(list, name) \ + t_strdup_printf(MAIL_ERRSTR_MAILBOX_NOT_FOUND, \ + mailbox_list_get_vname(list, name)) + enum mailbox_log_record_type; struct stat; struct dirent; diff -r a588b743d695 -r eece943c7521 src/plugins/acl/acl-mailbox.c --- a/src/plugins/acl/acl-mailbox.c Sun Oct 30 12:39:53 2011 +0100 +++ b/src/plugins/acl/acl-mailbox.c Sun Mar 24 12:09:39 2013 +0200 @@ -159,7 +159,7 @@ MAIL_ERRSTR_NO_PERMISSION); } else if (ret == 0) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name)); + T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname)); } } diff -r a588b743d695 -r eece943c7521 src/plugins/virtual/virtual-config.c --- a/src/plugins/virtual/virtual-config.c Sun Oct 30 12:39:53 2011 +0100 +++ b/src/plugins/virtual/virtual-config.c Sun Mar 24 12:09:39 2013 +0200 @@ -378,7 +378,7 @@ "Virtual mailbox missing configuration file"); } else if (errno == ENOENT) { mail_storage_set_error(storage, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(mbox->box.name)); + T_MAIL_ERR_MAILBOX_NOT_FOUND(mbox->box.vname)); } else { mail_storage_set_critical(storage, "stat(%s) failed: %m", box_path); From dovecot at dovecot.org Sun Mar 24 15:33:49 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 24 Mar 2013 15:33:49 +0200 Subject: dovecot-2.2: lib-storage: If INBOX isn't subscribed, don't retur... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/438561ec237b changeset: 16093:438561ec237b user: Timo Sirainen date: Sun Mar 24 15:33:36 2013 +0200 description: lib-storage: If INBOX isn't subscribed, don't return it in subscriptions list. diffstat: src/lib-storage/list/mailbox-list-iter.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r fed3adf86ab5 -r 438561ec237b src/lib-storage/list/mailbox-list-iter.c --- a/src/lib-storage/list/mailbox-list-iter.c Fri Mar 22 19:45:52 2013 +0200 +++ b/src/lib-storage/list/mailbox-list-iter.c Sun Mar 24 15:33:36 2013 +0200 @@ -732,7 +732,8 @@ ctx->patterns = p_new(pool, const char *, count + 1); for (i = 0; i < count; i++) ctx->patterns[i] = p_strdup(pool, patterns[i]); - if (patterns_match_inbox(namespaces, ctx->patterns)) { + if (patterns_match_inbox(namespaces, ctx->patterns) && + (flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) == 0) { /* we're going to list the INBOX. get its own flags (i.e. not [no]children) immediately, so if we end up seeing something else called INBOX (e.g. namespace prefix) we can show it From dovecot at dovecot.org Sun Mar 24 16:04:49 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 24 Mar 2013 16:04:49 +0200 Subject: dovecot-2.2: lib-storage: Fixed listing subscribed namespace pre... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7671f07867b7 changeset: 16094:7671f07867b7 user: Timo Sirainen date: Sun Mar 24 16:04:37 2013 +0200 description: lib-storage: Fixed listing subscribed namespace prefixes. diffstat: src/lib-storage/list/mailbox-list-iter.c | 22 +++++++++++----------- 1 files changed, 11 insertions(+), 11 deletions(-) diffs (46 lines): diff -r 438561ec237b -r 7671f07867b7 src/lib-storage/list/mailbox-list-iter.c --- a/src/lib-storage/list/mailbox-list-iter.c Sun Mar 24 15:33:36 2013 +0200 +++ b/src/lib-storage/list/mailbox-list-iter.c Sun Mar 24 16:04:37 2013 +0200 @@ -430,7 +430,6 @@ mailbox_list_ns_prefix_return(struct ns_list_iterate_context *ctx, struct mail_namespace *ns, bool has_children) { - struct mail_namespace *subs_ns; struct mailbox *box; enum mailbox_existence existence; int ret; @@ -460,13 +459,9 @@ if ((ctx->ctx.flags & (MAILBOX_LIST_ITER_RETURN_SUBSCRIBED | MAILBOX_LIST_ITER_SELECT_SUBSCRIBED)) != 0) { - subs_ns = mail_namespace_find_subscribable(ctx->namespaces, - ns->prefix); - if (subs_ns != NULL) { - mailbox_list_set_subscription_flags(subs_ns->list, - ctx->ns_info.vname, - &ctx->ns_info.flags); - } + mailbox_list_set_subscription_flags(ns->list, + ctx->ns_info.vname, + &ctx->ns_info.flags); } if (!mailbox_ns_prefix_check_selection_criteria(ctx)) return FALSE; @@ -608,9 +603,14 @@ ctx->inbox_info.flags |= MAILBOX_CHILDREN; ctx->inbox_info.flags &= ~MAILBOX_NOINFERIORS; } - if (mailbox_is_shared_inbox(info->ns, info->vname)) { - /* listing shared/$user/INBOX as shared/$user, which - we already listed as namespace prefix */ + if (info->ns->prefix_len > 0 && + strncmp(info->vname, info->ns->prefix, + info->ns->prefix_len-1) == 0 && + info->vname[info->ns->prefix_len-1] == '\0') { + /* this is an entry for namespace prefix, which we + already returned. (e.g. shared/$user/INBOX entry + returned as shared/$user, or when listing + subscribed namespace prefix). */ return FALSE; } From dovecot at dovecot.org Sun Mar 24 16:49:11 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 24 Mar 2013 16:49:11 +0200 Subject: dovecot-2.2: doveadm: Added "replicator status" command. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/660d1fd6fc9c changeset: 16096:660d1fd6fc9c user: Timo Sirainen date: Sun Mar 24 16:48:53 2013 +0200 description: doveadm: Added "replicator status" command. diffstat: src/doveadm/Makefile.am | 1 + src/doveadm/doveadm-replicator.c | 162 +++++++++++++++++++++++++++++++++++++++ src/doveadm/doveadm.c | 1 + src/doveadm/doveadm.h | 1 + 4 files changed, 165 insertions(+), 0 deletions(-) diffs (198 lines): diff -r 5271c894700c -r 660d1fd6fc9c src/doveadm/Makefile.am --- a/src/doveadm/Makefile.am Sun Mar 24 16:48:29 2013 +0200 +++ b/src/doveadm/Makefile.am Sun Mar 24 16:48:53 2013 +0200 @@ -101,6 +101,7 @@ doveadm-print-table.c \ doveadm-proxy.c \ doveadm-pw.c \ + doveadm-replicator.c \ doveadm-sis.c \ doveadm-stats.c \ doveadm-who.c \ diff -r 5271c894700c -r 660d1fd6fc9c src/doveadm/doveadm-replicator.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doveadm/doveadm-replicator.c Sun Mar 24 16:48:53 2013 +0200 @@ -0,0 +1,162 @@ +/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "ioloop.h" +#include "net.h" +#include "istream.h" +#include "write-full.h" +#include "master-service.h" +#include "doveadm.h" +#include "doveadm-print.h" + +#include +#include +#include +#include + +struct replicator_context { + const char *socket_path; + struct istream *input; +}; + +extern struct doveadm_cmd doveadm_cmd_replicator[]; + +static void replicator_cmd_help(doveadm_command_t *cmd) ATTR_NORETURN; + +static void +replicator_send(struct replicator_context *ctx, const char *data) +{ + if (write_full(i_stream_get_fd(ctx->input), data, strlen(data)) < 0) + i_fatal("write(%s) failed: %m", ctx->socket_path); +} + +static void replicator_connect(struct replicator_context *ctx) +{ +#define REPLICATOR_HANDSHAKE "VERSION\treplicator-doveadm-client\t1\t0\n" + const char *line; + int fd; + + fd = doveadm_connect(ctx->socket_path); + net_set_nonblock(fd, FALSE); + + ctx->input = i_stream_create_fd(fd, (size_t)-1, TRUE); + replicator_send(ctx, REPLICATOR_HANDSHAKE); + + alarm(5); + line = i_stream_read_next_line(ctx->input); + alarm(0); + if (line == NULL) { + if (ctx->input->stream_errno != 0) + i_fatal("read(%s) failed: %m", ctx->socket_path); + else if (ctx->input->eof) + i_fatal("%s disconnected", ctx->socket_path); + else + i_fatal("read(%s) timed out", ctx->socket_path); + } + if (!version_string_verify(line, "replicator-doveadm-server", 1)) { + i_fatal_status(EX_PROTOCOL, + "%s not a compatible replicator-doveadm socket", + ctx->socket_path); + } +} + +static void replicator_disconnect(struct replicator_context *ctx) +{ + if (ctx->input->stream_errno != 0) + i_fatal("read(%s) failed: %m", ctx->socket_path); + i_stream_destroy(&ctx->input); +} + +static struct replicator_context * +cmd_replicator_init(int argc, char *argv[], doveadm_command_t *cmd) +{ + struct replicator_context *ctx; + int c; + + ctx = t_new(struct replicator_context, 1); + ctx->socket_path = t_strconcat(doveadm_settings->base_dir, + "/replicator-doveadm", NULL); + + while ((c = getopt(argc, argv, "a:")) > 0) { + switch (c) { + case 'a': + ctx->socket_path = optarg; + break; + default: + replicator_cmd_help(cmd); + } + } + replicator_connect(ctx); + return ctx; +} + +static const char *time_ago(time_t t) +{ + int diff = ioloop_time - t; + + return t_strdup_printf("%02d:%02d:%02d", diff/3600, diff/60, diff%60); +} + +static void cmd_replicator_status(int argc, char *argv[]) +{ + struct replicator_context *ctx; + const char *line, *const *args; + time_t last_fast, last_full; + + ctx = cmd_replicator_init(argc, argv, cmd_replicator_status); + + doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE); + doveadm_print_header("username", "username", + DOVEADM_PRINT_HEADER_FLAG_EXPAND); + doveadm_print_header_simple("priority"); + doveadm_print_header_simple("fast sync"); + doveadm_print_header_simple("full sync"); + doveadm_print_header_simple("failed"); + + replicator_send(ctx, "STATUS\n"); + while ((line = i_stream_read_next_line(ctx->input)) != NULL) { + if (*line == '\0') + break; + T_BEGIN { + args = t_strsplit_tab(line); + if (str_array_length(args) >= 5 && + str_to_time(args[2], &last_fast) == 0 && + str_to_time(args[3], &last_full) == 0) { + doveadm_print(args[0]); + doveadm_print(args[1]); + doveadm_print(time_ago(last_fast)); + doveadm_print(time_ago(last_full)); + doveadm_print(args[4][0] == '0' ? "-" : "y"); + } + } T_END; + } + if (line == NULL) { + i_error("Director disconnected unexpectedly"); + doveadm_exit_code = EX_TEMPFAIL; + } + replicator_disconnect(ctx); +} + +struct doveadm_cmd doveadm_cmd_replicator[] = { + { cmd_replicator_status, "replicator status", + "[-a ] []" } +}; + +static void replicator_cmd_help(doveadm_command_t *cmd) +{ + unsigned int i; + + for (i = 0; i < N_ELEMENTS(doveadm_cmd_replicator); i++) { + if (doveadm_cmd_replicator[i].cmd == cmd) + help(&doveadm_cmd_replicator[i]); + } + i_unreached(); +} + +void doveadm_register_replicator_commands(void) +{ + unsigned int i; + + for (i = 0; i < N_ELEMENTS(doveadm_cmd_replicator); i++) + doveadm_register_cmd(&doveadm_cmd_replicator[i]); +} diff -r 5271c894700c -r 660d1fd6fc9c src/doveadm/doveadm.c --- a/src/doveadm/doveadm.c Sun Mar 24 16:48:29 2013 +0200 +++ b/src/doveadm/doveadm.c Sun Mar 24 16:48:53 2013 +0200 @@ -367,6 +367,7 @@ doveadm_register_mount_commands(); doveadm_register_proxy_commands(); doveadm_register_log_commands(); + doveadm_register_replicator_commands(); doveadm_dump_init(); doveadm_mail_init(); doveadm_load_modules(); diff -r 5271c894700c -r 660d1fd6fc9c src/doveadm/doveadm.h --- a/src/doveadm/doveadm.h Sun Mar 24 16:48:29 2013 +0200 +++ b/src/doveadm/doveadm.h Sun Mar 24 16:48:53 2013 +0200 @@ -46,5 +46,6 @@ void doveadm_register_log_commands(void); void doveadm_register_instance_commands(void); void doveadm_register_mount_commands(void); +void doveadm_register_replicator_commands(void); #endif From dovecot at dovecot.org Sun Mar 24 16:49:11 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 24 Mar 2013 16:49:11 +0200 Subject: dovecot-2.2: replicator: Added doveadm socket for communicating ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5271c894700c changeset: 16095:5271c894700c user: Timo Sirainen date: Sun Mar 24 16:48:29 2013 +0200 description: replicator: Added doveadm socket for communicating with "doveadm replicator". diffstat: src/replication/replication-common.h | 19 +++- src/replication/replicator/Makefile.am | 2 + src/replication/replicator/doveadm-connection.c | 114 +++++++++++++++++++++++ src/replication/replicator/doveadm-connection.h | 9 + src/replication/replicator/replicator-queue.c | 11 ++ src/replication/replicator/replicator-queue.h | 6 + src/replication/replicator/replicator-settings.c | 6 +- src/replication/replicator/replicator.c | 8 +- 8 files changed, 171 insertions(+), 4 deletions(-) diffs (278 lines): diff -r 7671f07867b7 -r 5271c894700c src/replication/replication-common.h --- a/src/replication/replication-common.h Sun Mar 24 16:04:37 2013 +0200 +++ b/src/replication/replication-common.h Sun Mar 24 16:48:29 2013 +0200 @@ -12,11 +12,28 @@ REPLICATION_PRIORITY_SYNC }; +static inline const char * +replicator_priority_to_str(enum replication_priority priority) +{ + switch (priority) { + case REPLICATION_PRIORITY_NONE: + return "none"; + case REPLICATION_PRIORITY_LOW: + return "low"; + case REPLICATION_PRIORITY_HIGH: + return "high"; + case REPLICATION_PRIORITY_SYNC: + return "sync"; + } +} + static inline int replication_priority_parse(const char *str, enum replication_priority *priority_r) { - if (strcmp(str, "low") == 0) + if (strcmp(str, "none") == 0) + *priority_r = REPLICATION_PRIORITY_NONE; + else if (strcmp(str, "low") == 0) *priority_r = REPLICATION_PRIORITY_LOW; else if (strcmp(str, "high") == 0) *priority_r = REPLICATION_PRIORITY_HIGH; diff -r 7671f07867b7 -r 5271c894700c src/replication/replicator/Makefile.am --- a/src/replication/replicator/Makefile.am Sun Mar 24 16:04:37 2013 +0200 +++ b/src/replication/replicator/Makefile.am Sun Mar 24 16:48:29 2013 +0200 @@ -15,6 +15,7 @@ replicator_DEPENDENCIES = $(LIBDOVECOT_DEPS) replicator_SOURCES = \ + doveadm-connection.c \ dsync-client.c \ replicator.c \ replicator-brain.c \ @@ -23,6 +24,7 @@ notify-connection.c noinst_HEADERS = \ + doveadm-connection.h \ dsync-client.h \ replicator-brain.h \ replicator-queue.h \ diff -r 7671f07867b7 -r 5271c894700c src/replication/replicator/doveadm-connection.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/replication/replicator/doveadm-connection.c Sun Mar 24 16:48:29 2013 +0200 @@ -0,0 +1,114 @@ +/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "connection.h" +#include "ostream.h" +#include "str.h" +#include "strescape.h" +#include "wildcard-match.h" +#include "master-service.h" +#include "replicator-queue.h" +#include "doveadm-connection.h" + +#include + +#define REPLICATOR_DOVEADM_MAJOR_VERSION 1 +#define REPLICATOR_DOVEADM_MINOR_VERSION 0 + +struct doveadm_connection { + struct connection conn; + struct replicator_queue *queue; +}; +static struct connection_list *doveadm_connections; + +static int +client_input_status(struct doveadm_connection *client, const char *const *args) +{ + struct replicator_user *const *users, *user; + unsigned int i, count; + const char *mask = args[0]; + string_t *str = t_str_new(128); + + users = replicator_queue_get_users(client->queue, &count); + for (i = 0; i < count; i++) { + user = users[i]; + if (mask != NULL && wildcard_match(user->username, mask)) + continue; + + str_truncate(str, 0); + str_append_tabescaped(str, user->username); + str_append_c(str, '\t'); + str_append(str, replicator_priority_to_str(user->priority)); + str_printfa(str, "\t%lld\t%lld\t%d\n", + (long long)user->last_fast_sync, + (long long)user->last_full_sync, + user->last_sync_failed); + o_stream_send(client->conn.output, str_data(str), str_len(str)); + } + o_stream_send(client->conn.output, "\n", 1); + return 0; +} + +static int client_input_args(struct connection *conn, const char *const *args) +{ + struct doveadm_connection *client = (struct doveadm_connection *)conn; + const char *cmd = args[0]; + + if (cmd == NULL) { + i_error("%s: Empty command", conn->name); + return 0; + } + args++; + + if (strcmp(cmd, "STATUS") == 0) + return client_input_status(client, args); + i_error("%s: Unknown command: %s", conn->name, cmd); + return -1; +} + +static void client_destroy(struct connection *conn) +{ + struct doveadm_connection *client = (struct doveadm_connection *)conn; + + connection_deinit(&client->conn); + i_free(client); + + master_service_client_connection_destroyed(master_service); +} + +void doveadm_connection_create(struct replicator_queue *queue, int fd) +{ + struct doveadm_connection *client; + + client = i_new(struct doveadm_connection, 1); + client->queue = queue; + connection_init_server(doveadm_connections, &client->conn, + "(doveadm client)", fd, fd); +} + +static struct connection_settings doveadm_conn_set = { + .service_name_in = "replicator-doveadm-client", + .service_name_out = "replicator-doveadm-server", + .major_version = REPLICATOR_DOVEADM_MAJOR_VERSION, + .minor_version = REPLICATOR_DOVEADM_MINOR_VERSION, + + .input_max_size = (size_t)-1, + .output_max_size = (size_t)-1, + .client = FALSE +}; + +static const struct connection_vfuncs doveadm_conn_vfuncs = { + .destroy = client_destroy, + .input_args = client_input_args +}; + +void doveadm_connections_init(void) +{ + doveadm_connections = connection_list_init(&doveadm_conn_set, + &doveadm_conn_vfuncs); +} + +void doveadm_connections_deinit(void) +{ + connection_list_deinit(&doveadm_connections); +} diff -r 7671f07867b7 -r 5271c894700c src/replication/replicator/doveadm-connection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/replication/replicator/doveadm-connection.h Sun Mar 24 16:48:29 2013 +0200 @@ -0,0 +1,9 @@ +#ifndef DOVEADM_CONNECTION_H +#define DOVEADM_CONNECTION_H + +void doveadm_connection_create(struct replicator_queue *queue, int fd); + +void doveadm_connections_init(void); +void doveadm_connections_deinit(void); + +#endif diff -r 7671f07867b7 -r 5271c894700c src/replication/replicator/replicator-queue.c --- a/src/replication/replicator/replicator-queue.c Sun Mar 24 16:04:37 2013 +0200 +++ b/src/replication/replicator/replicator-queue.c Sun Mar 24 16:48:29 2013 +0200 @@ -371,3 +371,14 @@ o_stream_destroy(&output); return ret; } + +struct replicator_user *const * +replicator_queue_get_users(struct replicator_queue *queue, + unsigned int *count_r) +{ + struct priorityq_item *const *items = + priorityq_items(queue->user_queue); + + *count_r = priorityq_count(queue->user_queue); + return (void *)items; +} diff -r 7671f07867b7 -r 5271c894700c src/replication/replicator/replicator-queue.h --- a/src/replication/replicator/replicator-queue.h Sun Mar 24 16:04:37 2013 +0200 +++ b/src/replication/replicator/replicator-queue.h Sun Mar 24 16:48:29 2013 +0200 @@ -8,6 +8,7 @@ struct priorityq_item item; char *username; + /* dsync state for incremental syncing */ char *state; /* last time this user's state was updated */ time_t last_update; @@ -58,4 +59,9 @@ int replicator_queue_import(struct replicator_queue *queue, const char *path); int replicator_queue_export(struct replicator_queue *queue, const char *path); +/* Returns an (unsorted) array of all users in the queue. */ +struct replicator_user *const * +replicator_queue_get_users(struct replicator_queue *queue, + unsigned int *count_r); + #endif diff -r 7671f07867b7 -r 5271c894700c src/replication/replicator/replicator-settings.c --- a/src/replication/replicator/replicator-settings.c Sun Mar 24 16:04:37 2013 +0200 +++ b/src/replication/replicator/replicator-settings.c Sun Mar 24 16:48:29 2013 +0200 @@ -8,10 +8,12 @@ /* */ static struct file_listener_settings replicator_unix_listeners_array[] = { - { "replicator", 0600, "$default_internal_user", "" } + { "replicator", 0600, "$default_internal_user", "" }, + { "replicator-doveadm", 0600, "$default_internal_user", "" } }; static struct file_listener_settings *replicator_unix_listeners[] = { - &replicator_unix_listeners_array[0] + &replicator_unix_listeners_array[0], + &replicator_unix_listeners_array[1] }; static buffer_t replicator_unix_listeners_buf = { replicator_unix_listeners, sizeof(replicator_unix_listeners), { 0, } diff -r 7671f07867b7 -r 5271c894700c src/replication/replicator/replicator.c --- a/src/replication/replicator/replicator.c Sun Mar 24 16:04:37 2013 +0200 +++ b/src/replication/replicator/replicator.c Sun Mar 24 16:48:29 2013 +0200 @@ -7,6 +7,7 @@ #include "master-service.h" #include "master-service-settings.h" #include "notify-connection.h" +#include "doveadm-connection.h" #include "replicator-brain.h" #include "replicator-queue.h" #include "replicator-settings.h" @@ -24,7 +25,10 @@ static void client_connected(struct master_service_connection *conn) { master_service_client_connection_accept(conn); - (void)notify_connection_create(conn->fd, queue); + if (strcmp(conn->name, "replicator-doveadm") == 0) + doveadm_connection_create(queue, conn->fd); + else + (void)notify_connection_create(conn->fd, queue); } static void replication_add_users(struct replicator_queue *queue) @@ -80,12 +84,14 @@ to_dump = timeout_add(REPLICATOR_DB_DUMP_INTERVAL_MSECS, replicator_dump_timeout, (void *)NULL); brain = replicator_brain_init(queue, set); + doveadm_connections_init(); } static void main_deinit(void) { const char *path; + doveadm_connections_deinit(); notify_connections_destroy_all(); replicator_brain_deinit(&brain); timeout_remove(&to_dump); From dovecot at dovecot.org Sun Mar 24 16:53:38 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 24 Mar 2013 16:53:38 +0200 Subject: dovecot-2.2: doveadm replicator status: Show sync time as "-" fo... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/85f4f6ff4551 changeset: 16098:85f4f6ff4551 user: Timo Sirainen date: Sun Mar 24 16:53:32 2013 +0200 description: doveadm replicator status: Show sync time as "-" for "never". diffstat: src/doveadm/doveadm-replicator.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r ae5699ba6324 -r 85f4f6ff4551 src/doveadm/doveadm-replicator.c --- a/src/doveadm/doveadm-replicator.c Sun Mar 24 16:52:39 2013 +0200 +++ b/src/doveadm/doveadm-replicator.c Sun Mar 24 16:53:32 2013 +0200 @@ -94,6 +94,8 @@ { int diff = ioloop_time - t; + if (t == 0) + return "-"; return t_strdup_printf("%02d:%02d:%02d", diff/3600, diff/60, diff%60); } From dovecot at dovecot.org Sun Mar 24 16:53:38 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 24 Mar 2013 16:53:38 +0200 Subject: dovecot-2.2: doveadm replicator status: Fixed user mask to work. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ae5699ba6324 changeset: 16097:ae5699ba6324 user: Timo Sirainen date: Sun Mar 24 16:52:39 2013 +0200 description: doveadm replicator status: Fixed user mask to work. diffstat: src/doveadm/doveadm-replicator.c | 9 +++++++-- src/replication/replicator/doveadm-connection.c | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diffs (38 lines): diff -r 660d1fd6fc9c -r ae5699ba6324 src/doveadm/doveadm-replicator.c --- a/src/doveadm/doveadm-replicator.c Sun Mar 24 16:48:53 2013 +0200 +++ b/src/doveadm/doveadm-replicator.c Sun Mar 24 16:52:39 2013 +0200 @@ -2,7 +2,7 @@ #include "lib.h" #include "ioloop.h" -#include "net.h" +#include "strescape.h" #include "istream.h" #include "write-full.h" #include "master-service.h" @@ -113,7 +113,12 @@ doveadm_print_header_simple("full sync"); doveadm_print_header_simple("failed"); - replicator_send(ctx, "STATUS\n"); + if (argv[1] == NULL) + replicator_send(ctx, "STATUS\n"); + else { + replicator_send(ctx, t_strdup_printf("STATUS\t%s\n", + str_tabescape(argv[1]))); + } while ((line = i_stream_read_next_line(ctx->input)) != NULL) { if (*line == '\0') break; diff -r 660d1fd6fc9c -r ae5699ba6324 src/replication/replicator/doveadm-connection.c --- a/src/replication/replicator/doveadm-connection.c Sun Mar 24 16:48:53 2013 +0200 +++ b/src/replication/replicator/doveadm-connection.c Sun Mar 24 16:52:39 2013 +0200 @@ -32,7 +32,7 @@ users = replicator_queue_get_users(client->queue, &count); for (i = 0; i < count; i++) { user = users[i]; - if (mask != NULL && wildcard_match(user->username, mask)) + if (mask != NULL && !wildcard_match(user->username, mask)) continue; str_truncate(str, 0); From dovecot at dovecot.org Sun Mar 24 17:04:33 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 24 Mar 2013 17:04:33 +0200 Subject: dovecot-2.2: replicator: Replicator queue export/import at exit/... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1af7c6f22793 changeset: 16099:1af7c6f22793 user: Timo Sirainen date: Sun Mar 24 17:04:22 2013 +0200 description: replicator: Replicator queue export/import at exit/startup wasn't really working. diffstat: src/replication/replicator/replicator-queue.c | 24 +++++++++++++++++------- 1 files changed, 17 insertions(+), 7 deletions(-) diffs (68 lines): diff -r 85f4f6ff4551 -r 1af7c6f22793 src/replication/replicator/replicator-queue.c --- a/src/replication/replicator/replicator-queue.c Sun Mar 24 16:53:32 2013 +0200 +++ b/src/replication/replicator/replicator-queue.c Sun Mar 24 17:04:22 2013 +0200 @@ -256,24 +256,27 @@ static int replicator_queue_import_line(struct replicator_queue *queue, const char *line) { - const char *const *args, *username; + const char *const *args, *username, *state; unsigned int priority; struct replicator_user *user, tmp_user; - /* */ + /* + */ args = t_strsplit_tabescaped(line); - if (str_array_length(args) < 5) + if (str_array_length(args) < 7) return -1; memset(&tmp_user, 0, sizeof(tmp_user)); username = args[0]; + state = t_strdup_noconst(args[6]); if (username[0] == '\0' || str_to_uint(args[1], &priority) < 0 || str_to_time(args[2], &tmp_user.last_update) < 0 || str_to_time(args[3], &tmp_user.last_fast_sync) < 0 || - str_to_time(args[3], &tmp_user.last_full_sync) < 0) + str_to_time(args[4], &tmp_user.last_full_sync) < 0) return -1; tmp_user.priority = priority; + tmp_user.last_sync_failed = args[5][0] != '0'; user = hash_table_lookup(queue->user_hash, username); if (user != NULL) { @@ -288,11 +291,14 @@ return 0; } } - user = replicator_queue_add(queue, tmp_user.username, + user = replicator_queue_add(queue, username, tmp_user.priority); user->last_update = tmp_user.last_update; user->last_fast_sync = tmp_user.last_fast_sync; user->last_full_sync = tmp_user.last_full_sync; + user->last_sync_failed = tmp_user.last_sync_failed; + i_free(user->state); + user->state = i_strdup(state); return 0; } @@ -330,10 +336,14 @@ replicator_queue_export_user(struct replicator_user *user, string_t *str) { str_append_tabescaped(str, user->username); - str_printfa(str, "\t%d\t%lld\t%lld\t%lld", (int)user->priority, + str_printfa(str, "\t%d\t%lld\t%lld\t%lld\t%d\t", (int)user->priority, (long long)user->last_update, (long long)user->last_fast_sync, - (long long)user->last_full_sync); + (long long)user->last_full_sync, + user->last_sync_failed); + if (user->state != NULL) + str_append_tabescaped(str, user->state); + str_append_c(str, '\n'); } int replicator_queue_export(struct replicator_queue *queue, const char *path) From dovecot at dovecot.org Sun Mar 24 17:22:02 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 24 Mar 2013 17:22:02 +0200 Subject: dovecot-2.2: replicator: If sync fails, retry it in 5 minutes. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c4138d8db3dd changeset: 16100:c4138d8db3dd user: Timo Sirainen date: Sun Mar 24 17:21:49 2013 +0200 description: replicator: If sync fails, retry it in 5 minutes. diffstat: src/replication/replicator/replicator-queue.c | 50 ++++++++++++++++++++++---- src/replication/replicator/replicator-queue.h | 6 ++- src/replication/replicator/replicator.c | 5 ++- 3 files changed, 50 insertions(+), 11 deletions(-) diffs (144 lines): diff -r 1af7c6f22793 -r c4138d8db3dd src/replication/replicator/replicator-queue.c --- a/src/replication/replicator/replicator-queue.c Sun Mar 24 17:04:22 2013 +0200 +++ b/src/replication/replicator/replicator-queue.c Sun Mar 24 17:21:49 2013 +0200 @@ -30,6 +30,7 @@ ARRAY(struct replicator_sync_lookup) sync_lookups; unsigned int full_sync_interval; + unsigned int failure_resync_interval; void (*change_callback)(void *context); void *change_context; @@ -50,6 +51,18 @@ return -1; if (user1->last_fast_sync > user2->last_fast_sync) return 1; + } else if (user1->last_sync_failed != user2->last_sync_failed) { + /* resync failures first */ + if (user1->last_sync_failed) + return -1; + else + return 1; + } else if (user1->last_sync_failed) { + /* both have failed. resync failures with fast-sync timestamp */ + if (user1->last_fast_sync < user2->last_fast_sync) + return -1; + if (user1->last_fast_sync > user2->last_fast_sync) + return 1; } else { /* nothing to replicate, but do still periodic full syncs */ if (user1->last_full_sync < user2->last_full_sync) @@ -60,12 +73,15 @@ return 0; } -struct replicator_queue *replicator_queue_init(unsigned int full_sync_interval) +struct replicator_queue * +replicator_queue_init(unsigned int full_sync_interval, + unsigned int failure_resync_interval) { struct replicator_queue *queue; queue = i_new(struct replicator_queue, 1); queue->full_sync_interval = full_sync_interval; + queue->failure_resync_interval = failure_resync_interval; queue->user_queue = priorityq_init(user_priority_cmp, 1024); hash_table_create(&queue->user_hash, default_pool, 1024, str_hash, strcmp); @@ -182,13 +198,35 @@ queue->change_callback(queue->change_context); } +static bool +replicator_queue_can_sync_now(struct replicator_queue *queue, + struct replicator_user *user, + unsigned int *next_secs_r) +{ + time_t next_sync; + + if (user->priority != REPLICATION_PRIORITY_NONE) + return TRUE; + + if (user->last_sync_failed) { + next_sync = user->last_fast_sync + + queue->failure_resync_interval; + } else { + next_sync = user->last_full_sync + queue->full_sync_interval; + } + if (next_sync <= ioloop_time) + return TRUE; + + *next_secs_r = next_sync - ioloop_time; + return FALSE; +} + struct replicator_user * replicator_queue_pop(struct replicator_queue *queue, unsigned int *next_secs_r) { struct priorityq_item *item; struct replicator_user *user; - time_t next_full_sync; item = priorityq_peek(queue->user_queue); if (item == NULL) { @@ -197,12 +235,8 @@ return NULL; } user = (struct replicator_user *)item; - - next_full_sync = user->last_full_sync + queue->full_sync_interval; - if (user->priority == REPLICATION_PRIORITY_NONE && - next_full_sync > ioloop_time) { - /* we don't want to do a full sync yet */ - *next_secs_r = next_full_sync - ioloop_time; + if (!replicator_queue_can_sync_now(queue, user, next_secs_r)) { + /* we don't want to sync the user yet */ return NULL; } priorityq_remove(queue->user_queue, &user->item); diff -r 1af7c6f22793 -r c4138d8db3dd src/replication/replicator/replicator-queue.h --- a/src/replication/replicator/replicator-queue.h Sun Mar 24 17:04:22 2013 +0200 +++ b/src/replication/replicator/replicator-queue.h Sun Mar 24 17:21:49 2013 +0200 @@ -12,7 +12,7 @@ char *state; /* last time this user's state was updated */ time_t last_update; - /* last_fast_run is always >= last_full_run. */ + /* last_fast_sync is always >= last_full_sync. */ time_t last_fast_sync, last_full_sync; enum replication_priority priority; @@ -24,7 +24,9 @@ typedef void replicator_sync_callback_t(bool success, void *context); -struct replicator_queue *replicator_queue_init(unsigned int full_sync_interval); +struct replicator_queue * +replicator_queue_init(unsigned int full_sync_interval, + unsigned int failure_resync_interval); void replicator_queue_deinit(struct replicator_queue **queue); /* Call the specified callback when data is added/removed/moved in queue diff -r 1af7c6f22793 -r c4138d8db3dd src/replication/replicator/replicator.c --- a/src/replication/replicator/replicator.c Sun Mar 24 17:04:22 2013 +0200 +++ b/src/replication/replicator/replicator.c Sun Mar 24 17:21:49 2013 +0200 @@ -14,6 +14,8 @@ #define REPLICATOR_AUTH_SERVICE_NAME "replicator" #define REPLICATOR_DB_DUMP_INTERVAL_MSECS (1000*60*15) +/* if syncing fails, try again in 5 minutes */ +#define REPLICATOR_FAILURE_RESYNC_INTERVAL_SECS (60*5) #define REPLICATOR_DB_FNAME "replicator.db" static struct replicator_queue *queue; @@ -79,7 +81,8 @@ sets = master_service_settings_get_others(master_service); set = sets[0]; - queue = replicator_queue_init(set->replication_full_sync_interval); + queue = replicator_queue_init(set->replication_full_sync_interval, + REPLICATOR_FAILURE_RESYNC_INTERVAL_SECS); replication_add_users(queue); to_dump = timeout_add(REPLICATOR_DB_DUMP_INTERVAL_MSECS, replicator_dump_timeout, (void *)NULL); From dovecot at dovecot.org Sun Mar 24 17:23:38 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 24 Mar 2013 17:23:38 +0200 Subject: dovecot-2.2: replication_full_sync_interval default changed from... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1fa248d2aef7 changeset: 16101:1fa248d2aef7 user: Timo Sirainen date: Sun Mar 24 17:23:33 2013 +0200 description: replication_full_sync_interval default changed from 12h -> 24h This allows doing full resyncs only at nights. diffstat: src/replication/replicator/replicator-settings.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r c4138d8db3dd -r 1fa248d2aef7 src/replication/replicator/replicator-settings.c --- a/src/replication/replicator/replicator-settings.c Sun Mar 24 17:21:49 2013 +0200 +++ b/src/replication/replicator/replicator-settings.c Sun Mar 24 17:23:33 2013 +0200 @@ -64,7 +64,7 @@ .auth_socket_path = "auth-userdb", .doveadm_socket_path = "doveadm-server", - .replication_full_sync_interval = 60*60*12, + .replication_full_sync_interval = 60*60*24, .replication_max_conns = 10 }; From dovecot at dovecot.org Sun Mar 24 17:48:37 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 24 Mar 2013 17:48:37 +0200 Subject: dovecot-2.2: doveadm: Added "replicator replicate" command to fo... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1b269672e33b changeset: 16102:1b269672e33b user: Timo Sirainen date: Sun Mar 24 17:48:17 2013 +0200 description: doveadm: Added "replicator replicate" command to force replication of user(s). diffstat: src/doveadm/doveadm-replicator.c | 57 ++++++++++++++++++++++-- src/replication/replicator/doveadm-connection.c | 41 +++++++++++++++++ 2 files changed, 93 insertions(+), 5 deletions(-) diffs (171 lines): diff -r 1fa248d2aef7 -r 1b269672e33b src/doveadm/doveadm-replicator.c --- a/src/doveadm/doveadm-replicator.c Sun Mar 24 17:23:33 2013 +0200 +++ b/src/doveadm/doveadm-replicator.c Sun Mar 24 17:48:17 2013 +0200 @@ -2,6 +2,7 @@ #include "lib.h" #include "ioloop.h" +#include "str.h" #include "strescape.h" #include "istream.h" #include "write-full.h" @@ -16,6 +17,7 @@ struct replicator_context { const char *socket_path; + const char *priority; struct istream *input; }; @@ -68,7 +70,8 @@ } static struct replicator_context * -cmd_replicator_init(int argc, char *argv[], doveadm_command_t *cmd) +cmd_replicator_init(int argc, char *argv[], const char *getopt_args, + doveadm_command_t *cmd) { struct replicator_context *ctx; int c; @@ -77,11 +80,14 @@ ctx->socket_path = t_strconcat(doveadm_settings->base_dir, "/replicator-doveadm", NULL); - while ((c = getopt(argc, argv, "a:")) > 0) { + while ((c = getopt(argc, argv, getopt_args)) > 0) { switch (c) { case 'a': ctx->socket_path = optarg; break; + case 'p': + ctx->priority = optarg; + break; default: replicator_cmd_help(cmd); } @@ -105,7 +111,7 @@ const char *line, *const *args; time_t last_fast, last_full; - ctx = cmd_replicator_init(argc, argv, cmd_replicator_status); + ctx = cmd_replicator_init(argc, argv, "a:", cmd_replicator_status); doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE); doveadm_print_header("username", "username", @@ -138,15 +144,56 @@ } T_END; } if (line == NULL) { - i_error("Director disconnected unexpectedly"); + i_error("Replicator disconnected unexpectedly"); doveadm_exit_code = EX_TEMPFAIL; } replicator_disconnect(ctx); } +static void cmd_replicator_replicate(int argc, char *argv[]) +{ + struct replicator_context *ctx; + string_t *str; + const char *line; + + if (argv[1] == NULL) + replicator_cmd_help(cmd_replicator_replicate); + + ctx = cmd_replicator_init(argc, argv, "a:p:", cmd_replicator_replicate); + + str = t_str_new(128); + str_append(str, "REPLICATE\t"); + if (ctx->priority == NULL) + str_append_tabescaped(str, "low"); + else + str_append_tabescaped(str, ctx->priority); + str_append_c(str, '\t'); + str_append_tabescaped(str, argv[1]); + str_append_c(str, '\n'); + replicator_send(ctx, str_c(str)); + + doveadm_print_init(DOVEADM_PRINT_TYPE_FLOW); + doveadm_print_header("result", "result", + DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE); + + line = i_stream_read_next_line(ctx->input); + if (line == NULL) { + i_error("Replicator disconnected unexpectedly"); + doveadm_exit_code = EX_TEMPFAIL; + } else if (line[0] != '+') { + i_error("Replicator failed: %s", line+1); + doveadm_exit_code = EX_USAGE; + } else { + doveadm_print(t_strdup_printf("%s users updated", line+1)); + } + replicator_disconnect(ctx); +} + struct doveadm_cmd doveadm_cmd_replicator[] = { { cmd_replicator_status, "replicator status", - "[-a ] []" } + "[-a ] []" }, + { cmd_replicator_replicate, "replicator replicate", + "[-a ] [-p ] " }, }; static void replicator_cmd_help(doveadm_command_t *cmd) diff -r 1fa248d2aef7 -r 1b269672e33b src/replication/replicator/doveadm-connection.c --- a/src/replication/replicator/doveadm-connection.c Sun Mar 24 17:23:33 2013 +0200 +++ b/src/replication/replicator/doveadm-connection.c Sun Mar 24 17:48:17 2013 +0200 @@ -49,6 +49,45 @@ return 0; } +static int +client_input_replicate(struct doveadm_connection *client, const char *const *args) +{ + struct replicator_user *const *queue_users, **users_dup; + unsigned int i, count, match_count; + const char *usermask; + enum replication_priority priority; + + /* | */ + if (str_array_length(args) != 2) { + i_error("%s: REPLICATE: Invalid parameters", client->conn.name); + return -1; + } + if (replication_priority_parse(args[0], &priority) < 0) { + o_stream_send_str(client->conn.output, "-Invalid priority\n"); + return 0; + } + usermask = args[1]; + if (strchr(usermask, '*') == NULL && strchr(usermask, '?') == NULL) { + replicator_queue_add(client->queue, usermask, priority); + o_stream_send_str(client->conn.output, "+1\n"); + return 0; + } + + queue_users = replicator_queue_get_users(client->queue, &count); + users_dup = i_new(struct replicator_user *, count+1); + for (i = match_count = 0; i < count; i++) { + if (wildcard_match(queue_users[i]->username, usermask)) + users_dup[match_count++] = queue_users[i]; + } + for (i = 0; i < match_count; i++) { + replicator_queue_add(client->queue, users_dup[i]->username, + priority); + } + o_stream_send_str(client->conn.output, + t_strdup_printf("+%u\n", match_count)); + return 0; +} + static int client_input_args(struct connection *conn, const char *const *args) { struct doveadm_connection *client = (struct doveadm_connection *)conn; @@ -62,6 +101,8 @@ if (strcmp(cmd, "STATUS") == 0) return client_input_status(client, args); + else if (strcmp(cmd, "REPLICATE") == 0) + return client_input_replicate(client, args); i_error("%s: Unknown command: %s", conn->name, cmd); return -1; } From dovecot at dovecot.org Sun Mar 24 18:14:29 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 24 Mar 2013 18:14:29 +0200 Subject: dovecot-2.2: doveadm: Table formatter now hides the titles if al... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/210282ae46e1 changeset: 16103:210282ae46e1 user: Timo Sirainen date: Sun Mar 24 18:13:53 2013 +0200 description: doveadm: Table formatter now hides the titles if all of them are marked hidden. diffstat: src/doveadm/doveadm-print-table.c | 20 ++++++++++++++++---- 1 files changed, 16 insertions(+), 4 deletions(-) diffs (43 lines): diff -r 1b269672e33b -r 210282ae46e1 src/doveadm/doveadm-print-table.c --- a/src/doveadm/doveadm-print-table.c Sun Mar 24 17:48:17 2013 +0200 +++ b/src/doveadm/doveadm-print-table.c Sun Mar 24 18:13:53 2013 +0200 @@ -135,16 +135,20 @@ } } -static void doveadm_buffer_flush(void) +static void doveadm_print_headers(void) { const struct doveadm_print_table_header *headers; - const char *const *valuep; unsigned int i, count; - doveadm_calc_header_length(); - headers = array_get(&ctx->headers, &count); + /* if all headers are hidden, don't print any of them */ for (i = 0; i < count; i++) { + if ((headers[i].flags & DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE) == 0) + break; + } + if (i == count) + return; + for (; i < count; i++) { if (i > 0) fprintf(stderr, " "); if ((headers[i].flags & @@ -157,6 +161,14 @@ } } fprintf(stderr, "\n"); +} + +static void doveadm_buffer_flush(void) +{ + const char *const *valuep; + + doveadm_calc_header_length(); + doveadm_print_headers(); array_foreach(&ctx->buffered_values, valuep) doveadm_print_next(*valuep); From dovecot at dovecot.org Sun Mar 24 18:14:29 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 24 Mar 2013 18:14:29 +0200 Subject: dovecot-2.2: doveadm replicator status: Without param... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a4d4edb63ff9 changeset: 16104:a4d4edb63ff9 user: Timo Sirainen date: Sun Mar 24 18:14:11 2013 +0200 description: doveadm replicator status: Without parameter show overview status. diffstat: src/doveadm/doveadm-replicator.c | 38 +++++++++++++++-- src/replication/replicator/doveadm-connection.c | 51 ++++++++++++++++++++++++- src/replication/replicator/replicator-queue.c | 9 +-- src/replication/replicator/replicator-queue.h | 5 ++ 4 files changed, 91 insertions(+), 12 deletions(-) diffs (174 lines): diff -r 210282ae46e1 -r a4d4edb63ff9 src/doveadm/doveadm-replicator.c --- a/src/doveadm/doveadm-replicator.c Sun Mar 24 18:13:53 2013 +0200 +++ b/src/doveadm/doveadm-replicator.c Sun Mar 24 18:14:11 2013 +0200 @@ -105,6 +105,31 @@ return t_strdup_printf("%02d:%02d:%02d", diff/3600, diff/60, diff%60); } +static void cmd_replicator_status_overview(struct replicator_context *ctx) +{ + char *line, *value; + + doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE); + doveadm_print_header("field", "field", + DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE); + doveadm_print_header("value", "value", + DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE); + + replicator_send(ctx, "STATUS\n"); + while ((line = i_stream_read_next_line(ctx->input)) != NULL) { + if (*line == '\0') + break; + value = strchr(line, '\t'); + if (value != NULL) + *value++ = '\0'; + else + value = ""; + doveadm_print(line); + doveadm_print(value); + } + replicator_disconnect(ctx); +} + static void cmd_replicator_status(int argc, char *argv[]) { struct replicator_context *ctx; @@ -113,6 +138,11 @@ ctx = cmd_replicator_init(argc, argv, "a:", cmd_replicator_status); + if (argv[1] == NULL) { + cmd_replicator_status_overview(ctx); + return; + } + doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE); doveadm_print_header("username", "username", DOVEADM_PRINT_HEADER_FLAG_EXPAND); @@ -121,12 +151,8 @@ doveadm_print_header_simple("full sync"); doveadm_print_header_simple("failed"); - if (argv[1] == NULL) - replicator_send(ctx, "STATUS\n"); - else { - replicator_send(ctx, t_strdup_printf("STATUS\t%s\n", - str_tabescape(argv[1]))); - } + replicator_send(ctx, t_strdup_printf("STATUS\t%s\n", + str_tabescape(argv[1]))); while ((line = i_stream_read_next_line(ctx->input)) != NULL) { if (*line == '\0') break; diff -r 210282ae46e1 -r a4d4edb63ff9 src/replication/replicator/doveadm-connection.c --- a/src/replication/replicator/doveadm-connection.c Sun Mar 24 18:13:53 2013 +0200 +++ b/src/replication/replicator/doveadm-connection.c Sun Mar 24 18:14:11 2013 +0200 @@ -21,6 +21,52 @@ }; static struct connection_list *doveadm_connections; +static int client_input_status_overview(struct doveadm_connection *client) +{ + struct replicator_user *const *users; + enum replication_priority priority; + unsigned int pending_counts[REPLICATION_PRIORITY_SYNC+1]; + unsigned int i, count, next_secs, pending_failed_count; + unsigned int pending_full_resync_count, waiting_failed_count; + string_t *str = t_str_new(256); + + memset(pending_counts, 0, sizeof(pending_counts)); + pending_failed_count = 0; waiting_failed_count = 0; + pending_full_resync_count = 0; + + users = replicator_queue_get_users(client->queue, &count); + for (i = 0; i < count; i++) { + if (users[i]->priority != REPLICATION_PRIORITY_NONE) + pending_counts[users[i]->priority]++; + else if (replicator_queue_want_sync_now(client->queue, + users[i], &next_secs)) { + if (users[i]->last_sync_failed) + pending_failed_count++; + else + pending_full_resync_count++; + } else { + if (users[i]->last_sync_failed) + waiting_failed_count++; + } + } + + for (priority = REPLICATION_PRIORITY_SYNC; priority > 0; priority--) { + str_printfa(str, "Queued '%s' requests\t%u\n", + replicator_priority_to_str(priority), + pending_counts[priority]); + } + str_printfa(str, "Queued 'failed' requests\t%u\n", + pending_failed_count); + str_printfa(str, "Queued 'full resync' requests\t%u\n", + pending_full_resync_count); + str_printfa(str, "Waiting 'failed' requests\t%u\n", + waiting_failed_count); + str_printfa(str, "Total number of known users\t%u\n", count); + str_append_c(str, '\n'); + o_stream_send(client->conn.output, str_data(str), str_len(str)); + return 0; +} + static int client_input_status(struct doveadm_connection *client, const char *const *args) { @@ -29,10 +75,13 @@ const char *mask = args[0]; string_t *str = t_str_new(128); + if (mask == NULL) + return client_input_status_overview(client); + users = replicator_queue_get_users(client->queue, &count); for (i = 0; i < count; i++) { user = users[i]; - if (mask != NULL && !wildcard_match(user->username, mask)) + if (!wildcard_match(user->username, mask)) continue; str_truncate(str, 0); diff -r 210282ae46e1 -r a4d4edb63ff9 src/replication/replicator/replicator-queue.c --- a/src/replication/replicator/replicator-queue.c Sun Mar 24 18:13:53 2013 +0200 +++ b/src/replication/replicator/replicator-queue.c Sun Mar 24 18:14:11 2013 +0200 @@ -198,10 +198,9 @@ queue->change_callback(queue->change_context); } -static bool -replicator_queue_can_sync_now(struct replicator_queue *queue, - struct replicator_user *user, - unsigned int *next_secs_r) +bool replicator_queue_want_sync_now(struct replicator_queue *queue, + struct replicator_user *user, + unsigned int *next_secs_r) { time_t next_sync; @@ -235,7 +234,7 @@ return NULL; } user = (struct replicator_user *)item; - if (!replicator_queue_can_sync_now(queue, user, next_secs_r)) { + if (!replicator_queue_want_sync_now(queue, user, next_secs_r)) { /* we don't want to sync the user yet */ return NULL; } diff -r 210282ae46e1 -r a4d4edb63ff9 src/replication/replicator/replicator-queue.h --- a/src/replication/replicator/replicator-queue.h Sun Mar 24 18:13:53 2013 +0200 +++ b/src/replication/replicator/replicator-queue.h Sun Mar 24 18:14:11 2013 +0200 @@ -61,6 +61,11 @@ int replicator_queue_import(struct replicator_queue *queue, const char *path); int replicator_queue_export(struct replicator_queue *queue, const char *path); +/* Returns TRUE if user replication can be started now, FALSE if not. When + returning FALSE, next_secs_r is set to user's next replication time. */ +bool replicator_queue_want_sync_now(struct replicator_queue *queue, + struct replicator_user *user, + unsigned int *next_secs_r); /* Returns an (unsorted) array of all users in the queue. */ struct replicator_user *const * replicator_queue_get_users(struct replicator_queue *queue, From dovecot at dovecot.org Sun Mar 24 18:48:38 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 24 Mar 2013 18:48:38 +0200 Subject: dovecot-2.2: imap: GENURLAUTH and URLFETCH didn't escape URL par... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d3e5585778f8 changeset: 16105:d3e5585778f8 user: Timo Sirainen date: Sun Mar 24 18:48:28 2013 +0200 description: imap: GENURLAUTH and URLFETCH didn't escape URL parameters when needed. diffstat: src/imap/cmd-genurlauth.c | 3 ++- src/imap/cmd-urlfetch.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diffs (40 lines): diff -r a4d4edb63ff9 -r d3e5585778f8 src/imap/cmd-genurlauth.c --- a/src/imap/cmd-genurlauth.c Sun Mar 24 18:14:11 2013 +0200 +++ b/src/imap/cmd-genurlauth.c Sun Mar 24 18:48:28 2013 +0200 @@ -3,6 +3,7 @@ #include "imap-common.h" #include "str.h" #include "imap-commands.h" +#include "imap-quote.h" #include "imap-urlauth.h" bool cmd_genurlauth(struct client_command_context *cmd) @@ -43,7 +44,7 @@ } str_append_c(response, ' '); - str_append(response, url); + imap_append_astring(response, url); } client_send_line(cmd->client, str_c(response)); diff -r a4d4edb63ff9 -r d3e5585778f8 src/imap/cmd-urlfetch.c --- a/src/imap/cmd-urlfetch.c Sun Mar 24 18:14:11 2013 +0200 +++ b/src/imap/cmd-urlfetch.c Sun Mar 24 18:48:28 2013 +0200 @@ -8,6 +8,7 @@ #include "istream.h" #include "ostream.h" #include "imap-url.h" +#include "imap-quote.h" #include "imap-common.h" #include "imap-commands.h" #include "imap-urlauth.h" @@ -184,7 +185,7 @@ ctx->extended = TRUE; str_append(response, "* URLFETCH "); - str_append(response, reply->url); + imap_append_astring(response, reply->url); str_append(response, " ("); if ((reply->flags & IMAP_URLAUTH_FETCH_FLAG_BODYPARTSTRUCTURE) != 0 && reply->bodypartstruct != NULL) { From dovecot at dovecot.org Sun Mar 24 18:58:27 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 24 Mar 2013 18:58:27 +0200 Subject: dovecot-2.2: doveadm-server: Don't continue handling commands if... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ce2b9b430eed changeset: 16106:ce2b9b430eed user: Timo Sirainen date: Sun Mar 24 18:58:20 2013 +0200 description: doveadm-server: Don't continue handling commands if input stream is already closed. This fixes trying to handle extra input from previous dsync command. diffstat: src/doveadm/client-connection.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r d3e5585778f8 -r ce2b9b430eed src/doveadm/client-connection.c --- a/src/doveadm/client-connection.c Sun Mar 24 18:48:28 2013 +0200 +++ b/src/doveadm/client-connection.c Sun Mar 24 18:58:20 2013 +0200 @@ -308,7 +308,8 @@ conn->authenticated = TRUE; } - while (ok && (line = i_stream_read_next_line(conn->input)) != NULL) { + while (ok && !conn->input->closed && + (line = i_stream_read_next_line(conn->input)) != NULL) { T_BEGIN { char **args; From dovecot at dovecot.org Sun Mar 24 19:04:26 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 24 Mar 2013 19:04:26 +0200 Subject: dovecot-2.2: mysql/pgsql: Don't bother logging about having conn... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/33e78edac8f5 changeset: 16107:33e78edac8f5 user: Timo Sirainen date: Sun Mar 24 19:04:15 2013 +0200 description: mysql/pgsql: Don't bother logging about having connected to the database. There's probably no good reason to have them? Errors are of course still logged. diffstat: src/lib-sql/driver-mysql.c | 3 --- src/lib-sql/driver-pgsql.c | 2 -- 2 files changed, 0 insertions(+), 5 deletions(-) diffs (25 lines): diff -r ce2b9b430eed -r 33e78edac8f5 src/lib-sql/driver-mysql.c --- a/src/lib-sql/driver-mysql.c Sun Mar 24 18:58:20 2013 +0200 +++ b/src/lib-sql/driver-mysql.c Sun Mar 24 19:04:15 2013 +0200 @@ -135,9 +135,6 @@ mysql_error(db->mysql), db->api.connect_delay); return -1; } else { - i_info("%s: Connected to database %s%s", mysql_prefix(db), - db->dbname, db->ssl_set ? " using SSL" : ""); - db->last_success = ioloop_time; sql_db_set_state(&db->api, SQL_DB_STATE_IDLE); return 1; diff -r ce2b9b430eed -r 33e78edac8f5 src/lib-sql/driver-pgsql.c --- a/src/lib-sql/driver-pgsql.c Sun Mar 24 18:58:20 2013 +0200 +++ b/src/lib-sql/driver-pgsql.c Sun Mar 24 19:04:15 2013 +0200 @@ -168,8 +168,6 @@ } if (io_dir == 0) { - i_info("%s: Connected to database %s", - pgsql_prefix(db), PQdb(db->pg)); if (db->to_connect != NULL) timeout_remove(&db->to_connect); driver_pgsql_set_state(db, SQL_DB_STATE_IDLE); From pigeonhole at rename-it.nl Mon Mar 25 13:34:20 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Mon, 25 Mar 2013 12:34:20 +0100 Subject: dovecot-2.2-pigeonhole: doveadm-sieve: Crash instead of writing ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/097764f6bbe3 changeset: 1728:097764f6bbe3 user: Stephan Bosch date: Mon Mar 25 12:34:13 2013 +0100 description: doveadm-sieve: Crash instead of writing empty .sieve files. Patch by Timo Sirainen. diffstat: src/plugins/doveadm-sieve/doveadm-sieve-plugin.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r cb910570ad88 -r 097764f6bbe3 src/plugins/doveadm-sieve/doveadm-sieve-plugin.c --- a/src/plugins/doveadm-sieve/doveadm-sieve-plugin.c Sat Mar 23 12:14:14 2013 +0100 +++ b/src/plugins/doveadm-sieve/doveadm-sieve-plugin.c Mon Mar 25 12:34:13 2013 +0100 @@ -214,6 +214,7 @@ break; } } + i_assert(input->eof); if (input->stream_errno != 0) { errno = input->stream_errno; mail_storage_set_critical(storage, From dovecot at dovecot.org Mon Mar 25 13:55:51 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 25 Mar 2013 13:55:51 +0200 Subject: dovecot-2.2: imap: Fixed more URL escaping in URLFETCH replies. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0634cf4acf8d changeset: 16108:0634cf4acf8d user: Timo Sirainen date: Mon Mar 25 13:55:41 2013 +0200 description: imap: Fixed more URL escaping in URLFETCH replies. diffstat: src/imap/cmd-urlfetch.c | 20 ++++++++++++-------- 1 files changed, 12 insertions(+), 8 deletions(-) diffs (50 lines): diff -r 33e78edac8f5 -r 0634cf4acf8d src/imap/cmd-urlfetch.c --- a/src/imap/cmd-urlfetch.c Sun Mar 24 19:04:15 2013 +0200 +++ b/src/imap/cmd-urlfetch.c Mon Mar 25 13:55:41 2013 +0200 @@ -167,25 +167,25 @@ struct imap_urlauth_fetch_reply *reply) { struct cmd_urlfetch_context *ctx = cmd->context; + string_t *response = t_str_new(256); int ret; + str_append(response, "* URLFETCH "); + imap_append_astring(response, reply->url); + if ((reply->flags & IMAP_URLAUTH_FETCH_FLAG_EXTENDED) == 0) { /* simple */ ctx->extended = FALSE; - client_send_line(cmd->client, t_strdup_printf( - "* URLFETCH %s {%"PRIuUOFF_T"}", - reply->url, reply->size)); + str_printfa(response, " {%"PRIuUOFF_T"}", reply->size); + client_send_line(cmd->client, str_c(response)); i_assert(reply->size == 0 || reply->input != NULL); } else { - string_t *response = t_str_new(256); bool metadata = FALSE; /* extended */ ctx->extended = TRUE; - str_append(response, "* URLFETCH "); - imap_append_astring(response, reply->url); str_append(response, " ("); if ((reply->flags & IMAP_URLAUTH_FETCH_FLAG_BODYPARTSTRUCTURE) != 0 && reply->bodypartstruct != NULL) { @@ -265,8 +265,12 @@ } } else { /* URL fetch failed */ - client_send_line(cmd->client, - t_strdup_printf("* URLFETCH %s NIL", reply->url)); + string_t *response = t_str_new(128); + + str_append(response, "* URLFETCH "); + imap_append_astring(response, reply->url); + str_append(response, " NIL"); + client_send_line(cmd->client, str_c(response)); if (reply->error != NULL) { client_send_line(cmd->client, t_strdup_printf( "* NO %s.", reply->error)); From dovecot at dovecot.org Mon Mar 25 14:18:30 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 25 Mar 2013 14:18:30 +0200 Subject: dovecot-2.2: dsync: Fixed syncing attribute streams. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/acb88f199704 changeset: 16109:acb88f199704 user: Timo Sirainen date: Mon Mar 25 14:18:20 2013 +0200 description: dsync: Fixed syncing attribute streams. diffstat: src/doveadm/dsync/dsync-ibc-stream.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r 0634cf4acf8d -r acb88f199704 src/doveadm/dsync/dsync-ibc-stream.c --- a/src/doveadm/dsync/dsync-ibc-stream.c Mon Mar 25 13:55:41 2013 +0200 +++ b/src/doveadm/dsync/dsync-ibc-stream.c Mon Mar 25 14:18:20 2013 +0200 @@ -1298,6 +1298,11 @@ if (ibc->minor_version < DSYNC_PROTOCOL_MINOR_HAVE_ATTRIBUTES) return DSYNC_IBC_RECV_RET_FINISHED; + if (ibc->value_input != NULL) { + /* wait until the mail's stream has been read */ + return DSYNC_IBC_RECV_RET_TRYAGAIN; + } + if (ibc->cur_attr != NULL) { /* finished reading the stream, return the mail now */ *attr_r = ibc->cur_attr; From dovecot at dovecot.org Mon Mar 25 15:56:40 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 25 Mar 2013 15:56:40 +0200 Subject: dovecot-2.1: doveadm, indexer: Don't crash if STATUS_LAST_CACHED... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/73feea4d22aa changeset: 14937:73feea4d22aa user: Timo Sirainen date: Fri Feb 22 10:31:38 2013 +0200 description: doveadm, indexer: Don't crash if STATUS_LAST_CACHED_SEQ lookup fails. (I'm sure I did this change already once, where did it go?..) diffstat: src/doveadm/doveadm-mail-index.c | 6 +++--- src/indexer/master-connection.c | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diffs (35 lines): diff -r eece943c7521 -r 73feea4d22aa src/doveadm/doveadm-mail-index.c --- a/src/doveadm/doveadm-mail-index.c Sun Mar 24 12:09:39 2013 +0200 +++ b/src/doveadm/doveadm-mail-index.c Fri Feb 22 10:31:38 2013 +0200 @@ -38,10 +38,10 @@ int ret = 0; if (mailbox_get_metadata(box, MAILBOX_METADATA_PRECACHE_FIELDS, - &metadata) < 0) + &metadata) < 0 || + mailbox_get_status(box, STATUS_MESSAGES | STATUS_LAST_CACHED_SEQ, + &status) < 0) return -1; - mailbox_get_open_status(box, STATUS_MESSAGES | STATUS_LAST_CACHED_SEQ, - &status); seq = status.last_cached_seq + 1; if (seq > status.messages) { diff -r eece943c7521 -r 73feea4d22aa src/indexer/master-connection.c --- a/src/indexer/master-connection.c Sun Mar 24 12:09:39 2013 +0200 +++ b/src/indexer/master-connection.c Fri Feb 22 10:31:38 2013 +0200 @@ -68,11 +68,10 @@ int ret = 0; if (mailbox_get_metadata(box, MAILBOX_METADATA_PRECACHE_FIELDS, - &metadata) < 0) + &metadata) < 0 || + mailbox_get_status(box, STATUS_MESSAGES | STATUS_LAST_CACHED_SEQ, + &status) < 0) return -1; - - mailbox_get_open_status(box, STATUS_MESSAGES | STATUS_LAST_CACHED_SEQ, - &status); seq = status.last_cached_seq + 1; trans = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_NO_CACHE_DEC); From dovecot at dovecot.org Mon Mar 25 16:20:00 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 25 Mar 2013 16:20:00 +0200 Subject: dovecot-2.1: doveadm: Added "batch" command to run multiple mail... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/8cc28a5a3f4f changeset: 14938:8cc28a5a3f4f user: Timo Sirainen date: Mon Mar 25 16:19:54 2013 +0200 description: doveadm: Added "batch" command to run multiple mail commands. This only makes sense when the commands are run with -A or -u , so that the commands are run for the same user before moving onto the next user. diffstat: src/doveadm/Makefile.am | 1 + src/doveadm/doveadm-mail-batch.c | 162 +++++++++++++++++++++++++++++++++++++++ src/doveadm/doveadm-mail.c | 54 ++++++++---- src/doveadm/doveadm-mail.h | 4 + 4 files changed, 204 insertions(+), 17 deletions(-) diffs (truncated from 304 to 300 lines): diff -r 73feea4d22aa -r 8cc28a5a3f4f src/doveadm/Makefile.am --- a/src/doveadm/Makefile.am Fri Feb 22 10:31:38 2013 +0200 +++ b/src/doveadm/Makefile.am Mon Mar 25 16:19:54 2013 +0200 @@ -68,6 +68,7 @@ common = \ doveadm-mail.c \ doveadm-mail-altmove.c \ + doveadm-mail-batch.c \ doveadm-mail-expunge.c \ doveadm-mail-fetch.c \ doveadm-mail-import.c \ diff -r 73feea4d22aa -r 8cc28a5a3f4f src/doveadm/doveadm-mail-batch.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doveadm/doveadm-mail-batch.c Mon Mar 25 16:19:54 2013 +0200 @@ -0,0 +1,162 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "array.h" +#include "doveadm-mail.h" + +#include + +struct batch_cmd_context { + struct doveadm_mail_cmd_context ctx; + ARRAY_DEFINE(commands, struct doveadm_mail_cmd_context *); +}; + +static int cmd_batch_prerun(struct doveadm_mail_cmd_context *_ctx, + struct mail_storage_service_user *service_user, + const char **error_r) +{ + struct batch_cmd_context *ctx = (struct batch_cmd_context *)_ctx; + struct doveadm_mail_cmd_context *const *cmdp; + int ret = 0; + + array_foreach(&ctx->commands, cmdp) { + if ((*cmdp)->v.prerun != NULL && + (*cmdp)->v.prerun(*cmdp, service_user, error_r) < 0) { + ret = -1; + break; + } + } + return ret; +} + +static int cmd_batch_run(struct doveadm_mail_cmd_context *_ctx, + struct mail_user *user) +{ + struct batch_cmd_context *ctx = (struct batch_cmd_context *)_ctx; + struct doveadm_mail_cmd_context *const *cmdp; + int ret = 0; + + array_foreach(&ctx->commands, cmdp) { + if ((*cmdp)->v.run(*cmdp, user) < 0) { + ret = -1; + break; + } + } + return ret; +} + +static void +cmd_batch_add(struct batch_cmd_context *batchctx, + int argc, const char *const *argv) +{ + struct doveadm_mail_cmd_context *subctx; + const struct doveadm_mail_cmd *cmd; + const char *getopt_args; + int c; + + cmd = doveadm_mail_cmd_find_from_argv(argv[0], &argc, &argv); + if (cmd == NULL) { + i_fatal_status(EX_USAGE, "doveadm batch: Unknown subcommand %s", + argv[1]); + } + + subctx = doveadm_mail_cmd_init(cmd, doveadm_settings); + subctx->full_args = argv + 1; + subctx->service_flags |= batchctx->ctx.service_flags; + + optind = 1; + getopt_args = subctx->getopt_args != NULL ? subctx->getopt_args : ""; + while ((c = getopt(argc, (void *)argv, getopt_args)) > 0) { + if (subctx->v.parse_arg == NULL || + !subctx->v.parse_arg(subctx, c)) + doveadm_mail_help(cmd); + } + argv += optind; + if (argv[0] != NULL && cmd->usage_args == NULL) { + i_fatal_status(EX_USAGE, "doveadm %s: Unknown parameter: %s", + cmd->name, argv[0]); + } + subctx->args = argv; + if (subctx->v.preinit != NULL) + subctx->v.preinit(subctx); + array_append(&batchctx->commands, &subctx, 1); +} + +static void +cmd_batch_preinit(struct doveadm_mail_cmd_context *_ctx) +{ + const char *const *args = _ctx->args; + struct batch_cmd_context *ctx = (struct batch_cmd_context *)_ctx; + ARRAY_TYPE(const_string) sep_args; + const char *sep = args[0]; + unsigned int i, start; + int argc; + const char *const *argv; + + if (sep == NULL || args[1] == NULL) + doveadm_mail_help_name("batch"); + args++; + + p_array_init(&ctx->commands, _ctx->pool, 8); + p_array_init(&sep_args, _ctx->pool, 16); + for (i = start = 0;; i++) { + if (args[i] != NULL && strcmp(args[i], sep) != 0) { + array_append(&sep_args, &args[i], 1); + continue; + } + if (i > start) { + (void)array_append_space(&sep_args); + argc = i - start; + argv = array_idx(&sep_args, start); + cmd_batch_add(ctx, argc, argv); + start = i+1; + } + if (args[i] == NULL) + break; + } + (void)array_append_space(&sep_args); +} + +static void +cmd_batch_init(struct doveadm_mail_cmd_context *_ctx, + const char *const args[] ATTR_UNUSED) +{ + struct batch_cmd_context *ctx = (struct batch_cmd_context *)_ctx; + struct doveadm_mail_cmd_context *const *cmdp; + struct batch_cmd_context *subctx; + + array_foreach(&ctx->commands, cmdp) { + subctx = (struct batch_cmd_context *)*cmdp; + subctx->ctx.storage_service = _ctx->storage_service; + if (subctx->ctx.v.init != NULL) + subctx->ctx.v.init(&subctx->ctx, subctx->ctx.args); + } +} + +static void cmd_batch_deinit(struct doveadm_mail_cmd_context *_ctx) +{ + struct batch_cmd_context *ctx = (struct batch_cmd_context *)_ctx; + struct doveadm_mail_cmd_context *const *cmdp; + + array_foreach(&ctx->commands, cmdp) { + if ((*cmdp)->v.deinit != NULL) + (*cmdp)->v.deinit(*cmdp); + } +} + +static struct doveadm_mail_cmd_context *cmd_batch_alloc(void) +{ + struct batch_cmd_context *ctx; + + ctx = doveadm_mail_cmd_alloc(struct batch_cmd_context); + ctx->ctx.v.preinit = cmd_batch_preinit; + ctx->ctx.v.init = cmd_batch_init; + ctx->ctx.v.prerun = cmd_batch_prerun; + ctx->ctx.v.run = cmd_batch_run; + ctx->ctx.v.deinit = cmd_batch_deinit; + return &ctx->ctx; +} + +struct doveadm_mail_cmd cmd_batch = { + cmd_batch_alloc, "batch", " [ [..]]" +}; diff -r 73feea4d22aa -r 8cc28a5a3f4f src/doveadm/doveadm-mail.c --- a/src/doveadm/doveadm-mail.c Fri Feb 22 10:31:38 2013 +0200 +++ b/src/doveadm/doveadm-mail.c Mon Mar 25 16:19:54 2013 +0200 @@ -541,59 +541,78 @@ } static bool -doveadm_mail_try_run_multi_word(const struct doveadm_mail_cmd *cmd, - const char *cmdname, int argc, char *argv[]) +doveadm_mail_cmd_try_find_multi_word(const struct doveadm_mail_cmd *cmd, + const char *cmdname, int *argc, + const char *const **argv) { unsigned int len; - if (argc < 2) + if (*argc < 2) return FALSE; + *argc -= 1; + *argv += 1; - len = strlen(argv[1]); - if (strncmp(cmdname, argv[1], len) != 0) + len = strlen((*argv)[0]); + if (strncmp(cmdname, (*argv)[0], len) != 0) return FALSE; if (cmdname[len] == ' ') { /* more args */ - return doveadm_mail_try_run_multi_word(cmd, cmdname + len + 1, - argc - 1, argv + 1); + return doveadm_mail_cmd_try_find_multi_word(cmd, cmdname + len + 1, + argc, argv); } if (cmdname[len] != '\0') return FALSE; /* match */ - doveadm_mail_cmd(cmd, argc - 1, argv + 1); return TRUE; } -bool doveadm_mail_try_run(const char *cmd_name, int argc, char *argv[]) +const struct doveadm_mail_cmd * +doveadm_mail_cmd_find_from_argv(const char *cmd_name, int *argc, + const char *const **argv) { const struct doveadm_mail_cmd *cmd; unsigned int cmd_name_len; + const char *const *orig_argv; + int orig_argc; - i_assert(argc > 0); + i_assert(*argc > 0); cmd_name_len = strlen(cmd_name); array_foreach(&doveadm_mail_cmds, cmd) { - if (strcmp(cmd->name, cmd_name) == 0) { - doveadm_mail_cmd(cmd, argc, argv); - return TRUE; - } + if (strcmp(cmd->name, cmd_name) == 0) + return cmd; /* see if it matches a multi-word command */ if (strncmp(cmd->name, cmd_name, cmd_name_len) == 0 && cmd->name[cmd_name_len] == ' ') { const char *subcmd = cmd->name + cmd_name_len + 1; - if (doveadm_mail_try_run_multi_word(cmd, subcmd, - argc, argv)) - return TRUE; + orig_argc = *argc; + orig_argv = *argv; + if (doveadm_mail_cmd_try_find_multi_word(cmd, subcmd, + argc, argv)) + return cmd; + *argc = orig_argc; + *argv = orig_argv; } } return FALSE; } +bool doveadm_mail_try_run(const char *cmd_name, int argc, char *argv[]) +{ + const struct doveadm_mail_cmd *cmd; + + cmd = doveadm_mail_cmd_find_from_argv(cmd_name, &argc, (void *)&argv); + if (cmd == NULL) + return FALSE; + doveadm_mail_cmd(cmd, argc, argv); + return TRUE; +} + void doveadm_mail_register_cmd(const struct doveadm_mail_cmd *cmd) { /* for now we'll just assume that cmd will be permanently in memory */ @@ -686,6 +705,7 @@ &cmd_mailbox_subscribe, &cmd_mailbox_unsubscribe, &cmd_mailbox_status, + &cmd_batch, &cmd_dsync_backup, &cmd_dsync_mirror, &cmd_dsync_server diff -r 73feea4d22aa -r 8cc28a5a3f4f src/doveadm/doveadm-mail.h --- a/src/doveadm/doveadm-mail.h Fri Feb 22 10:31:38 2013 +0200 +++ b/src/doveadm/doveadm-mail.h Mon Mar 25 16:19:54 2013 +0200 @@ -95,6 +95,9 @@ void doveadm_mail_init(void); void doveadm_mail_deinit(void); +const struct doveadm_mail_cmd * +doveadm_mail_cmd_find_from_argv(const char *cmd_name, int *argc, + const char *const **argv); struct doveadm_mail_cmd_context * doveadm_mail_cmd_init(const struct doveadm_mail_cmd *cmd, const struct doveadm_settings *set); @@ -145,5 +148,6 @@ struct doveadm_mail_cmd cmd_mailbox_subscribe; struct doveadm_mail_cmd cmd_mailbox_unsubscribe; From dovecot at dovecot.org Mon Mar 25 17:02:22 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 25 Mar 2013 17:02:22 +0200 Subject: dovecot-2.2: doveadm sync/backup: Added -g to sync only t... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c51873a8e0d9 changeset: 16110:c51873a8e0d9 user: Timo Sirainen date: Mon Mar 25 17:02:15 2013 +0200 description: doveadm sync/backup: Added -g to sync only the specified mailbox (by GUID) Similar to -m . diffstat: src/doveadm/dsync/doveadm-dsync.c | 23 ++++++++--- src/doveadm/dsync/dsync-brain-mailbox-tree.c | 6 ++- src/doveadm/dsync/dsync-brain-private.h | 3 +- src/doveadm/dsync/dsync-brain.c | 6 +++ src/doveadm/dsync/dsync-brain.h | 3 + src/doveadm/dsync/dsync-ibc-pipe.c | 2 + src/doveadm/dsync/dsync-ibc-stream.c | 13 ++++++- src/doveadm/dsync/dsync-ibc.h | 2 + src/doveadm/dsync/dsync-mailbox-tree-fill.c | 53 +++++++++++++++++++-------- src/doveadm/dsync/dsync-mailbox-tree.h | 7 ++- 10 files changed, 88 insertions(+), 30 deletions(-) diffs (truncated from 345 to 300 lines): diff -r acb88f199704 -r c51873a8e0d9 src/doveadm/dsync/doveadm-dsync.c --- a/src/doveadm/dsync/doveadm-dsync.c Mon Mar 25 14:18:20 2013 +0200 +++ b/src/doveadm/dsync/doveadm-dsync.c Mon Mar 25 17:02:15 2013 +0200 @@ -36,7 +36,7 @@ #include #include -#define DSYNC_COMMON_GETOPT_ARGS "+dEfl:m:n:Nr:Rs:" +#define DSYNC_COMMON_GETOPT_ARGS "+dEfg:l:m:n:Nr:Rs:" #define DSYNC_REMOTE_CMD_EXIT_WAIT_SECS 30 enum dsync_run_type { @@ -49,6 +49,7 @@ struct doveadm_mail_cmd_context ctx; enum dsync_brain_sync_type sync_type; const char *mailbox, *namespace_prefix; + guid_128_t mailbox_guid; const char *state_input, *rawlog_path; const char *remote_name; @@ -75,6 +76,7 @@ unsigned int backup:1; unsigned int reverse_backup:1; unsigned int remote_user_prefix:1; + unsigned int no_mail_sync:1; }; static bool legacy_dsync = FALSE; @@ -468,13 +470,12 @@ else if (ctx->backup) brain_flags |= DSYNC_BRAIN_FLAG_BACKUP_SEND; + if (ctx->no_mail_sync) + brain_flags |= DSYNC_BRAIN_FLAG_NO_MAIL_SYNC; if (doveadm_debug) brain_flags |= DSYNC_BRAIN_FLAG_DEBUG; - if (ctx->mailbox != NULL && *ctx->mailbox == '\0') { - brain_flags |= DSYNC_BRAIN_FLAG_NO_MAIL_SYNC; - ctx->mailbox = NULL; - } brain = dsync_brain_master_init(user, ibc, sync_ns, ctx->mailbox, + ctx->mailbox_guid, ctx->sync_type, brain_flags, ctx->lock_timeout, ctx->state_input == NULL ? "" : @@ -766,13 +767,23 @@ case 'f': ctx->sync_type = DSYNC_BRAIN_SYNC_TYPE_FULL; break; + case 'g': + if (optarg[0] == '\0') + ctx->no_mail_sync = TRUE; + else if (guid_128_from_string(optarg, ctx->mailbox_guid) < 0 || + guid_128_is_empty(ctx->mailbox_guid)) + i_error("Invalid -g parameter: %s", optarg); + break; case 'l': ctx->lock = TRUE; if (str_to_uint(optarg, &ctx->lock_timeout) < 0) i_error("Invalid -l parameter: %s", optarg); break; case 'm': - ctx->mailbox = optarg; + if (optarg[0] == '\0') + ctx->no_mail_sync = TRUE; + else + ctx->mailbox = optarg; break; case 'n': ctx->namespace_prefix = optarg; diff -r acb88f199704 -r c51873a8e0d9 src/doveadm/dsync/dsync-brain-mailbox-tree.c --- a/src/doveadm/dsync/dsync-brain-mailbox-tree.c Mon Mar 25 14:18:20 2013 +0200 +++ b/src/doveadm/dsync/dsync-brain-mailbox-tree.c Mon Mar 25 17:02:15 2013 +0200 @@ -85,14 +85,16 @@ /* fill the local mailbox tree */ if (brain->sync_ns != NULL) { if (dsync_mailbox_tree_fill(brain->local_mailbox_tree, - brain->sync_ns, brain->sync_box) < 0) + brain->sync_ns, brain->sync_box, + brain->sync_box_guid) < 0) brain->failed = TRUE; } else { for (ns = brain->user->namespaces; ns != NULL; ns = ns->next) { if (!dsync_brain_want_namespace(brain, ns)) continue; if (dsync_mailbox_tree_fill(brain->local_mailbox_tree, - ns, brain->sync_box) < 0) + ns, brain->sync_box, + brain->sync_box_guid) < 0) brain->failed = TRUE; } } diff -r acb88f199704 -r c51873a8e0d9 src/doveadm/dsync/dsync-brain-private.h --- a/src/doveadm/dsync/dsync-brain-private.h Mon Mar 25 14:18:20 2013 +0200 +++ b/src/doveadm/dsync/dsync-brain-private.h Mon Mar 25 17:02:15 2013 +0200 @@ -50,7 +50,8 @@ struct mail_user *user; struct dsync_ibc *ibc; struct mail_namespace *sync_ns; - char *sync_box; + const char *sync_box; + guid_128_t sync_box_guid; enum dsync_brain_sync_type sync_type; unsigned int lock_timeout; diff -r acb88f199704 -r c51873a8e0d9 src/doveadm/dsync/dsync-brain.c --- a/src/doveadm/dsync/dsync-brain.c Mon Mar 25 14:18:20 2013 +0200 +++ b/src/doveadm/dsync/dsync-brain.c Mon Mar 25 17:02:15 2013 +0200 @@ -87,6 +87,7 @@ struct dsync_brain * dsync_brain_master_init(struct mail_user *user, struct dsync_ibc *ibc, struct mail_namespace *sync_ns, const char *sync_box, + const guid_128_t sync_box_guid, enum dsync_brain_sync_type sync_type, enum dsync_brain_flags flags, unsigned int lock_timeout, const char *state) @@ -103,6 +104,7 @@ if (sync_ns != NULL) brain->sync_ns = sync_ns; brain->sync_box = p_strdup(brain->pool, sync_box); + memcpy(brain->sync_box_guid, sync_box_guid, sizeof(brain->sync_box_guid)); brain->lock_timeout = lock_timeout; brain->master_brain = TRUE; dsync_brain_set_flags(brain, flags); @@ -121,6 +123,8 @@ ibc_set.hostname = my_hostdomain(); ibc_set.sync_ns_prefix = sync_ns == NULL ? NULL : sync_ns->prefix; ibc_set.sync_box = sync_box; + memcpy(ibc_set.sync_box_guid, sync_box_guid, + sizeof(ibc_set.sync_box_guid)); ibc_set.sync_type = sync_type; ibc_set.lock_timeout = lock_timeout; /* reverse the backup direction for the slave */ @@ -302,6 +306,8 @@ ibc_set->sync_ns_prefix); } brain->sync_box = p_strdup(brain->pool, ibc_set->sync_box); + memcpy(brain->sync_box_guid, ibc_set->sync_box_guid, + sizeof(brain->sync_box_guid)); i_assert(brain->sync_type == DSYNC_BRAIN_SYNC_TYPE_UNKNOWN); brain->sync_type = ibc_set->sync_type; dsync_brain_set_flags(brain, ibc_set->brain_flags); diff -r acb88f199704 -r c51873a8e0d9 src/doveadm/dsync/dsync-brain.h --- a/src/doveadm/dsync/dsync-brain.h Mon Mar 25 14:18:20 2013 +0200 +++ b/src/doveadm/dsync/dsync-brain.h Mon Mar 25 17:02:15 2013 +0200 @@ -1,6 +1,8 @@ #ifndef DSYNC_BRAIN_H #define DSYNC_BRAIN_H +#include "guid.h" + struct mail_namespace; struct mail_user; struct dsync_ibc; @@ -31,6 +33,7 @@ struct dsync_brain * dsync_brain_master_init(struct mail_user *user, struct dsync_ibc *ibc, struct mail_namespace *sync_ns, const char *sync_box, + const guid_128_t sync_box_guid, enum dsync_brain_sync_type sync_type, enum dsync_brain_flags flags, unsigned int lock_timeout, const char *state); diff -r acb88f199704 -r c51873a8e0d9 src/doveadm/dsync/dsync-ibc-pipe.c --- a/src/doveadm/dsync/dsync-ibc-pipe.c Mon Mar 25 14:18:20 2013 +0200 +++ b/src/doveadm/dsync/dsync-ibc-pipe.c Mon Mar 25 17:02:15 2013 +0200 @@ -161,6 +161,8 @@ item->u.set = *set; item->u.set.sync_ns_prefix = p_strdup(item->pool, set->sync_ns_prefix); item->u.set.sync_box = p_strdup(item->pool, set->sync_box); + memcpy(item->u.set.sync_box_guid, set->sync_box_guid, + sizeof(item->u.set.sync_box_guid)); } static enum dsync_ibc_recv_ret diff -r acb88f199704 -r c51873a8e0d9 src/doveadm/dsync/dsync-ibc-stream.c --- a/src/doveadm/dsync/dsync-ibc-stream.c Mon Mar 25 14:18:20 2013 +0200 +++ b/src/doveadm/dsync/dsync-ibc-stream.c Mon Mar 25 17:02:15 2013 +0200 @@ -70,7 +70,8 @@ { .name = "handshake", .chr = 'H', .required_keys = "hostname", - .optional_keys = "sync_ns_prefix sync_box sync_type debug sync_visible_namespaces " + .optional_keys = "sync_ns_prefix sync_box sync_box_guid sync_type " + "debug sync_visible_namespaces " "send_mail_requests backup_send backup_recv lock_timeout" }, { .name = "mailbox_state", @@ -589,6 +590,10 @@ } if (set->sync_box != NULL) dsync_serializer_encode_add(encoder, "sync_box", set->sync_box); + if (!guid_128_is_empty(set->sync_box_guid)) { + dsync_serializer_encode_add(encoder, "sync_box_guid", + guid_128_to_string(set->sync_box_guid)); + } sync_type[0] = sync_type[1] = '\0'; switch (set->sync_type) { @@ -655,6 +660,12 @@ set->sync_ns_prefix = p_strdup(pool, value); if (dsync_deserializer_decode_try(decoder, "sync_box", &value)) set->sync_box = p_strdup(pool, value); + if (dsync_deserializer_decode_try(decoder, "sync_box_guid", &value) && + guid_128_from_string(value, set->sync_box_guid) < 0) { + dsync_ibc_input_error(ibc, decoder, + "Invalid sync_box_guid: %s", value); + return DSYNC_IBC_RECV_RET_TRYAGAIN; + } if (dsync_deserializer_decode_try(decoder, "sync_type", &value)) { switch (value[0]) { case 'f': diff -r acb88f199704 -r c51873a8e0d9 src/doveadm/dsync/dsync-ibc.h --- a/src/doveadm/dsync/dsync-ibc.h Mon Mar 25 14:18:20 2013 +0200 +++ b/src/doveadm/dsync/dsync-ibc.h Mon Mar 25 17:02:15 2013 +0200 @@ -37,6 +37,8 @@ const char *sync_ns_prefix; /* if non-NULL, sync only this mailbox name */ const char *sync_box; + /* if non-empty, sync only this mailbox GUID */ + guid_128_t sync_box_guid; enum dsync_brain_sync_type sync_type; enum dsync_brain_flags brain_flags; diff -r acb88f199704 -r c51873a8e0d9 src/doveadm/dsync/dsync-mailbox-tree-fill.c --- a/src/doveadm/dsync/dsync-mailbox-tree-fill.c Mon Mar 25 14:18:20 2013 +0200 +++ b/src/doveadm/dsync/dsync-mailbox-tree-fill.c Mon Mar 25 17:02:15 2013 +0200 @@ -31,6 +31,17 @@ } static int +dsync_mailbox_tree_add_exists_node(struct dsync_mailbox_tree *tree, + const struct mailbox_info *info, + struct dsync_mailbox_node **node_r) +{ + if (dsync_mailbox_tree_add_node(tree, info, node_r) < 0) + return -1; + (*node_r)->existence = DSYNC_MAILBOX_NODE_EXISTS; + return 0; +} + +static int dsync_mailbox_tree_get_selectable(struct mailbox *box, struct mailbox_metadata *metadata_r, struct mailbox_status *status_r) @@ -55,7 +66,8 @@ } static int dsync_mailbox_tree_add(struct dsync_mailbox_tree *tree, - const struct mailbox_info *info) + const struct mailbox_info *info, + const guid_128_t box_guid) { struct dsync_mailbox_node *node; struct mailbox *box; @@ -63,16 +75,14 @@ struct mailbox_status status; const char *errstr; enum mail_error error; + int ret = 0; if ((info->flags & MAILBOX_NONEXISTENT) != 0) return 0; - - if (dsync_mailbox_tree_add_node(tree, info, &node) < 0) - return -1; - node->existence = DSYNC_MAILBOX_NODE_EXISTS; - - if ((info->flags & MAILBOX_NOSELECT) != 0) - return 0; + if ((info->flags & MAILBOX_NOSELECT) != 0) { + return !guid_128_is_empty(box_guid) ? 0 : + dsync_mailbox_tree_add_exists_node(tree, info, &node); + } /* get GUID and UIDVALIDITY for selectable mailbox */ box = mailbox_alloc(info->ns->list, info->vname, 0); @@ -88,16 +98,24 @@ default: i_error("Failed to access mailbox %s: %s", info->vname, errstr); - mailbox_free(&box); - return -1; + ret = -1; } - } else { - memcpy(node->mailbox_guid, metadata.guid, - sizeof(node->mailbox_guid)); - node->uid_validity = status.uidvalidity; - node->uid_next = status.uidnext; + mailbox_free(&box); + return ret; } mailbox_free(&box); + + if (!guid_128_is_empty(box_guid) && + !guid_128_equals(box_guid, metadata.guid)) { + /* unwanted mailbox */ + return 0; + } + if (dsync_mailbox_tree_add_exists_node(tree, info, &node) < 0) From dovecot at dovecot.org Mon Mar 25 17:57:00 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 25 Mar 2013 17:57:00 +0200 Subject: dovecot-2.2: ldap: Don't crash if attributes have no @subrequests. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3de93139afce changeset: 16111:3de93139afce user: Timo Sirainen date: Mon Mar 25 17:56:53 2013 +0200 description: ldap: Don't crash if attributes have no @subrequests. diffstat: src/auth/db-ldap.c | 22 +++++++++++++--------- 1 files changed, 13 insertions(+), 9 deletions(-) diffs (39 lines): diff -r c51873a8e0d9 -r 3de93139afce src/auth/db-ldap.c --- a/src/auth/db-ldap.c Mon Mar 25 17:02:15 2013 +0200 +++ b/src/auth/db-ldap.c Mon Mar 25 17:56:53 2013 +0200 @@ -806,11 +806,13 @@ if (srequest->result != NULL) ldap_msgfree(srequest->result); - array_foreach(&srequest->named_results, named_res) { - if (named_res->result == res) - res = NULL; - if (named_res->result != NULL) - ldap_msgfree(named_res->result); + if (array_is_created(&srequest->named_results)) { + array_foreach(&srequest->named_results, named_res) { + if (named_res->result == res) + res = NULL; + if (named_res->result != NULL) + ldap_msgfree(named_res->result); + } } } if (res != NULL) @@ -1449,10 +1451,12 @@ ctx->debug = t_str_new(256); get_ldap_fields(ctx, conn, ldap_request->result, ""); - array_foreach(&ldap_request->named_results, named_res) { - suffix = t_strdup_printf("@%s", named_res->field->name); - if (named_res->result != NULL) - get_ldap_fields(ctx, conn, named_res->result, suffix); + if (array_is_created(&ldap_request->named_results)) { + array_foreach(&ldap_request->named_results, named_res) { + suffix = t_strdup_printf("@%s", named_res->field->name); + if (named_res->result != NULL) + get_ldap_fields(ctx, conn, named_res->result, suffix); + } } return ctx; } From dovecot at dovecot.org Mon Mar 25 18:10:23 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 25 Mar 2013 18:10:23 +0200 Subject: dovecot-2.2: ldap: Various crashfixes Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a6f8c4d6252e changeset: 16112:a6f8c4d6252e user: Timo Sirainen date: Mon Mar 25 18:10:16 2013 +0200 description: ldap: Various crashfixes diffstat: src/auth/db-ldap.c | 25 +++++++++++++++++++------ src/auth/db-ldap.h | 2 ++ src/auth/userdb-ldap.c | 1 + 3 files changed, 22 insertions(+), 6 deletions(-) diffs (72 lines): diff -r 3de93139afce -r a6f8c4d6252e src/auth/db-ldap.c --- a/src/auth/db-ldap.c Mon Mar 25 17:56:53 2013 +0200 +++ b/src/auth/db-ldap.c Mon Mar 25 18:10:16 2013 +0200 @@ -752,7 +752,7 @@ ldap_err2string(ret)); res = NULL; } - if (ret == LDAP_SUCCESS && srequest != NULL) { + if (ret == LDAP_SUCCESS && srequest != NULL && !srequest->multi_entry) { /* expand any @results */ if (!final_result) { if (db_ldap_search_save_result(srequest, res) < 0) { @@ -779,11 +779,22 @@ aqueue_delete(conn->request_queue, idx); } - T_BEGIN { - if (res != NULL && srequest != NULL && srequest->result != NULL) - request->callback(conn, request, srequest->result); - request->callback(conn, request, res); - } T_END; + if (srequest == NULL) { + T_BEGIN { + request->callback(conn, request, res); + } T_END; + } else { + T_BEGIN { + LDAPMessage *orig_result = srequest->result; + + if (res != NULL && srequest->result != NULL) + request->callback(conn, request, srequest->result); + + srequest->result = res; + request->callback(conn, request, res); + srequest->result = orig_result; + } T_END; + } if (idx > 0) { /* see if there are timed out requests */ @@ -1440,6 +1451,8 @@ const char *suffix; pool_t pool; + i_assert(ldap_request->result != NULL); + pool = pool_alloconly_create("ldap result iter", 1024); ctx = p_new(pool, struct db_ldap_result_iterate_context, 1); ctx->pool = pool; diff -r 3de93139afce -r a6f8c4d6252e src/auth/db-ldap.h --- a/src/auth/db-ldap.h Mon Mar 25 17:56:53 2013 +0200 +++ b/src/auth/db-ldap.h Mon Mar 25 18:10:16 2013 +0200 @@ -122,6 +122,8 @@ LDAPMessage *result; ARRAY(struct ldap_request_named_result) named_results; unsigned int name_idx; + + bool multi_entry; }; struct ldap_request_bind { diff -r 3de93139afce -r a6f8c4d6252e src/auth/userdb-ldap.c --- a/src/auth/userdb-ldap.c Mon Mar 25 17:56:53 2013 +0200 +++ b/src/auth/userdb-ldap.c Mon Mar 25 18:10:16 2013 +0200 @@ -221,6 +221,7 @@ request->request.filter = p_strdup(auth_request->pool, str_c(str)); request->request.attr_map = &conn->iterate_attr_map; request->request.attributes = conn->iterate_attr_names; + request->request.multi_entry = TRUE; if (global_auth_settings->debug) { i_debug("ldap: iterate: base=%s scope=%s filter=%s fields=%s", From dovecot at dovecot.org Tue Mar 26 10:26:03 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 26 Mar 2013 10:26:03 +0200 Subject: dovecot-2.2: ldap: Improved sub-dn-lookup error message. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8ca1aba14888 changeset: 16113:8ca1aba14888 user: Timo Sirainen date: Tue Mar 26 10:25:50 2013 +0200 description: ldap: Improved sub-dn-lookup error message. diffstat: src/auth/db-ldap.c | 17 +++++++++++++---- 1 files changed, 13 insertions(+), 4 deletions(-) diffs (34 lines): diff -r a6f8c4d6252e -r 8ca1aba14888 src/auth/db-ldap.c --- a/src/auth/db-ldap.c Mon Mar 25 18:10:16 2013 +0200 +++ b/src/auth/db-ldap.c Tue Mar 26 10:25:50 2013 +0200 @@ -710,6 +710,7 @@ LDAPMessage *res) { struct ldap_request_search *srequest = NULL; + const struct ldap_request_named_result *named_res; int ret; bool final_result; @@ -746,10 +747,18 @@ struct ldap_request_search *srequest = (struct ldap_request_search *)request; - auth_request_log_error(request->auth_request, "ldap", - "ldap_search(base=%s filter=%s) failed: %s", - srequest->base, srequest->filter, - ldap_err2string(ret)); + if (!array_is_created(&request->named_results)) { + auth_request_log_error(request->auth_request, "ldap", + "ldap_search(base=%s filter=%s) failed: %s", + srequest->base, srequest->filter, + ldap_err2string(ret)); + } else { + named_res = array_idx(&request->named_results, + request->name_idx); + auth_request_log_error(request->auth_request, "ldap", + "ldap_search(base=%s) failed: %s", + named_res->dn, ldap_err2string(ret)); + } res = NULL; } if (ret == LDAP_SUCCESS && srequest != NULL && !srequest->multi_entry) { From dovecot at dovecot.org Tue Mar 26 10:35:50 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 26 Mar 2013 10:35:50 +0200 Subject: dovecot-2.2: ldap: Compiling fix to previous change Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3396bc2575f5 changeset: 16114:3396bc2575f5 user: Timo Sirainen date: Tue Mar 26 10:35:38 2013 +0200 description: ldap: Compiling fix to previous change diffstat: src/auth/db-ldap.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (21 lines): diff -r 8ca1aba14888 -r 3396bc2575f5 src/auth/db-ldap.c --- a/src/auth/db-ldap.c Tue Mar 26 10:25:50 2013 +0200 +++ b/src/auth/db-ldap.c Tue Mar 26 10:35:38 2013 +0200 @@ -747,14 +747,14 @@ struct ldap_request_search *srequest = (struct ldap_request_search *)request; - if (!array_is_created(&request->named_results)) { + if (!array_is_created(&srequest->named_results)) { auth_request_log_error(request->auth_request, "ldap", "ldap_search(base=%s filter=%s) failed: %s", srequest->base, srequest->filter, ldap_err2string(ret)); } else { - named_res = array_idx(&request->named_results, - request->name_idx); + named_res = array_idx(&srequest->named_results, + srequest->name_idx); auth_request_log_error(request->auth_request, "ldap", "ldap_search(base=%s) failed: %s", named_res->dn, ldap_err2string(ret)); From dovecot at dovecot.org Tue Mar 26 10:36:55 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 26 Mar 2013 10:36:55 +0200 Subject: dovecot-2.2: ldap: Crashfix Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/aa8e77ab2b60 changeset: 16115:aa8e77ab2b60 user: Timo Sirainen date: Tue Mar 26 10:36:49 2013 +0200 description: ldap: Crashfix diffstat: src/auth/db-ldap.c | 45 ++++++++++++++++++--------------------------- src/auth/db-ldap.h | 3 ++- src/auth/passdb-ldap.c | 9 +++++---- src/auth/userdb-ldap.c | 10 ++++++---- 4 files changed, 31 insertions(+), 36 deletions(-) diffs (215 lines): diff -r 3396bc2575f5 -r aa8e77ab2b60 src/auth/db-ldap.c --- a/src/auth/db-ldap.c Tue Mar 26 10:35:38 2013 +0200 +++ b/src/auth/db-ldap.c Tue Mar 26 10:36:49 2013 +0200 @@ -158,7 +158,7 @@ struct db_ldap_result_iterate_context * db_ldap_result_iterate_init_full(struct ldap_connection *conn, struct ldap_request_search *ldap_request, - bool iter_dn_values); + LDAPMessage *res, bool iter_dn_values); static int deref2str(const char *str) { @@ -547,14 +547,15 @@ } static int db_ldap_fields_get_dn(struct ldap_connection *conn, - struct ldap_request_search *request) + struct ldap_request_search *request, + LDAPMessage *res) { struct auth_request *auth_request = request->request.auth_request; struct ldap_request_named_result *named_res; struct db_ldap_result_iterate_context *ldap_iter; const char *name, *const *values; - ldap_iter = db_ldap_result_iterate_init_full(conn, request, TRUE); + ldap_iter = db_ldap_result_iterate_init_full(conn, request, res, TRUE); while (db_ldap_result_iterate_next(ldap_iter, &name, &values)) { if (values[1] != NULL) { auth_request_log_warning(auth_request, "ldap", @@ -668,7 +669,8 @@ } static int db_ldap_search_next_subsearch(struct ldap_connection *conn, - struct ldap_request_search *request) + struct ldap_request_search *request, + LDAPMessage *res) { struct ldap_request_named_result *named_res; const struct ldap_field *field; @@ -683,7 +685,7 @@ named_res = array_append_space(&request->named_results); named_res->field = field; } - if (db_ldap_fields_get_dn(conn, request) < 0) + if (db_ldap_fields_get_dn(conn, request, res) < 0) return -1; } else { request->name_idx++; @@ -773,7 +775,7 @@ return FALSE; } } else { - ret = db_ldap_search_next_subsearch(conn, srequest); + ret = db_ldap_search_next_subsearch(conn, srequest, res); if (ret > 0) { /* free this result, but not the others */ ldap_msgfree(res); @@ -788,22 +790,12 @@ aqueue_delete(conn->request_queue, idx); } - if (srequest == NULL) { - T_BEGIN { - request->callback(conn, request, res); - } T_END; - } else { - T_BEGIN { - LDAPMessage *orig_result = srequest->result; + T_BEGIN { + if (res != NULL && srequest != NULL && srequest->result != NULL) + request->callback(conn, request, srequest->result); - if (res != NULL && srequest->result != NULL) - request->callback(conn, request, srequest->result); - - srequest->result = res; - request->callback(conn, request, res); - srequest->result = orig_result; - } T_END; - } + request->callback(conn, request, res); + } T_END; if (idx > 0) { /* see if there are timed out requests */ @@ -1453,15 +1445,13 @@ struct db_ldap_result_iterate_context * db_ldap_result_iterate_init_full(struct ldap_connection *conn, struct ldap_request_search *ldap_request, - bool iter_dn_values) + LDAPMessage *res, bool iter_dn_values) { struct db_ldap_result_iterate_context *ctx; const struct ldap_request_named_result *named_res; const char *suffix; pool_t pool; - i_assert(ldap_request->result != NULL); - pool = pool_alloconly_create("ldap result iter", 1024); ctx = p_new(pool, struct db_ldap_result_iterate_context, 1); ctx->pool = pool; @@ -1472,7 +1462,7 @@ if (ctx->auth_request->set->debug) ctx->debug = t_str_new(256); - get_ldap_fields(ctx, conn, ldap_request->result, ""); + get_ldap_fields(ctx, conn, res, ""); if (array_is_created(&ldap_request->named_results)) { array_foreach(&ldap_request->named_results, named_res) { suffix = t_strdup_printf("@%s", named_res->field->name); @@ -1485,9 +1475,10 @@ struct db_ldap_result_iterate_context * db_ldap_result_iterate_init(struct ldap_connection *conn, - struct ldap_request_search *ldap_request) + struct ldap_request_search *ldap_request, + LDAPMessage *res) { - return db_ldap_result_iterate_init_full(conn, ldap_request, FALSE); + return db_ldap_result_iterate_init_full(conn, ldap_request, res, FALSE); } static const char *db_ldap_field_get_default(const char *data) diff -r 3396bc2575f5 -r aa8e77ab2b60 src/auth/db-ldap.h --- a/src/auth/db-ldap.h Tue Mar 26 10:35:38 2013 +0200 +++ b/src/auth/db-ldap.h Tue Mar 26 10:36:49 2013 +0200 @@ -196,7 +196,8 @@ struct db_ldap_result_iterate_context * db_ldap_result_iterate_init(struct ldap_connection *conn, - struct ldap_request_search *ldap_request); + struct ldap_request_search *ldap_request, + LDAPMessage *res); bool db_ldap_result_iterate_next(struct db_ldap_result_iterate_context *ctx, const char **name_r, const char *const **values_r); diff -r 3396bc2575f5 -r aa8e77ab2b60 src/auth/passdb-ldap.c --- a/src/auth/passdb-ldap.c Tue Mar 26 10:35:38 2013 +0200 +++ b/src/auth/passdb-ldap.c Tue Mar 26 10:36:49 2013 +0200 @@ -41,12 +41,13 @@ static void ldap_query_save_result(struct ldap_connection *conn, struct auth_request *auth_request, - struct ldap_request_search *ldap_request) + struct ldap_request_search *ldap_request, + LDAPMessage *res) { struct db_ldap_result_iterate_context *ldap_iter; const char *name, *const *values; - ldap_iter = db_ldap_result_iterate_init(conn, ldap_request); + ldap_iter = db_ldap_result_iterate_init(conn, ldap_request, res); while (db_ldap_result_iterate_next(ldap_iter, &name, &values)) { if (values[1] != NULL) { auth_request_log_warning(auth_request, "ldap", @@ -129,7 +130,7 @@ if (ldap_request->entries++ == 0) { /* first entry */ ldap_query_save_result(conn, auth_request, - &ldap_request->request.search); + &ldap_request->request.search, res); } } @@ -245,7 +246,7 @@ /* first entry */ ldap_query_save_result(conn, auth_request, - &passdb_ldap_request->request.search); + &passdb_ldap_request->request.search, res); /* save dn */ dn = ldap_get_dn(conn->ld, res); diff -r 3396bc2575f5 -r aa8e77ab2b60 src/auth/userdb-ldap.c --- a/src/auth/userdb-ldap.c Tue Mar 26 10:35:38 2013 +0200 +++ b/src/auth/userdb-ldap.c Tue Mar 26 10:36:49 2013 +0200 @@ -44,14 +44,15 @@ static void ldap_query_get_result(struct ldap_connection *conn, struct auth_request *auth_request, - struct ldap_request_search *ldap_request) + struct ldap_request_search *ldap_request, + LDAPMessage *res) { struct db_ldap_result_iterate_context *ldap_iter; const char *name, *const *values; auth_request_init_userdb_reply(auth_request); - ldap_iter = db_ldap_result_iterate_init(conn, ldap_request); + ldap_iter = db_ldap_result_iterate_init(conn, ldap_request, res); while (db_ldap_result_iterate_next(ldap_iter, &name, &values)) { auth_request_set_userdb_field_values(auth_request, name, values); @@ -100,7 +101,8 @@ if (urequest->entries++ == 0) { /* first entry */ - ldap_query_get_result(conn, auth_request, &urequest->request); + ldap_query_get_result(conn, auth_request, + &urequest->request, res); } } @@ -167,7 +169,7 @@ request->create_time = ioloop_time; ctx->in_callback = TRUE; - ldap_iter = db_ldap_result_iterate_init(conn, &urequest->request); + ldap_iter = db_ldap_result_iterate_init(conn, &urequest->request, res); while (db_ldap_result_iterate_next(ldap_iter, &name, &values)) { if (strcmp(name, "user") != 0) { i_warning("ldap: iterate: " From dovecot at dovecot.org Tue Mar 26 14:38:44 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 26 Mar 2013 14:38:44 +0200 Subject: dovecot-2.2: ldap: Another fix to sub-dn-lookup. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0fbeb82f3f95 changeset: 16116:0fbeb82f3f95 user: Timo Sirainen date: Tue Mar 26 14:38:30 2013 +0200 description: ldap: Another fix to sub-dn-lookup. diffstat: src/auth/db-ldap.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r aa8e77ab2b60 -r 0fbeb82f3f95 src/auth/db-ldap.c --- a/src/auth/db-ldap.c Tue Mar 26 10:36:49 2013 +0200 +++ b/src/auth/db-ldap.c Tue Mar 26 14:38:30 2013 +0200 @@ -675,6 +675,9 @@ struct ldap_request_named_result *named_res; const struct ldap_field *field; + if (request->result != NULL) + res = request->result; + if (!array_is_created(&request->named_results)) { /* see if we need to do more LDAP queries */ p_array_init(&request->named_results, From dovecot at dovecot.org Tue Mar 26 22:39:54 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 26 Mar 2013 22:39:54 +0200 Subject: dovecot-2.2: dsync: Crashfix when importing from storage without... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/494d1a69fc1c changeset: 16117:494d1a69fc1c user: Timo Sirainen date: Tue Mar 26 22:39:38 2013 +0200 description: dsync: Crashfix when importing from storage without GUIDs. diffstat: src/doveadm/dsync/dsync-mailbox-import.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 0fbeb82f3f95 -r 494d1a69fc1c src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Tue Mar 26 14:38:30 2013 +0200 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Tue Mar 26 22:39:38 2013 +0200 @@ -506,6 +506,7 @@ } pmail = (struct mail_private *)importer->cur_mail; importer->cur_hdr_hash = p_strdup(pmail->pool, hdr_hash); + importer->cur_guid = ""; } /* make sure next_local_seq gets updated in case we came here because of min_uid */ From dovecot at dovecot.org Tue Mar 26 22:41:48 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 26 Mar 2013 22:41:48 +0200 Subject: dovecot-2.2: dsync: Allow syncing same mail root dirs if indexes... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0c52fb39ca3d changeset: 16118:0c52fb39ca3d user: Timo Sirainen date: Tue Mar 26 22:40:57 2013 +0200 description: dsync: Allow syncing same mail root dirs if indexes are different. Fixes dsyncing with storages that have no mail root dirs. diffstat: src/doveadm/dsync/doveadm-dsync.c | 23 +++++++++++++++-------- 1 files changed, 15 insertions(+), 8 deletions(-) diffs (41 lines): diff -r 494d1a69fc1c -r 0c52fb39ca3d src/doveadm/dsync/doveadm-dsync.c --- a/src/doveadm/dsync/doveadm-dsync.c Tue Mar 26 22:39:38 2013 +0200 +++ b/src/doveadm/dsync/doveadm-dsync.c Tue Mar 26 22:40:57 2013 +0200 @@ -276,6 +276,16 @@ return TRUE; } +static bool paths_are_equal(struct mail_user *user1, struct mail_user *user2, + enum mailbox_list_path_type type) +{ + const char *path1, *path2; + + return mailbox_list_get_root_path(user1->namespaces->list, type, &path1) && + mailbox_list_get_root_path(user2->namespaces->list, type, &path2) && + strcmp(path1, path2) == 0; +} + static int cmd_dsync_run_local(struct dsync_cmd_context *ctx, struct mail_user *user, struct dsync_brain *brain, struct dsync_ibc *ibc2) @@ -315,15 +325,12 @@ mail_user_unref(&user2); return -1; } - if (mailbox_list_get_root_path(user->namespaces->list, - MAILBOX_LIST_PATH_TYPE_MAILBOX, - &path1) && - mailbox_list_get_root_path(user2->namespaces->list, - MAILBOX_LIST_PATH_TYPE_MAILBOX, - &path2) && - strcmp(path1, path2) == 0) { + if (paths_are_equal(user, user2, MAILBOX_LIST_PATH_TYPE_MAILBOX) && + paths_are_equal(user, user2, MAILBOX_LIST_PATH_TYPE_INDEX)) { i_error("Both source and destination mail_location " - "points to same directory: %s", path1); + "points to same directory: %s", + mailbox_list_get_root_forced(user->namespaces->list, + MAILBOX_LIST_PATH_TYPE_MAILBOX)); ctx->ctx.exit_code = EX_CONFIG; mail_user_unref(&user2); return -1; From dovecot at dovecot.org Tue Mar 26 22:41:48 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 26 Mar 2013 22:41:48 +0200 Subject: dovecot-2.2: dsync: Allow doveadm plugins to override local_loca... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d7893c4460c3 changeset: 16119:d7893c4460c3 user: Timo Sirainen date: Tue Mar 26 22:41:32 2013 +0200 description: dsync: Allow doveadm plugins to override local_location at run(). diffstat: src/doveadm/dsync/doveadm-dsync.c | 20 ++++++++++++++------ 1 files changed, 14 insertions(+), 6 deletions(-) diffs (71 lines): diff -r 0c52fb39ca3d -r d7893c4460c3 src/doveadm/dsync/doveadm-dsync.c --- a/src/doveadm/dsync/doveadm-dsync.c Tue Mar 26 22:40:57 2013 +0200 +++ b/src/doveadm/dsync/doveadm-dsync.c Tue Mar 26 22:41:32 2013 +0200 @@ -77,6 +77,7 @@ unsigned int reverse_backup:1; unsigned int remote_user_prefix:1; unsigned int no_mail_sync:1; + unsigned int local_location_from_arg:1; }; static bool legacy_dsync = FALSE; @@ -293,18 +294,23 @@ struct dsync_brain *brain2; struct mail_user *user2; struct setting_parser_context *set_parser; - const char *set_line, *path1, *path2; + const char *set_line, *location; bool brain1_running, brain2_running, changed1, changed2; int ret; - i_assert(ctx->local_location != NULL); + if (ctx->local_location_from_arg) + location = ctx->ctx.args[0]; + else { + i_assert(ctx->local_location != NULL); + location = ctx->local_location; + } i_set_failure_prefix("dsync(%s): ", user->username); /* update mail_location and create another user for the second location. */ set_parser = mail_storage_service_user_get_settings_parser(ctx->ctx.cur_service_user); - set_line = t_strconcat("mail_location=", ctx->local_location, NULL); + set_line = t_strconcat("mail_location=", location, NULL); if (settings_parse_line(set_parser, set_line) < 0) i_unreached(); ret = mail_storage_service_next(ctx->ctx.storage_service, @@ -680,7 +686,7 @@ const char **error_r) { struct dsync_cmd_context *ctx = (struct dsync_cmd_context *)_ctx; - const char *const *remote_cmd_args = NULL; + const char *local_location, *const *remote_cmd_args = NULL; const struct mail_user_settings *user_set; const struct mail_storage_settings *mail_set; const char *username = ""; @@ -703,6 +709,7 @@ _ctx->exit_code = DOVEADM_EX_NOTFOUND; return -1; } + local_location = ctx->local_location; } else { /* if we're executing remotely, give -u parameter if we also did a userdb lookup. */ @@ -713,12 +720,13 @@ /* it's a mail_location */ if (_ctx->args[1] != NULL) doveadm_mail_help_name(_ctx->cmd->name); - ctx->local_location = _ctx->args[0]; + ctx->local_location_from_arg = TRUE; + local_location = _ctx->args[0]; } } if (remote_cmd_args == NULL && ctx->local_location != NULL) { - if (parse_location(ctx, mail_set, ctx->local_location, + if (parse_location(ctx, mail_set, local_location, &remote_cmd_args, error_r) < 0) return -1; } From dovecot at dovecot.org Tue Mar 26 22:41:48 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 26 Mar 2013 22:41:48 +0200 Subject: dovecot-2.2: lib-storage: Added assert. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/11d61991a525 changeset: 16120:11d61991a525 user: Timo Sirainen date: Tue Mar 26 22:41:43 2013 +0200 description: lib-storage: Added assert. diffstat: src/lib-storage/mail.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (15 lines): diff -r d7893c4460c3 -r 11d61991a525 src/lib-storage/mail.c --- a/src/lib-storage/mail.c Tue Mar 26 22:41:32 2013 +0200 +++ b/src/lib-storage/mail.c Tue Mar 26 22:41:43 2013 +0200 @@ -266,7 +266,10 @@ { struct mail_private *p = (struct mail_private *)mail; - return p->v.get_special(mail, field, value_r); + if (p->v.get_special(mail, field, value_r) < 0) + return -1; + i_assert(*value_r != NULL); + return 0; } struct mail *mail_get_real_mail(struct mail *mail) From dovecot at dovecot.org Wed Mar 27 09:17:02 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 27 Mar 2013 09:17:02 +0200 Subject: dovecot-2.2: Compiler warning fix Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/10bcadab431c changeset: 16121:10bcadab431c user: Timo Sirainen date: Wed Mar 27 09:16:42 2013 +0200 description: Compiler warning fix diffstat: src/replication/replication-common.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 11d61991a525 -r 10bcadab431c src/replication/replication-common.h --- a/src/replication/replication-common.h Tue Mar 26 22:41:43 2013 +0200 +++ b/src/replication/replication-common.h Wed Mar 27 09:16:42 2013 +0200 @@ -25,6 +25,7 @@ case REPLICATION_PRIORITY_SYNC: return "sync"; } + i_unreached(); } static inline int From dovecot at dovecot.org Wed Mar 27 09:17:02 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 27 Mar 2013 09:17:02 +0200 Subject: dovecot-2.2: dsync: Don't access uninitialized variable Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/37711fb8369f changeset: 16122:37711fb8369f user: Timo Sirainen date: Wed Mar 27 09:16:56 2013 +0200 description: dsync: Don't access uninitialized variable diffstat: src/doveadm/dsync/doveadm-dsync.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 10bcadab431c -r 37711fb8369f src/doveadm/dsync/doveadm-dsync.c --- a/src/doveadm/dsync/doveadm-dsync.c Wed Mar 27 09:16:42 2013 +0200 +++ b/src/doveadm/dsync/doveadm-dsync.c Wed Mar 27 09:16:56 2013 +0200 @@ -686,7 +686,7 @@ const char **error_r) { struct dsync_cmd_context *ctx = (struct dsync_cmd_context *)_ctx; - const char *local_location, *const *remote_cmd_args = NULL; + const char *local_location = NULL, *const *remote_cmd_args = NULL; const struct mail_user_settings *user_set; const struct mail_storage_settings *mail_set; const char *username = ""; From dovecot at dovecot.org Wed Mar 27 12:51:09 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 27 Mar 2013 12:51:09 +0200 Subject: dovecot-2.1: lib-index: Removed obsolete 16bit size check assert... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/87d0c4056b4d changeset: 14939:87d0c4056b4d user: Timo Sirainen date: Wed Mar 27 12:51:02 2013 +0200 description: lib-index: Removed obsolete 16bit size check asserts from mail_index_update_header_ext() diffstat: src/lib-index/mail-index-transaction-update.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r 8cc28a5a3f4f -r 87d0c4056b4d src/lib-index/mail-index-transaction-update.c --- a/src/lib-index/mail-index-transaction-update.c Mon Mar 25 16:19:54 2013 +0200 +++ b/src/lib-index/mail-index-transaction-update.c Wed Mar 27 12:51:02 2013 +0200 @@ -871,8 +871,8 @@ struct mail_index_transaction_ext_hdr_update *hdr; size_t new_size; - i_assert(offset <= (uint16_t)-1 && size <= (uint16_t)-1 && - offset + size <= (uint16_t)-1); + i_assert(offset <= (uint32_t)-1 && size <= (uint32_t)-1 && + offset + size <= (uint32_t)-1); if (!array_is_created(&t->ext_hdr_updates)) i_array_init(&t->ext_hdr_updates, ext_id + 2); From dovecot at dovecot.org Wed Mar 27 12:53:42 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 27 Mar 2013 12:53:42 +0200 Subject: dovecot-2.2: dsync: Use i_fatal() for invalid parameters, like t... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b4040180f30c changeset: 16123:b4040180f30c user: Timo Sirainen date: Wed Mar 27 12:53:35 2013 +0200 description: dsync: Use i_fatal() for invalid parameters, like the rest of doveadm commands. Probably the parse_arg() API should be changed to allow reporting errors. diffstat: src/doveadm/dsync/doveadm-dsync.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (18 lines): diff -r 37711fb8369f -r b4040180f30c src/doveadm/dsync/doveadm-dsync.c --- a/src/doveadm/dsync/doveadm-dsync.c Wed Mar 27 09:16:56 2013 +0200 +++ b/src/doveadm/dsync/doveadm-dsync.c Wed Mar 27 12:53:35 2013 +0200 @@ -787,12 +787,12 @@ ctx->no_mail_sync = TRUE; else if (guid_128_from_string(optarg, ctx->mailbox_guid) < 0 || guid_128_is_empty(ctx->mailbox_guid)) - i_error("Invalid -g parameter: %s", optarg); + i_fatal("Invalid -g parameter: %s", optarg); break; case 'l': ctx->lock = TRUE; if (str_to_uint(optarg, &ctx->lock_timeout) < 0) - i_error("Invalid -l parameter: %s", optarg); + i_fatal("Invalid -l parameter: %s", optarg); break; case 'm': if (optarg[0] == '\0') From dovecot at dovecot.org Wed Mar 27 14:45:30 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 27 Mar 2013 14:45:30 +0200 Subject: dovecot-2.2: lib-fs: Always keep the error in the parentmost fs. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d4014211c154 changeset: 16124:d4014211c154 user: Timo Sirainen date: Wed Mar 27 14:45:14 2013 +0200 description: lib-fs: Always keep the error in the parentmost fs. This fixes problems with getting the correct error message when wrapper filesystems are used. diffstat: src/lib-fs/fs-api-private.h | 1 + src/lib-fs/fs-api.c | 25 +++++++- src/lib-fs/fs-metawrap.c | 111 +++++++++---------------------------------- 3 files changed, 44 insertions(+), 93 deletions(-) diffs (truncated from 315 to 300 lines): diff -r b4040180f30c -r d4014211c154 src/lib-fs/fs-api-private.h --- a/src/lib-fs/fs-api-private.h Wed Mar 27 12:53:35 2013 +0200 +++ b/src/lib-fs/fs-api-private.h Wed Mar 27 14:45:14 2013 +0200 @@ -53,6 +53,7 @@ }; struct fs { + struct fs *parent; /* for wrapper filesystems */ const char *name; struct fs_vfuncs v; char *temp_path_prefix; diff -r b4040180f30c -r d4014211c154 src/lib-fs/fs-api.c --- a/src/lib-fs/fs-api.c Wed Mar 27 12:53:35 2013 +0200 +++ b/src/lib-fs/fs-api.c Wed Mar 27 14:45:14 2013 +0200 @@ -227,8 +227,24 @@ file->fs->v.get_path(file); } +static void ATTR_FORMAT(2, 0) +fs_set_verror(struct fs *fs, const char *fmt, va_list args) +{ + /* the error is always kept in the parentmost fs */ + if (fs->parent != NULL) + fs_set_verror(fs->parent, fmt, args); + else { + str_truncate(fs->last_error, 0); + str_vprintfa(fs->last_error, fmt, args); + } +} + const char *fs_last_error(struct fs *fs) { + /* the error is always kept in the parentmost fs */ + if (fs->parent != NULL) + return fs_last_error(fs->parent); + if (str_len(fs->last_error) == 0) return "BUG: Unknown fs error"; return str_c(fs->last_error); @@ -529,8 +545,7 @@ va_list args; va_start(args, fmt); - str_truncate(fs->last_error, 0); - str_vprintfa(fs->last_error, fmt, args); + fs_set_verror(fs, fmt, args); va_end(args); } @@ -539,9 +554,9 @@ va_list args; va_start(args, fmt); - str_truncate(fs->last_error, 0); - str_vprintfa(fs->last_error, fmt, args); - i_error("fs-%s: %s", fs->name, str_c(fs->last_error)); + fs_set_verror(fs, fmt, args); + + i_error("fs-%s: %s", fs->name, fs_last_error(fs)); va_end(args); } diff -r b4040180f30c -r d4014211c154 src/lib-fs/fs-metawrap.c --- a/src/lib-fs/fs-metawrap.c Wed Mar 27 12:53:35 2013 +0200 +++ b/src/lib-fs/fs-metawrap.c Wed Mar 27 14:45:14 2013 +0200 @@ -15,7 +15,6 @@ struct metawrap_fs { struct fs fs; - struct fs *super; bool wrap_metadata; }; @@ -29,18 +28,6 @@ bool metadata_read; }; -static void fs_metawrap_copy_error(struct metawrap_fs *fs) -{ - fs_set_error(&fs->fs, "%s", fs_last_error(fs->super)); -} - -static void fs_metawrap_file_copy_error(struct metawrap_fs_file *file) -{ - struct metawrap_fs *fs = (struct metawrap_fs *)file->file.fs; - - fs_metawrap_copy_error(fs); -} - static struct fs *fs_metawrap_alloc(void) { struct metawrap_fs *fs; @@ -70,11 +57,11 @@ parent_name = t_strdup_until(args, parent_args); parent_args++; } - if (fs_init(parent_name, parent_args, set, &fs->super, &error) < 0) { + if (fs_init(parent_name, parent_args, set, &_fs->parent, &error) < 0) { fs_set_error(_fs, "%s: %s", parent_name, error); return -1; } - if ((fs_get_properties(fs->super) & FS_PROPERTY_METADATA) == 0) + if ((fs_get_properties(_fs->parent) & FS_PROPERTY_METADATA) == 0) fs->wrap_metadata = TRUE; return 0; } @@ -83,8 +70,8 @@ { struct metawrap_fs *fs = (struct metawrap_fs *)_fs; - if (fs->super != NULL) - fs_deinit(&fs->super); + if (_fs->parent != NULL) + fs_deinit(&_fs->parent); i_free(fs); } @@ -93,7 +80,7 @@ const struct metawrap_fs *fs = (const struct metawrap_fs *)_fs; enum fs_properties props; - props = fs_get_properties(fs->super); + props = fs_get_properties(_fs->parent); if (fs->wrap_metadata) { /* we don't have a quick stat() to see the file's size, because of the metadata header */ @@ -118,12 +105,12 @@ /* avoid unnecessarily creating two seekable streams */ flags &= ~FS_OPEN_FLAG_SEEKABLE; - file->super = fs_file_init(fs->super, path, mode | flags); + file->super = fs_file_init(_fs->parent, path, mode | flags); if (file->fs->wrap_metadata && mode == FS_OPEN_MODE_READONLY && (flags & FS_OPEN_FLAG_ASYNC) == 0) { /* use async stream for super, so fs_read_stream() won't create another seekable stream unneededly */ - file->super_read = fs_file_init(fs->super, path, mode | flags | + file->super_read = fs_file_init(_fs->parent, path, mode | flags | FS_OPEN_FLAG_ASYNC); } else { file->super_read = file->super; @@ -164,13 +151,7 @@ static int fs_metawrap_wait_async(struct fs *_fs) { - struct metawrap_fs *fs = (struct metawrap_fs *)_fs; - - if (fs_wait_async(fs->super) < 0) { - fs_metawrap_copy_error(fs); - return -1; - } - return 0; + return fs_wait_async(_fs->parent); } static void @@ -192,13 +173,8 @@ struct metawrap_fs_file *file = (struct metawrap_fs_file *)_file; char c; - if (!file->fs->wrap_metadata) { - if (fs_get_metadata(file->super, metadata_r) < 0) { - fs_metawrap_file_copy_error(file); - return -1; - } - return 0; - } + if (!file->fs->wrap_metadata) + return fs_get_metadata(file->super, metadata_r); if (!file->metadata_read) { if (fs_read(_file, &c, 1) < 0) @@ -221,13 +197,9 @@ static ssize_t fs_metawrap_read(struct fs_file *_file, void *buf, size_t size) { struct metawrap_fs_file *file = (struct metawrap_fs_file *)_file; - ssize_t ret; - if (!file->fs->wrap_metadata) { - if ((ret = fs_read(file->super, buf, size)) < 0) - fs_metawrap_file_copy_error(file); - return ret; - } + if (!file->fs->wrap_metadata) + return fs_read(file->super, buf, size); return fs_read_via_stream(_file, buf, size); } @@ -275,13 +247,8 @@ { struct metawrap_fs_file *file = (struct metawrap_fs_file *)_file; - if (!file->fs->wrap_metadata) { - if (fs_write(file->super, data, size) < 0) { - fs_metawrap_file_copy_error(file); - return -1; - } - return 0; - } + if (!file->fs->wrap_metadata) + return fs_write(file->super, data, size); return fs_write_via_stream(_file, data, size); } @@ -343,9 +310,6 @@ } else { ret = fs_write_stream_finish(file->super, &file->super_output); } - - if (ret < 0) - fs_metawrap_file_copy_error(file); return ret; } @@ -354,11 +318,7 @@ { struct metawrap_fs_file *file = (struct metawrap_fs_file *)_file; - if (fs_lock(file->super, secs, lock_r) < 0) { - fs_metawrap_file_copy_error(file); - return -1; - } - return 0; + return fs_lock(file->super, secs, lock_r); } static void fs_metawrap_unlock(struct fs_lock *_lock ATTR_UNUSED) @@ -370,11 +330,7 @@ { struct metawrap_fs_file *file = (struct metawrap_fs_file *)_file; - if (fs_exists(file->super) < 0) { - fs_metawrap_copy_error(file->fs); - return -1; - } - return 0; + return fs_exists(file->super); } static int fs_metawrap_stat(struct fs_file *_file, struct stat *st_r) @@ -384,13 +340,8 @@ uoff_t input_size; ssize_t ret; - if (!file->fs->wrap_metadata) { - if (fs_stat(file->super, st_r) < 0) { - fs_metawrap_copy_error(file->fs); - return -1; - } - return 0; - } + if (!file->fs->wrap_metadata) + return fs_stat(file->super, st_r); input = fs_read_stream(_file, IO_BLOCK_SIZE); if ((ret = i_stream_get_size(input, TRUE, &input_size)) < 0) { fs_set_error(_file->fs, "i_stream_get_size(%s) failed: %m", @@ -406,7 +357,6 @@ if (fs_stat(file->super, st_r) < 0) { i_assert(errno != EAGAIN); /* read should have caught this */ - fs_metawrap_copy_error(file->fs); return -1; } st_r->st_size = input_size; @@ -418,13 +368,8 @@ struct metawrap_fs_file *src = (struct metawrap_fs_file *)_src; struct metawrap_fs_file *dest = (struct metawrap_fs_file *)_dest; - if (!dest->fs->wrap_metadata) { - if (fs_copy(src->super, dest->super) < 0) { - fs_metawrap_copy_error(src->fs); - return -1; - } - return 0; - } + if (!dest->fs->wrap_metadata) + return fs_copy(src->super, dest->super); return fs_default_copy(_src, _dest); } @@ -433,31 +378,21 @@ struct metawrap_fs_file *src = (struct metawrap_fs_file *)_src; struct metawrap_fs_file *dest = (struct metawrap_fs_file *)_dest; - if (fs_rename(src->super, dest->super) < 0) { - fs_metawrap_copy_error(src->fs); - return -1; - } - return 0; + return fs_rename(src->super, dest->super); } static int fs_metawrap_delete(struct fs_file *_file) { struct metawrap_fs_file *file = (struct metawrap_fs_file *)_file; - if (fs_delete(file->super) < 0) { - fs_metawrap_copy_error(file->fs); - return -1; - } From dovecot at dovecot.org Wed Mar 27 21:10:42 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 27 Mar 2013 21:10:42 +0200 Subject: dovecot-2.2: maildir: If maildir_broken_filename_sizes=yes, don'... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6d9444ea1c9a changeset: 16125:6d9444ea1c9a user: Timo Sirainen date: Wed Mar 27 21:10:35 2013 +0200 description: maildir: If maildir_broken_filename_sizes=yes, don't try to fix sizes in filenames. diffstat: src/lib-storage/index/maildir/maildir-mail.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r d4014211c154 -r 6d9444ea1c9a src/lib-storage/index/maildir/maildir-mail.c --- a/src/lib-storage/index/maildir/maildir-mail.c Wed Mar 27 14:45:14 2013 +0200 +++ b/src/lib-storage/index/maildir/maildir-mail.c Wed Mar 27 21:10:35 2013 +0200 @@ -687,6 +687,11 @@ uoff_t size; char wrong_key; + if (mbox->storage->set->maildir_broken_filename_sizes) { + /* never try to fix sizes in maildir filenames */ + return; + } + if (maildir_sync_lookup(mbox, mail->uid, &flags, &fname) <= 0) return; if (strchr(fname, MAILDIR_EXTRA_SEP) == NULL) From dovecot at dovecot.org Thu Mar 28 11:37:16 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 28 Mar 2013 11:37:16 +0200 Subject: dovecot-2.2: maildir++ quota: Fixed relative quota_grace when ta... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/426701831d00 changeset: 16126:426701831d00 user: Timo Sirainen date: Thu Mar 28 11:37:07 2013 +0200 description: maildir++ quota: Fixed relative quota_grace when taking limit from maildirsize file diffstat: src/plugins/quota/quota-private.h | 1 + src/plugins/quota/quota.c | 15 ++++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diffs (56 lines): diff -r 6d9444ea1c9a -r 426701831d00 src/plugins/quota/quota-private.h --- a/src/plugins/quota/quota-private.h Wed Mar 27 21:10:35 2013 +0200 +++ b/src/plugins/quota/quota-private.h Thu Mar 28 11:37:07 2013 +0200 @@ -90,6 +90,7 @@ /* If user is under quota before saving a mail, allow the last mail to bring the user over quota by this many bytes. */ uint64_t last_mail_max_extra_bytes; + struct quota_rule grace_rule; /* Limits in default_rule override backend's quota limits */ unsigned int force_default_rule:1; diff -r 6d9444ea1c9a -r 426701831d00 src/plugins/quota/quota.c --- a/src/plugins/quota/quota.c Wed Mar 27 21:10:35 2013 +0200 +++ b/src/plugins/quota/quota.c Thu Mar 28 11:37:07 2013 +0200 @@ -451,6 +451,9 @@ quota_rule_recalculate_relative_rules(&warning_rule->rule, bytes_limit, count_limit); } + quota_rule_recalculate_relative_rules(&root_set->grace_rule, + bytes_limit, 0); + root_set->last_mail_max_extra_bytes = root_set->grace_rule.bytes_limit; } static int @@ -610,7 +613,6 @@ { const char *set_name, *value, *error; char *p; - struct quota_rule rule; set_name = t_strconcat(root_name, "_grace", NULL); value = mail_user_plugin_getenv(user, set_name); @@ -619,18 +621,17 @@ value = QUOTA_DEFAULT_GRACE; } - memset(&rule, 0, sizeof(rule)); - rule.bytes_limit = strtoll(value, &p, 10); + root_set->grace_rule.bytes_limit = strtoll(value, &p, 10); - if (quota_limit_parse(root_set, &rule, p, 1, - &rule.bytes_limit, &error) < 0) { + if (quota_limit_parse(root_set, &root_set->grace_rule, p, 1, + &root_set->grace_rule.bytes_limit, &error) < 0) { *error_r = p_strdup_printf(root_set->set->pool, "Invalid %s value '%s': %s", set_name, value, error); return -1; } - quota_rule_recalculate_relative_rules(&rule, + quota_rule_recalculate_relative_rules(&root_set->grace_rule, root_set->default_rule.bytes_limit, 0); - root_set->last_mail_max_extra_bytes = rule.bytes_limit; + root_set->last_mail_max_extra_bytes = root_set->grace_rule.bytes_limit; return 0; } From pigeonhole at rename-it.nl Thu Mar 28 22:28:01 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 28 Mar 2013 21:28:01 +0100 Subject: dovecot-2.2-pigeonhole: doveadm-sieve: Implemented obtaining las... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/c6e283350b5d changeset: 1729:c6e283350b5d user: Stephan Bosch date: Thu Mar 28 21:27:53 2013 +0100 description: doveadm-sieve: Implemented obtaining last modification time for the active script attribute. It compiles, doesn't break normal ManageSieve operation, but it remains untested otherwise. diffstat: src/lib-sievestorage/sieve-storage-private.h | 2 + src/lib-sievestorage/sieve-storage-script.c | 26 +++++++++++++++++++++++- src/lib-sievestorage/sieve-storage-script.h | 2 + src/lib-sievestorage/sieve-storage.c | 16 ++++++++++++++ src/plugins/doveadm-sieve/doveadm-sieve-plugin.c | 5 +++- 5 files changed, 49 insertions(+), 2 deletions(-) diffs (125 lines): diff -r 097764f6bbe3 -r c6e283350b5d src/lib-sievestorage/sieve-storage-private.h --- a/src/lib-sievestorage/sieve-storage-private.h Mon Mar 25 12:34:13 2013 +0100 +++ b/src/lib-sievestorage/sieve-storage-private.h Thu Mar 28 21:27:53 2013 +0100 @@ -63,5 +63,7 @@ struct sieve_script *sieve_storage_script_init_from_path (struct sieve_storage *storage, const char *path, const char *scriptname); +void sieve_storage_mark_modified(struct sieve_storage *storage); + #endif diff -r 097764f6bbe3 -r c6e283350b5d src/lib-sievestorage/sieve-storage-script.c --- a/src/lib-sievestorage/sieve-storage-script.c Mon Mar 25 12:34:13 2013 +0100 +++ b/src/lib-sievestorage/sieve-storage-script.c Thu Mar 28 21:27:53 2013 +0100 @@ -406,10 +406,12 @@ sieve_storage_set_critical(storage, "sieve_storage_deactivate(): " "error on unlink(%s): %m", storage->active_path); return -1; - } else + } else { return 0; + } } + sieve_storage_mark_modified(storage); return 1; } @@ -528,6 +530,7 @@ } } + sieve_storage_mark_modified(storage); return activated; } @@ -542,6 +545,27 @@ return ret; } +int sieve_storage_get_active_script_last_change +(struct sieve_storage *storage, time_t *last_change_r) +{ + struct stat st; + + /* Try direct lstat first */ + if (lstat(storage->active_path, &st) == 0) { + *last_change_r = st.st_mtime; + return 0; + } + + /* Check error */ + if (errno != ENOENT) { + sieve_storage_set_critical(storage, "lstat(%s) failed: %m", + storage->active_path); + } + + /* Fall back to statting storage directory */ + return sieve_storage_get_last_change(storage, last_change_r); +} + int sieve_storage_script_rename (struct sieve_script *script, const char *newname) { diff -r 097764f6bbe3 -r c6e283350b5d src/lib-sievestorage/sieve-storage-script.h --- a/src/lib-sievestorage/sieve-storage-script.h Mon Mar 25 12:34:13 2013 +0100 +++ b/src/lib-sievestorage/sieve-storage-script.h Thu Mar 28 21:27:53 2013 +0100 @@ -18,6 +18,8 @@ struct sieve_script *sieve_storage_get_active_script (struct sieve_storage *storage); +int sieve_storage_get_active_script_last_change + (struct sieve_storage *storage, time_t *last_change_r); int sieve_storage_script_is_active(struct sieve_script *script); diff -r 097764f6bbe3 -r c6e283350b5d src/lib-sievestorage/sieve-storage.c --- a/src/lib-sievestorage/sieve-storage.c Mon Mar 25 12:34:13 2013 +0100 +++ b/src/lib-sievestorage/sieve-storage.c Thu Mar 28 21:27:53 2013 +0100 @@ -22,6 +22,7 @@ #include #include #include +#include #define SIEVE_DEFAULT_PATH "~/.dovecot."SIEVE_SCRIPT_FILEEXT @@ -586,6 +587,21 @@ return storage->error != NULL ? storage->error : "Unknown error"; } +void sieve_storage_mark_modified(struct sieve_storage *storage) +{ + if ( utime(storage->dir, NULL) < 0 ) { + switch ( errno ) { + case ENOENT: + break; + case EACCES: + i_error("sieve-storage: %s", eacces_error_get("utime", storage->dir)); + break; + default: + i_error("sieve-storage: utime(%s) failed: %m", storage->dir); + } + } +} + int sieve_storage_get_last_change (struct sieve_storage *storage, time_t *last_change_r) { diff -r 097764f6bbe3 -r c6e283350b5d src/plugins/doveadm-sieve/doveadm-sieve-plugin.c --- a/src/plugins/doveadm-sieve/doveadm-sieve-plugin.c Mon Mar 25 12:34:13 2013 +0100 +++ b/src/plugins/doveadm-sieve/doveadm-sieve-plugin.c Thu Mar 28 21:27:53 2013 +0100 @@ -268,8 +268,11 @@ { int ret; - /* FIXME: set value_r->last_change */ ret = sieve_storage_get_active_scriptname(sstorage, &value_r->value); + if (ret >= 0) { + ret = sieve_storage_get_active_script_last_change + (sstorage, &value_r->last_change); + } if (ret < 0) mail_storage_set_internal_error(storage); return ret; From pigeonhole at rename-it.nl Thu Mar 28 22:32:13 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 28 Mar 2013 21:32:13 +0100 Subject: dovecot-2.1-pigeonhole: lib-sievestorage: A few debug messages w... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/3ba1c379a6b8 changeset: 1678:3ba1c379a6b8 user: Stephan Bosch date: Thu Mar 28 21:31:59 2013 +0100 description: lib-sievestorage: A few debug messages were still logged using i_info() instead of i_debug(). diffstat: src/lib-sievestorage/sieve-storage-script.c | 2 +- src/lib-sievestorage/sieve-storage.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diffs (29 lines): diff -r 06c89405bdc6 -r 3ba1c379a6b8 src/lib-sievestorage/sieve-storage-script.c --- a/src/lib-sievestorage/sieve-storage-script.c Sun Mar 03 18:03:33 2013 +0100 +++ b/src/lib-sievestorage/sieve-storage-script.c Thu Mar 28 21:31:59 2013 +0100 @@ -356,7 +356,7 @@ if ( S_ISLNK( st.st_mode ) ) { if ( storage->debug ) - i_info( "sieve-storage: nothing to rescue %s.", storage->active_path); + i_debug( "sieve-storage: nothing to rescue %s.", storage->active_path); return TRUE; /* Nothing to rescue */ } diff -r 06c89405bdc6 -r 3ba1c379a6b8 src/lib-sievestorage/sieve-storage.c --- a/src/lib-sievestorage/sieve-storage.c Sun Mar 03 18:03:33 2013 +0100 +++ b/src/lib-sievestorage/sieve-storage.c Thu Mar 28 21:31:59 2013 +0100 @@ -447,11 +447,11 @@ if ( debug ) { if ( storage->max_storage > 0 ) { - i_info("sieve-storage: quota: storage limit: %llu bytes", + i_debug("sieve-storage: quota: storage limit: %llu bytes", (unsigned long long int) storage->max_storage); } if ( storage->max_scripts > 0 ) { - i_info("sieve-storage: quota: script count limit: %llu scripts", + i_debug("sieve-storage: quota: script count limit: %llu scripts", (unsigned long long int) storage->max_scripts); } } From pigeonhole at rename-it.nl Thu Mar 28 22:33:39 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 28 Mar 2013 21:33:39 +0100 Subject: dovecot-2.2-pigeonhole: lib-sievestorage: A few debug messages w... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/3ba1c379a6b8 changeset: 1730:3ba1c379a6b8 user: Stephan Bosch date: Thu Mar 28 21:31:59 2013 +0100 description: lib-sievestorage: A few debug messages were still logged using i_info() instead of i_debug(). diffstat: src/lib-sievestorage/sieve-storage-script.c | 2 +- src/lib-sievestorage/sieve-storage.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diffs (29 lines): diff -r 06c89405bdc6 -r 3ba1c379a6b8 src/lib-sievestorage/sieve-storage-script.c --- a/src/lib-sievestorage/sieve-storage-script.c Sun Mar 03 18:03:33 2013 +0100 +++ b/src/lib-sievestorage/sieve-storage-script.c Thu Mar 28 21:31:59 2013 +0100 @@ -356,7 +356,7 @@ if ( S_ISLNK( st.st_mode ) ) { if ( storage->debug ) - i_info( "sieve-storage: nothing to rescue %s.", storage->active_path); + i_debug( "sieve-storage: nothing to rescue %s.", storage->active_path); return TRUE; /* Nothing to rescue */ } diff -r 06c89405bdc6 -r 3ba1c379a6b8 src/lib-sievestorage/sieve-storage.c --- a/src/lib-sievestorage/sieve-storage.c Sun Mar 03 18:03:33 2013 +0100 +++ b/src/lib-sievestorage/sieve-storage.c Thu Mar 28 21:31:59 2013 +0100 @@ -447,11 +447,11 @@ if ( debug ) { if ( storage->max_storage > 0 ) { - i_info("sieve-storage: quota: storage limit: %llu bytes", + i_debug("sieve-storage: quota: storage limit: %llu bytes", (unsigned long long int) storage->max_storage); } if ( storage->max_scripts > 0 ) { - i_info("sieve-storage: quota: script count limit: %llu scripts", + i_debug("sieve-storage: quota: script count limit: %llu scripts", (unsigned long long int) storage->max_scripts); } } From pigeonhole at rename-it.nl Thu Mar 28 22:33:39 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 28 Mar 2013 21:33:39 +0100 Subject: dovecot-2.2-pigeonhole: Merged changes from Pigeonhole v0.3 tree. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/42f11a1be763 changeset: 1731:42f11a1be763 user: Stephan Bosch date: Thu Mar 28 21:33:31 2013 +0100 description: Merged changes from Pigeonhole v0.3 tree. diffstat: src/lib-sievestorage/sieve-storage-script.c | 2 +- src/lib-sievestorage/sieve-storage.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diffs (29 lines): diff -r c6e283350b5d -r 42f11a1be763 src/lib-sievestorage/sieve-storage-script.c --- a/src/lib-sievestorage/sieve-storage-script.c Thu Mar 28 21:27:53 2013 +0100 +++ b/src/lib-sievestorage/sieve-storage-script.c Thu Mar 28 21:33:31 2013 +0100 @@ -356,7 +356,7 @@ if ( S_ISLNK( st.st_mode ) ) { if ( storage->debug ) - i_info( "sieve-storage: nothing to rescue %s.", storage->active_path); + i_debug( "sieve-storage: nothing to rescue %s.", storage->active_path); return TRUE; /* Nothing to rescue */ } diff -r c6e283350b5d -r 42f11a1be763 src/lib-sievestorage/sieve-storage.c --- a/src/lib-sievestorage/sieve-storage.c Thu Mar 28 21:27:53 2013 +0100 +++ b/src/lib-sievestorage/sieve-storage.c Thu Mar 28 21:33:31 2013 +0100 @@ -448,11 +448,11 @@ if ( debug ) { if ( storage->max_storage > 0 ) { - i_info("sieve-storage: quota: storage limit: %llu bytes", + i_debug("sieve-storage: quota: storage limit: %llu bytes", (unsigned long long int) storage->max_storage); } if ( storage->max_scripts > 0 ) { - i_info("sieve-storage: quota: script count limit: %llu scripts", + i_debug("sieve-storage: quota: script count limit: %llu scripts", (unsigned long long int) storage->max_scripts); } } From pigeonhole at rename-it.nl Thu Mar 28 23:12:10 2013 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 28 Mar 2013 22:12:10 +0100 Subject: dovecot-2.1-pigeonhole: lib-sievestorage: Fixed a few potential ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/b086291b9b9a changeset: 1679:b086291b9b9a user: Stephan Bosch date: Thu Mar 28 22:12:03 2013 +0100 description: lib-sievestorage: Fixed a few potential problems in script save code. diffstat: src/lib-sievestorage/sieve-storage-save.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (30 lines): diff -r 3ba1c379a6b8 -r b086291b9b9a src/lib-sievestorage/sieve-storage-save.c --- a/src/lib-sievestorage/sieve-storage-save.c Thu Mar 28 21:31:59 2013 +0100 +++ b/src/lib-sievestorage/sieve-storage-save.c Thu Mar 28 22:12:03 2013 +0100 @@ -202,7 +202,7 @@ ctx = p_new(pool, struct sieve_save_context, 1); ctx->pool = pool; ctx->storage = storage; - ctx->scriptname = scriptname; + ctx->scriptname = p_strdup(pool, scriptname); ctx->scriptobject = NULL; T_BEGIN { @@ -305,7 +305,7 @@ if ( ctx->scriptobject == NULL ) { if ( ctx->storage->error_code == SIEVE_ERROR_NOT_FOUND ) { sieve_storage_set_critical(ctx->storage, - "save: Temporary script file with name '%s' got lost, " + "save: Temporary script file '%s' got lost, " "which should not happen (possibly deleted externally).", ctx->tmp_path); } @@ -324,7 +324,7 @@ const char *scriptname; int ret; - ret = sieve_storage_get_active_scriptfile(ctx->storage, &scriptname); + ret = sieve_storage_get_active_scriptname(ctx->storage, &scriptname); if ( ret > 0 ) { /* Is the requested script active? */ result = ( strcmp(ctx->scriptname, scriptname) == 0 ); From dovecot at dovecot.org Sun Mar 31 11:23:46 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 31 Mar 2013 11:23:46 +0300 Subject: dovecot-2.1: lib-master: Ignore mountpoints under /tmp and /var/... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/9d79ef9cf337 changeset: 14940:9d79ef9cf337 user: Timo Sirainen date: Sun Mar 31 11:23:42 2013 +0300 description: lib-master: Ignore mountpoints under /tmp and /var/tmp by default. diffstat: src/lib-master/mountpoint-list.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 87d0c4056b4d -r 9d79ef9cf337 src/lib-master/mountpoint-list.c --- a/src/lib-master/mountpoint-list.c Wed Mar 27 12:51:02 2013 +0200 +++ b/src/lib-master/mountpoint-list.c Sun Mar 31 11:23:42 2013 +0300 @@ -56,6 +56,8 @@ "/sys", "/proc", "/var/run", + "/var/tmp", + "/tmp", "/run", #ifdef __APPLE__ "/Volumes", From dovecot at dovecot.org Sun Mar 31 16:46:54 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 31 Mar 2013 16:46:54 +0300 Subject: dovecot-2.2: lib-storage: Create a default namespace for auto-cr... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f617e2fcce66 changeset: 16127:f617e2fcce66 user: Timo Sirainen date: Sun Mar 31 16:46:11 2013 +0300 description: lib-storage: Create a default namespace for auto-created shared mail_users. Some code nowadays requires user to have prefix="" namespace. diffstat: src/lib-storage/index/shared/shared-storage.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diffs (23 lines): diff -r 426701831d00 -r f617e2fcce66 src/lib-storage/index/shared/shared-storage.c --- a/src/lib-storage/index/shared/shared-storage.c Thu Mar 28 11:37:07 2013 +0200 +++ b/src/lib-storage/index/shared/shared-storage.c Sun Mar 31 16:46:11 2013 +0300 @@ -318,11 +318,19 @@ p_strdup(user->pool, storage->unexpanded_location); new_ns->unexpanded_set = unexpanded_ns_set; + /* We need to create a prefix="" namespace for the owner */ + if (mail_namespaces_init_location(owner, str_c(location), &error) < 0) { + mail_namespace_destroy(new_ns); + mail_user_unref(&owner); + return -1; + } + if (mail_storage_create(new_ns, NULL, _storage->flags | MAIL_STORAGE_FLAG_NO_AUTOVERIFY, &error) < 0) { mailbox_list_set_critical(list, "Namespace '%s': %s", new_ns->prefix, error); mail_namespace_destroy(new_ns); + mail_user_unref(&owner); return -1; } if ((new_ns->flags & NAMESPACE_FLAG_UNUSABLE) == 0 && From dovecot at dovecot.org Sun Mar 31 16:46:55 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 31 Mar 2013 16:46:55 +0300 Subject: dovecot-2.2: lib-storage: Don't reset mail_save_context.copying|... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f31d241d5371 changeset: 16128:f31d241d5371 user: Timo Sirainen date: Sun Mar 31 16:46:45 2013 +0300 description: lib-storage: Don't reset mail_save_context.copying|moving|copying_via_save too early. diffstat: src/lib-storage/index/index-storage.c | 3 --- src/lib-storage/mail-storage.c | 6 ++++++ 2 files changed, 6 insertions(+), 3 deletions(-) diffs (50 lines): diff -r f617e2fcce66 -r f31d241d5371 src/lib-storage/index/index-storage.c --- a/src/lib-storage/index/index-storage.c Sun Mar 31 16:46:11 2013 +0300 +++ b/src/lib-storage/index/index-storage.c Sun Mar 31 16:46:45 2013 +0300 @@ -759,9 +759,6 @@ memset(&ctx->data, 0, sizeof(ctx->data)); ctx->unfinished = FALSE; - ctx->copying_via_save = FALSE; - ctx->saving = FALSE; - ctx->moving = FALSE; } static void diff -r f617e2fcce66 -r f31d241d5371 src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Sun Mar 31 16:46:11 2013 +0300 +++ b/src/lib-storage/mail-storage.c Sun Mar 31 16:46:45 2013 +0300 @@ -2026,6 +2026,7 @@ if (keywords != NULL) mailbox_keywords_unref(&keywords); i_assert(!ctx->unfinished); + ctx->saving = FALSE; return ret; } @@ -2047,6 +2048,7 @@ mail->v.close(&mail->mail); } i_assert(!ctx->unfinished); + ctx->saving = FALSE; } struct mailbox_transaction_context * @@ -2084,6 +2086,9 @@ if (keywords != NULL) mailbox_keywords_unref(&keywords); i_assert(!ctx->unfinished); + + ctx->copying_via_save = FALSE; + ctx->saving = FALSE; return ret; } @@ -2096,6 +2101,7 @@ return -1; mail_expunge(mail); + ctx->moving = FALSE; return 0; } From dovecot at dovecot.org Sun Mar 31 17:25:24 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 31 Mar 2013 17:25:24 +0300 Subject: dovecot-2.2: lib-storage: mailbox_get_status() no longer forces ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/12136db6e31f changeset: 16129:12136db6e31f user: Timo Sirainen date: Sun Mar 31 17:24:35 2013 +0300 description: lib-storage: mailbox_get_status() no longer forces mailbox to be synced. This fixes copying messages with keywords to a virtual mailbox, where syncing happened too late and caused assert-crash (status was only used to lookup list of keywords). The crash could have been solved another way too, but it's probably better if automatic syncing isn't always performed. doveadm index -n parameter handling also relies on this behavior. diffstat: src/lib-storage/index/index-status.c | 2 -- src/lib-storage/mail-storage.h | 5 ++++- 2 files changed, 4 insertions(+), 3 deletions(-) diffs (27 lines): diff -r f31d241d5371 -r 12136db6e31f src/lib-storage/index/index-status.c --- a/src/lib-storage/index/index-status.c Sun Mar 31 16:46:45 2013 +0300 +++ b/src/lib-storage/index/index-status.c Sun Mar 31 17:24:35 2013 +0300 @@ -36,8 +36,6 @@ if (!box->opened) { if (mailbox_open(box) < 0) return -1; - } - if (!box->synced) { if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FAST) < 0) return -1; } diff -r f31d241d5371 -r 12136db6e31f src/lib-storage/mail-storage.h --- a/src/lib-storage/mail-storage.h Sun Mar 31 16:46:45 2013 +0300 +++ b/src/lib-storage/mail-storage.h Sun Mar 31 17:24:35 2013 +0300 @@ -541,7 +541,10 @@ do forced CLOSE. */ bool mailbox_is_inconsistent(struct mailbox *box); -/* Gets the mailbox status information, opening the mailbox if necessary. */ +/* Gets the mailbox status information. If mailbox isn't opened yet, try to + return the results from mailbox list indexes. Otherwise the mailbox is + opened and synced. If the mailbox is already opened, no syncing is done + automatically. */ int mailbox_get_status(struct mailbox *box, enum mailbox_status_items items, struct mailbox_status *status_r); /* Gets the mailbox status, requires that mailbox is already opened. */ From dovecot at dovecot.org Sun Mar 31 17:25:24 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 31 Mar 2013 17:25:24 +0300 Subject: dovecot-2.2: virtual plugin: Fixed saving/copying messages to vi... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9a8119326bd0 changeset: 16130:9a8119326bd0 user: Timo Sirainen date: Sun Mar 31 17:25:10 2013 +0300 description: virtual plugin: Fixed saving/copying messages to virtual mailbox. diffstat: src/lib-storage/mail-storage.c | 9 +++++---- src/plugins/virtual/virtual-save.c | 6 +++++- 2 files changed, 10 insertions(+), 5 deletions(-) diffs (49 lines): diff -r 12136db6e31f -r 9a8119326bd0 src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Sun Mar 31 17:24:35 2013 +0300 +++ b/src/lib-storage/mail-storage.c Sun Mar 31 17:25:10 2013 +0300 @@ -1813,7 +1813,6 @@ { struct mailbox_transaction_context *t = *_t; unsigned int save_count = t->save_count; - bool assign_uids = (t->flags & MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS) != 0; int ret; t->box->transaction_count--; @@ -1823,9 +1822,11 @@ T_BEGIN { ret = t->box->v.transaction_commit(t, changes_r); } T_END; - i_assert(ret < 0 || - seq_range_count(&changes_r->saved_uids) == save_count || - (array_count(&changes_r->saved_uids) == 0 && !assign_uids)); + /* either all the saved messages get UIDs or none, because a) we + failed, b) MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS not set, + c) backend doesn't support it (e.g. virtual plugin) */ + i_assert(seq_range_count(&changes_r->saved_uids) == save_count || + array_count(&changes_r->saved_uids) == 0); if (ret < 0 && changes_r->pool != NULL) pool_unref(&changes_r->pool); return ret; diff -r 12136db6e31f -r 9a8119326bd0 src/plugins/virtual/virtual-save.c --- a/src/plugins/virtual/virtual-save.c Sun Mar 31 17:24:35 2013 +0300 +++ b/src/plugins/virtual/virtual-save.c Sun Mar 31 17:25:10 2013 +0300 @@ -113,7 +113,10 @@ { struct virtual_save_context *ctx = (struct virtual_save_context *)_ctx; - return mailbox_save_finish(&ctx->backend_save_ctx); + if (mailbox_save_finish(&ctx->backend_save_ctx) < 0) + return -1; + _ctx->unfinished = FALSE; + return 0; } void virtual_save_cancel(struct mail_save_context *_ctx) @@ -122,6 +125,7 @@ if (ctx->backend_save_ctx != NULL) mailbox_save_cancel(&ctx->backend_save_ctx); + _ctx->unfinished = FALSE; } void virtual_save_free(struct mail_save_context *_ctx) From dovecot at dovecot.org Sun Mar 31 17:40:43 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 31 Mar 2013 17:40:43 +0300 Subject: dovecot-2.1: auth: Allow using userdb_userdb_import in passdb qu... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/cd919c490ea6 changeset: 14941:cd919c490ea6 user: Timo Sirainen date: Sun Mar 31 17:40:12 2013 +0300 description: auth: Allow using userdb_userdb_import in passdb query to set multiple userdb fields. diffstat: src/auth/auth-request.c | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+), 0 deletions(-) diffs (38 lines): diff -r 9d79ef9cf337 -r cd919c490ea6 src/auth/auth-request.c --- a/src/auth/auth-request.c Sun Mar 31 11:23:42 2013 +0300 +++ b/src/auth/auth-request.c Sun Mar 31 17:40:12 2013 +0300 @@ -1242,6 +1242,22 @@ return TRUE; } +static void +auth_request_userdb_userdb_import(struct auth_request *request, + const char *args, const char *default_scheme) +{ + const char *key, *value, *const *arg = t_strsplit(args, "\t"); + + for (; *arg != NULL; arg++) { + value = strchr(*arg, '='); + if (value == NULL) + key = *arg; + else + key = t_strdup_until(*arg, value++); + auth_request_set_field(request, key, value, default_scheme); + } +} + void auth_request_set_field(struct auth_request *request, const char *name, const char *value, const char *default_scheme) @@ -1287,6 +1303,11 @@ auth_request_validate_networks(request, value); } else if (strncmp(name, "userdb_", 7) == 0) { /* for prefetch userdb */ + if (strcmp(name, "userdb_userdb_import") == 0) { + auth_request_userdb_userdb_import(request, value, + default_scheme); + return; + } if (request->userdb_reply == NULL) auth_request_init_userdb_reply(request); auth_request_set_userdb_field(request, name + 7, value); From dovecot at dovecot.org Sun Mar 31 17:44:47 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 31 Mar 2013 17:44:47 +0300 Subject: dovecot-2.1: auth: Renamed userdb_userdb_import to passdb_import... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/963c6f616aa4 changeset: 14942:963c6f616aa4 user: Timo Sirainen date: Sun Mar 31 17:44:34 2013 +0300 description: auth: Renamed userdb_userdb_import to passdb_import, since that's what it really is. diffstat: src/auth/auth-request.c | 12 +++++------- 1 files changed, 5 insertions(+), 7 deletions(-) diffs (31 lines): diff -r cd919c490ea6 -r 963c6f616aa4 src/auth/auth-request.c --- a/src/auth/auth-request.c Sun Mar 31 17:40:12 2013 +0300 +++ b/src/auth/auth-request.c Sun Mar 31 17:44:34 2013 +0300 @@ -1243,8 +1243,8 @@ } static void -auth_request_userdb_userdb_import(struct auth_request *request, - const char *args, const char *default_scheme) +auth_request_passdb_import(struct auth_request *request, + const char *args, const char *default_scheme) { const char *key, *value, *const *arg = t_strsplit(args, "\t"); @@ -1301,13 +1301,11 @@ request->passdb_password = NULL; } else if (strcmp(name, "allow_nets") == 0) { auth_request_validate_networks(request, value); + } else if (strcmp(name, "passdb_import") == 0) { + auth_request_passdb_import(request, value, default_scheme); + return; } else if (strncmp(name, "userdb_", 7) == 0) { /* for prefetch userdb */ - if (strcmp(name, "userdb_userdb_import") == 0) { - auth_request_userdb_userdb_import(request, value, - default_scheme); - return; - } if (request->userdb_reply == NULL) auth_request_init_userdb_reply(request); auth_request_set_userdb_field(request, name + 7, value); From dovecot at dovecot.org Sun Mar 31 18:04:17 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 31 Mar 2013 18:04:17 +0300 Subject: dovecot-2.1: auth: Fixed passdb_import not to crash when =value ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/00de06c6cc21 changeset: 14943:00de06c6cc21 user: Timo Sirainen date: Sun Mar 31 17:47:52 2013 +0300 description: auth: Fixed passdb_import not to crash when =value isn't given. diffstat: src/auth/auth-request.c | 12 +++--------- 1 files changed, 3 insertions(+), 9 deletions(-) diffs (23 lines): diff -r 963c6f616aa4 -r 00de06c6cc21 src/auth/auth-request.c --- a/src/auth/auth-request.c Sun Mar 31 17:44:34 2013 +0300 +++ b/src/auth/auth-request.c Sun Mar 31 17:47:52 2013 +0300 @@ -1246,16 +1246,10 @@ auth_request_passdb_import(struct auth_request *request, const char *args, const char *default_scheme) { - const char *key, *value, *const *arg = t_strsplit(args, "\t"); + const char *const *arg; - for (; *arg != NULL; arg++) { - value = strchr(*arg, '='); - if (value == NULL) - key = *arg; - else - key = t_strdup_until(*arg, value++); - auth_request_set_field(request, key, value, default_scheme); - } + for (arg = t_strsplit(args, "\t"); *arg != NULL; arg++) + auth_request_set_field_keyvalue(request, *arg, default_scheme); } void auth_request_set_field(struct auth_request *request, From dovecot at dovecot.org Sun Mar 31 18:04:17 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 31 Mar 2013 18:04:17 +0300 Subject: dovecot-2.1: auth: Implemented userdb_import and userdb_userdb_i... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/78eb04213251 changeset: 14944:78eb04213251 user: Timo Sirainen date: Sun Mar 31 18:03:50 2013 +0300 description: auth: Implemented userdb_import and userdb_userdb_import fields. diffstat: src/auth/auth-request.c | 42 +++++++++++++++++++++++++++++++++++------- 1 files changed, 35 insertions(+), 7 deletions(-) diffs (78 lines): diff -r 00de06c6cc21 -r 78eb04213251 src/auth/auth-request.c --- a/src/auth/auth-request.c Sun Mar 31 17:47:52 2013 +0300 +++ b/src/auth/auth-request.c Sun Mar 31 18:03:50 2013 +0300 @@ -1243,13 +1243,15 @@ } static void -auth_request_passdb_import(struct auth_request *request, - const char *args, const char *default_scheme) +auth_request_passdb_import(struct auth_request *request, const char *args, + const char *key_prefix, const char *default_scheme) { - const char *const *arg; + const char *const *arg, *field; - for (arg = t_strsplit(args, "\t"); *arg != NULL; arg++) - auth_request_set_field_keyvalue(request, *arg, default_scheme); + for (arg = t_strsplit(args, "\t"); *arg != NULL; arg++) { + field = t_strconcat(key_prefix, *arg, NULL); + auth_request_set_field_keyvalue(request, field, default_scheme); + } } void auth_request_set_field(struct auth_request *request, @@ -1296,10 +1298,18 @@ } else if (strcmp(name, "allow_nets") == 0) { auth_request_validate_networks(request, value); } else if (strcmp(name, "passdb_import") == 0) { - auth_request_passdb_import(request, value, default_scheme); + auth_request_passdb_import(request, value, "", default_scheme); return; } else if (strncmp(name, "userdb_", 7) == 0) { /* for prefetch userdb */ + if (strcmp(name, "userdb_userdb_import") == 0) { + /* we need can't put the whole userdb_userdb_import + value to extra_cache_fields or it doesn't work + properly. so handle this explicitly. */ + auth_request_passdb_import(request, value, + "userdb_", default_scheme); + return; + } if (request->userdb_reply == NULL) auth_request_init_userdb_reply(request); auth_request_set_userdb_field(request, name + 7, value); @@ -1380,6 +1390,24 @@ } } +static void +auth_request_userdb_import(struct auth_request *request, const char *args) +{ + const char *key, *value, *const *arg; + + for (arg = t_strsplit(args, "\t"); *arg != NULL; arg++) { + value = strchr(*arg, '='); + if (value == NULL) { + key = *arg; + value = ""; + } else { + key = t_strdup_until(*arg, value); + value++; + } + auth_request_set_userdb_field(request, key, value); + } +} + void auth_request_set_userdb_field(struct auth_request *request, const char *name, const char *value) { @@ -1409,7 +1437,7 @@ auth_request_set_uidgid_file(request, value); return; } else if (strcmp(name, "userdb_import") == 0) { - auth_stream_reply_import(request->userdb_reply, value); + auth_request_userdb_import(request, value); return; } else if (strcmp(name, "system_user") == 0) { /* FIXME: the system_user is for backwards compatibility */ From dovecot at dovecot.org Sun Mar 31 18:15:13 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 31 Mar 2013 18:15:13 +0300 Subject: dovecot-2.2: auth: nodelay and nopassword fields weren't handled... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/37cd62516b37 changeset: 16131:37cd62516b37 user: Timo Sirainen date: Sun Mar 31 18:15:00 2013 +0300 description: auth: nodelay and nopassword fields weren't handled correctly. diffstat: src/auth/auth-request.c | 18 +++++++++--------- 1 files changed, 9 insertions(+), 9 deletions(-) diffs (35 lines): diff -r 9a8119326bd0 -r 37cd62516b37 src/auth/auth-request.c --- a/src/auth/auth-request.c Sun Mar 31 17:25:10 2013 +0300 +++ b/src/auth/auth-request.c Sun Mar 31 18:15:00 2013 +0300 @@ -1326,8 +1326,13 @@ if (auth_request_try_update_username(request, name, value)) { /* don't change the original value so it gets saved correctly to cache. */ - } else if (strcmp(name, "nodelay") == 0) { - /* don't delay replying to client of the failure */ + } else if (strcmp(name, "allow_nets") == 0) { + auth_request_validate_networks(request, value); + } else if (strncmp(name, "userdb_", 7) == 0) { + /* for prefetch userdb */ + if (request->userdb_reply == NULL) + auth_request_init_userdb_reply(request); + auth_request_set_userdb_field(request, name + 7, value); } else if (strcmp(name, "nopassword") == 0) { /* NULL password - anything goes */ const char *password = request->passdb_password; @@ -1343,13 +1348,8 @@ } } request->passdb_password = NULL; - } else if (strcmp(name, "allow_nets") == 0) { - auth_request_validate_networks(request, value); - } else if (strncmp(name, "userdb_", 7) == 0) { - /* for prefetch userdb */ - if (request->userdb_reply == NULL) - auth_request_init_userdb_reply(request); - auth_request_set_userdb_field(request, name + 7, value); + auth_fields_add(request->extra_fields, name, value, 0); + return; } else { /* these fields are returned to client */ auth_fields_add(request->extra_fields, name, value, 0); From dovecot at dovecot.org Sun Mar 31 18:25:02 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 31 Mar 2013 18:25:02 +0300 Subject: dovecot-2.2: dsync: If remote doesn't send some mails, don't exi... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0eef38d78069 changeset: 16132:0eef38d78069 user: Timo Sirainen date: Sun Mar 31 18:24:54 2013 +0300 description: dsync: If remote doesn't send some mails, don't exit with code 0. diffstat: src/doveadm/dsync/dsync-mailbox-import.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (19 lines): diff -r 37cd62516b37 -r 0eef38d78069 src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Sun Mar 31 18:15:00 2013 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Sun Mar 31 18:24:54 2013 +0300 @@ -2156,6 +2156,7 @@ i_error("Mailbox %s: Remote didn't send mail GUID=%s (UID=%u)", mailbox_get_vname(importer->box), mail->guid, mail->remote_uid); + importer->failed = TRUE; } } hash_table_iterate_deinit(&iter); @@ -2177,6 +2178,7 @@ i_error("Mailbox %s: Remote didn't send mail UID=%u", mailbox_get_vname(importer->box), mail->remote_uid); + importer->failed = TRUE; } } hash_table_iterate_deinit(&iter); From dovecot at dovecot.org Sun Mar 31 18:35:26 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 31 Mar 2013 18:35:26 +0300 Subject: dovecot-2.2: dsync: Don't crash if second user initialization fa... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/85e619b556ee changeset: 16133:85e619b556ee user: Timo Sirainen date: Sun Mar 31 18:35:13 2013 +0300 description: dsync: Don't crash if second user initialization fails. diffstat: src/doveadm/dsync/doveadm-dsync.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diffs (11 lines): diff -r 0eef38d78069 -r 85e619b556ee src/doveadm/dsync/doveadm-dsync.c --- a/src/doveadm/dsync/doveadm-dsync.c Sun Mar 31 18:24:54 2013 +0300 +++ b/src/doveadm/dsync/doveadm-dsync.c Sun Mar 31 18:35:13 2013 +0300 @@ -317,7 +317,6 @@ ctx->ctx.cur_service_user, &user2); if (ret < 0) { ctx->ctx.exit_code = ret == -1 ? EX_TEMPFAIL : EX_CONFIG; - mail_user_unref(&user2); return -1; } user2->admin = TRUE; From dovecot at dovecot.org Sun Mar 31 18:44:59 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 31 Mar 2013 18:44:59 +0300 Subject: dovecot-2.2: dsync: Fixed syncing without GUIDs. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/800836bd8f2e changeset: 16134:800836bd8f2e user: Timo Sirainen date: Sun Mar 31 18:43:13 2013 +0300 description: dsync: Fixed syncing without GUIDs. diffstat: src/doveadm/dsync/dsync-mailbox-export.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 85e619b556ee -r 800836bd8f2e src/doveadm/dsync/dsync-mailbox-export.c --- a/src/doveadm/dsync/dsync-mailbox-export.c Sun Mar 31 18:35:13 2013 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-export.c Sun Mar 31 18:43:13 2013 +0300 @@ -691,7 +691,7 @@ range = array_get(&exporter->requested_uids, &count); for (i = 0; i < count; i++) { mailbox_get_seq_range(exporter->box, - range->seq1, range->seq2, + range[i].seq1, range[i].seq2, &seq1, &seq2); seq_range_array_add_range(&sarg->value.seqset, seq1, seq2); From dovecot at dovecot.org Sun Mar 31 19:02:44 2013 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 31 Mar 2013 19:02:44 +0300 Subject: dovecot-2.2: quota: Added more debug logs about quota_grace Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c75b26e1d17f changeset: 16135:c75b26e1d17f user: Timo Sirainen date: Sun Mar 31 19:02:32 2013 +0300 description: quota: Added more debug logs about quota_grace diffstat: src/plugins/quota/quota-private.h | 1 + src/plugins/quota/quota.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 0 deletions(-) diffs (50 lines): diff -r 800836bd8f2e -r c75b26e1d17f src/plugins/quota/quota-private.h --- a/src/plugins/quota/quota-private.h Sun Mar 31 18:43:13 2013 +0300 +++ b/src/plugins/quota/quota-private.h Sun Mar 31 19:02:32 2013 +0300 @@ -26,6 +26,7 @@ const char *quota_exceeded_msg; unsigned int debug:1; + unsigned int initialized:1; }; struct quota_rule { diff -r 800836bd8f2e -r c75b26e1d17f src/plugins/quota/quota.c --- a/src/plugins/quota/quota.c Sun Mar 31 18:43:13 2013 +0300 +++ b/src/plugins/quota/quota.c Sun Mar 31 19:02:32 2013 +0300 @@ -227,6 +227,8 @@ pool_unref(&pool); return 0; } + + quota_set->initialized = TRUE; *set_r = quota_set; return 1; } @@ -454,6 +456,13 @@ quota_rule_recalculate_relative_rules(&root_set->grace_rule, bytes_limit, 0); root_set->last_mail_max_extra_bytes = root_set->grace_rule.bytes_limit; + + if (root_set->set->debug && root_set->set->initialized) { + i_debug("Quota root %s: Recalculated relative rules with " + "bytes=%lld count=%lld. Now grace=%llu", root_set->name, + (long long)bytes_limit, (long long)count_limit, + (unsigned long long)root_set->last_mail_max_extra_bytes); + } } static int @@ -632,6 +641,12 @@ quota_rule_recalculate_relative_rules(&root_set->grace_rule, root_set->default_rule.bytes_limit, 0); root_set->last_mail_max_extra_bytes = root_set->grace_rule.bytes_limit; + if (root_set->set->debug) { + i_debug("Quota grace: root=%s bytes=%lld%s", + root_set->name, (long long)root_set->grace_rule.bytes_limit, + root_set->grace_rule.bytes_percent == 0 ? "" : + t_strdup_printf(" (%u%%)", root_set->grace_rule.bytes_percent)); + } return 0; }