From pigeonhole at rename-it.nl Thu Jan 2 00:59:44 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Wed, 01 Jan 2014 23:59:44 +0100 Subject: dovecot-2.2-pigeonhole: Updated copyright notices to include the... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/32beba3bfd8d changeset: 1836:32beba3bfd8d user: Stephan Bosch date: Wed Jan 01 23:58:16 2014 +0100 description: Updated copyright notices to include the year 2014. diffstat: doc/man/pigeonhole.7.in | 4 ++-- doc/man/sieve-dump.1.in | 4 ++-- doc/man/sieve-filter.1.in | 4 ++-- doc/man/sieve-test.1.in | 4 ++-- doc/man/sievec.1.in | 4 ++-- src/lib-managesieve/managesieve-arg.c | 2 +- src/lib-managesieve/managesieve-arg.h | 2 +- src/lib-managesieve/managesieve-parser.c | 2 +- src/lib-managesieve/managesieve-parser.h | 2 +- src/lib-managesieve/managesieve-quote.c | 2 +- src/lib-managesieve/managesieve-quote.h | 2 +- src/lib-sieve-tool/mail-raw.c | 2 +- src/lib-sieve-tool/mail-raw.h | 2 +- src/lib-sieve-tool/sieve-tool.c | 2 +- src/lib-sieve-tool/sieve-tool.h | 2 +- src/lib-sieve/cmd-discard.c | 2 +- src/lib-sieve/cmd-if.c | 2 +- src/lib-sieve/cmd-keep.c | 2 +- src/lib-sieve/cmd-redirect.c | 2 +- src/lib-sieve/cmd-require.c | 2 +- src/lib-sieve/cmd-stop.c | 2 +- src/lib-sieve/cmp-i-ascii-casemap.c | 2 +- src/lib-sieve/cmp-i-octet.c | 2 +- src/lib-sieve/ext-encoded-character.c | 2 +- src/lib-sieve/ext-envelope.c | 2 +- src/lib-sieve/ext-fileinto.c | 2 +- src/lib-sieve/ext-reject.c | 2 +- src/lib-sieve/mcht-contains.c | 2 +- src/lib-sieve/mcht-is.c | 2 +- src/lib-sieve/mcht-matches.c | 2 +- src/lib-sieve/plugins/body/ext-body-common.c | 2 +- src/lib-sieve/plugins/body/ext-body-common.h | 2 +- src/lib-sieve/plugins/body/ext-body.c | 2 +- src/lib-sieve/plugins/body/tst-body.c | 2 +- src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c | 2 +- src/lib-sieve/plugins/copy/ext-copy.c | 2 +- src/lib-sieve/plugins/copy/sieve-ext-copy.h | 2 +- src/lib-sieve/plugins/date/ext-date-common.c | 2 +- src/lib-sieve/plugins/date/ext-date-common.h | 2 +- src/lib-sieve/plugins/date/ext-date.c | 2 +- src/lib-sieve/plugins/date/tst-date.c | 2 +- src/lib-sieve/plugins/editheader/cmd-addheader.c | 2 +- src/lib-sieve/plugins/editheader/cmd-deleteheader.c | 2 +- src/lib-sieve/plugins/editheader/ext-editheader-common.c | 2 +- src/lib-sieve/plugins/editheader/ext-editheader-common.h | 2 +- src/lib-sieve/plugins/editheader/ext-editheader-limits.h | 2 +- src/lib-sieve/plugins/editheader/ext-editheader.c | 2 +- src/lib-sieve/plugins/enotify/cmd-notify.c | 2 +- src/lib-sieve/plugins/enotify/ext-enotify-common.c | 2 +- src/lib-sieve/plugins/enotify/ext-enotify-common.h | 2 +- src/lib-sieve/plugins/enotify/ext-enotify-limits.h | 2 +- src/lib-sieve/plugins/enotify/ext-enotify.c | 2 +- src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c | 2 +- src/lib-sieve/plugins/enotify/mailto/uri-mailto.c | 2 +- src/lib-sieve/plugins/enotify/mailto/uri-mailto.h | 2 +- src/lib-sieve/plugins/enotify/sieve-ext-enotify.h | 2 +- src/lib-sieve/plugins/enotify/tst-notify-method-capability.c | 2 +- src/lib-sieve/plugins/enotify/tst-valid-notify-method.c | 2 +- src/lib-sieve/plugins/enotify/vmodf-encodeurl.c | 2 +- src/lib-sieve/plugins/environment/ext-environment-common.c | 2 +- src/lib-sieve/plugins/environment/ext-environment-common.h | 2 +- src/lib-sieve/plugins/environment/ext-environment.c | 2 +- src/lib-sieve/plugins/environment/sieve-ext-environment.h | 2 +- src/lib-sieve/plugins/environment/tst-environment.c | 2 +- src/lib-sieve/plugins/ihave/cmd-error.c | 2 +- src/lib-sieve/plugins/ihave/ext-ihave-binary.c | 2 +- src/lib-sieve/plugins/ihave/ext-ihave-binary.h | 2 +- src/lib-sieve/plugins/ihave/ext-ihave-common.c | 2 +- src/lib-sieve/plugins/ihave/ext-ihave-common.h | 2 +- src/lib-sieve/plugins/ihave/ext-ihave.c | 2 +- src/lib-sieve/plugins/ihave/tst-ihave.c | 2 +- src/lib-sieve/plugins/imap4flags/cmd-flag.c | 2 +- src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c | 2 +- src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h | 2 +- src/lib-sieve/plugins/imap4flags/ext-imap4flags.c | 2 +- src/lib-sieve/plugins/imap4flags/ext-imapflags.c | 2 +- src/lib-sieve/plugins/imap4flags/tag-flags.c | 2 +- src/lib-sieve/plugins/imap4flags/tst-hasflag.c | 2 +- src/lib-sieve/plugins/include/cmd-global.c | 2 +- src/lib-sieve/plugins/include/cmd-include.c | 2 +- src/lib-sieve/plugins/include/cmd-return.c | 2 +- src/lib-sieve/plugins/include/ext-include-binary.c | 2 +- src/lib-sieve/plugins/include/ext-include-binary.h | 2 +- src/lib-sieve/plugins/include/ext-include-common.c | 2 +- src/lib-sieve/plugins/include/ext-include-common.h | 2 +- src/lib-sieve/plugins/include/ext-include-limits.h | 2 +- src/lib-sieve/plugins/include/ext-include-variables.c | 2 +- src/lib-sieve/plugins/include/ext-include-variables.h | 2 +- src/lib-sieve/plugins/include/ext-include.c | 2 +- src/lib-sieve/plugins/mailbox/ext-mailbox-common.h | 2 +- src/lib-sieve/plugins/mailbox/ext-mailbox.c | 2 +- src/lib-sieve/plugins/mailbox/tag-mailbox-create.c | 2 +- src/lib-sieve/plugins/mailbox/tst-mailboxexists.c | 2 +- src/lib-sieve/plugins/metadata/ext-metadata-common.h | 2 +- src/lib-sieve/plugins/metadata/ext-metadata.c | 2 +- src/lib-sieve/plugins/metadata/tst-metadata.c | 2 +- src/lib-sieve/plugins/metadata/tst-metadataexists.c | 2 +- src/lib-sieve/plugins/notify/cmd-denotify.c | 2 +- src/lib-sieve/plugins/notify/cmd-notify.c | 2 +- src/lib-sieve/plugins/notify/ext-notify-common.c | 2 +- src/lib-sieve/plugins/notify/ext-notify-common.h | 2 +- src/lib-sieve/plugins/notify/ext-notify-limits.h | 2 +- src/lib-sieve/plugins/notify/ext-notify.c | 2 +- src/lib-sieve/plugins/regex/ext-regex-common.c | 2 +- src/lib-sieve/plugins/regex/ext-regex-common.h | 2 +- src/lib-sieve/plugins/regex/ext-regex.c | 2 +- src/lib-sieve/plugins/regex/mcht-regex.c | 2 +- src/lib-sieve/plugins/relational/ext-relational-common.c | 2 +- src/lib-sieve/plugins/relational/ext-relational-common.h | 2 +- src/lib-sieve/plugins/relational/ext-relational.c | 2 +- src/lib-sieve/plugins/relational/mcht-count.c | 2 +- src/lib-sieve/plugins/relational/mcht-value.c | 2 +- src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c | 2 +- src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.h | 2 +- src/lib-sieve/plugins/spamvirustest/ext-spamvirustest.c | 2 +- src/lib-sieve/plugins/spamvirustest/tst-spamvirustest.c | 2 +- src/lib-sieve/plugins/subaddress/ext-subaddress.c | 2 +- src/lib-sieve/plugins/vacation/cmd-vacation.c | 2 +- src/lib-sieve/plugins/vacation/ext-vacation-common.c | 2 +- src/lib-sieve/plugins/vacation/ext-vacation-common.h | 2 +- src/lib-sieve/plugins/vacation/ext-vacation-seconds.c | 2 +- src/lib-sieve/plugins/vacation/ext-vacation.c | 2 +- src/lib-sieve/plugins/variables/cmd-set.c | 2 +- src/lib-sieve/plugins/variables/ext-variables-arguments.c | 2 +- src/lib-sieve/plugins/variables/ext-variables-arguments.h | 2 +- src/lib-sieve/plugins/variables/ext-variables-common.c | 2 +- src/lib-sieve/plugins/variables/ext-variables-common.h | 2 +- src/lib-sieve/plugins/variables/ext-variables-dump.c | 2 +- src/lib-sieve/plugins/variables/ext-variables-dump.h | 2 +- src/lib-sieve/plugins/variables/ext-variables-limits.h | 2 +- src/lib-sieve/plugins/variables/ext-variables-modifiers.c | 2 +- src/lib-sieve/plugins/variables/ext-variables-modifiers.h | 2 +- src/lib-sieve/plugins/variables/ext-variables-name.c | 2 +- src/lib-sieve/plugins/variables/ext-variables-name.h | 2 +- src/lib-sieve/plugins/variables/ext-variables-namespaces.c | 2 +- src/lib-sieve/plugins/variables/ext-variables-namespaces.h | 2 +- src/lib-sieve/plugins/variables/ext-variables-operands.c | 2 +- src/lib-sieve/plugins/variables/ext-variables-operands.h | 2 +- src/lib-sieve/plugins/variables/ext-variables.c | 2 +- src/lib-sieve/plugins/variables/sieve-ext-variables.h | 2 +- src/lib-sieve/plugins/variables/tst-string.c | 2 +- src/lib-sieve/plugins/vnd.dovecot/debug/cmd-debug-log.c | 2 +- src/lib-sieve/plugins/vnd.dovecot/debug/ext-debug-common.h | 2 +- src/lib-sieve/plugins/vnd.dovecot/debug/ext-debug.c | 2 +- src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate-common.c | 2 +- src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate-common.h | 2 +- src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate.c | 2 +- src/lib-sieve/plugins/vnd.dovecot/duplicate/tst-duplicate.c | 2 +- src/lib-sieve/sieve-actions.c | 2 +- src/lib-sieve/sieve-actions.h | 2 +- src/lib-sieve/sieve-address-parts.c | 2 +- src/lib-sieve/sieve-address-parts.h | 2 +- src/lib-sieve/sieve-address.c | 2 +- src/lib-sieve/sieve-address.h | 2 +- src/lib-sieve/sieve-ast.c | 2 +- src/lib-sieve/sieve-ast.h | 2 +- src/lib-sieve/sieve-binary-code.c | 2 +- src/lib-sieve/sieve-binary-debug.c | 2 +- src/lib-sieve/sieve-binary-dumper.c | 2 +- src/lib-sieve/sieve-binary-dumper.h | 2 +- src/lib-sieve/sieve-binary-file.c | 2 +- src/lib-sieve/sieve-binary-private.h | 2 +- src/lib-sieve/sieve-binary.c | 2 +- src/lib-sieve/sieve-binary.h | 2 +- src/lib-sieve/sieve-code-dumper.c | 2 +- src/lib-sieve/sieve-code-dumper.h | 2 +- src/lib-sieve/sieve-code.c | 2 +- src/lib-sieve/sieve-code.h | 2 +- src/lib-sieve/sieve-commands.c | 2 +- src/lib-sieve/sieve-commands.h | 2 +- src/lib-sieve/sieve-common.h | 2 +- src/lib-sieve/sieve-comparators.c | 2 +- src/lib-sieve/sieve-comparators.h | 2 +- src/lib-sieve/sieve-config.h | 2 +- src/lib-sieve/sieve-dump.h | 2 +- src/lib-sieve/sieve-error-private.h | 2 +- src/lib-sieve/sieve-error.c | 2 +- src/lib-sieve/sieve-error.h | 2 +- src/lib-sieve/sieve-extensions.c | 2 +- src/lib-sieve/sieve-extensions.h | 2 +- src/lib-sieve/sieve-generator.c | 2 +- src/lib-sieve/sieve-generator.h | 2 +- src/lib-sieve/sieve-interpreter.c | 2 +- src/lib-sieve/sieve-interpreter.h | 2 +- src/lib-sieve/sieve-lexer.c | 2 +- src/lib-sieve/sieve-lexer.h | 2 +- src/lib-sieve/sieve-limits.h | 2 +- src/lib-sieve/sieve-match-types.c | 2 +- src/lib-sieve/sieve-match-types.h | 2 +- src/lib-sieve/sieve-match.c | 2 +- src/lib-sieve/sieve-match.h | 2 +- src/lib-sieve/sieve-message.c | 2 +- src/lib-sieve/sieve-message.h | 2 +- src/lib-sieve/sieve-objects.c | 2 +- src/lib-sieve/sieve-objects.h | 2 +- src/lib-sieve/sieve-parser.c | 2 +- src/lib-sieve/sieve-parser.h | 2 +- src/lib-sieve/sieve-plugins.c | 2 +- src/lib-sieve/sieve-plugins.h | 2 +- src/lib-sieve/sieve-result.c | 2 +- src/lib-sieve/sieve-result.h | 2 +- src/lib-sieve/sieve-runtime-trace.c | 2 +- src/lib-sieve/sieve-runtime-trace.h | 2 +- src/lib-sieve/sieve-runtime.h | 2 +- src/lib-sieve/sieve-script-dict.c | 2 +- src/lib-sieve/sieve-script-file.c | 2 +- src/lib-sieve/sieve-script-file.h | 2 +- src/lib-sieve/sieve-script-private.h | 2 +- src/lib-sieve/sieve-script.c | 2 +- src/lib-sieve/sieve-script.h | 2 +- src/lib-sieve/sieve-settings.c | 2 +- src/lib-sieve/sieve-settings.h | 2 +- src/lib-sieve/sieve-smtp.c | 2 +- src/lib-sieve/sieve-smtp.h | 2 +- src/lib-sieve/sieve-stringlist.c | 2 +- src/lib-sieve/sieve-stringlist.h | 2 +- src/lib-sieve/sieve-types.h | 2 +- src/lib-sieve/sieve-validator.c | 2 +- src/lib-sieve/sieve-validator.h | 2 +- src/lib-sieve/sieve.c | 2 +- src/lib-sieve/sieve.h | 2 +- src/lib-sieve/tst-address.c | 2 +- src/lib-sieve/tst-allof.c | 2 +- src/lib-sieve/tst-anyof.c | 2 +- src/lib-sieve/tst-exists.c | 2 +- src/lib-sieve/tst-header.c | 2 +- src/lib-sieve/tst-not.c | 2 +- src/lib-sieve/tst-size.c | 2 +- src/lib-sieve/tst-truefalse.c | 2 +- src/lib-sieve/util/edit-mail.c | 2 +- src/lib-sieve/util/edit-mail.h | 2 +- src/lib-sieve/util/program-client-local.c | 2 +- src/lib-sieve/util/program-client-private.h | 2 +- src/lib-sieve/util/program-client-remote.c | 2 +- src/lib-sieve/util/program-client.c | 2 +- src/lib-sieve/util/program-client.h | 2 +- src/lib-sieve/util/rfc2822.c | 2 +- src/lib-sieve/util/rfc2822.h | 2 +- src/lib-sievestorage/sieve-storage-list.c | 2 +- src/lib-sievestorage/sieve-storage-list.h | 2 +- src/lib-sievestorage/sieve-storage-private.h | 2 +- src/lib-sievestorage/sieve-storage-quota.c | 2 +- src/lib-sievestorage/sieve-storage-quota.h | 2 +- src/lib-sievestorage/sieve-storage-save.c | 2 +- src/lib-sievestorage/sieve-storage-save.h | 2 +- src/lib-sievestorage/sieve-storage-script.c | 2 +- src/lib-sievestorage/sieve-storage-script.h | 2 +- src/lib-sievestorage/sieve-storage.c | 2 +- src/lib-sievestorage/sieve-storage.h | 2 +- src/managesieve-login/client-authenticate.c | 2 +- src/managesieve-login/client-authenticate.h | 2 +- src/managesieve-login/client.c | 2 +- src/managesieve-login/client.h | 2 +- src/managesieve-login/managesieve-login-settings-plugin.c | 2 +- src/managesieve-login/managesieve-login-settings-plugin.h | 2 +- src/managesieve-login/managesieve-login-settings.c | 2 +- src/managesieve-login/managesieve-login-settings.h | 2 +- src/managesieve-login/managesieve-proxy.c | 2 +- src/managesieve-login/managesieve-proxy.h | 2 +- src/managesieve/cmd-capability.c | 2 +- src/managesieve/cmd-deletescript.c | 2 +- src/managesieve/cmd-getscript.c | 2 +- src/managesieve/cmd-havespace.c | 2 +- src/managesieve/cmd-listscripts.c | 2 +- src/managesieve/cmd-logout.c | 2 +- src/managesieve/cmd-noop.c | 2 +- src/managesieve/cmd-putscript.c | 2 +- src/managesieve/cmd-renamescript.c | 2 +- src/managesieve/cmd-setactive.c | 2 +- src/managesieve/main.c | 2 +- src/managesieve/managesieve-capabilities.c | 2 +- src/managesieve/managesieve-capabilities.h | 2 +- src/managesieve/managesieve-client.c | 2 +- src/managesieve/managesieve-client.h | 2 +- src/managesieve/managesieve-commands.c | 2 +- src/managesieve/managesieve-commands.h | 2 +- src/managesieve/managesieve-common.h | 2 +- src/managesieve/managesieve-quota.c | 2 +- src/managesieve/managesieve-quota.h | 2 +- src/managesieve/managesieve-settings.c | 2 +- src/managesieve/managesieve-settings.h | 2 +- src/plugins/doveadm-sieve/doveadm-sieve-plugin.c | 2 +- src/plugins/lda-sieve/lda-sieve-plugin.c | 2 +- src/plugins/lda-sieve/lda-sieve-plugin.h | 2 +- src/plugins/sieve-extprograms/cmd-execute.c | 2 +- src/plugins/sieve-extprograms/cmd-filter.c | 2 +- src/plugins/sieve-extprograms/cmd-pipe.c | 2 +- src/plugins/sieve-extprograms/ext-execute.c | 2 +- src/plugins/sieve-extprograms/ext-filter.c | 2 +- src/plugins/sieve-extprograms/ext-pipe.c | 2 +- src/plugins/sieve-extprograms/sieve-extprograms-common.c | 2 +- src/plugins/sieve-extprograms/sieve-extprograms-common.h | 2 +- src/plugins/sieve-extprograms/sieve-extprograms-plugin.c | 2 +- src/plugins/sieve-extprograms/sieve-extprograms-plugin.h | 2 +- src/sieve-tools/sieve-dump.c | 2 +- src/sieve-tools/sieve-filter.c | 2 +- src/sieve-tools/sieve-test.c | 2 +- src/sieve-tools/sievec.c | 2 +- src/testsuite/cmd-test-binary.c | 2 +- src/testsuite/cmd-test-config.c | 2 +- src/testsuite/cmd-test-fail.c | 2 +- src/testsuite/cmd-test-mailbox.c | 2 +- src/testsuite/cmd-test-message.c | 2 +- src/testsuite/cmd-test-result.c | 2 +- src/testsuite/cmd-test-set.c | 2 +- src/testsuite/cmd-test.c | 2 +- src/testsuite/ext-testsuite.c | 2 +- src/testsuite/testsuite-arguments.c | 2 +- src/testsuite/testsuite-arguments.h | 2 +- src/testsuite/testsuite-binary.c | 2 +- src/testsuite/testsuite-binary.h | 2 +- src/testsuite/testsuite-common.c | 2 +- src/testsuite/testsuite-common.h | 2 +- src/testsuite/testsuite-log.c | 2 +- src/testsuite/testsuite-log.h | 2 +- src/testsuite/testsuite-mailstore.c | 2 +- src/testsuite/testsuite-mailstore.h | 2 +- src/testsuite/testsuite-message.c | 2 +- src/testsuite/testsuite-message.h | 2 +- src/testsuite/testsuite-objects.c | 2 +- src/testsuite/testsuite-objects.h | 2 +- src/testsuite/testsuite-result.c | 2 +- src/testsuite/testsuite-result.h | 2 +- src/testsuite/testsuite-script.c | 2 +- src/testsuite/testsuite-script.h | 2 +- src/testsuite/testsuite-settings.c | 2 +- src/testsuite/testsuite-settings.h | 2 +- src/testsuite/testsuite-smtp.c | 2 +- src/testsuite/testsuite-smtp.h | 2 +- src/testsuite/testsuite-substitutions.c | 2 +- src/testsuite/testsuite-substitutions.h | 2 +- src/testsuite/testsuite-variables.c | 2 +- src/testsuite/testsuite-variables.h | 2 +- src/testsuite/testsuite.c | 2 +- src/testsuite/tst-test-error.c | 2 +- src/testsuite/tst-test-multiscript.c | 2 +- src/testsuite/tst-test-result-action.c | 2 +- src/testsuite/tst-test-result-execute.c | 2 +- src/testsuite/tst-test-script-compile.c | 2 +- src/testsuite/tst-test-script-run.c | 2 +- 340 files changed, 345 insertions(+), 345 deletions(-) diffs (truncated from 3070 to 300 lines): diff -r cab3d18a00c9 -r 32beba3bfd8d doc/man/pigeonhole.7.in --- a/doc/man/pigeonhole.7.in Mon Dec 30 17:54:23 2013 +0100 +++ b/doc/man/pigeonhole.7.in Wed Jan 01 23:58:16 2014 +0100 @@ -1,5 +1,5 @@ -.\" Copyright (c) 2010-2013 Pigeonhole authors, see the included COPYING file -.TH "PIGEONHOLE" 7 "2013-05-09" "Pigeonhole for Dovecot v2.2" "Pigeonhole" +.\" Copyright (c) 2010-2014 Pigeonhole authors, see the included COPYING file +.TH "PIGEONHOLE" 7 "2014-01-01" "Pigeonhole for Dovecot v2.2" "Pigeonhole" .\"------------------------------------------------------------------------ .SH NAME pigeonhole \- Overview of the Pigeonhole project\(aqs Sieve support for the diff -r cab3d18a00c9 -r 32beba3bfd8d doc/man/sieve-dump.1.in --- a/doc/man/sieve-dump.1.in Mon Dec 30 17:54:23 2013 +0100 +++ b/doc/man/sieve-dump.1.in Wed Jan 01 23:58:16 2014 +0100 @@ -1,5 +1,5 @@ -.\" Copyright (c) 2010-2013 Pigeonhole authors, see the included COPYING file -.TH "SIEVE\-DUMP" 1 "2013-05-09" "Pigeonhole for Dovecot v2.2" "Pigeonhole" +.\" Copyright (c) 2010-2014 Pigeonhole authors, see the included COPYING file +.TH "SIEVE\-DUMP" 1 "2014-01-01" "Pigeonhole for Dovecot v2.2" "Pigeonhole" .\"------------------------------------------------------------------------ .SH NAME sieve\-dump \- Pigeonhole\(aqs Sieve script binary dump tool diff -r cab3d18a00c9 -r 32beba3bfd8d doc/man/sieve-filter.1.in --- a/doc/man/sieve-filter.1.in Mon Dec 30 17:54:23 2013 +0100 +++ b/doc/man/sieve-filter.1.in Wed Jan 01 23:58:16 2014 +0100 @@ -1,5 +1,5 @@ -.\" Copyright (c) 2010-2013 Pigeonhole authors, see the included COPYING file -.TH "SIEVE\-FILTER" 1 "2013-05-09" "Pigeonhole for Dovecot v2.2" "Pigeonhole" +.\" Copyright (c) 2010-2014 Pigeonhole authors, see the included COPYING file +.TH "SIEVE\-FILTER" 1 "2014-01-01" "Pigeonhole for Dovecot v2.2" "Pigeonhole" .SH NAME sieve\-filter \- Pigeonhole\(aqs Sieve mailbox filter tool diff -r cab3d18a00c9 -r 32beba3bfd8d doc/man/sieve-test.1.in --- a/doc/man/sieve-test.1.in Mon Dec 30 17:54:23 2013 +0100 +++ b/doc/man/sieve-test.1.in Wed Jan 01 23:58:16 2014 +0100 @@ -1,5 +1,5 @@ -.\" Copyright (c) 2010-2013 Pigeonhole authors, see the included COPYING file -.TH "SIEVE\-TEST" 1 "2013-05-09" "Pigeonhole for Dovecot v2.2" "Pigeonhole" +.\" Copyright (c) 2010-2014 Pigeonhole authors, see the included COPYING file +.TH "SIEVE\-TEST" 1 "2014-01-01" "Pigeonhole for Dovecot v2.2" "Pigeonhole" .SH NAME sieve\-test \- Pigeonhole\(aqs Sieve script tester .\"------------------------------------------------------------------------ diff -r cab3d18a00c9 -r 32beba3bfd8d doc/man/sievec.1.in --- a/doc/man/sievec.1.in Mon Dec 30 17:54:23 2013 +0100 +++ b/doc/man/sievec.1.in Wed Jan 01 23:58:16 2014 +0100 @@ -1,5 +1,5 @@ -.\" Copyright (c) 2010-2013 Pigeonhole authors, see the included COPYING file -.TH "SIEVEC" 1 "2013-05-09" "Pigeonhole for Dovecot v2.2" "Pigeonhole" +.\" Copyright (c) 2010-2014 Pigeonhole authors, see the included COPYING file +.TH "SIEVEC" 1 "2014-01-01" "Pigeonhole for Dovecot v2.2" "Pigeonhole" .\"------------------------------------------------------------------------ .SH NAME sievec \- Pigeonhole\(aqs Sieve script compiler diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-managesieve/managesieve-arg.c --- a/src/lib-managesieve/managesieve-arg.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-managesieve/managesieve-arg.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ #include "lib.h" diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-managesieve/managesieve-arg.h --- a/src/lib-managesieve/managesieve-arg.h Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-managesieve/managesieve-arg.h Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ #ifndef __MANAGESIEVE_ARG_H diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-managesieve/managesieve-parser.c --- a/src/lib-managesieve/managesieve-parser.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-managesieve/managesieve-parser.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ #include "lib.h" diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-managesieve/managesieve-parser.h --- a/src/lib-managesieve/managesieve-parser.h Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-managesieve/managesieve-parser.h Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ #ifndef __MANAGESIEVE_PARSER_H diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-managesieve/managesieve-quote.c --- a/src/lib-managesieve/managesieve-quote.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-managesieve/managesieve-quote.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ #include "lib.h" diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-managesieve/managesieve-quote.h --- a/src/lib-managesieve/managesieve-quote.h Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-managesieve/managesieve-quote.h Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ #ifndef __IMAP_QUOTE_H diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve-tool/mail-raw.c --- a/src/lib-sieve-tool/mail-raw.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve-tool/mail-raw.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ #include "lib.h" diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve-tool/mail-raw.h --- a/src/lib-sieve-tool/mail-raw.h Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve-tool/mail-raw.h Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ #ifndef __MAIL_RAW_H diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve-tool/sieve-tool.c --- a/src/lib-sieve-tool/sieve-tool.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve-tool/sieve-tool.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ #include "lib.h" diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve-tool/sieve-tool.h --- a/src/lib-sieve-tool/sieve-tool.h Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve-tool/sieve-tool.h Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ #ifndef __SIEVE_TOOL_H diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve/cmd-discard.c --- a/src/lib-sieve/cmd-discard.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve/cmd-discard.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ #include "lib.h" diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve/cmd-if.c --- a/src/lib-sieve/cmd-if.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve/cmd-if.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ #include "sieve-common.h" diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve/cmd-keep.c --- a/src/lib-sieve/cmd-keep.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve/cmd-keep.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ #include "lib.h" diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve/cmd-redirect.c --- a/src/lib-sieve/cmd-redirect.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve/cmd-redirect.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ #include "lib.h" diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve/cmd-require.c --- a/src/lib-sieve/cmd-require.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve/cmd-require.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ #include "lib.h" diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve/cmd-stop.c --- a/src/lib-sieve/cmd-stop.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve/cmd-stop.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ #include "sieve-common.h" diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve/cmp-i-ascii-casemap.c --- a/src/lib-sieve/cmp-i-ascii-casemap.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve/cmp-i-ascii-casemap.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ /* Comparator 'i;ascii-casemap': diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve/cmp-i-octet.c --- a/src/lib-sieve/cmp-i-octet.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve/cmp-i-octet.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ /* Comparator 'i;octet': diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve/ext-encoded-character.c --- a/src/lib-sieve/ext-encoded-character.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve/ext-encoded-character.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ /* Extension encoded-character diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve/ext-envelope.c --- a/src/lib-sieve/ext-envelope.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve/ext-envelope.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ /* Extension envelope diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve/ext-fileinto.c --- a/src/lib-sieve/ext-fileinto.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve/ext-fileinto.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ /* Extension fileinto diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve/ext-reject.c --- a/src/lib-sieve/ext-reject.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve/ext-reject.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ /* Extension reject diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve/mcht-contains.c --- a/src/lib-sieve/mcht-contains.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve/mcht-contains.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ /* Match-type ':contains' diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve/mcht-is.c --- a/src/lib-sieve/mcht-is.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve/mcht-is.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ /* Match-type ':is': diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve/mcht-matches.c --- a/src/lib-sieve/mcht-matches.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve/mcht-matches.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ /* Match-type ':matches' diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve/plugins/body/ext-body-common.c --- a/src/lib-sieve/plugins/body/ext-body-common.c Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve/plugins/body/ext-body-common.c Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ #include "lib.h" diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve/plugins/body/ext-body-common.h --- a/src/lib-sieve/plugins/body/ext-body-common.h Mon Dec 30 17:54:23 2013 +0100 +++ b/src/lib-sieve/plugins/body/ext-body-common.h Wed Jan 01 23:58:16 2014 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file +/* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file */ #ifndef __EXT_BODY_COMMON_H diff -r cab3d18a00c9 -r 32beba3bfd8d src/lib-sieve/plugins/body/ext-body.c --- a/src/lib-sieve/plugins/body/ext-body.c Mon Dec 30 17:54:23 2013 +0100 From pigeonhole at rename-it.nl Sat Jan 4 03:13:52 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 04 Jan 2014 02:13:52 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve/util: program-client: Added su... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/5c3b0283524b changeset: 1837:5c3b0283524b user: Stephan Bosch date: Sat Jan 04 02:13:44 2014 +0100 description: lib-sieve/util: program-client: Added support for retrieving side-channel data through extra fds. Some programs can be instructed to output special status information to an extra fd other than stdout or stderr. Also added an option to drop stderr output from program to /dev/null. diffstat: src/lib-sieve/util/program-client-local.c | 99 ++++++++++++++++++-- src/lib-sieve/util/program-client-private.h | 15 +++- src/lib-sieve/util/program-client-remote.c | 4 +- src/lib-sieve/util/program-client.c | 128 +++++++++++++++++++++++++-- src/lib-sieve/util/program-client.h | 17 +++- 5 files changed, 236 insertions(+), 27 deletions(-) diffs (truncated from 528 to 300 lines): diff -r 32beba3bfd8d -r 5c3b0283524b src/lib-sieve/util/program-client-local.c --- a/src/lib-sieve/util/program-client-local.c Wed Jan 01 23:58:16 2014 +0100 +++ b/src/lib-sieve/util/program-client-local.c Sat Jan 04 02:13:44 2014 +0100 @@ -28,17 +28,18 @@ static void exec_child (const char *bin_path, const char *const *args, const char *const *envs, - int in_fd, int out_fd) + int in_fd, int out_fd, int *extra_fds, bool drop_stderr) { ARRAY_TYPE(const_string) exec_args; + /* Setup stdin/stdout */ + if ( in_fd < 0 ) { in_fd = open("/dev/null", O_RDONLY); if ( in_fd == -1 ) i_fatal("open(/dev/null) failed: %m"); } - if ( out_fd < 0 ) { out_fd = open("/dev/null", O_WRONLY); @@ -51,12 +52,34 @@ if ( dup2(out_fd, STDOUT_FILENO) < 0 ) i_fatal("dup2(stdout) failed: %m"); - /* Close all fds */ if ( close(in_fd) < 0 ) i_error("close(in_fd) failed: %m"); if ( (out_fd != in_fd) && close(out_fd) < 0 ) i_error("close(out_fd) failed: %m"); + /* Drop stderr if requested */ + if ( drop_stderr ) { + int err_fd = open("/dev/null", O_WRONLY); + if ( err_fd == -1 ) + i_fatal("open(/dev/null) failed: %m"); + if ( dup2(err_fd, STDERR_FILENO) < 0 ) + i_fatal("dup2(stderr) failed: %m"); + if ( close(err_fd) < 0 ) + i_error("close(err_fd) failed: %m"); + } + + /* Setup extra fds */ + if ( extra_fds != NULL ) { + for (; *extra_fds != -1; extra_fds += 2 ) { + if ( dup2(extra_fds[0], extra_fds[1]) < 0 ) + i_fatal("dup2(extra_fd=%d) failed: %m", extra_fds[1]); + if ( close(extra_fds[0]) < 0 ) + i_error("close(extra_fd=%d) failed: %m", extra_fds[1]); + } + } + + /* Compose argv */ + t_array_init(&exec_args, 16); array_append(&exec_args, &bin_path, 1); if ( args != NULL ) { @@ -65,12 +88,16 @@ } (void)array_append_space(&exec_args); + /* Setup environment */ + env_clean(); if ( envs != NULL ) { for (; *envs != NULL; envs++) env_put(*envs); } + /* Execute */ + args = array_idx(&exec_args, 0); execvp_const(args[0], args); } @@ -81,7 +108,11 @@ struct program_client_local *slclient = (struct program_client_local *) pclient; int fd[2] = { -1, -1 }; + struct program_client_extra_fd *efds = NULL; + int *parent_extra_fds = NULL, *child_extra_fds = NULL; + unsigned int xfd_count = 0, i; + /* create normal I/O fd */ if ( pclient->input != NULL || pclient->output != NULL || pclient->output_seekable ) { if ( socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0 ) { @@ -90,14 +121,46 @@ } } + /* create pipes for additional output through side-channel fds */ + if ( array_is_created(&pclient->extra_fds) ) { + int extra_fd[2]; + + efds = array_get_modifiable(&pclient->extra_fds, &xfd_count); + if ( xfd_count > 0 ) { + parent_extra_fds = t_malloc(sizeof(int) * xfd_count); + child_extra_fds = t_malloc(sizeof(int) * xfd_count * 2 + 1); + for ( i = 0; i < xfd_count; i++ ) { + if ( pipe(extra_fd) < 0 ) { + i_error("pipe() failed: %m"); + return -1; + } + parent_extra_fds[i] = extra_fd[0]; + child_extra_fds[i*2+0] = extra_fd[1]; + child_extra_fds[i*2+1] = efds[i].child_fd; + } + child_extra_fds[xfd_count*2] = -1; + } + } + + /* fork child */ if ( (slclient->pid = fork()) == (pid_t)-1 ) { i_error("fork() failed: %m"); + + /* clean up */ if ( fd[0] >= 0 && close(fd[0]) < 0 ) { i_error("close(pipe_fd[0]) failed: %m"); } if ( fd[1] >= 0 && close(fd[1]) < 0 ) { i_error("close(pipe_fd[1]) failed: %m"); } + for ( i = 0; i < xfd_count; i++ ) { + if ( close(child_extra_fds[i*2]) < 0 ) { + i_error("close(extra_fd[1]) failed: %m"); + } + if ( close(parent_extra_fds[i]) < 0 ) { + i_error("close(extra_fd[0]) failed: %m"); + } + } return -1; } @@ -109,27 +172,37 @@ if ( fd[1] >= 0 && close(fd[1]) < 0 ) { i_error("close(pipe_fd[1]) failed: %m"); } + for ( i = 0; i < xfd_count; i++ ) { + if ( close(parent_extra_fds[i]) < 0 ) + i_error("close(extra_fd[0]) failed: %m"); + } if ( array_is_created(&pclient->envs) ) envs = array_get(&pclient->envs, &count); exec_child(pclient->path, pclient->args, envs, ( pclient->input != NULL ? fd[0] : -1 ), - ( pclient->output != NULL || pclient->output_seekable ? fd[0] : -1 )); + ( pclient->output != NULL || pclient->output_seekable ? fd[0] : -1 ), + child_extra_fds, pclient->set.drop_stderr); i_unreached(); } /* parent */ - if ( fd[0] >= 0 && close(fd[0]) < 0 ) { + if ( fd[0] >= 0 && close(fd[0]) < 0 ) i_error("close(pipe_fd[0]) failed: %m"); - } - if ( fd[1] >= 0 ) { net_set_nonblock(fd[1], TRUE); pclient->fd_in = ( pclient->output != NULL || pclient->output_seekable ? fd[1] : -1 ); pclient->fd_out = ( pclient->input != NULL ? fd[1] : -1 ); } + for ( i = 0; i < xfd_count; i++ ) { + if ( close(child_extra_fds[i*2]) < 0 ) + i_error("close(extra_fd[1]) failed: %m"); + net_set_nonblock(parent_extra_fds[i], TRUE); + efds[i].parent_fd = parent_extra_fds[i]; + } + program_client_init_streams(pclient); return program_client_connected(pclient); } @@ -158,9 +231,9 @@ /* Calculate timeout */ runtime = ioloop_time - pclient->start_time; - if ( !force && pclient->set->input_idle_timeout_secs > 0 && - runtime < (time_t)pclient->set->input_idle_timeout_secs ) - timeout = pclient->set->input_idle_timeout_secs - runtime; + if ( !force && pclient->set.input_idle_timeout_secs > 0 && + runtime < (time_t)pclient->set.input_idle_timeout_secs ) + timeout = pclient->set.input_idle_timeout_secs - runtime; if ( pclient->debug ) { i_debug("waiting for program `%s' to finish after %llu seconds", @@ -169,7 +242,7 @@ /* Wait for child to exit */ force = force || - (timeout == 0 && pclient->set->input_idle_timeout_secs > 0); + (timeout == 0 && pclient->set.input_idle_timeout_secs > 0); if ( !force ) { alarm(timeout); ret = waitpid(pid, &status, 0); @@ -189,7 +262,7 @@ if ( pclient->debug ) { i_debug("program `%s' execution timed out after %llu seconds: " "sending TERM signal", pclient->path, - (unsigned long long int)pclient->set->input_idle_timeout_secs); + (unsigned long long int)pclient->set.input_idle_timeout_secs); } /* Kill child gently first */ @@ -278,7 +351,7 @@ switch ( error ) { case PROGRAM_CLIENT_ERROR_RUN_TIMEOUT: i_error("program `%s' execution timed out (> %d secs)", - pclient->path, pclient->set->input_idle_timeout_secs); + pclient->path, pclient->set.input_idle_timeout_secs); break; default: break; diff -r 32beba3bfd8d -r 5c3b0283524b src/lib-sieve/util/program-client-private.h --- a/src/lib-sieve/util/program-client-private.h Wed Jan 01 23:58:16 2014 +0100 +++ b/src/lib-sieve/util/program-client-private.h Sat Jan 04 02:13:44 2014 +0100 @@ -14,9 +14,20 @@ PROGRAM_CLIENT_ERROR_UNKNOWN }; +struct program_client_extra_fd { + struct program_client *pclient; + + int child_fd, parent_fd; + struct istream *input; + struct io *io; + + program_client_fd_callback_t *callback; + void *context; +}; + struct program_client { pool_t pool; - const struct program_client_settings *set; + struct program_client_settings set; char *path; const char **args; @@ -32,6 +43,8 @@ struct ostream *output, *program_output; char *temp_prefix; + ARRAY(struct program_client_extra_fd) extra_fds; + enum program_client_error error; int exit_code; diff -r 32beba3bfd8d -r 5c3b0283524b src/lib-sieve/util/program-client-remote.c --- a/src/lib-sieve/util/program-client-remote.c Wed Jan 01 23:58:16 2014 +0100 +++ b/src/lib-sieve/util/program-client-remote.c Sat Jan 04 02:13:44 2014 +0100 @@ -288,11 +288,11 @@ switch ( error ) { case PROGRAM_CLIENT_ERROR_CONNECT_TIMEOUT: i_error("program `%s' socket connection timed out (> %d msecs)", - pclient->path, pclient->set->client_connect_timeout_msecs); + pclient->path, pclient->set.client_connect_timeout_msecs); break; case PROGRAM_CLIENT_ERROR_RUN_TIMEOUT: i_error("program `%s' execution timed out (> %d secs)", - pclient->path, pclient->set->input_idle_timeout_secs); + pclient->path, pclient->set.input_idle_timeout_secs); break; default: break; diff -r 32beba3bfd8d -r 5c3b0283524b src/lib-sieve/util/program-client.c --- a/src/lib-sieve/util/program-client.c Wed Jan 01 23:58:16 2014 +0100 +++ b/src/lib-sieve/util/program-client.c Sat Jan 04 02:13:44 2014 +0100 @@ -29,9 +29,9 @@ static int program_client_connect(struct program_client *pclient) { - if (pclient->set->client_connect_timeout_msecs != 0) { + if (pclient->set.client_connect_timeout_msecs != 0) { pclient->to = timeout_add - (pclient->set->client_connect_timeout_msecs, + (pclient->set.client_connect_timeout_msecs, program_client_connect_timeout, pclient); } @@ -55,6 +55,26 @@ return ret; } +static void program_client_disconnect_extra_fds +(struct program_client *pclient) +{ + struct program_client_extra_fd *efds; + unsigned int i, count; + + if (!array_is_created(&pclient->extra_fds)) + return; + + efds = array_get_modifiable(&pclient->extra_fds, &count); + for ( i = 0; i < count; i++ ) { + if ( efds[i].input != NULL ) From pigeonhole at rename-it.nl Sun Jan 5 11:40:57 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 05 Jan 2014 10:40:57 +0100 Subject: dovecot-2.2-pigeonhole: Adjusted dovecot.m4 to make second-level... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/a9df92d2314a changeset: 1838:a9df92d2314a user: Stephan Bosch date: Sun Jan 05 10:40:38 2014 +0100 description: Adjusted dovecot.m4 to make second-level plugin packages work properly at distcheck. diffstat: m4/dovecot.m4 | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 5c3b0283524b -r a9df92d2314a m4/dovecot.m4 --- a/m4/dovecot.m4 Sat Jan 04 02:13:44 2014 +0100 +++ b/m4/dovecot.m4 Sun Jan 05 10:40:38 2014 +0100 @@ -6,7 +6,7 @@ # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. -# serial 11 +# serial 12 AC_DEFUN([DC_DOVECOT_MODULEDIR],[ AC_ARG_WITH(moduledir, @@ -70,7 +70,7 @@ cd $dovecotdir abs_dovecotdir=`pwd` cd $old - DISTCHECK_CONFIGURE_FLAGS="--with-dovecot=$abs_dovecotdir --without-dovecot-install-dirs --disable-shared" + DISTCHECK_CONFIGURE_FLAGS="--with-dovecot=$abs_dovecotdir --without-dovecot-install-dirs" eval `grep -i '^dovecot_[[a-z_]]*=' "$dovecotdir"/dovecot-config` eval `grep '^LIBDOVECOT[[A-Z_]]*=' "$dovecotdir"/dovecot-config` From pigeonhole at rename-it.nl Sun Jan 5 12:16:36 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 05 Jan 2014 11:16:36 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve/util: Fixed small memory leak ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/bc0657f52394 changeset: 1839:bc0657f52394 user: Stephan Bosch date: Sun Jan 05 11:15:45 2014 +0100 description: lib-sieve/util: Fixed small memory leak in program client. diffstat: src/lib-sieve/util/program-client-local.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r a9df92d2314a -r bc0657f52394 src/lib-sieve/util/program-client-local.c --- a/src/lib-sieve/util/program-client-local.c Sun Jan 05 10:40:38 2014 +0100 +++ b/src/lib-sieve/util/program-client-local.c Sun Jan 05 11:15:45 2014 +0100 @@ -366,7 +366,7 @@ pool_t pool; pool = pool_alloconly_create("program client local", 1024); - pclient = i_new(struct program_client_local, 1); + pclient = p_new(pool, struct program_client_local, 1); program_client_init(&pclient->client, pool, bin_path, args, set); pclient->client.connect = program_client_local_connect; pclient->client.close_output = program_client_local_close_output; From pigeonhole at rename-it.nl Sun Jan 5 12:16:37 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 05 Jan 2014 11:16:37 +0100 Subject: dovecot-2.2-pigeonhole: Fixed Valgrind in testsuite using libtoo... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/080972c83cba changeset: 1840:080972c83cba user: Stephan Bosch date: Sun Jan 05 11:16:25 2014 +0100 description: Fixed Valgrind in testsuite using libtool --mode=execute. diffstat: Makefile.am | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r bc0657f52394 -r 080972c83cba Makefile.am --- a/Makefile.am Sun Jan 05 11:15:45 2014 +0100 +++ b/Makefile.am Sun Jan 05 11:16:25 2014 +0100 @@ -25,7 +25,7 @@ TESTSUITE_BIN = $(top_builddir)/src/testsuite/testsuite $(TESTSUITE_OPTIONS) if TESTSUITE_VALGRIND -TEST_BIN = valgrind -q --error-exitcode=1 --show-reachable=yes --leak-check=full $(TESTSUITE_BIN) +TEST_BIN = libtool --mode=execute valgrind -q --error-exitcode=1 --show-reachable=yes --leak-check=full $(TESTSUITE_BIN) else TEST_BIN = $(TESTSUITE_BIN) endif From pigeonhole at rename-it.nl Tue Jan 7 19:57:58 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 07 Jan 2014 18:57:58 +0100 Subject: dovecot-2.2-pigeonhole: lda-sieve plugin: Changed name of main s... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/3115b97ad1c1 changeset: 1841:3115b97ad1c1 user: Stephan Bosch date: Tue Jan 07 18:54:57 2014 +0100 description: lda-sieve plugin: Changed name of main script. diffstat: src/plugins/lda-sieve/lda-sieve-plugin.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 080972c83cba -r 3115b97ad1c1 src/plugins/lda-sieve/lda-sieve-plugin.c --- a/src/plugins/lda-sieve/lda-sieve-plugin.c Sun Jan 05 11:16:25 2014 +0100 +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c Tue Jan 07 18:54:57 2014 +0100 @@ -627,7 +627,7 @@ user_location = lda_sieve_get_personal_location(svinst, mdctx->dest_user); if ( user_location != NULL ) { srctx->user_script = sieve_script_create_open_as - (svinst, user_location, "main script", master_ehandler, &error); + (svinst, user_location, "main_script", master_ehandler, &error); if ( srctx->user_script == NULL ) { switch ( error ) { From pigeonhole at rename-it.nl Tue Jan 7 19:57:58 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 07 Jan 2014 18:57:58 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: Changed sieve_script_binary_g... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/a70f5f097033 changeset: 1842:a70f5f097033 user: Stephan Bosch date: Tue Jan 07 18:57:38 2014 +0100 description: lib-sieve: Changed sieve_script_binary_get_directory() to sieve_script_binary_get_prefix(). This function now returns the binary prefix (file path until '.svbin) rather than just the path of the directory where the binary would be stored. diffstat: src/lib-sieve/sieve-script-file.c | 16 +++++++++++----- src/lib-sieve/sieve-script-private.h | 3 ++- src/lib-sieve/sieve-script.c | 8 ++++---- src/lib-sieve/sieve-script.h | 2 +- 4 files changed, 18 insertions(+), 11 deletions(-) diffs (119 lines): diff -r 3115b97ad1c1 -r a70f5f097033 src/lib-sieve/sieve-script-file.c --- a/src/lib-sieve/sieve-script-file.c Tue Jan 07 18:54:57 2014 +0100 +++ b/src/lib-sieve/sieve-script-file.c Tue Jan 07 18:57:38 2014 +0100 @@ -122,7 +122,7 @@ struct sieve_error_handler *ehandler = _script->ehandler; pool_t pool = _script->pool; const char *name = _script->name; - const char *filename, *dirpath, *basename, *binpath; + const char *filename, *dirpath, *basename, *binpath, *binprefix; struct stat st; struct stat lnk_st; bool success = TRUE; @@ -220,10 +220,15 @@ if ( _script->bin_dir != NULL ) { binpath = sieve_binfile_from_name(name); binpath = t_strconcat(_script->bin_dir, "/", binpath, NULL); + binprefix = t_strconcat(_script->bin_dir, "/", name, NULL); } else { binpath = sieve_binfile_from_name(basename); - if ( *dirpath != '\0' ) + if ( *dirpath != '\0' ) { binpath = t_strconcat(dirpath, "/", binpath, NULL); + binprefix = t_strconcat(dirpath, "/", basename, NULL); + } else { + binprefix = basename; + } } script->st = st; @@ -232,6 +237,7 @@ script->filename = p_strdup(pool, filename); script->dirpath = p_strdup(pool, dirpath); script->binpath = p_strdup(pool, binpath); + script->binprefix = p_strdup(pool, binprefix); if ( script->script.name == NULL || strcmp(script->script.name, basename) == 0 ) @@ -354,12 +360,12 @@ script->st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO), error_r); } -static const char *sieve_file_script_binary_get_directory +static const char *sieve_file_script_binary_get_prefix (struct sieve_script *_script) { struct sieve_file_script *script = (struct sieve_file_script *)_script; - return script-> dirpath; + return script-> binprefix; } const struct sieve_script sieve_file_script = { @@ -376,7 +382,7 @@ NULL, sieve_file_script_binary_load, sieve_file_script_binary_save, - sieve_file_script_binary_get_directory, + sieve_file_script_binary_get_prefix, sieve_file_script_get_size, diff -r 3115b97ad1c1 -r a70f5f097033 src/lib-sieve/sieve-script-private.h --- a/src/lib-sieve/sieve-script-private.h Tue Jan 07 18:54:57 2014 +0100 +++ b/src/lib-sieve/sieve-script-private.h Tue Jan 07 18:57:38 2014 +0100 @@ -32,7 +32,7 @@ int (*binary_save) (struct sieve_script *script, struct sieve_binary *sbin, bool update, enum sieve_error *error_r); - const char *(*binary_get_directory) + const char *(*binary_get_prefix) (struct sieve_script *script); int (*get_size) @@ -88,6 +88,7 @@ const char *dirpath; const char *filename; const char *binpath; + const char *binprefix; int fd; }; diff -r 3115b97ad1c1 -r a70f5f097033 src/lib-sieve/sieve-script.c --- a/src/lib-sieve/sieve-script.c Tue Jan 07 18:54:57 2014 +0100 +++ b/src/lib-sieve/sieve-script.c Tue Jan 07 18:57:38 2014 +0100 @@ -542,18 +542,18 @@ return script->v.binary_save(script, sbin, update, error_r); } -const char *sieve_script_binary_get_directory +const char *sieve_script_binary_get_prefix (struct sieve_script *script) { if ( script->bin_dir != NULL && sieve_script_setup_bindir(script, 0700) >= 0 ) { - return script->bin_dir; + return t_strconcat(script->bin_dir, "/", script->name, NULL); } - if ( script->v.binary_get_directory == NULL ) + if ( script->v.binary_get_prefix == NULL ) return NULL; - return script->v.binary_get_directory(script); + return script->v.binary_get_prefix(script); } int sieve_script_setup_bindir diff -r 3115b97ad1c1 -r a70f5f097033 src/lib-sieve/sieve-script.h --- a/src/lib-sieve/sieve-script.h Tue Jan 07 18:54:57 2014 +0100 +++ b/src/lib-sieve/sieve-script.h Tue Jan 07 18:57:38 2014 +0100 @@ -68,7 +68,7 @@ (struct sieve_script *script, struct sieve_binary *sbin, bool update, enum sieve_error *error_r); -const char *sieve_script_binary_get_directory +const char *sieve_script_binary_get_prefix (struct sieve_script *script); /* From dovecot at dovecot.org Tue Jan 7 21:33:47 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 07 Jan 2014 21:33:47 +0200 Subject: dovecot-2.2: imap proxy: Set proxy_state correctly also with pro... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a0e04a5aadab changeset: 17089:a0e04a5aadab user: Timo Sirainen date: Tue Jan 07 14:33:29 2014 -0500 description: imap proxy: Set proxy_state correctly also with proxy_nopipelining. diffstat: src/imap-login/imap-proxy.c | 19 ++++++++++--------- 1 files changed, 10 insertions(+), 9 deletions(-) diffs (37 lines): diff -r 6b8ae0ba5959 -r a0e04a5aadab src/imap-login/imap-proxy.c --- a/src/imap-login/imap-proxy.c Mon Dec 23 15:30:31 2013 +0200 +++ b/src/imap-login/imap-proxy.c Tue Jan 07 14:33:29 2014 -0500 @@ -276,14 +276,6 @@ } o_stream_nsend(output, str_data(str), str_len(str)); return 1; - } else if (strncmp(line, "C OK ", 5) == 0 && - client->proxy_password != NULL) { - /* pipelining was disabled, send the login now. */ - str = t_str_new(128); - if (proxy_write_login(imap_client, str) < 0) - return -1; - o_stream_nsend(output, str_data(str), str_len(str)); - return 1; } else if (strncmp(line, "L OK ", 5) == 0) { /* Login successful. Send this line to client. */ client->proxy_state = IMAP_PROXY_STATE_LOGIN; @@ -339,8 +331,17 @@ imap_client->proxy_backend_capability = i_strdup(line + 13); return 0; } else if (strncmp(line, "C ", 2) == 0) { - /* Reply to CAPABILITY command we sent, ignore it */ + /* Reply to CAPABILITY command we sent */ client->proxy_state = IMAP_PROXY_STATE_CAPABILITY; + if (strncmp(line, "C OK ", 5) == 0 && + client->proxy_password != NULL) { + /* pipelining was disabled, send the login now. */ + str = t_str_new(128); + if (proxy_write_login(imap_client, str) < 0) + return -1; + o_stream_nsend(output, str_data(str), str_len(str)); + return 1; + } return 0; } else if (strncasecmp(line, "I ", 2) == 0 || strncasecmp(line, "* ID ", 5) == 0) { From dovecot at dovecot.org Wed Jan 8 18:24:52 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 08 Jan 2014 18:24:52 +0200 Subject: dovecot-2.2: lib-storage: Implemented get_metadata() for fail-ma... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f9a11e81209f changeset: 17090:f9a11e81209f user: Timo Sirainen date: Wed Jan 08 11:24:36 2014 -0500 description: lib-storage: Implemented get_metadata() for fail-mailbox. This fixes a crash when a nonexistent mailbox was allocated and accessed (via LAYOUT=index). diffstat: src/lib-storage/fail-mailbox.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-) diffs (29 lines): diff -r a0e04a5aadab -r f9a11e81209f src/lib-storage/fail-mailbox.c --- a/src/lib-storage/fail-mailbox.c Tue Jan 07 14:33:29 2014 -0500 +++ b/src/lib-storage/fail-mailbox.c Wed Jan 08 11:24:36 2014 -0500 @@ -88,6 +88,16 @@ return -1; } +static int +fail_mailbox_get_metadata(struct mailbox *box, + enum mailbox_metadata_items items ATTR_UNUSED, + struct mailbox_metadata *metadata_r ATTR_UNUSED) +{ + mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname)); + return -1; +} + static int fail_mailbox_set_subscribed(struct mailbox *box, bool set ATTR_UNUSED) { @@ -257,7 +267,7 @@ fail_mailbox_delete, fail_mailbox_rename, fail_mailbox_get_status, - NULL, + fail_mailbox_get_metadata, fail_mailbox_set_subscribed, NULL, NULL, From dovecot at dovecot.org Fri Jan 10 00:19:32 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Jan 2014 00:19:32 +0200 Subject: dovecot-2.2: doveadm fs delete: Added -n parameter to asynchrono... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b6ab0e056c0b changeset: 17091:b6ab0e056c0b user: Timo Sirainen date: Fri Jan 10 00:19:19 2014 +0200 description: doveadm fs delete: Added -n parameter to asynchronously delete multiple files at once. diffstat: src/doveadm/doveadm-fs.c | 130 +++++++++++++++++++++++++++++++++++++++------- 1 files changed, 108 insertions(+), 22 deletions(-) diffs (185 lines): diff -r f9a11e81209f -r b6ab0e056c0b src/doveadm/doveadm-fs.c --- a/src/doveadm/doveadm-fs.c Wed Jan 08 11:24:36 2014 -0500 +++ b/src/doveadm/doveadm-fs.c Fri Jan 10 00:19:19 2014 +0200 @@ -9,6 +9,7 @@ #include "doveadm.h" #include +#include static void fs_cmd_help(doveadm_command_t *cmd); static void cmd_fs_delete(int argc, char *argv[]); @@ -181,56 +182,123 @@ fs_deinit(&fs); } -static void cmd_fs_delete_dir_recursive(struct fs *fs, const char *path) +struct fs_delete_ctx { + unsigned int files_count; + struct fs_file **files; +}; + +static bool cmd_fs_delete_ctx_run(struct fs_delete_ctx *ctx) +{ + unsigned int i; + bool ret = FALSE; + + for (i = 0; i < ctx->files_count; i++) { + if (ctx->files[i] == NULL) + ; + else if (fs_delete(ctx->files[i]) == 0) + fs_file_deinit(&ctx->files[i]); + else if (errno == EAGAIN) + ret = TRUE; + else { + i_error("fs_delete(%s) failed: %s", + fs_file_path(ctx->files[i]), + fs_file_last_error(ctx->files[i])); + doveadm_exit_code = EX_TEMPFAIL; + } + } + return ret; +} + +static void +cmd_fs_delete_dir_recursive(struct fs *fs, unsigned int async_count, + const char *path) { struct fs_iter *iter; - struct fs_file *file; - ARRAY_TYPE(const_string) dirs; + ARRAY_TYPE(const_string) fnames; + struct fs_delete_ctx ctx; const char *fname, *const *fnamep; + unsigned int i; + + memset(&ctx, 0, sizeof(ctx)); + ctx.files_count = I_MAX(async_count, 1); + ctx.files = t_new(struct fs_file *, ctx.files_count); /* delete subdirs first. all fs backends can't handle recursive lookups, so save the list first. */ - t_array_init(&dirs, 8); + t_array_init(&fnames, 8); iter = fs_iter_init(fs, path, FS_ITER_FLAG_DIRS); while ((fname = fs_iter_next(iter)) != NULL) { fname = t_strdup(fname); - array_append(&dirs, &fname, 1); + array_append(&fnames, &fname, 1); } if (fs_iter_deinit(&iter) < 0) { i_error("fs_iter_deinit(%s) failed: %s", path, fs_last_error(fs)); doveadm_exit_code = EX_TEMPFAIL; } - array_foreach(&dirs, fnamep) T_BEGIN { - cmd_fs_delete_dir_recursive(fs, + array_foreach(&fnames, fnamep) T_BEGIN { + cmd_fs_delete_dir_recursive(fs, async_count, t_strdup_printf("%s/%s", path, *fnamep)); } T_END; - /* delete files */ + /* delete files. again because we're doing this asynchronously finish + the iteration first. */ + array_clear(&fnames); iter = fs_iter_init(fs, path, 0); - while ((fname = fs_iter_next(iter)) != NULL) T_BEGIN { - file = fs_file_init(fs, t_strdup_printf("%s/%s", path, fname), - FS_OPEN_MODE_READONLY); - if (fs_delete(file) < 0) { - i_error("fs_delete(%s) failed: %s", - fs_file_path(file), fs_file_last_error(file)); - doveadm_exit_code = EX_TEMPFAIL; - } - fs_file_deinit(&file); - } T_END; + while ((fname = fs_iter_next(iter)) != NULL) { + fname = t_strdup(fname); + array_append(&fnames, &fname, 1); + } if (fs_iter_deinit(&iter) < 0) { i_error("fs_iter_deinit(%s) failed: %s", path, fs_last_error(fs)); doveadm_exit_code = EX_TEMPFAIL; } + + array_foreach(&fnames, fnamep) T_BEGIN { + fname = *fnamep; + retry: + for (i = 0; i < ctx.files_count; i++) { + if (ctx.files[i] != NULL) + continue; + + ctx.files[i] = fs_file_init(fs, + t_strdup_printf("%s/%s", path, fname), + FS_OPEN_MODE_READONLY | FS_OPEN_FLAG_ASYNC | + FS_OPEN_FLAG_ASYNC_NOQUEUE); + fname = NULL; + break; + } + cmd_fs_delete_ctx_run(&ctx); + if (fname != NULL) { + if (fs_wait_async(fs) < 0) { + i_error("fs_wait_async() failed: %s", fs_last_error(fs)); + doveadm_exit_code = EX_TEMPFAIL; + break; + } + goto retry; + } + } T_END; + while (doveadm_exit_code == 0 && cmd_fs_delete_ctx_run(&ctx)) { + if (fs_wait_async(fs) < 0) { + i_error("fs_wait_async() failed: %s", fs_last_error(fs)); + doveadm_exit_code = EX_TEMPFAIL; + break; + } + } + for (i = 0; i < ctx.files_count; i++) { + if (ctx.files[i] != NULL) + fs_file_deinit(&ctx.files[i]); + } } -static void cmd_fs_delete_recursive(int argc, char *argv[]) +static void +cmd_fs_delete_recursive(int argc, char *argv[], unsigned int async_count) { struct fs *fs; fs = cmd_fs_init(&argc, &argv, 1, cmd_fs_delete); - cmd_fs_delete_dir_recursive(fs, argv[0]); + cmd_fs_delete_dir_recursive(fs, async_count, argv[0]); fs_deinit(&fs); } @@ -238,9 +306,27 @@ { struct fs *fs; struct fs_file *file; + bool recursive = FALSE; + unsigned int async_count = 0; + int c; - if (null_strcmp(argv[1], "-R") == 0) { - cmd_fs_delete_recursive(argc-1, argv+1); + while ((c = getopt(argc, argv, "Rn:")) > 0) { + switch (c) { + case 'R': + recursive = TRUE; + break; + case 'n': + if (str_to_uint(optarg, &async_count) < 0) + i_fatal("Invalid -n parameter: %s", optarg); + break; + default: + fs_cmd_help(cmd_fs_delete); + } + } + argc -= optind; argv += optind; + + if (recursive) { + cmd_fs_delete_recursive(argc+1, argv-1, async_count); return; } From dovecot at dovecot.org Fri Jan 10 20:00:53 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Jan 2014 20:00:53 +0200 Subject: dovecot-2.2: imap proxy: Avoid duplicate CAPABILITY reply when b... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4dd86f75346b changeset: 17092:4dd86f75346b user: Timo Sirainen date: Fri Jan 10 13:00:39 2014 -0500 description: imap proxy: Avoid duplicate CAPABILITY reply when backend is Dovecot. This happened if the client sent a CAPABILITY command to the proxy. diffstat: src/imap-login/imap-proxy.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) diffs (19 lines): diff -r b6ab0e056c0b -r 4dd86f75346b src/imap-login/imap-proxy.c --- a/src/imap-login/imap-proxy.c Fri Jan 10 00:19:19 2014 +0200 +++ b/src/imap-login/imap-proxy.c Fri Jan 10 13:00:39 2014 -0500 @@ -63,7 +63,14 @@ unsigned int len; const char *mech_name, *error; - if (client->proxy_backend_capability == NULL) { + /* Send CAPABILITY command if we don't know the capabilities yet. + Also as kind of a Dovecot-backend workaround if the client insisted + on sending CAPABILITY command (even though our banner already sent + it), send the (unnecessary) CAPABILITY command to backend as well + to avoid sending the CAPABILITY reply twice (untagged and OK resp + code). */ + if (client->proxy_backend_capability == NULL || + client->client_ignores_capability_resp_code) { str_append(str, "C CAPABILITY\r\n"); if (client->common.proxy_nopipelining) { /* authenticate only after receiving C OK reply. */ From dovecot at dovecot.org Fri Jan 10 21:59:21 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Jan 2014 21:59:21 +0200 Subject: dovecot-2.2: lib-master: Added unit test for master_service_sett... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9360aeba0099 changeset: 17093:9360aeba0099 user: Timo Sirainen date: Fri Jan 10 21:59:15 2014 +0200 description: lib-master: Added unit test for master_service_settings_cache_read() diffstat: src/lib-master/Makefile.am | 22 +++ src/lib-master/test-master-service-settings-cache.c | 113 ++++++++++++++++++++ 2 files changed, 135 insertions(+), 0 deletions(-) diffs (153 lines): diff -r 4dd86f75346b -r 9360aeba0099 src/lib-master/Makefile.am --- a/src/lib-master/Makefile.am Fri Jan 10 13:00:39 2014 -0500 +++ b/src/lib-master/Makefile.am Fri Jan 10 21:59:15 2014 +0200 @@ -4,6 +4,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-test \ -I$(top_srcdir)/src/lib-settings \ -I$(top_srcdir)/src/lib-ssl-iostream \ -DPKG_RUNDIR=\""$(rundir)"\" \ @@ -48,3 +49,24 @@ pkginc_libdir=$(pkgincludedir) pkginc_lib_HEADERS = $(headers) + +test_programs = \ + test-master-service-settings-cache + +noinst_PROGRAMS = $(test_programs) + +test_libs = \ + ../lib-test/libtest.la \ + ../lib/liblib.la + +test_deps = $(noinst_LTLIBRARIES) $(test_libs) + +test_master_service_settings_cache_SOURCES = test-master-service-settings-cache.c +test_master_service_settings_cache_LDADD = master-service-settings-cache.lo ../lib-settings/libsettings.la $(test_libs) +test_master_service_settings_cache_DEPENDENCIES = $(test_deps) ../lib-settings/libsettings.la + +check: check-am check-test +check-test: all-am + for bin in $(test_programs); do \ + if ! $(RUN_TEST) ./$$bin; then exit 1; fi; \ + done diff -r 4dd86f75346b -r 9360aeba0099 src/lib-master/test-master-service-settings-cache.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-master/test-master-service-settings-cache.c Fri Jan 10 21:59:15 2014 +0200 @@ -0,0 +1,113 @@ +/* Copyright (c) 2014 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "test-common.h" +#include "settings-parser.h" +#include "master-service-private.h" +#include "master-service-settings.h" +#include "master-service-settings-cache.h" + +#include + +struct master_service *master_service; + +static struct master_service test_master_service; +static struct master_service_settings set; +static struct master_service_settings_input input; +static struct master_service_settings_output output; +static struct master_service_settings_cache *cache; + +struct test_service_settings { + const char *foo; +}; + +#undef DEF +#define DEF(type, name) \ + { type, #name, offsetof(struct test_service_settings, name), NULL } + +static const struct setting_define test_setting_defines[] = { + DEF(SET_STR, foo), + SETTING_DEFINE_LIST_END +}; + +static const struct test_service_settings test_default_settings = { + .foo = "" +}; + +static const struct setting_parser_info test_setting_parser_info = { + .module_name = "module", + .defines = test_setting_defines, + .defaults = &test_default_settings, + + .type_offset = (size_t)-1, + .struct_size = sizeof(struct test_service_settings), + + .parent_offset = (size_t)-1 +}; + +int master_service_settings_read(struct master_service *service ATTR_UNUSED, + const struct master_service_settings_input *input ATTR_UNUSED, + struct master_service_settings_output *output_r, + const char **error_r ATTR_UNUSED) +{ + *output_r = output; + return 0; +} + +const struct master_service_settings * +master_service_settings_get(struct master_service *service ATTR_UNUSED) +{ + return &set; +} + +static void test_master_service_settings_cache_once(void) +{ + const struct setting_parser_context *parser; + const char *error; + + output.used_local = output.service_uses_local && rand() % 2; + if (output.used_local) { + input.local_ip.family = AF_INET; + input.local_ip.u.ip4.s_addr = 100 + rand() % 100; + } + output.used_remote = output.service_uses_remote && rand() % 2; + if (output.used_remote) { + input.remote_ip.family = AF_INET; + input.remote_ip.u.ip4.s_addr = 100 + rand() % 100; + } + test_assert(master_service_settings_cache_read(cache, &input, NULL, &parser, &error) == 0); +} + +static void test_master_service_settings_cache(void) +{ + int i, j; + + for (i = 1; i < 4; i++) { + cache = master_service_settings_cache_init(master_service, + "module", "service_name"); + output.service_uses_local = (i & 1) != 0; + output.service_uses_remote = (i & 2) != 0; + for (j = 0; j < 1000; j++) + test_master_service_settings_cache_once(); + master_service_settings_cache_deinit(&cache); + } +} + +int main(void) +{ + static void (*test_functions[])(void) = { + test_master_service_settings_cache, + NULL + }; + + memset(&input, 0, sizeof(input)); + input.module = "module"; + input.service = "service_name"; + + set.config_cache_size = 1024*4; + test_master_service.set_parser = + settings_parser_init(pool_alloconly_create("set pool", 1024), + &test_setting_parser_info, 0); + master_service = &test_master_service; + return test_run(test_functions); +} From dovecot at dovecot.org Fri Jan 10 22:00:54 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Jan 2014 22:00:54 +0200 Subject: dovecot-2.2: lib-http: Added option to the header parser to make... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4650bfc057fb changeset: 17094:4650bfc057fb user: Stephan Bosch date: Fri Jan 10 15:00:28 2014 -0500 description: lib-http: Added option to the header parser to make it lenient towards illegal characters in header field content. The offending characters are then skipped without error. This is required for the http client as a workaround for bugs in certain HTTP servers. This behavior is explicitly not enabled for the http-request-parser as used by our own HTTP server implementation. diffstat: src/lib-http/http-header-parser.c | 26 ++++++++++++++--- src/lib-http/http-header-parser.h | 2 +- src/lib-http/http-message-parser.c | 7 ++-- src/lib-http/http-message-parser.h | 4 ++- src/lib-http/http-request-parser.c | 2 +- src/lib-http/http-response-parser.c | 2 +- src/lib-http/http-transfer-chunked.c | 3 +- src/lib-http/test-http-header-parser.c | 44 +++++++++++++++++++++++++---- src/lib-http/test-http-response-parser.c | 46 ++++++++++++++++++++++++------- 9 files changed, 105 insertions(+), 31 deletions(-) diffs (truncated from 370 to 300 lines): diff -r 9360aeba0099 -r 4650bfc057fb src/lib-http/http-header-parser.c --- a/src/lib-http/http-header-parser.c Fri Jan 10 21:59:15 2014 +0200 +++ b/src/lib-http/http-header-parser.c Fri Jan 10 15:00:28 2014 -0500 @@ -37,16 +37,19 @@ buffer_t *value_buf; enum http_header_parse_state state; + + unsigned int lenient:1; }; struct http_header_parser * http_header_parser_init(struct istream *input, - const struct http_header_limits *limits) + const struct http_header_limits *limits, bool lenient) { struct http_header_parser *parser; parser = i_new(struct http_header_parser, 1); parser->input = input; + parser->lenient = lenient; parser->name = str_new(default_pool, 128); parser->value_buf = buffer_create_dynamic(default_pool, 4096); @@ -116,14 +119,27 @@ static int http_header_parse_content(struct http_header_parser *parser) { - const unsigned char *first = parser->cur; + const unsigned char *first; /* field-content = *( HTAB / SP / VCHAR / obs-text ) */ - while (parser->cur < parser->end && http_char_is_text(*parser->cur)) - parser->cur++; + do { + first = parser->cur; + while (parser->cur < parser->end && http_char_is_text(*parser->cur)) { + parser->cur++; + } + buffer_append(parser->value_buf, first, parser->cur-first); - buffer_append(parser->value_buf, first, parser->cur-first); + if (!parser->lenient) + break; + + /* We'll be lenient here to accommodate for some bad servers. We just + drop offending characters */ + while (parser->cur < parser->end && !http_char_is_text(*parser->cur) && + (*parser->cur != '\r' && *parser->cur != '\n')) + parser->cur++; + } while (parser->cur < parser->end && + (*parser->cur != '\r' && *parser->cur != '\n')); if (parser->cur == parser->end) return 0; diff -r 9360aeba0099 -r 4650bfc057fb src/lib-http/http-header-parser.h --- a/src/lib-http/http-header-parser.h Fri Jan 10 21:59:15 2014 +0200 +++ b/src/lib-http/http-header-parser.h Fri Jan 10 15:00:28 2014 -0500 @@ -6,7 +6,7 @@ struct http_header_parser * http_header_parser_init(struct istream *input, - const struct http_header_limits *limits); + const struct http_header_limits *limits, bool lenient); void http_header_parser_deinit(struct http_header_parser **_parser); void http_header_parser_reset(struct http_header_parser *parser); diff -r 9360aeba0099 -r 4650bfc057fb src/lib-http/http-message-parser.c --- a/src/lib-http/http-message-parser.c Fri Jan 10 21:59:15 2014 +0200 +++ b/src/lib-http/http-message-parser.c Fri Jan 10 15:00:28 2014 -0500 @@ -14,13 +14,14 @@ void http_message_parser_init(struct http_message_parser *parser, struct istream *input, const struct http_header_limits *hdr_limits, - uoff_t max_payload_size) + uoff_t max_payload_size, bool lenient) { memset(parser, 0, sizeof(*parser)); parser->input = input; if (hdr_limits != NULL) parser->header_limits = *hdr_limits; parser->max_payload_size = max_payload_size; + parser->lenient = lenient; } void http_message_parser_deinit(struct http_message_parser *parser) @@ -39,8 +40,8 @@ i_assert(parser->payload == NULL); if (parser->header_parser == NULL) { - parser->header_parser = - http_header_parser_init(parser->input, &parser->header_limits); + parser->header_parser = http_header_parser_init + (parser->input, &parser->header_limits, parser->lenient); } else { http_header_parser_reset(parser->header_parser); } diff -r 9360aeba0099 -r 4650bfc057fb src/lib-http/http-message-parser.h --- a/src/lib-http/http-message-parser.h Fri Jan 10 21:59:15 2014 +0200 +++ b/src/lib-http/http-message-parser.h Fri Jan 10 15:00:28 2014 -0500 @@ -51,11 +51,13 @@ pool_t msg_pool; struct http_message msg; + + unsigned int lenient:1; }; void http_message_parser_init(struct http_message_parser *parser, struct istream *input, const struct http_header_limits *hdr_limits, - uoff_t max_payload_size) ATTR_NULL(3); + uoff_t max_payload_size, bool lenient) ATTR_NULL(3); void http_message_parser_deinit(struct http_message_parser *parser); void http_message_parser_restart(struct http_message_parser *parser, pool_t pool); diff -r 9360aeba0099 -r 4650bfc057fb src/lib-http/http-request-parser.c --- a/src/lib-http/http-request-parser.c Fri Jan 10 21:59:15 2014 +0200 +++ b/src/lib-http/http-request-parser.c Fri Jan 10 15:00:28 2014 -0500 @@ -66,7 +66,7 @@ max_payload_size = HTTP_REQUEST_DEFAULT_MAX_PAYLOAD_SIZE; http_message_parser_init - (&parser->parser, input, &hdr_limits, max_payload_size); + (&parser->parser, input, &hdr_limits, max_payload_size, FALSE); return parser; } diff -r 9360aeba0099 -r 4650bfc057fb src/lib-http/http-response-parser.c --- a/src/lib-http/http-response-parser.c Fri Jan 10 21:59:15 2014 +0200 +++ b/src/lib-http/http-response-parser.c Fri Jan 10 15:00:28 2014 -0500 @@ -37,7 +37,7 @@ /* FIXME: implement status line limit */ parser = i_new(struct http_response_parser, 1); - http_message_parser_init(&parser->parser, input, hdr_limits, 0); + http_message_parser_init(&parser->parser, input, hdr_limits, 0, TRUE); return parser; } diff -r 9360aeba0099 -r 4650bfc057fb src/lib-http/http-transfer-chunked.c --- a/src/lib-http/http-transfer-chunked.c Fri Jan 10 21:59:15 2014 +0200 +++ b/src/lib-http/http-transfer-chunked.c Fri Jan 10 15:00:28 2014 -0500 @@ -434,9 +434,10 @@ int ret; if (tcstream->header_parser == NULL) { + /* NOTE: trailer is currently ignored */ /* FIXME: limit trailer size */ tcstream->header_parser = - http_header_parser_init(tcstream->istream.parent, 0); + http_header_parser_init(tcstream->istream.parent, 0, TRUE); } while ((ret=http_header_parse_next_field(tcstream->header_parser, diff -r 9360aeba0099 -r 4650bfc057fb src/lib-http/test-http-header-parser.c --- a/src/lib-http/test-http-header-parser.c Fri Jan 10 21:59:15 2014 +0200 +++ b/src/lib-http/test-http-header-parser.c Fri Jan 10 15:00:28 2014 -0500 @@ -1,6 +1,7 @@ /* Copyright (c) 2013 Dovecot authors, see the included COPYING file */ #include "test-lib.h" +#include "str-sanitize.h" #include "istream.h" #include "test-common.h" #include "http-response.h" @@ -83,6 +84,16 @@ { NULL, NULL } }; +static struct http_header_parse_result valid_header_parse_result6[] = { + { "X-Frop", "This text\x80 contains obs-text\x81 characters" }, + { NULL, NULL } +}; + +static struct http_header_parse_result valid_header_parse_result7[] = { + { "X-Frop", "This text contains invalid characters" }, + { NULL, NULL } +}; + static const struct http_header_parse_test valid_header_parse_tests[] = { { .header = "Date: Sat, 06 Oct 2012 16:01:44 GMT\r\n" @@ -150,6 +161,16 @@ .header = "\r\n", .fields = valid_header_parse_result5 + },{ + .header = + "X-Frop: This text\x80 contains obs-text\x81 characters\r\n" + "\r\n", + .fields = valid_header_parse_result6 + },{ + .header = + "X-Frop: This text\x01 contains invalid\x7f characters\r\n" + "\r\n", + .fields = valid_header_parse_result7 } }; @@ -173,7 +194,7 @@ header_len = strlen(header); limits = &valid_header_parse_tests[i].limits; input = test_istream_create_data(header, header_len); - parser = http_header_parser_init(input, limits); + parser = http_header_parser_init(input, limits, TRUE); test_begin(t_strdup_printf("http header valid [%d]", i)); @@ -196,15 +217,16 @@ field_value = t_strndup(field_data, field_size); if (result->name == NULL) { - test_out_reason("valid", FALSE, - t_strdup_printf("%s: %s", field_name, field_value)); + test_out_reason("valid", FALSE, t_strdup_printf + ("%s: %s", field_name, str_sanitize(field_value, 100))); break; } test_out_reason("valid", strcmp(result->name, field_name) == 0 && - strcmp(result->value, field_value) == 0, - t_strdup_printf("%s: %s", field_name, field_value)); + strcmp(result->value, field_value) == 0, + t_strdup_printf("%s: %s", field_name, + str_sanitize(field_value, 100))); j++; } @@ -238,10 +260,15 @@ .header = "Host: p5-lrqzb4yavu4l7nagydw-428649-i2-v6exp3-ds.metric.example.com\n" "User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0)\n" - "Accept:\t\timage/png,image/*;q=0.8,*/\177;q=0.5\n" + "Accept:\t\timage/png,image/*;q=0.8,*/\1;q=0.5\n" "\n" },{ .header = + "Date: Sat, 06 Oct 2012 17:18:22 GMT\r\n" + "Server: Apache/2.2.3\177 (CentOS)\r\n" + "\r\n" + },{ + .header = "Date: Sat, 06 Oct 2012 17:12:37 GMT\r\n" "Server: Apache/2.2.16 (Debian) PHP/5.3.3-7+squeeze14 with\r\n" "Suhosin-Patch proxy_html/3.0.1 mod_python/3.3.1 Python/2.6.6\r\n" @@ -249,6 +276,9 @@ "\r\n" },{ .header = + "Date: Sat, 06 Oct 2012 17:12:37 GMT\r\n" + },{ + .header = "Age: 58 \r\n" "Date: Sun, 04 Aug 2013 09:33:09 GMT\r\n" "Expires: Sun, 04 Aug 2013 09:34:08 GMT\r\n" @@ -318,7 +348,7 @@ header = invalid_header_parse_tests[i].header; limits = &invalid_header_parse_tests[i].limits; input = i_stream_create_from_data(header, strlen(header)); - parser = http_header_parser_init(input, limits); + parser = http_header_parser_init(input, limits, FALSE); test_begin(t_strdup_printf("http header invalid [%d]", i)); diff -r 9360aeba0099 -r 4650bfc057fb src/lib-http/test-http-response-parser.c --- a/src/lib-http/test-http-response-parser.c Fri Jan 10 21:59:15 2014 +0200 +++ b/src/lib-http/test-http-response-parser.c Fri Jan 10 15:00:28 2014 -0500 @@ -20,7 +20,7 @@ const char *payload; }; -/* Valid header tests */ +/* Valid response tests */ static const struct http_response_parse_test valid_response_parse_tests[] = { @@ -39,7 +39,7 @@ "This is a piece of stupid text.\r\n", .status = 200, .payload = "This is a piece of stupid text.\r\n" - },{ + },{ .response = "HTTP/1.1 200 OK\r\n" "Date: Sun, 07 Oct 2012 13:02:27 GMT\r\n" @@ -134,7 +134,7 @@ } test_out("parse success", ret == 0); - + if (ret == 0) { /* verify last response only */ test_out(t_strdup_printf("response->status = %d",test->status), @@ -156,6 +156,10 @@ buffer_free(&payload_buffer); } From dovecot at dovecot.org Fri Jan 10 22:00:54 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Jan 2014 22:00:54 +0200 Subject: dovecot-2.2: http: Improved HTTP header parser state machine and... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/012d6d22aa67 changeset: 17095:012d6d22aa67 user: Stephan Bosch date: Fri Jan 10 15:00:39 2014 -0500 description: http: Improved HTTP header parser state machine and error messages. diffstat: src/lib-http/http-header-parser.c | 62 +++++++++++++++++++------------------- 1 files changed, 31 insertions(+), 31 deletions(-) diffs (114 lines): diff -r 4650bfc057fb -r 012d6d22aa67 src/lib-http/http-header-parser.c --- a/src/lib-http/http-header-parser.c Fri Jan 10 15:00:28 2014 -0500 +++ b/src/lib-http/http-header-parser.c Fri Jan 10 15:00:39 2014 -0500 @@ -19,7 +19,6 @@ HTTP_HEADER_PARSE_STATE_CR, HTTP_HEADER_PARSE_STATE_LF, HTTP_HEADER_PARSE_STATE_NEW_LINE, - HTTP_HEADER_PARSE_STATE_LAST_LINE, HTTP_HEADER_PARSE_STATE_EOH }; @@ -172,16 +171,24 @@ case HTTP_HEADER_PARSE_STATE_INIT: buffer_set_used_size(parser->value_buf, 0); str_truncate(parser->name, 0); + if (*parser->cur == '\r') { + /* last CRLF */ + parser->cur++; + parser->state = HTTP_HEADER_PARSE_STATE_EOH; + if (parser->cur == parser->end) + return 0; + break; + } else if (*parser->cur == '\n') { + /* last LF */ + parser->state = HTTP_HEADER_PARSE_STATE_EOH; + break; + } + /* next line */ parser->state = HTTP_HEADER_PARSE_STATE_NAME; /* fall through */ case HTTP_HEADER_PARSE_STATE_NAME: - if (http_char_is_token(*parser->cur)) { - if ((ret=http_header_parse_name(parser)) <= 0) - return ret; - } else if (*parser->cur != ':' && str_len(parser->name) == 0) { - parser->state = HTTP_HEADER_PARSE_STATE_LAST_LINE; - break; - } + if ((ret=http_header_parse_name(parser)) <= 0) + return ret; parser->state = HTTP_HEADER_PARSE_STATE_COLON; /* fall through */ case HTTP_HEADER_PARSE_STATE_COLON: @@ -216,6 +223,12 @@ case HTTP_HEADER_PARSE_STATE_CR: if (*parser->cur == '\r') { parser->cur++; + } else if (*parser->cur != '\n') { + parser->error = t_strdup_printf + ("Invalid character %s in content of header field '%s'", + _chr_sanitize(*parser->cur), + str_sanitize(str_c(parser->name),64)); + return -1; } parser->state = HTTP_HEADER_PARSE_STATE_LF; if (parser->cur == parser->end) @@ -224,7 +237,7 @@ case HTTP_HEADER_PARSE_STATE_LF: if (*parser->cur != '\n') { parser->error = t_strdup_printf - ("Expected line end after header field '%s', but found %s", + ("Expected LF after CR at end of header field '%s', but found %s", str_sanitize(str_c(parser->name),64), _chr_sanitize(*parser->cur)); return -1; @@ -240,31 +253,14 @@ buffer_append_c(parser->value_buf, ' '); parser->state = HTTP_HEADER_PARSE_STATE_OWS; break; - } + } + /* next header line */ parser->state = HTTP_HEADER_PARSE_STATE_INIT; return 1; - case HTTP_HEADER_PARSE_STATE_LAST_LINE: - if (*parser->cur == '\r') { - /* last CRLF */ - parser->cur++; - parser->state = HTTP_HEADER_PARSE_STATE_EOH; - if (parser->cur == parser->end) - return 0; - break; - } else if (*parser->cur == '\n') { - /* header fully parsed */ - parser->cur++; - parser->state = HTTP_HEADER_PARSE_STATE_EOH; - return 1; - } - parser->error = t_strdup_printf - ("Expected CRLF or header field name, but found %s", - _chr_sanitize(*parser->cur)); - return -1; case HTTP_HEADER_PARSE_STATE_EOH: if (*parser->cur != '\n') { parser->error = t_strdup_printf - ("Expected LF after CR at end of header, but found %s", + ("Encountered stray CR at beginning of header line, followed by %s", _chr_sanitize(*parser->cur)); return -1; } @@ -350,7 +346,11 @@ } i_assert(ret != -2); - if (ret < 0) - *error_r = "Stream error"; + if (ret < 0) { + if (i_stream_is_eof(parser->input)) + *error_r = "Premature end of input"; + else + *error_r = "Stream error"; + } return ret; } From pigeonhole at rename-it.nl Mon Jan 13 00:24:08 2014 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 12 Jan 2014 23:24:08 +0100 Subject: dovecot-2.2-pigeonhole: Prevent compiled binaries in testsuite f... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/e111a2393a92 changeset: 1843:e111a2393a92 user: Stephan Bosch date: Sun Jan 12 23:23:50 2014 +0100 description: Prevent compiled binaries in testsuite from ending up in distribution tarball. diffstat: Makefile.am | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r a70f5f097033 -r e111a2393a92 Makefile.am --- a/Makefile.am Tue Jan 07 18:57:38 2014 +0100 +++ b/Makefile.am Sun Jan 12 23:23:50 2014 +0100 @@ -12,6 +12,9 @@ COPYING.LGPL \ ChangeLog +dist-hook: + rm -rf `find $(distdir)/tests -type f -name '*.svbin'` + pkginc_libdir=$(dovecot_pkgincludedir)/sieve nodist_pkginc_lib_HEADERS = pigeonhole-config.h From dovecot at dovecot.org Mon Jan 13 20:57:28 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Jan 2014 20:57:28 +0200 Subject: dovecot-2.2: doveadm fs delete: Fixed non-recursive deletion bro... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/436117bbac78 changeset: 17096:436117bbac78 user: Timo Sirainen date: Mon Jan 13 20:57:12 2014 +0200 description: doveadm fs delete: Fixed non-recursive deletion broken by previous commit diffstat: src/doveadm/doveadm-fs.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (16 lines): diff -r 012d6d22aa67 -r 436117bbac78 src/doveadm/doveadm-fs.c --- a/src/doveadm/doveadm-fs.c Fri Jan 10 15:00:39 2014 -0500 +++ b/src/doveadm/doveadm-fs.c Mon Jan 13 20:57:12 2014 +0200 @@ -323,10 +323,10 @@ fs_cmd_help(cmd_fs_delete); } } - argc -= optind; argv += optind; + argc -= optind-1; argv += optind-1; if (recursive) { - cmd_fs_delete_recursive(argc+1, argv-1, async_count); + cmd_fs_delete_recursive(argc, argv, async_count); return; } From dovecot at dovecot.org Mon Jan 13 22:44:46 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Jan 2014 22:44:46 +0200 Subject: dovecot-2.2: iostream-temp: Support o_stream_pwrite() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3df6ebae9e5a changeset: 17097:3df6ebae9e5a user: Timo Sirainen date: Mon Jan 13 22:44:34 2014 +0200 description: iostream-temp: Support o_stream_pwrite() diffstat: src/lib/iostream-temp.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-) diffs (36 lines): diff -r 436117bbac78 -r 3df6ebae9e5a src/lib/iostream-temp.c --- a/src/lib/iostream-temp.c Mon Jan 13 20:57:12 2014 +0200 +++ b/src/lib/iostream-temp.c Mon Jan 13 22:44:34 2014 +0200 @@ -188,6 +188,24 @@ instream, IO_BLOCK_SIZE); } +static int +o_stream_temp_write_at(struct ostream_private *stream, + const void *data, size_t size, uoff_t offset) +{ + struct temp_ostream *tstream = (struct temp_ostream *)stream; + + if (tstream->fd == -1) { + i_assert(stream->ostream.offset == tstream->buf->used); + buffer_write(tstream->buf, offset, data, size); + stream->ostream.offset = tstream->buf->used; + } else if (pwrite_full(tstream->fd, data, size, offset) < 0) { + stream->ostream.stream_errno = errno; + i_close_fd(&tstream->fd); + return -1; + } + return 0; +} + struct ostream *iostream_temp_create(const char *temp_path_prefix, enum iostream_temp_flags flags) { @@ -197,6 +215,7 @@ tstream = i_new(struct temp_ostream, 1); tstream->ostream.sendv = o_stream_temp_sendv; tstream->ostream.send_istream = o_stream_temp_send_istream; + tstream->ostream.write_at = o_stream_temp_write_at; tstream->ostream.iostream.close = o_stream_temp_close; tstream->temp_path_prefix = i_strdup(temp_path_prefix); tstream->flags = flags; From dovecot at dovecot.org Mon Jan 13 22:58:33 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Jan 2014 22:58:33 +0200 Subject: dovecot-2.2: dbox: Removed unused code. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9927ab6b99a1 changeset: 17098:9927ab6b99a1 user: Timo Sirainen date: Mon Jan 13 15:58:13 2014 -0500 description: dbox: Removed unused code. diffstat: src/lib-storage/index/dbox-common/dbox-file.h | 1 - src/lib-storage/index/dbox-multi/mdbox-file.c | 2 +- 2 files changed, 1 insertions(+), 2 deletions(-) diffs (23 lines): diff -r 3df6ebae9e5a -r 9927ab6b99a1 src/lib-storage/index/dbox-common/dbox-file.h --- a/src/lib-storage/index/dbox-common/dbox-file.h Mon Jan 13 22:44:34 2014 +0200 +++ b/src/lib-storage/index/dbox-common/dbox-file.h Mon Jan 13 15:58:13 2014 -0500 @@ -121,7 +121,6 @@ uoff_t metadata_read_offset; unsigned int appending:1; - unsigned int deleted:1; unsigned int corrupted:1; }; diff -r 3df6ebae9e5a -r 9927ab6b99a1 src/lib-storage/index/dbox-multi/mdbox-file.c --- a/src/lib-storage/index/dbox-multi/mdbox-file.c Mon Jan 13 22:44:34 2014 +0200 +++ b/src/lib-storage/index/dbox-multi/mdbox-file.c Mon Jan 13 15:58:13 2014 -0500 @@ -278,7 +278,7 @@ if (mfile->file_id != 0) { count = array_count(&mfile->storage->open_files); - if (!file->deleted && count <= MDBOX_MAX_OPEN_UNUSED_FILES) { + if (count <= MDBOX_MAX_OPEN_UNUSED_FILES) { /* we can leave this file open for now */ mdbox_file_close_later(mfile); return; From dovecot at dovecot.org Tue Jan 14 02:43:20 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Jan 2014 02:43:20 +0200 Subject: dovecot-2.2: auth: Send original_user to auth client also when t... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/61142fbbecf0 changeset: 17099:61142fbbecf0 user: Timo Sirainen date: Tue Jan 14 02:43:09 2014 +0200 description: auth: Send original_user to auth client also when there aren't any extra fields. diffstat: src/auth/auth-request-handler.c | 11 +++++------ 1 files changed, 5 insertions(+), 6 deletions(-) diffs (21 lines): diff -r 9927ab6b99a1 -r 61142fbbecf0 src/auth/auth-request-handler.c --- a/src/auth/auth-request-handler.c Mon Jan 13 15:58:13 2014 -0500 +++ b/src/auth/auth-request-handler.c Tue Jan 14 02:43:09 2014 +0200 @@ -166,12 +166,11 @@ static void auth_str_append_extra_fields(struct auth_request *request, string_t *dest) { - if (auth_fields_is_empty(request->extra_fields)) - return; - - str_append_c(dest, '\t'); - auth_fields_append(request->extra_fields, dest, - AUTH_FIELD_FLAG_HIDDEN, 0); + if (!auth_fields_is_empty(request->extra_fields)) { + str_append_c(dest, '\t'); + auth_fields_append(request->extra_fields, dest, + AUTH_FIELD_FLAG_HIDDEN, 0); + } if (request->original_username != NULL && null_strcmp(request->original_username, request->user) != 0) { From dovecot at dovecot.org Tue Jan 14 03:25:13 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Jan 2014 03:25:13 +0200 Subject: dovecot-2.2: auth, login, mail: Added %{auth_user}, %{auth_usern... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5350000a999b changeset: 17100:5350000a999b user: Timo Sirainen date: Tue Jan 14 03:24:47 2014 +0200 description: auth, login, mail: Added %{auth_user}, %{auth_username} and %{auth_domain} They expand to the SASL authentication ID. So if master user login is done, it expands to the master user. If username changes during authentication, it expands to the original username. Otherwise %{user} and %{auth_user} are equal. diffstat: src/auth/auth-request-handler.c | 68 ++++++++++++++++++++------------- src/lib-storage/mail-storage-service.c | 31 ++++++++++++--- src/lib-storage/mail-user.c | 12 ++++++ src/lib-storage/mail-user.h | 2 +- src/login-common/client-common.c | 49 +++++++++++++++--------- src/login-common/client-common.h | 2 +- src/login-common/sasl-server.c | 10 +++++ 7 files changed, 119 insertions(+), 55 deletions(-) diffs (truncated from 379 to 300 lines): diff -r 61142fbbecf0 -r 5350000a999b src/auth/auth-request-handler.c --- a/src/auth/auth-request-handler.c Tue Jan 14 02:43:09 2014 +0200 +++ b/src/auth/auth-request-handler.c Tue Jan 14 03:24:47 2014 +0200 @@ -177,6 +177,8 @@ auth_str_add_keyvalue(dest, "original_user", request->original_username); } + if (request->master_user != NULL) + auth_str_add_keyvalue(dest, "auth_user", request->master_user); if (!request->auth_only && auth_fields_exists(request->extra_fields, "proxy")) { @@ -621,6 +623,44 @@ return TRUE; } +static void auth_str_append_userdb_extra_fields(struct auth_request *request, + string_t *dest) +{ + str_append_c(dest, '\t'); + auth_fields_append(request->userdb_reply, dest, + AUTH_FIELD_FLAG_HIDDEN, 0); + + if (request->master_user != NULL && + !auth_fields_exists(request->userdb_reply, "master_user")) { + auth_str_add_keyvalue(dest, "master_user", + request->master_user); + } + if (*request->set->anonymous_username != '\0' && + strcmp(request->user, request->set->anonymous_username) == 0) { + /* this is an anonymous login, either via ANONYMOUS + SASL mechanism or simply logging in as the anonymous + user via another mechanism */ + str_append(dest, "\tanonymous"); + } + /* generate auth_token when master service provided session_pid */ + if (request->request_auth_token && + request->session_pid != (pid_t)-1) { + const char *auth_token = + auth_token_get(request->service, + dec2str(request->session_pid), + request->user, + request->session_id); + auth_str_add_keyvalue(dest, "auth_token", auth_token); + } + if (request->master_user != NULL) { + auth_str_add_keyvalue(dest, "auth_user", request->master_user); + } else if (request->original_username != NULL && + strcmp(request->original_username, request->user) != 0) { + auth_str_add_keyvalue(dest, "auth_user", + request->original_username); + } +} + static void userdb_callback(enum userdb_result result, struct auth_request *request) { @@ -651,33 +691,7 @@ case USERDB_RESULT_OK: str_printfa(str, "USER\t%u\t", request->id); str_append_tabescaped(str, request->user); - str_append_c(str, '\t'); - auth_fields_append(request->userdb_reply, str, - AUTH_FIELD_FLAG_HIDDEN, 0); - - if (request->master_user != NULL && - !auth_fields_exists(request->userdb_reply, "master_user")) { - auth_str_add_keyvalue(str, "master_user", - request->master_user); - } - if (*request->set->anonymous_username != '\0' && - strcmp(request->user, - request->set->anonymous_username) == 0) { - /* this is an anonymous login, either via ANONYMOUS - SASL mechanism or simply logging in as the anonymous - user via another mechanism */ - str_append(str, "\tanonymous"); - } - /* generate auth_token when master service provided session_pid */ - if (request->request_auth_token && - request->session_pid != (pid_t)-1) { - const char *auth_token = - auth_token_get(request->service, - dec2str(request->session_pid), - request->user, - request->session_id); - auth_str_add_keyvalue(str, "auth_token", auth_token); - } + auth_str_append_userdb_extra_fields(request, str); break; } handler->master_callback(str_c(str), request->master); diff -r 61142fbbecf0 -r 5350000a999b src/lib-storage/mail-storage-service.c --- a/src/lib-storage/mail-storage-service.c Tue Jan 14 02:43:09 2014 +0200 +++ b/src/lib-storage/mail-storage-service.c Tue Jan 14 03:24:47 2014 +0200 @@ -75,7 +75,7 @@ enum mail_storage_service_flags flags; struct ioloop_context *ioloop_ctx; - const char *log_prefix, *auth_token; + const char *log_prefix, *auth_token, *auth_user; const char *system_groups_user, *uid_source, *gid_source; const struct mail_user_settings *user_set; @@ -278,6 +278,8 @@ #endif } else if (strncmp(line, "auth_token=", 11) == 0) { user->auth_token = p_strdup(user->pool, line+11); + } else if (strncmp(line, "auth_user=", 10) == 0) { + user->auth_user = p_strdup(user->pool, line+10); } else if (strncmp(line, "admin=", 6) == 0) { user->admin = line[6] == 'y' || line[6] == 'Y' || line[6] == '1'; @@ -376,6 +378,7 @@ static const struct var_expand_table * get_var_expand_table(struct master_service *service, + struct mail_storage_service_user *user, struct mail_storage_service_input *input, struct mail_storage_service_privileges *priv) { @@ -390,6 +393,9 @@ { 'i', NULL, "uid" }, { '\0', NULL, "gid" }, { '\0', NULL, "session" }, + { '\0', NULL, "auth_user" }, + { '\0', NULL, "auth_username" }, + { '\0', NULL, "auth_domain" }, { '\0', NULL, NULL } }; struct var_expand_table *tab; @@ -408,6 +414,15 @@ tab[7].value = dec2str(priv->uid == (uid_t)-1 ? geteuid() : priv->uid); tab[8].value = dec2str(priv->gid == (gid_t)-1 ? getegid() : priv->gid); tab[9].value = input->session_id; + if (user == NULL || user->auth_user == NULL) { + tab[10].value = tab[0].value; + tab[11].value = tab[1].value; + tab[12].value = tab[2].value; + } else { + tab[10].value = user->auth_user; + tab[11].value = t_strcut(user->auth_user, '@'); + tab[12].value = strchr(user->auth_user, '@'); + } return tab; } @@ -420,12 +435,12 @@ memset(&priv, 0, sizeof(priv)); priv.uid = (uid_t)-1; priv.gid = (gid_t)-1; - return get_var_expand_table(ctx->service, input, &priv); + return get_var_expand_table(ctx->service, NULL, input, &priv); } static const char * user_expand_varstr(struct master_service *service, - struct mail_storage_service_input *input, + struct mail_storage_service_user *user, struct mail_storage_service_privileges *priv, const char *str) { @@ -437,7 +452,8 @@ i_assert(*str == SETTING_STRVAR_UNEXPANDED[0]); ret = t_str_new(256); - var_expand(ret, str + 1, get_var_expand_table(service, input, priv)); + var_expand(ret, str + 1, + get_var_expand_table(service, user, &user->input, priv)); return str_c(ret); } @@ -492,9 +508,9 @@ /* variable strings are expanded in mail_user_init(), but we need the home and chroot sooner so do them separately here. */ - priv_r->home = user_expand_varstr(ctx->service, &user->input, priv_r, + priv_r->home = user_expand_varstr(ctx->service, user, priv_r, user->user_set->mail_home); - priv_r->chroot = user_expand_varstr(ctx->service, &user->input, priv_r, + priv_r->chroot = user_expand_varstr(ctx->service, user, priv_r, user->user_set->mail_chroot); return 0; } @@ -627,6 +643,7 @@ mail_user->anonymous = user->anonymous; mail_user->admin = user->admin; mail_user->auth_token = p_strdup(mail_user->pool, user->auth_token); + mail_user->auth_user = p_strdup(mail_user->pool, user->auth_user); mail_set = mail_user_set_get_storage_set(mail_user); @@ -699,7 +716,7 @@ str = t_str_new(256); var_expand(str, user->user_set->mail_log_prefix, - get_var_expand_table(ctx->service, &user->input, priv)); + get_var_expand_table(ctx->service, user, &user->input, priv)); user->log_prefix = p_strdup(user->pool, str_c(str)); } T_END; diff -r 61142fbbecf0 -r 5350000a999b src/lib-storage/mail-user.c --- a/src/lib-storage/mail-user.c Tue Jan 14 02:43:09 2014 +0200 +++ b/src/lib-storage/mail-user.c Tue Jan 14 03:24:47 2014 +0200 @@ -207,6 +207,9 @@ { 'p', NULL, "pid" }, { 'i', NULL, "uid" }, { '\0', NULL, "gid" }, + { '\0', NULL, "auth_user" }, + { '\0', NULL, "auth_username" }, + { '\0', NULL, "auth_domain" }, { '\0', NULL, NULL } }; struct var_expand_table *tab; @@ -232,6 +235,15 @@ tab[7].value = my_pid; tab[8].value = p_strdup(user->pool, dec2str(user->uid)); tab[9].value = p_strdup(user->pool, dec2str(user->gid)); + if (user->auth_user == NULL) { + tab[10].value = tab[0].value; + tab[11].value = tab[1].value; + tab[12].value = tab[2].value; + } else { + tab[10].value = user->auth_user; + tab[11].value = t_strcut(user->auth_user, '@'); + tab[12].value = strchr(user->auth_user, '@'); + } user->var_expand_table = tab; return user->var_expand_table; diff -r 61142fbbecf0 -r 5350000a999b src/lib-storage/mail-user.h --- a/src/lib-storage/mail-user.h Tue Jan 14 02:43:09 2014 +0200 +++ b/src/lib-storage/mail-user.h Tue Jan 14 03:24:47 2014 +0200 @@ -24,7 +24,7 @@ gid_t gid; const char *service; struct ip_addr *local_ip, *remote_ip; - const char *auth_token; + const char *auth_token, *auth_user; const struct var_expand_table *var_expand_table; /* If non-NULL, fail the user initialization with this error. diff -r 61142fbbecf0 -r 5350000a999b src/login-common/client-common.c --- a/src/login-common/client-common.c Tue Jan 14 02:43:09 2014 +0200 +++ b/src/login-common/client-common.c Tue Jan 14 03:24:47 2014 +0200 @@ -273,6 +273,7 @@ i_free(client->proxy_master_user); i_free(client->virtual_user); i_free(client->virtual_user_orig); + i_free(client->virtual_auth_user); i_free(client->auth_mech_name); i_free(client->master_data_prefix); pool_unref(&client->pool); @@ -474,28 +475,37 @@ { '\0', NULL, "orig_user" }, { '\0', NULL, "orig_username" }, { '\0', NULL, "orig_domain" }, + { '\0', NULL, "auth_user" }, + { '\0', NULL, "auth_username" }, + { '\0', NULL, "auth_domain" }, { '\0', NULL, NULL } }; +static void +get_var_expand_users(struct var_expand_table *tab, const char *user) +{ + unsigned int i; + + tab[0].value = user; + tab[1].value = t_strcut(user, '@'); + tab[2].value = strchr(user, '@'); + if (tab[2].value != NULL) tab[2].value++; + + for (i = 0; i < 3; i++) + tab[i].value = str_sanitize(tab[i].value, 80); +} + static const struct var_expand_table * get_var_expand_table(struct client *client) { struct var_expand_table *tab; - unsigned int i; tab = t_malloc(sizeof(login_var_expand_empty_tab)); memcpy(tab, login_var_expand_empty_tab, sizeof(login_var_expand_empty_tab)); - if (client->virtual_user != NULL) { - tab[0].value = client->virtual_user; - tab[1].value = t_strcut(client->virtual_user, '@'); - tab[2].value = strchr(client->virtual_user, '@'); - if (tab[2].value != NULL) tab[2].value++; - - for (i = 0; i < 3; i++) - tab[i].value = str_sanitize(tab[i].value, 80); - } + if (client->virtual_user != NULL) + get_var_expand_users(tab, client->virtual_user); tab[3].value = login_binary->protocol; tab[4].value = getenv("HOME"); From dovecot at dovecot.org Tue Jan 14 03:33:41 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Jan 2014 03:33:41 +0200 Subject: dovecot-2.2: *-login: Fix to previous commit: Default auth_user ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/632a1c79cdc3 changeset: 17101:632a1c79cdc3 user: Timo Sirainen date: Tue Jan 14 03:33:35 2014 +0200 description: *-login: Fix to previous commit: Default auth_user to original_user diffstat: src/login-common/client-common.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (16 lines): diff -r 5350000a999b -r 632a1c79cdc3 src/login-common/client-common.c --- a/src/login-common/client-common.c Tue Jan 14 03:24:47 2014 +0200 +++ b/src/login-common/client-common.c Tue Jan 14 03:33:35 2014 +0200 @@ -547,9 +547,9 @@ if (client->virtual_auth_user != NULL) get_var_expand_users(tab+22, client->virtual_auth_user); else { - tab[22].value = tab[0].value; - tab[23].value = tab[1].value; - tab[24].value = tab[2].value; + tab[22].value = tab[19].value; + tab[23].value = tab[20].value; + tab[24].value = tab[21].value; } return tab; } From dovecot at dovecot.org Wed Jan 15 00:29:29 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Jan 2014 00:29:29 +0200 Subject: dovecot-2.2: lib-http: Allow calling http_client_request_add_hea... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/63244d272133 changeset: 17102:63244d272133 user: Timo Sirainen date: Wed Jan 15 00:28:20 2014 +0200 description: lib-http: Allow calling http_client_request_add_header() when retrying requests. diffstat: src/lib-http/http-client-request.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diffs (16 lines): diff -r 632a1c79cdc3 -r 63244d272133 src/lib-http/http-client-request.c --- a/src/lib-http/http-client-request.c Tue Jan 14 03:33:35 2014 +0200 +++ b/src/lib-http/http-client-request.c Wed Jan 15 00:28:20 2014 +0200 @@ -201,7 +201,11 @@ void http_client_request_add_header(struct http_client_request *req, const char *key, const char *value) { - i_assert(req->state == HTTP_REQUEST_STATE_NEW); + i_assert(req->state == HTTP_REQUEST_STATE_NEW || + /* allow calling for retries */ + req->state == HTTP_REQUEST_STATE_GOT_RESPONSE || + req->state == HTTP_REQUEST_STATE_ABORTED); + /* mark presence of special headers */ switch (key[0]) { case 'c': case 'C': From dovecot at dovecot.org Wed Jan 15 00:29:29 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Jan 2014 00:29:29 +0200 Subject: dovecot-2.2: lib-http: Added http_client_request_remove_header() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3f3c9f93a0b3 changeset: 17103:3f3c9f93a0b3 user: Timo Sirainen date: Wed Jan 15 00:28:35 2014 +0200 description: lib-http: Added http_client_request_remove_header() diffstat: src/lib-http/http-client-request.c | 28 ++++++++++++++++++++++++++++ src/lib-http/http-client.h | 2 ++ 2 files changed, 30 insertions(+), 0 deletions(-) diffs (50 lines): diff -r 63244d272133 -r 3f3c9f93a0b3 src/lib-http/http-client-request.c --- a/src/lib-http/http-client-request.c Wed Jan 15 00:28:20 2014 +0200 +++ b/src/lib-http/http-client-request.c Wed Jan 15 00:28:35 2014 +0200 @@ -240,6 +240,34 @@ str_printfa(req->headers, "%s: %s\r\n", key, value); } +void http_client_request_remove_header(struct http_client_request *req, + const char *key) +{ + const unsigned char *data, *p; + size_t size, line_len, line_start_pos; + unsigned int key_len = strlen(key); + + i_assert(req->state == HTTP_REQUEST_STATE_NEW || + /* allow calling for retries */ + req->state == HTTP_REQUEST_STATE_GOT_RESPONSE || + req->state == HTTP_REQUEST_STATE_ABORTED); + + data = str_data(req->headers); + size = str_len(req->headers); + while ((p = memchr(data, '\n', size)) != NULL) { + line_len = (p+1) - data; + if (size > key_len && i_memcasecmp(data, key, key_len) == 0 && + data[key_len] == ':' && data[key_len+1] == ' ') { + /* key was found from header, replace its value */ + line_start_pos = str_len(req->headers) - size; + str_delete(req->headers, line_start_pos, line_len); + break; + } + size -= line_len; + data += line_len; + } +} + void http_client_request_set_date(struct http_client_request *req, time_t date) { diff -r 63244d272133 -r 3f3c9f93a0b3 src/lib-http/http-client.h --- a/src/lib-http/http-client.h Wed Jan 15 00:28:20 2014 +0200 +++ b/src/lib-http/http-client.h Wed Jan 15 00:28:35 2014 +0200 @@ -172,6 +172,8 @@ void http_client_request_add_header(struct http_client_request *req, const char *key, const char *value); +void http_client_request_remove_header(struct http_client_request *req, + const char *key); void http_client_request_set_date(struct http_client_request *req, time_t date); From dovecot at dovecot.org Wed Jan 15 00:58:15 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Jan 2014 00:58:15 +0200 Subject: dovecot-2.2: lib-compression: Added initial support for LZ4 Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fb4a0a84da50 changeset: 17104:fb4a0a84da50 user: Timo Sirainen date: Wed Jan 15 00:57:59 2014 +0200 description: lib-compression: Added initial support for LZ4 There's no standard file format for LZ4, so we created our own. The code has had only minimal testing currently, so there may be bugs. diffstat: configure.ac | 26 +++ src/lib-compression/Makefile.am | 2 + src/lib-compression/compression.c | 18 ++ src/lib-compression/iostream-lz4.h | 30 +++ src/lib-compression/istream-lz4.c | 318 +++++++++++++++++++++++++++++++++++++ src/lib-compression/istream-zlib.h | 1 + src/lib-compression/ostream-lz4.c | 188 +++++++++++++++++++++ src/lib-compression/ostream-zlib.h | 1 + 8 files changed, 584 insertions(+), 0 deletions(-) diffs (truncated from 674 to 300 lines): diff -r 3f3c9f93a0b3 -r fb4a0a84da50 configure.ac --- a/configure.ac Wed Jan 15 00:28:35 2014 +0200 +++ b/configure.ac Wed Jan 15 00:57:59 2014 +0200 @@ -184,6 +184,11 @@ TEST_WITH(lzma, $withval), want_lzma=auto) +AC_ARG_WITH(lz4, +AS_HELP_STRING([--with-lz4], [Build with LZ4 compression support]), + TEST_WITH(lz4, $withval), + want_lz4=auto) + AC_ARG_WITH(libcap, AS_HELP_STRING([--with-libcap], [Build with libcap support (Dropping capabilities).]), TEST_WITH(libcap, $withval), @@ -2691,6 +2696,27 @@ ]) fi AC_SUBST(COMPRESS_LIBS) + +if test "$want_lz4" != "no"; then + AC_CHECK_HEADER(lz4.h, [ + AC_CHECK_LIB(lz4, LZ4_compress, [ + have_lz4=yes + have_compress_lib=yes + AC_DEFINE(HAVE_LZ4,, Define if you have lz4 library) + COMPRESS_LIBS="$COMPRESS_LIBS -llz4" + ], [ + if test "$want_lz4" = "yes"; then + AC_ERROR([Can't build with lz4 support: liblz4 not found]) + fi + ]) + ], [ + if test "$want_lz4" = "yes"; then + AC_ERROR([Can't build with lz4 support: lz4.h not found]) + fi + ]) +fi +AC_SUBST(COMPRESS_LIBS) + AM_CONDITIONAL(BUILD_ZLIB_PLUGIN, test "$have_compress_lib" = "yes") RPCGEN=${RPCGEN-rpcgen} diff -r 3f3c9f93a0b3 -r fb4a0a84da50 src/lib-compression/Makefile.am --- a/src/lib-compression/Makefile.am Wed Jan 15 00:28:35 2014 +0200 +++ b/src/lib-compression/Makefile.am Wed Jan 15 00:57:59 2014 +0200 @@ -7,9 +7,11 @@ libcompression_la_SOURCES = \ compression.c \ istream-lzma.c \ + istream-lz4.c \ istream-zlib.c \ istream-bzlib.c \ ostream-lzma.c \ + ostream-lz4.c \ ostream-zlib.c \ ostream-bzlib.c libcompression_la_LIBADD = \ diff -r 3f3c9f93a0b3 -r fb4a0a84da50 src/lib-compression/compression.c --- a/src/lib-compression/compression.c Wed Jan 15 00:28:35 2014 +0200 +++ b/src/lib-compression/compression.c Wed Jan 15 00:57:59 2014 +0200 @@ -4,6 +4,7 @@ #include "istream.h" #include "istream-zlib.h" #include "ostream-zlib.h" +#include "iostream-lz4.h" #include "compression.h" #ifndef HAVE_ZLIB @@ -20,6 +21,10 @@ # define i_stream_create_lzma NULL # define o_stream_create_lzma NULL #endif +#ifndef HAVE_LZ4 +# define i_stream_create_lz4 NULL +# define o_stream_create_lz4 NULL +#endif static bool is_compressed_zlib(struct istream *input) { @@ -63,6 +68,17 @@ return memcmp(data, "\xfd\x37\x7a\x58\x5a", 6) == 0; } +static bool is_compressed_lz4(struct istream *input) +{ + const unsigned char *data; + size_t size; + + if (i_stream_read_data(input, &data, &size, 6 - 1) <= 0) + return FALSE; + /* there is no standard LZ4 header, so we've created our own */ + return memcmp(data, IOSTREAM_LZ4_MAGIC, IOSTREAM_LZ4_MAGIC_LEN) == 0; +} + const struct compression_handler *compression_lookup_handler(const char *name) { unsigned int i; @@ -113,5 +129,7 @@ i_stream_create_deflate, o_stream_create_deflate }, { "xz", ".xz", is_compressed_xz, i_stream_create_lzma, o_stream_create_lzma }, + { "lz4", ".lz4", is_compressed_lz4, + i_stream_create_lz4, o_stream_create_lz4 }, { NULL, NULL, NULL, NULL, NULL } }; diff -r 3f3c9f93a0b3 -r fb4a0a84da50 src/lib-compression/iostream-lz4.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-compression/iostream-lz4.h Wed Jan 15 00:57:59 2014 +0200 @@ -0,0 +1,30 @@ +#ifndef IOSTREAM_LZ4_H +#define IOSTREAM_LZ4_H + +/* + Dovecot's LZ4 compressed files contain: + + IOSTREAM_LZ4_HEADER + n x (4 byte big-endian: compressed chunk length, compressed chunk) +*/ + +#define IOSTREAM_LZ4_MAGIC "Dovecot-LZ4\x0d\x2a\x9b\xc5" +#define IOSTREAM_LZ4_MAGIC_LEN (sizeof(IOSTREAM_LZ4_MAGIC)-1) + +struct iostream_lz4_header { + unsigned char magic[IOSTREAM_LZ4_MAGIC_LEN]; + /* OSTREAM_LZ4_CHUNK_SIZE in big-endian */ + unsigned char max_uncompressed_chunk_size[4]; +}; + +/* How large chunks we're buffering into memory before compressing them */ +#define OSTREAM_LZ4_CHUNK_SIZE (1024*64) +/* How large chunks we allow in input data before returning a failure. + This must be at least OSTREAM_LZ4_CHUNK_SIZE, but for future compatibility + should be somewhat higher (but not too high to avoid wasting memory for + corrupted files). */ +#define ISTREAM_LZ4_CHUNK_SIZE (1024*1024) + +#define IOSTREAM_LZ4_CHUNK_PREFIX_LEN 4 /* big-endian size of chunk */ + +#endif diff -r 3f3c9f93a0b3 -r fb4a0a84da50 src/lib-compression/istream-lz4.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-compression/istream-lz4.c Wed Jan 15 00:57:59 2014 +0200 @@ -0,0 +1,318 @@ +/* Copyright (c) 2013-2014 Dovecot authors, see the included COPYING file */ + +#include "lib.h" + +#ifdef HAVE_LZ4 + +#include "buffer.h" +#include "istream-private.h" +#include "istream-zlib.h" +#include "iostream-lz4.h" +#include + +struct lz4_istream { + struct istream_private istream; + + uoff_t stream_size; + struct stat last_parent_statbuf; + + buffer_t *chunk_buf; + uint32_t chunk_size, chunk_left, max_uncompressed_chunk_size; + + unsigned int log_errors:1; + unsigned int marked:1; + unsigned int header_read:1; +}; + +static void i_stream_lz4_close(struct iostream_private *stream, + bool close_parent) +{ + struct lz4_istream *zstream = (struct lz4_istream *)stream; + + buffer_free(&zstream->chunk_buf); + if (close_parent) + i_stream_close(zstream->istream.parent); +} + +static void lz4_read_error(struct lz4_istream *zstream, const char *error) +{ + io_stream_set_error(&zstream->istream.iostream, + "lz4.read(%s): %s at %"PRIuUOFF_T, + i_stream_get_name(&zstream->istream.istream), error, + zstream->istream.abs_start_offset + + zstream->istream.istream.v_offset); + if (zstream->log_errors) + i_error("%s", zstream->istream.iostream.error); +} + +static int i_stream_lz4_read_header(struct lz4_istream *zstream) +{ + const struct iostream_lz4_header *hdr; + const unsigned char *data; + size_t size; + int ret; + + ret = i_stream_read_data(zstream->istream.parent, &data, &size, + sizeof(*hdr)-1); + if (ret < 0) { + zstream->istream.istream.stream_errno = + zstream->istream.parent->stream_errno; + return ret; + } + if (ret == 0 && !zstream->istream.istream.eof) + return 0; + hdr = (const void *)data; + if (ret == 0 || memcmp(hdr->magic, IOSTREAM_LZ4_MAGIC, + IOSTREAM_LZ4_MAGIC_LEN) != 0) { + lz4_read_error(zstream, "wrong magic in header (not lz4 file?)"); + zstream->istream.istream.stream_errno = EINVAL; + return -1; + } + zstream->max_uncompressed_chunk_size = + ((uint32_t)hdr->max_uncompressed_chunk_size[0] << 24) | + (hdr->max_uncompressed_chunk_size[1] << 16) | + (hdr->max_uncompressed_chunk_size[2] << 8) | + hdr->max_uncompressed_chunk_size[3]; + if (zstream->max_uncompressed_chunk_size > ISTREAM_LZ4_CHUNK_SIZE) { + lz4_read_error(zstream, t_strdup_printf( + "lz4 max chunk size too large (%u > %u)", + zstream->max_uncompressed_chunk_size, + ISTREAM_LZ4_CHUNK_SIZE)); + zstream->istream.istream.stream_errno = EINVAL; + return -1; + } + i_stream_skip(zstream->istream.parent, sizeof(*hdr)); + return 1; +} + +static ssize_t i_stream_lz4_read(struct istream_private *stream) +{ + struct lz4_istream *zstream = (struct lz4_istream *)stream; + const unsigned char *data; + size_t size, max_size; + int ret; + + if (!zstream->header_read) { + if ((ret = i_stream_lz4_read_header(zstream)) <= 0) + return ret; + zstream->header_read = TRUE; + } + + if (zstream->chunk_left == 0) { + ret = i_stream_read_data(stream->parent, &data, &size, + IOSTREAM_LZ4_CHUNK_PREFIX_LEN); + if (ret < 0) { + stream->istream.stream_errno = + stream->parent->stream_errno; + if (stream->istream.stream_errno != 0) { + stream->istream.eof = TRUE; + zstream->stream_size = stream->istream.v_offset + + stream->pos - stream->skip; + } + return ret; + } + if (ret == 0 && !stream->istream.eof) + return 0; + zstream->chunk_size = zstream->chunk_left = + ((uint32_t)data[0] << 24) | + (data[1] << 16) | (data[2] << 8) | data[3]; + if (zstream->chunk_size == 0 || + zstream->chunk_size > ISTREAM_LZ4_CHUNK_SIZE) { + lz4_read_error(zstream, t_strdup_printf( + "invalid lz4 chunk size: %u", zstream->chunk_size)); + stream->istream.stream_errno = EINVAL; + return -1; + } + i_stream_skip(stream->parent, IOSTREAM_LZ4_CHUNK_PREFIX_LEN); + buffer_set_used_size(zstream->chunk_buf, 0); + } + + /* read the whole compressed chunk into memory */ + while (zstream->chunk_left > 0 && + (ret = i_stream_read_data(zstream->istream.parent, + &data, &size, 0)) > 0) { + if (size > zstream->chunk_left) + size = zstream->chunk_left; + buffer_append(zstream->chunk_buf, data, size); + i_stream_skip(zstream->istream.parent, size); + zstream->chunk_left -= size; + } + if (zstream->chunk_left > 0) { + if (ret == -1 && zstream->istream.parent->stream_errno == 0) { + lz4_read_error(zstream, "truncated lz4 chunk"); + stream->istream.stream_errno = EINVAL; + return -1; + } + zstream->istream.istream.stream_errno = + zstream->istream.parent->stream_errno; + return ret; + } + /* if we already have max_buffer_size amount of data, fail here */ + i_stream_compress(stream); + if (stream->pos >= stream->max_buffer_size) + return -2; + /* allocate enough space for the old data and the new + decompressed chunk. we don't know the original compressed size, + so just allocate the max amount of memory. */ From dovecot at dovecot.org Wed Jan 15 03:49:53 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Jan 2014 03:49:53 +0200 Subject: dovecot-2.2: Makefile: Added missing iostream-lz4.h Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ccb3535bf650 changeset: 17105:ccb3535bf650 user: Timo Sirainen date: Wed Jan 15 03:49:42 2014 +0200 description: Makefile: Added missing iostream-lz4.h diffstat: src/lib-compression/Makefile.am | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r fb4a0a84da50 -r ccb3535bf650 src/lib-compression/Makefile.am --- a/src/lib-compression/Makefile.am Wed Jan 15 00:57:59 2014 +0200 +++ b/src/lib-compression/Makefile.am Wed Jan 15 03:49:42 2014 +0200 @@ -20,6 +20,7 @@ pkginc_libdir = $(pkgincludedir) pkginc_lib_HEADERS = \ compression.h \ + iostream-lz4.h \ istream-zlib.h \ ostream-zlib.h From dovecot at dovecot.org Wed Jan 15 22:03:38 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Jan 2014 22:03:38 +0200 Subject: dovecot-2.2: imap-proxy: Recent changes caused CAPABILITY repeat... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d06f4f1bdaaf changeset: 17106:d06f4f1bdaaf user: Timo Sirainen date: Wed Jan 15 15:03:22 2014 -0500 description: imap-proxy: Recent changes caused CAPABILITY repeating with pipelining disabled. diffstat: src/imap-login/client.h | 1 + src/imap-login/imap-proxy.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diffs (27 lines): diff -r ccb3535bf650 -r d06f4f1bdaaf src/imap-login/client.h --- a/src/imap-login/client.h Wed Jan 15 03:49:42 2014 +0200 +++ b/src/imap-login/client.h Wed Jan 15 15:03:22 2014 -0500 @@ -21,6 +21,7 @@ unsigned int proxy_seen_banner:1; unsigned int skip_line:1; unsigned int id_logged:1; + unsigned int proxy_capability_request_sent:1; unsigned int client_ignores_capability_resp_code:1; unsigned int auth_mech_name_parsed:1; }; diff -r ccb3535bf650 -r d06f4f1bdaaf src/imap-login/imap-proxy.c --- a/src/imap-login/imap-proxy.c Wed Jan 15 03:49:42 2014 +0200 +++ b/src/imap-login/imap-proxy.c Wed Jan 15 15:03:22 2014 -0500 @@ -69,8 +69,10 @@ it), send the (unnecessary) CAPABILITY command to backend as well to avoid sending the CAPABILITY reply twice (untagged and OK resp code). */ - if (client->proxy_backend_capability == NULL || - client->client_ignores_capability_resp_code) { + if (!client->proxy_capability_request_sent && + (client->proxy_backend_capability == NULL || + client->client_ignores_capability_resp_code)) { + client->proxy_capability_request_sent = TRUE; str_append(str, "C CAPABILITY\r\n"); if (client->common.proxy_nopipelining) { /* authenticate only after receiving C OK reply. */ From dovecot at dovecot.org Wed Jan 15 22:07:58 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Jan 2014 22:07:58 +0200 Subject: dovecot-2.2: imap-proxy: Fixed resetting proxy state after faile... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5abd643c0dd2 changeset: 17107:5abd643c0dd2 user: Timo Sirainen date: Wed Jan 15 15:07:50 2014 -0500 description: imap-proxy: Fixed resetting proxy state after failed login. diffstat: src/imap-login/imap-proxy.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r d06f4f1bdaaf -r 5abd643c0dd2 src/imap-login/imap-proxy.c --- a/src/imap-login/imap-proxy.c Wed Jan 15 15:03:22 2014 -0500 +++ b/src/imap-login/imap-proxy.c Wed Jan 15 15:07:50 2014 -0500 @@ -376,6 +376,7 @@ imap_client->proxy_sasl_ir = FALSE; imap_client->proxy_seen_banner = FALSE; + imap_client->proxy_capability_request_sent = FALSE; client->proxy_state = IMAP_PROXY_STATE_NONE; } From dovecot at dovecot.org Wed Jan 15 22:11:30 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Jan 2014 22:11:30 +0200 Subject: dovecot-2.2: lib-index: Keep track of views and transactions in ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3f352534af56 changeset: 17108:3f352534af56 user: Timo Sirainen date: Wed Jan 15 22:11:22 2014 +0200 description: lib-index: Keep track of views and transactions in linked lists. This makes debugging easier. diffstat: src/lib-index/mail-index-private.h | 2 +- src/lib-index/mail-index-transaction-private.h | 1 + src/lib-index/mail-index-transaction.c | 3 +++ src/lib-index/mail-index-view-private.h | 2 ++ src/lib-index/mail-index-view.c | 10 +++++----- src/lib-index/mail-index.c | 2 +- 6 files changed, 13 insertions(+), 7 deletions(-) diffs (123 lines): diff -r 5abd643c0dd2 -r 3f352534af56 src/lib-index/mail-index-private.h --- a/src/lib-index/mail-index-private.h Wed Jan 15 15:07:50 2014 -0500 +++ b/src/lib-index/mail-index-private.h Wed Jan 15 22:11:22 2014 +0200 @@ -214,7 +214,7 @@ uint32_t keywords_ext_id; uint32_t modseq_ext_id; - unsigned int view_count; + struct mail_index_view *views; /* Module-specific contexts. */ ARRAY(union mail_index_module_context *) module_contexts; diff -r 5abd643c0dd2 -r 3f352534af56 src/lib-index/mail-index-transaction-private.h --- a/src/lib-index/mail-index-transaction-private.h Wed Jan 15 15:07:50 2014 -0500 +++ b/src/lib-index/mail-index-transaction-private.h Wed Jan 15 22:11:22 2014 +0200 @@ -36,6 +36,7 @@ }; struct mail_index_transaction { + struct mail_index_transaction *prev, *next; int refcount; enum mail_index_transaction_flags flags; diff -r 5abd643c0dd2 -r 3f352534af56 src/lib-index/mail-index-transaction.c --- a/src/lib-index/mail-index-transaction.c Wed Jan 15 15:07:50 2014 -0500 +++ b/src/lib-index/mail-index-transaction.c Wed Jan 15 22:11:22 2014 +0200 @@ -4,6 +4,7 @@ #include "ioloop.h" #include "array.h" #include "bsearch-insert-pos.h" +#include "llist.h" #include "mail-index-private.h" #include "mail-transaction-log-private.h" #include "mail-index-transaction-private.h" @@ -50,6 +51,7 @@ mail_index_transaction_reset_v(t); + DLLIST_REMOVE(&t->view->transactions_list, t); array_free(&t->module_contexts); mail_index_view_transaction_unref(t->view); if (t->latest_view != NULL) @@ -311,6 +313,7 @@ i_array_init(&t->module_contexts, I_MIN(5, mail_index_module_register.id)); + DLLIST_PREPEND(&view->transactions_list, t); if (hook_mail_index_transaction_created != NULL) hook_mail_index_transaction_created(t); diff -r 5abd643c0dd2 -r 3f352534af56 src/lib-index/mail-index-view-private.h --- a/src/lib-index/mail-index-view-private.h Wed Jan 15 15:07:50 2014 -0500 +++ b/src/lib-index/mail-index-view-private.h Wed Jan 15 22:11:22 2014 +0200 @@ -44,6 +44,7 @@ }; struct mail_index_view { + struct mail_index_view *prev, *next; int refcount; struct mail_index_view_vfuncs v; @@ -69,6 +70,7 @@ /* Module-specific contexts. */ ARRAY(union mail_index_view_module_context *) module_contexts; + struct mail_index_transaction *transactions_list; int transactions; unsigned int inconsistent:1; diff -r 5abd643c0dd2 -r 3f352534af56 src/lib-index/mail-index-view.c --- a/src/lib-index/mail-index-view.c Wed Jan 15 15:07:50 2014 -0500 +++ b/src/lib-index/mail-index-view.c Wed Jan 15 22:11:22 2014 +0200 @@ -3,6 +3,7 @@ #include "lib.h" #include "array.h" #include "buffer.h" +#include "llist.h" #include "mail-index-view-private.h" #include "mail-transaction-log.h" @@ -47,7 +48,7 @@ i_array_init(&dest->module_contexts, I_MIN(5, mail_index_module_register.id)); - dest->index->view_count++; + DLLIST_PREPEND(&dest->index->views, dest); } void mail_index_view_ref(struct mail_index_view *view) @@ -58,9 +59,9 @@ static void view_close(struct mail_index_view *view) { i_assert(view->refcount == 0); - i_assert(view->index->view_count > 0); + i_assert(view->index->views != NULL); - view->index->view_count--; + DLLIST_REMOVE(&view->index->views, view); mail_transaction_log_view_close(&view->log_view); @@ -626,8 +627,7 @@ i_array_init(&view->module_contexts, I_MIN(5, mail_index_module_register.id)); - - index->view_count++; + DLLIST_PREPEND(&index->views, view); return view; } diff -r 5abd643c0dd2 -r 3f352534af56 src/lib-index/mail-index.c --- a/src/lib-index/mail-index.c Wed Jan 15 15:07:50 2014 -0500 +++ b/src/lib-index/mail-index.c Wed Jan 15 22:11:22 2014 +0200 @@ -636,7 +636,7 @@ return; i_assert(!index->syncing); - i_assert(index->view_count == 0); + i_assert(index->views == NULL); if (index->map != NULL) mail_index_unmap(&index->map); From dovecot at dovecot.org Wed Jan 15 22:50:54 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Jan 2014 22:50:54 +0200 Subject: dovecot-2.2: stats: Track clock time as well as user/sys CPU time. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/43c02090c6cf changeset: 17109:43c02090c6cf user: Timo Sirainen date: Wed Jan 15 15:50:38 2014 -0500 description: stats: Track clock time as well as user/sys CPU time. diffstat: src/plugins/stats/stats-plugin.c | 5 +++++ src/plugins/stats/stats-plugin.h | 2 ++ src/stats/mail-stats.c | 1 + src/stats/mail-stats.h | 2 +- 4 files changed, 9 insertions(+), 1 deletions(-) diffs (64 lines): diff -r 3f352534af56 -r 43c02090c6cf src/plugins/stats/stats-plugin.c --- a/src/plugins/stats/stats-plugin.c Wed Jan 15 22:11:22 2014 +0200 +++ b/src/plugins/stats/stats-plugin.c Wed Jan 15 15:50:38 2014 -0500 @@ -196,6 +196,7 @@ stats_r->invol_cs = usage.ru_nivcsw; stats_r->disk_input = (unsigned long long)usage.ru_inblock * 512ULL; stats_r->disk_output = (unsigned long long)usage.ru_oublock * 512ULL; + (void)gettimeofday(&stats_r->clock_time, NULL); process_read_io_stats(stats_r); user_trans_stats_get(suser, &stats_r->trans_stats); } @@ -251,6 +252,8 @@ &old_stats->user_cpu); timeval_add_diff(&dest->sys_cpu, &new_stats->sys_cpu, &old_stats->sys_cpu); + timeval_add_diff(&dest->clock_time, &new_stats->clock_time, + &old_stats->clock_time); trans_stats_dec(&dest->trans_stats, &old_stats->trans_stats); trans_stats_add(&dest->trans_stats, &new_stats->trans_stats); } @@ -263,6 +266,8 @@ (long)stats->user_cpu.tv_usec); str_printfa(str, "\tscpu=%ld.%ld", (long)stats->sys_cpu.tv_sec, (long)stats->sys_cpu.tv_usec); + str_printfa(str, "\ttime=%ld.%ld", (long)stats->clock_time.tv_sec, + (long)stats->clock_time.tv_usec); str_printfa(str, "\tminflt=%u", stats->min_faults); str_printfa(str, "\tmajflt=%u", stats->maj_faults); str_printfa(str, "\tvolcs=%u", stats->vol_cs); diff -r 3f352534af56 -r 43c02090c6cf src/plugins/stats/stats-plugin.h --- a/src/plugins/stats/stats-plugin.h Wed Jan 15 22:11:22 2014 +0200 +++ b/src/plugins/stats/stats-plugin.h Wed Jan 15 15:50:38 2014 -0500 @@ -14,6 +14,8 @@ struct mail_stats { /* user/system CPU time used */ struct timeval user_cpu, sys_cpu; + /* clock time used (not counting the time in ioloop wait) */ + struct timeval clock_time; /* minor / major page faults */ uint32_t min_faults, maj_faults; /* voluntary / involuntary context switches */ diff -r 3f352534af56 -r 43c02090c6cf src/stats/mail-stats.c --- a/src/stats/mail-stats.c Wed Jan 15 22:11:22 2014 +0200 +++ b/src/stats/mail-stats.c Wed Jan 15 15:50:38 2014 -0500 @@ -19,6 +19,7 @@ #define EN(parsename, name) E(parsename, name, TYPE_NUM) E("ucpu", user_cpu, TYPE_TIMEVAL), E("scpu", sys_cpu, TYPE_TIMEVAL), + E("time", clock_time, TYPE_TIMEVAL), EN("minflt", min_faults), EN("majflt", maj_faults), EN("volcs", vol_cs), diff -r 3f352534af56 -r 43c02090c6cf src/stats/mail-stats.h --- a/src/stats/mail-stats.h Wed Jan 15 22:11:22 2014 +0200 +++ b/src/stats/mail-stats.h Wed Jan 15 15:50:38 2014 -0500 @@ -5,7 +5,7 @@ #include "guid.h" struct mail_stats { - struct timeval user_cpu, sys_cpu; + struct timeval user_cpu, sys_cpu, clock_time; uint32_t min_faults, maj_faults; uint32_t vol_cs, invol_cs; uint64_t disk_input, disk_output; From dovecot at dovecot.org Wed Jan 15 22:54:26 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Jan 2014 22:54:26 +0200 Subject: dovecot-2.2: stats: Also export the clock_time to doveadm. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d6b6d83efb4e changeset: 17110:d6b6d83efb4e user: Timo Sirainen date: Wed Jan 15 15:54:14 2014 -0500 description: stats: Also export the clock_time to doveadm. diffstat: src/stats/client-export.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (21 lines): diff -r 43c02090c6cf -r d6b6d83efb4e src/stats/client-export.c --- a/src/stats/client-export.c Wed Jan 15 15:50:38 2014 -0500 +++ b/src/stats/client-export.c Wed Jan 15 15:54:14 2014 -0500 @@ -97,7 +97,7 @@ static void client_export_mail_stats(string_t *str, const struct mail_stats *stats) { -#define MAIL_STATS_HEADER "\tuser_cpu\tsys_cpu" \ +#define MAIL_STATS_HEADER "\tuser_cpu\tsys_cpu\tclock_time" \ "\tmin_faults\tmaj_faults\tvol_cs\tinvol_cs" \ "\tdisk_input\tdisk_output" \ "\tread_count\tread_bytes\twrite_count\twrite_bytes" \ @@ -108,6 +108,8 @@ (unsigned int)stats->user_cpu.tv_usec); str_printfa(str, "\t%ld.%06u", (long)stats->sys_cpu.tv_sec, (unsigned int)stats->sys_cpu.tv_usec); + str_printfa(str, "\t%ld.%06u", (long)stats->clock_time.tv_sec, + (unsigned int)stats->clock_time.tv_usec); str_printfa(str, "\t%u\t%u", stats->min_faults, stats->maj_faults); str_printfa(str, "\t%u\t%u", stats->vol_cs, stats->invol_cs); str_printfa(str, "\t%llu\t%llu", From dovecot at dovecot.org Wed Jan 15 22:58:03 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Jan 2014 22:58:03 +0200 Subject: dovecot-2.2: stats plugin: Fixed updating clock_time Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/bdec18a1aa40 changeset: 17111:bdec18a1aa40 user: Timo Sirainen date: Wed Jan 15 15:57:50 2014 -0500 description: stats plugin: Fixed updating clock_time diffstat: src/plugins/stats/stats-plugin.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r d6b6d83efb4e -r bdec18a1aa40 src/plugins/stats/stats-plugin.c --- a/src/plugins/stats/stats-plugin.c Wed Jan 15 15:54:14 2014 -0500 +++ b/src/plugins/stats/stats-plugin.c Wed Jan 15 15:57:50 2014 -0500 @@ -211,6 +211,8 @@ it to NULL. when we get back to one user we'll need to set the global user again somewhere. do it here. */ stats_global_user = user; + /* skip time spent waiting in ioloop */ + suser->pre_io_stats.clock_time = ioloop_timeval; } else { i_assert(stats_global_user == NULL); From dovecot at dovecot.org Wed Jan 15 23:45:07 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Jan 2014 23:45:07 +0200 Subject: dovecot-2.2: liblib: Added str_unescape_next() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9735c6fb7e39 changeset: 17112:9735c6fb7e39 user: Timo Sirainen date: Wed Jan 15 16:44:04 2014 -0500 description: liblib: Added str_unescape_next() diffstat: src/lib/strescape.c | 24 ++++++++++++++++++++++++ src/lib/strescape.h | 5 +++++ src/lib/test-strescape.c | 13 ++++++++++++- 3 files changed, 41 insertions(+), 1 deletions(-) diffs (79 lines): diff -r bdec18a1aa40 -r 9735c6fb7e39 src/lib/strescape.c --- a/src/lib/strescape.c Wed Jan 15 15:57:50 2014 -0500 +++ b/src/lib/strescape.c Wed Jan 15 16:44:04 2014 -0500 @@ -77,6 +77,30 @@ return start; } +int str_unescape_next(const char **str, const char **unescaped_r) +{ + const char *p; + char *escaped; + bool esc_found = FALSE; + + for (p = *str; *p != '\0'; p++) { + if (*p == '"') + break; + else if (*p == '\\') { + if (p[1] == '\0') + return -1; + esc_found = TRUE; + p++; + } + } + if (*p != '"') + return -1; + escaped = p_strdup_until(unsafe_data_stack_pool, *str, p); + *str = p+1; + *unescaped_r = !esc_found ? escaped : str_unescape(escaped); + return 0; +} + void str_append_tabescaped(string_t *dest, const char *src) { for (; *src != '\0'; src++) { diff -r bdec18a1aa40 -r 9735c6fb7e39 src/lib/strescape.h --- a/src/lib/strescape.h Wed Jan 15 15:57:50 2014 -0500 +++ b/src/lib/strescape.h Wed Jan 15 16:44:04 2014 -0500 @@ -12,6 +12,11 @@ /* remove all '\' characters */ char *str_unescape(char *str); +/* Remove all '\' chars from str until '"' is reached and return the unescaped + string. *str is updated to point to the character after the '"'. Returns 0 + if ok, -1 if '"' wasn't found. */ +int str_unescape_next(const char **str, const char **unescaped_r); + /* For Dovecot's internal protocols: Escape \001, \t, \r and \n characters using \001. */ const char *str_tabescape(const char *str); diff -r bdec18a1aa40 -r 9735c6fb7e39 src/lib/test-strescape.c --- a/src/lib/test-strescape.c Wed Jan 15 15:57:50 2014 -0500 +++ b/src/lib/test-strescape.c Wed Jan 15 16:44:04 2014 -0500 @@ -25,7 +25,7 @@ { "\001\001\t\t\r\r\n\n", "\0011\0011\001t\001t\001r\001r\001n\001n" } }; unsigned char buf[1 << CHAR_BIT]; - const char *escaped, *tabstr; + const char *escaped, *tabstr, *unesc_str; string_t *str; unsigned int i; @@ -57,6 +57,17 @@ } test_end(); + test_begin("str_unescape_next"); + escaped = "foo\"bar\\\"b\\\\az\"plop"; + test_assert(str_unescape_next(&escaped, &unesc_str) == 0); + test_assert(strcmp(unesc_str, "foo") == 0); + test_assert(str_unescape_next(&escaped, &unesc_str) == 0); + test_assert(strcmp(unesc_str, "bar\"b\\az") == 0); + test_assert(str_unescape_next(&escaped, &unesc_str) == -1); + escaped = "foo\\"; + test_assert(str_unescape_next(&escaped, &unesc_str) == -1); + test_end(); + test_begin("str_tabescape"); for (i = 0; i < N_ELEMENTS(tabesc); i++) { test_assert(strcmp(str_tabunescape(t_strdup_noconst(tabesc[i].output)), From dovecot at dovecot.org Fri Jan 17 23:11:07 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 17 Jan 2014 23:11:07 +0200 Subject: dovecot-2.2: acl: Code cleanup by moving around the code and ren... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a217a938f9ae changeset: 17113:a217a938f9ae user: Timo Sirainen date: Fri Jan 17 16:10:56 2014 -0500 description: acl: Code cleanup by moving around the code and renaming functions. diffstat: src/plugins/acl/Makefile.am | 1 + src/plugins/acl/acl-api-private.h | 11 + src/plugins/acl/acl-api.c | 225 ++++++++++++ src/plugins/acl/acl-backend-vfile-update.c | 258 +++++++++++++ src/plugins/acl/acl-backend-vfile.c | 542 +--------------------------- src/plugins/acl/acl-backend-vfile.h | 20 + 6 files changed, 539 insertions(+), 518 deletions(-) diffs (truncated from 1200 to 300 lines): diff -r 9735c6fb7e39 -r a217a938f9ae src/plugins/acl/Makefile.am --- a/src/plugins/acl/Makefile.am Wed Jan 15 16:44:04 2014 -0500 +++ b/src/plugins/acl/Makefile.am Fri Jan 17 16:10:56 2014 -0500 @@ -22,6 +22,7 @@ acl-backend.c \ acl-backend-vfile.c \ acl-backend-vfile-acllist.c \ + acl-backend-vfile-update.c \ acl-cache.c \ acl-lookup-dict.c \ acl-mailbox.c \ diff -r 9735c6fb7e39 -r a217a938f9ae src/plugins/acl/acl-api-private.h --- a/src/plugins/acl/acl-api-private.h Wed Jan 15 16:44:04 2014 -0500 +++ b/src/plugins/acl/acl-api-private.h Fri Jan 17 16:10:56 2014 -0500 @@ -92,5 +92,16 @@ const char *id, const char *const *rights, const char **error_r); const char *acl_rights_export(const struct acl_rights *rights); +int acl_rights_cmp(const struct acl_rights *r1, const struct acl_rights *r2); + +const char *const * +acl_right_names_parse(pool_t pool, const char *acl, const char **error_r); +void acl_right_names_write(string_t *dest, const char *const *rights); +void acl_right_names_merge(pool_t pool, const char *const **destp, + const char *const *src, bool dup_strings); +bool acl_right_names_modify(pool_t pool, + const char *const **rightsp, + const char *const *modify_rights, + enum acl_modify_mode modify_mode); #endif diff -r 9735c6fb7e39 -r a217a938f9ae src/plugins/acl/acl-api.c --- a/src/plugins/acl/acl-api.c Wed Jan 15 16:44:04 2014 -0500 +++ b/src/plugins/acl/acl-api.c Fri Jan 17 16:10:56 2014 -0500 @@ -9,6 +9,26 @@ #include "acl-cache.h" #include "acl-api-private.h" +struct acl_letter_map { + char letter; + const char *name; +}; + +static const struct acl_letter_map acl_letter_map[] = { + { 'l', MAIL_ACL_LOOKUP }, + { 'r', MAIL_ACL_READ }, + { 'w', MAIL_ACL_WRITE }, + { 's', MAIL_ACL_WRITE_SEEN }, + { 't', MAIL_ACL_WRITE_DELETED }, + { 'i', MAIL_ACL_INSERT }, + { 'p', MAIL_ACL_POST }, + { 'e', MAIL_ACL_EXPUNGE }, + { 'k', MAIL_ACL_CREATE }, + { 'x', MAIL_ACL_DELETE }, + { 'a', MAIL_ACL_ADMIN }, + { '\0', NULL } +}; + struct acl_object *acl_object_init_from_name(struct acl_backend *backend, const char *name) { @@ -313,6 +333,23 @@ return str_c(str); } +int acl_rights_cmp(const struct acl_rights *r1, const struct acl_rights *r2) +{ + int ret; + + if (r1->global != r2->global) { + /* globals have higher priority than locals */ + return r1->global ? 1 : -1; + } + + ret = r1->id_type - r2->id_type; + if (ret != 0) + return ret; + + return null_strcmp(r1->identifier, r2->identifier); +} + + bool acl_rights_has_nonowner_lookup_changes(const struct acl_rights *rights) { const char *const *p; @@ -358,3 +395,191 @@ } return 0; } + +static const char *const * +acl_right_names_alloc(pool_t pool, ARRAY_TYPE(const_string) *rights_arr, + bool dup_strings) +{ + const char **ret, *const *rights; + unsigned int i, dest, count; + + /* sort the rights first so we can easily drop duplicates */ + array_sort(rights_arr, i_strcmp_p); + + /* @UNSAFE */ + rights = array_get(rights_arr, &count); + ret = p_new(pool, const char *, count + 1); + if (count > 0) { + ret[0] = rights[0]; + for (i = dest = 1; i < count; i++) { + if (strcmp(rights[i-1], rights[i]) != 0) + ret[dest++] = rights[i]; + } + ret[dest] = NULL; + if (dup_strings) { + for (i = 0; i < dest; i++) + ret[i] = p_strdup(pool, ret[i]); + } + } + return ret; +} + +const char *const * +acl_right_names_parse(pool_t pool, const char *acl, const char **error_r) +{ + ARRAY_TYPE(const_string) rights; + const char *const *names; + unsigned int i; + + /* parse IMAP ACL list */ + while (*acl == ' ' || *acl == '\t') + acl++; + + t_array_init(&rights, 64); + while (*acl != '\0' && *acl != ' ' && *acl != '\t' && *acl != ':') { + for (i = 0; acl_letter_map[i].letter != '\0'; i++) { + if (acl_letter_map[i].letter == *acl) + break; + } + + if (acl_letter_map[i].letter == '\0') { + *error_r = t_strdup_printf("Unknown ACL '%c'", *acl); + return NULL; + } + + array_append(&rights, &acl_letter_map[i].name, 1); + acl++; + } + while (*acl == ' ' || *acl == '\t') acl++; + + if (*acl != '\0') { + /* parse our own extended ACLs */ + if (*acl != ':') { + *error_r = "Missing ':' prefix in ACL extensions"; + return NULL; + } + + names = t_strsplit_spaces(acl + 1, ", \t"); + for (; *names != NULL; names++) { + const char *name = p_strdup(pool, *names); + array_append(&rights, &name, 1); + } + } + + return acl_right_names_alloc(pool, &rights, FALSE); +} + +void acl_right_names_write(string_t *dest, const char *const *rights) +{ + char c2[2]; + unsigned int i, j, pos; + + c2[1] = '\0'; + pos = str_len(dest); + for (i = 0; rights[i] != NULL; i++) { + /* use letters if possible */ + for (j = 0; acl_letter_map[j].name != NULL; j++) { + if (strcmp(rights[i], acl_letter_map[j].name) == 0) { + c2[0] = acl_letter_map[j].letter; + str_insert(dest, pos, c2); + pos++; + break; + } + } + if (acl_letter_map[j].name == NULL) { + /* fallback to full name */ + str_append_c(dest, ' '); + str_append(dest, rights[i]); + } + } + if (pos + 1 < str_len(dest)) { + c2[0] = ':'; + str_insert(dest, pos + 1, c2); + } +} + +void acl_right_names_merge(pool_t pool, const char *const **destp, + const char *const *src, bool dup_strings) +{ + const char *const *dest = *destp; + ARRAY_TYPE(const_string) rights; + unsigned int i; + + t_array_init(&rights, 64); + if (dest != NULL) { + for (i = 0; dest[i] != NULL; i++) + array_append(&rights, &dest[i], 1); + } + if (src != NULL) { + for (i = 0; src[i] != NULL; i++) + array_append(&rights, &src[i], 1); + } + + *destp = acl_right_names_alloc(pool, &rights, dup_strings); +} + +bool acl_right_names_modify(pool_t pool, + const char *const **rightsp, + const char *const *modify_rights, + enum acl_modify_mode modify_mode) +{ + const char *const *old_rights = *rightsp; + const char *const *new_rights = NULL; + const char *null = NULL; + ARRAY_TYPE(const_string) rights; + unsigned int i, j; + + if (modify_rights == NULL && modify_mode != ACL_MODIFY_MODE_CLEAR) { + /* nothing to do here */ + return FALSE; + } + + switch (modify_mode) { + case ACL_MODIFY_MODE_REMOVE: + if (old_rights == NULL || *old_rights == NULL) { + /* nothing to do */ + return FALSE; + } + t_array_init(&rights, 64); + for (i = 0; old_rights[i] != NULL; i++) { + for (j = 0; modify_rights[j] != NULL; j++) { + if (strcmp(old_rights[i], modify_rights[j]) == 0) + break; + } + if (modify_rights[j] == NULL) + array_append(&rights, &old_rights[i], 1); + } + new_rights = &null; + modify_rights = array_count(&rights) == 0 ? NULL : + array_idx(&rights, 0); + acl_right_names_merge(pool, &new_rights, modify_rights, TRUE); + break; + case ACL_MODIFY_MODE_ADD: + new_rights = old_rights; + acl_right_names_merge(pool, &new_rights, modify_rights, TRUE); + break; + case ACL_MODIFY_MODE_REPLACE: + new_rights = &null; + acl_right_names_merge(pool, &new_rights, modify_rights, TRUE); + break; + case ACL_MODIFY_MODE_CLEAR: + if (*rightsp == NULL) { + /* ACL didn't exist before either */ + return FALSE; + } + *rightsp = NULL; + return TRUE; + } + i_assert(new_rights != NULL); + *rightsp = new_rights; + + if (old_rights == NULL) + return new_rights[0] != NULL; + + /* see if anything changed */ + for (i = 0; old_rights[i] != NULL && new_rights[i] != NULL; i++) { + if (strcmp(old_rights[i], new_rights[i]) != 0) + return TRUE; + } + return old_rights[i] != NULL || new_rights[i] != NULL; +} diff -r 9735c6fb7e39 -r a217a938f9ae src/plugins/acl/acl-backend-vfile-update.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plugins/acl/acl-backend-vfile-update.c Fri Jan 17 16:10:56 2014 -0500 @@ -0,0 +1,258 @@ +/* Copyright (c) 2006-2014 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "array.h" +#include "bsearch-insert-pos.h" +#include "ioloop.h" +#include "str.h" +#include "strescape.h" +#include "file-dotlock.h" +#include "ostream.h" +#include "mailbox-list.h" +#include "mail-storage-private.h" +#include "acl-cache.h" +#include "acl-backend-vfile.h" + +#include + +static struct dotlock_settings dotlock_set = { + .timeout = 30, From dovecot at dovecot.org Fri Jan 17 23:24:03 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 17 Jan 2014 23:24:03 +0200 Subject: dovecot-2.2: acl: More code cleanups. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/498fcb82fcb6 changeset: 17114:498fcb82fcb6 user: Timo Sirainen date: Fri Jan 17 16:23:49 2014 -0500 description: acl: More code cleanups. diffstat: src/plugins/acl/acl-api-private.h | 2 + src/plugins/acl/acl-api.c | 50 +++++++++++++++++++ src/plugins/acl/acl-backend-vfile-update.c | 4 +- src/plugins/acl/acl-backend-vfile.c | 77 ++++------------------------- 4 files changed, 66 insertions(+), 67 deletions(-) diffs (214 lines): diff -r a217a938f9ae -r 498fcb82fcb6 src/plugins/acl/acl-api-private.h --- a/src/plugins/acl/acl-api-private.h Fri Jan 17 16:10:56 2014 -0500 +++ b/src/plugins/acl/acl-api-private.h Fri Jan 17 16:23:49 2014 -0500 @@ -92,6 +92,8 @@ const char *id, const char *const *rights, const char **error_r); const char *acl_rights_export(const struct acl_rights *rights); +int acl_rights_parse_line(const char *line, pool_t pool, + struct acl_rights *rights_r, const char **error_r); int acl_rights_cmp(const struct acl_rights *r1, const struct acl_rights *r2); const char *const * diff -r a217a938f9ae -r 498fcb82fcb6 src/plugins/acl/acl-api.c --- a/src/plugins/acl/acl-api.c Fri Jan 17 16:10:56 2014 -0500 +++ b/src/plugins/acl/acl-api.c Fri Jan 17 16:23:49 2014 -0500 @@ -3,6 +3,7 @@ #include "lib.h" #include "array.h" #include "str.h" +#include "strescape.h" #include "hash.h" #include "mail-user.h" #include "mailbox-list.h" @@ -333,6 +334,55 @@ return str_c(str); } +int acl_rights_parse_line(const char *line, pool_t pool, + struct acl_rights *rights_r, const char **error_r) +{ + const char *id_str, *const *right_names, *error = NULL; + + if (*line == '\0' || *line == '#') + return 0; + + /* [] [:] */ + if (*line == '"') { + line++; + if (str_unescape_next(&line, &id_str) < 0 || + (line[0] != ' ' && line[0] != '\0')) { + *error_r = "Invalid quoted ID"; + return -1; + } + if (line[0] == ' ') + line++; + } else { + id_str = line; + line = strchr(id_str, ' '); + if (line == NULL) + line = ""; + else + id_str = t_strdup_until(id_str, line++); + } + + memset(rights_r, 0, sizeof(*rights_r)); + + right_names = acl_right_names_parse(pool, line, &error); + if (*id_str != '-') + rights_r->rights = right_names; + else { + id_str++; + rights_r->neg_rights = right_names; + } + + if (acl_identifier_parse(id_str, rights_r) < 0) + error = t_strdup_printf("Unknown ID '%s'", id_str); + + if (error != NULL) { + *error_r = error; + return -1; + } + + rights_r->identifier = p_strdup(pool, rights_r->identifier); + return 0; +} + int acl_rights_cmp(const struct acl_rights *r1, const struct acl_rights *r2) { int ret; diff -r a217a938f9ae -r 498fcb82fcb6 src/plugins/acl/acl-backend-vfile-update.c --- a/src/plugins/acl/acl-backend-vfile-update.c Fri Jan 17 16:10:56 2014 -0500 +++ b/src/plugins/acl/acl-backend-vfile-update.c Fri Jan 17 16:23:49 2014 -0500 @@ -8,12 +8,12 @@ #include "strescape.h" #include "file-dotlock.h" #include "ostream.h" -#include "mailbox-list.h" -#include "mail-storage-private.h" +#include "mail-storage.h" #include "acl-cache.h" #include "acl-backend-vfile.h" #include +#include static struct dotlock_settings dotlock_set = { .timeout = 30, diff -r a217a938f9ae -r 498fcb82fcb6 src/plugins/acl/acl-backend-vfile.c --- a/src/plugins/acl/acl-backend-vfile.c Fri Jan 17 16:10:56 2014 -0500 +++ b/src/plugins/acl/acl-backend-vfile.c Fri Jan 17 16:23:49 2014 -0500 @@ -3,18 +3,12 @@ #include "lib.h" #include "ioloop.h" #include "array.h" -#include "str.h" -#include "strescape.h" #include "istream.h" -#include "ostream.h" #include "nfs-workarounds.h" #include "mail-storage-private.h" -#include "mailbox-list-private.h" -#include "mail-namespace.h" #include "acl-cache.h" #include "acl-backend-vfile.h" -#include #include #include #include @@ -270,61 +264,6 @@ i_free(aclobj); } -static int -acl_object_vfile_parse_line(struct acl_object_vfile *aclobj, bool global, - const char *path, const char *line, - unsigned int linenum) -{ - struct acl_rights rights; - const char *id_str, *const *right_names, *error = NULL; - - if (*line == '\0' || *line == '#') - return 0; - - /* [] [:] */ - if (*line == '"') { - line++; - if (str_unescape_next(&line, &id_str) < 0 || - (line[0] != ' ' && line[0] != '\0')) { - i_error("ACL file %s line %u: Invalid quoted ID", - path, linenum); - return -1; - } - if (line[0] == ' ') - line++; - } else { - id_str = line; - line = strchr(id_str, ' '); - if (line == NULL) - line = ""; - else - id_str = t_strdup_until(id_str, line++); - } - - memset(&rights, 0, sizeof(rights)); - rights.global = global; - - right_names = acl_right_names_parse(aclobj->rights_pool, line, &error); - if (*id_str != '-') - rights.rights = right_names; - else { - id_str++; - rights.neg_rights = right_names; - } - - if (acl_identifier_parse(id_str, &rights) < 0) - error = t_strdup_printf("Unknown ID '%s'", id_str); - - if (error != NULL) { - i_error("ACL file %s line %u: %s", path, linenum, error); - return -1; - } - - rights.identifier = p_strdup(aclobj->rights_pool, rights.identifier); - array_append(&aclobj->rights, &rights, 1); - return 0; -} - static void acl_backend_remove_all_access(struct acl_object_vfile *aclobj) { static const char *null = NULL; @@ -348,7 +287,8 @@ { struct istream *input; struct stat st; - const char *line; + struct acl_rights rights; + const char *line, *error; unsigned int linenum; int fd, ret = 0; @@ -402,12 +342,19 @@ linenum = 1; while ((line = i_stream_read_next_line(input)) != NULL) { T_BEGIN { - ret = acl_object_vfile_parse_line(aclobj, global, - path, line, - linenum++); + ret = acl_rights_parse_line(line, aclobj->rights_pool, + &rights, &error); + rights.global = global; + if (ret < 0) { + i_error("ACL file %s line %u: %s", + path, linenum, error); + } else { + array_append(&aclobj->rights, &rights, 1); + } } T_END; if (ret < 0) break; + linenum++; } if (ret < 0) { From dovecot at dovecot.org Sat Jan 18 00:33:56 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 18 Jan 2014 00:33:56 +0200 Subject: dovecot-2.2: acl: Moved acl_rights array from vfile-specific cod... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/018c66251db6 changeset: 17115:018c66251db6 user: Timo Sirainen date: Fri Jan 17 17:33:47 2014 -0500 description: acl: Moved acl_rights array from vfile-specific code to generic struct acl_object. diffstat: src/plugins/acl/acl-api-private.h | 12 + src/plugins/acl/acl-api.c | 170 +++++++++++++++++++++ src/plugins/acl/acl-backend-vfile-update.c | 17 +- src/plugins/acl/acl-backend-vfile.c | 225 ++-------------------------- src/plugins/acl/acl-backend-vfile.h | 3 - 5 files changed, 214 insertions(+), 213 deletions(-) diffs (truncated from 616 to 300 lines): diff -r 498fcb82fcb6 -r 018c66251db6 src/plugins/acl/acl-api-private.h --- a/src/plugins/acl/acl-api-private.h Fri Jan 17 16:23:49 2014 -0500 +++ b/src/plugins/acl/acl-api-private.h Fri Jan 17 17:33:47 2014 -0500 @@ -67,6 +67,9 @@ struct acl_object { struct acl_backend *backend; char *name; + + pool_t rights_pool; + ARRAY(struct acl_rights) rights; }; struct acl_object_list_iter { @@ -78,6 +81,12 @@ extern const char *const all_mailbox_rights[]; +struct acl_object_list_iter * +acl_default_object_list_init(struct acl_object *aclobj); +int acl_default_object_list_next(struct acl_object_list_iter *iter, + struct acl_rights *rights_r); +void acl_default_object_list_deinit(struct acl_object_list_iter *iter); + const char *const * acl_backend_mask_get_names(struct acl_backend *backend, const struct acl_mask *mask, pool_t pool); @@ -95,6 +104,7 @@ int acl_rights_parse_line(const char *line, pool_t pool, struct acl_rights *rights_r, const char **error_r); int acl_rights_cmp(const struct acl_rights *r1, const struct acl_rights *r2); +void acl_rights_sort(struct acl_object *aclobj); const char *const * acl_right_names_parse(pool_t pool, const char *acl, const char **error_r); @@ -105,5 +115,7 @@ const char *const **rightsp, const char *const *modify_rights, enum acl_modify_mode modify_mode); +void acl_object_rebuild_cache(struct acl_object *aclobj); +void acl_object_remove_all_access(struct acl_object *aclobj); #endif diff -r 498fcb82fcb6 -r 018c66251db6 src/plugins/acl/acl-api.c --- a/src/plugins/acl/acl-api.c Fri Jan 17 16:23:49 2014 -0500 +++ b/src/plugins/acl/acl-api.c Fri Jan 17 17:33:47 2014 -0500 @@ -185,6 +185,43 @@ iter->aclobj->backend->v.object_list_deinit(iter); } +struct acl_object_list_iter * +acl_default_object_list_init(struct acl_object *aclobj) +{ + struct acl_object_list_iter *iter; + + iter = i_new(struct acl_object_list_iter, 1); + iter->aclobj = aclobj; + + if (!array_is_created(&aclobj->rights)) { + /* we may have the object cached, but we don't have all the + rights read into memory */ + acl_cache_flush(aclobj->backend->cache, aclobj->name); + } + + if (aclobj->backend->v.object_refresh_cache(aclobj) < 0) + iter->failed = TRUE; + return iter; +} + +int acl_default_object_list_next(struct acl_object_list_iter *iter, + struct acl_rights *rights_r) +{ + const struct acl_rights *rights; + + if (iter->idx == array_count(&iter->aclobj->rights)) + return 0; + + rights = array_idx(&iter->aclobj->rights, iter->idx++); + *rights_r = *rights; + return 1; +} + +void acl_default_object_list_deinit(struct acl_object_list_iter *iter) +{ + i_free(iter); +} + struct acl_mailbox_list_context * acl_backend_nonowner_lookups_iter_init(struct acl_backend *backend) { @@ -399,6 +436,35 @@ return null_strcmp(r1->identifier, r2->identifier); } +void acl_rights_sort(struct acl_object *aclobj) +{ + struct acl_rights *rights; + unsigned int i, dest, count; + + if (!array_is_created(&aclobj->rights)) + return; + + array_sort(&aclobj->rights, acl_rights_cmp); + + /* merge identical identifiers */ + rights = array_get_modifiable(&aclobj->rights, &count); + for (dest = 0, i = 1; i < count; i++) { + if (acl_rights_cmp(&rights[i], &rights[dest]) == 0) { + /* add i's rights to dest and delete i */ + acl_right_names_merge(aclobj->rights_pool, + &rights[dest].rights, + rights[i].rights, FALSE); + acl_right_names_merge(aclobj->rights_pool, + &rights[dest].neg_rights, + rights[i].neg_rights, FALSE); + } else { + if (++dest != i) + rights[dest] = rights[i]; + } + } + if (++dest != count) + array_delete(&aclobj->rights, dest, count - dest); +} bool acl_rights_has_nonowner_lookup_changes(const struct acl_rights *rights) { @@ -633,3 +699,107 @@ } return old_rights[i] != NULL || new_rights[i] != NULL; } + +static void apply_owner_default_rights(struct acl_object *aclobj) +{ + struct acl_rights_update ru; + const char *null = NULL; + + memset(&ru, 0, sizeof(ru)); + ru.modify_mode = ACL_MODIFY_MODE_REPLACE; + ru.neg_modify_mode = ACL_MODIFY_MODE_REPLACE; + ru.rights.id_type = ACL_ID_OWNER; + ru.rights.rights = aclobj->backend->default_rights; + ru.rights.neg_rights = &null; + acl_cache_update(aclobj->backend->cache, aclobj->name, &ru); +} + +void acl_object_rebuild_cache(struct acl_object *aclobj) +{ + struct acl_rights_update ru; + enum acl_modify_mode add_mode; + const struct acl_rights *rights, *prev_match = NULL; + unsigned int i, count; + bool first_global = TRUE; + + acl_cache_flush(aclobj->backend->cache, aclobj->name); + + if (!array_is_created(&aclobj->rights)) + return; + + /* Rights are sorted by their 1) locals first, globals next, + 2) acl_id_type. We'll apply only the rights matching ourself. + + Every time acl_id_type or local/global changes, the new ACLs will + replace all of the existing ACLs. Basically this means that if + user belongs to multiple matching groups or group-overrides, their + ACLs are merged. In all other situations the ACLs are replaced + (because there aren't duplicate rights entries and a user can't + match multiple usernames). */ + memset(&ru, 0, sizeof(ru)); + rights = array_get(&aclobj->rights, &count); + if (!acl_backend_user_is_owner(aclobj->backend)) + i = 0; + else { + /* we're the owner. skip over all rights entries until we + reach ACL_ID_OWNER or higher, or alternatively when we + reach a global ACL (even ACL_ID_ANYONE overrides owner's + rights if it's global) */ + for (i = 0; i < count; i++) { + if (rights[i].id_type >= ACL_ID_OWNER || + rights[i].global) + break; + } + apply_owner_default_rights(aclobj); + /* now continue applying the rest of the rights, + if there are any */ + } + for (; i < count; i++) { + if (!acl_backend_rights_match_me(aclobj->backend, &rights[i])) + continue; + + if (prev_match == NULL || + prev_match->id_type != rights[i].id_type || + prev_match->global != rights[i].global) { + /* replace old ACLs */ + add_mode = ACL_MODIFY_MODE_REPLACE; + } else { + /* merging to existing ACLs */ + i_assert(rights[i].id_type == ACL_ID_GROUP || + rights[i].id_type == ACL_ID_GROUP_OVERRIDE); + add_mode = ACL_MODIFY_MODE_ADD; + } + prev_match = &rights[i]; + + /* If [neg_]rights is NULL it needs to be ignored. + The easiest way to do that is to just mark it with + REMOVE mode */ + ru.modify_mode = rights[i].rights == NULL ? + ACL_MODIFY_MODE_REMOVE : add_mode; + ru.neg_modify_mode = rights[i].neg_rights == NULL ? + ACL_MODIFY_MODE_REMOVE : add_mode; + ru.rights = rights[i]; + if (rights[i].global && first_global) { + /* first global: reset negative ACLs so local ACLs + can't mess things up via them */ + first_global = FALSE; + ru.neg_modify_mode = ACL_MODIFY_MODE_REPLACE; + } + acl_cache_update(aclobj->backend->cache, aclobj->name, &ru); + } +} + +void acl_object_remove_all_access(struct acl_object *aclobj) +{ + static const char *null = NULL; + struct acl_rights rights; + + memset(&rights, 0, sizeof(rights)); + rights.id_type = ACL_ID_ANYONE; + rights.rights = &null; + array_append(&aclobj->rights, &rights, 1); + + rights.id_type = ACL_ID_OWNER; + rights.rights = &null; + array_append(&aclobj->rights, &rights, 1); +} diff -r 498fcb82fcb6 -r 018c66251db6 src/plugins/acl/acl-backend-vfile-update.c --- a/src/plugins/acl/acl-backend-vfile-update.c Fri Jan 17 16:23:49 2014 -0500 +++ b/src/plugins/acl/acl-backend-vfile-update.c Fri Jan 17 17:33:47 2014 -0500 @@ -56,7 +56,7 @@ } static bool -vfile_object_modify_right(struct acl_object_vfile *aclobj, unsigned int idx, +vfile_object_modify_right(struct acl_object *aclobj, unsigned int idx, const struct acl_rights_update *update) { struct acl_rights *right; @@ -78,7 +78,7 @@ } static bool -vfile_object_add_right(struct acl_object_vfile *aclobj, unsigned int idx, +vfile_object_add_right(struct acl_object *aclobj, unsigned int idx, const struct acl_rights_update *update) { struct acl_rights right; @@ -129,7 +129,7 @@ } static int -acl_backend_vfile_update_write(struct acl_object_vfile *aclobj, +acl_backend_vfile_update_write(struct acl_object *aclobj, int fd, const char *path) { struct ostream *output; @@ -193,7 +193,8 @@ int acl_backend_vfile_object_update(struct acl_object *_aclobj, const struct acl_rights_update *update) { - struct acl_object_vfile *aclobj = (struct acl_object_vfile *)_aclobj; + 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; @@ -212,11 +213,11 @@ if (fd == -1) return -1; - if (!array_bsearch_insert_pos(&aclobj->rights, &update->rights, + if (!array_bsearch_insert_pos(&_aclobj->rights, &update->rights, acl_rights_cmp, &i)) - changed = vfile_object_add_right(aclobj, i, update); + changed = vfile_object_add_right(_aclobj, i, update); else - changed = vfile_object_modify_right(aclobj, i, update); + changed = vfile_object_modify_right(_aclobj, i, update); if (!changed) { file_dotlock_delete(&dotlock); return 0; @@ -228,7 +229,7 @@ /* 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) { + if (acl_backend_vfile_update_write(_aclobj, fd, path) < 0) { file_dotlock_delete(&dotlock); acl_cache_flush(_aclobj->backend->cache, _aclobj->name); return -1; diff -r 498fcb82fcb6 -r 018c66251db6 src/plugins/acl/acl-backend-vfile.c --- a/src/plugins/acl/acl-backend-vfile.c Fri Jan 17 16:23:49 2014 -0500 +++ b/src/plugins/acl/acl-backend-vfile.c Fri Jan 17 17:33:47 2014 -0500 From dovecot at dovecot.org Sat Jan 18 00:36:43 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 18 Jan 2014 00:36:43 +0200 Subject: dovecot-2.2: acl: Minor macro naming cleanup Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6018854c8c91 changeset: 17116:6018854c8c91 user: Timo Sirainen date: Fri Jan 17 17:36:29 2014 -0500 description: acl: Minor macro naming cleanup diffstat: src/plugins/acl/acl-backend-vfile.c | 14 +++++++------- src/plugins/acl/acl-backend-vfile.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diffs (68 lines): diff -r 018c66251db6 -r 6018854c8c91 src/plugins/acl/acl-backend-vfile.c --- a/src/plugins/acl/acl-backend-vfile.c Fri Jan 17 17:33:47 2014 -0500 +++ b/src/plugins/acl/acl-backend-vfile.c Fri Jan 17 17:36:29 2014 -0500 @@ -166,17 +166,17 @@ if (validity->last_check + (time_t)backend->cache_secs > ioloop_time) { /* use the cached value */ - return validity->last_mtime != VALIDITY_MTIME_NOTFOUND; + return validity->last_mtime != ACL_VFILE_VALIDITY_MTIME_NOTFOUND; } validity->last_check = ioloop_time; if (stat(path, &st) < 0) { if (errno == ENOENT || errno == ENOTDIR) { - validity->last_mtime = VALIDITY_MTIME_NOTFOUND; + validity->last_mtime = ACL_VFILE_VALIDITY_MTIME_NOTFOUND; return 0; } if (errno == EACCES) { - validity->last_mtime = VALIDITY_MTIME_NOACCESS; + validity->last_mtime = ACL_VFILE_VALIDITY_MTIME_NOACCESS; return 1; } i_error("stat(%s) failed: %m", path); @@ -283,14 +283,14 @@ if (errno == ENOENT || errno == ENOTDIR) { if (aclobj->backend->debug) i_debug("acl vfile: file %s not found", path); - validity->last_mtime = VALIDITY_MTIME_NOTFOUND; + validity->last_mtime = ACL_VFILE_VALIDITY_MTIME_NOTFOUND; } else if (errno == EACCES) { if (aclobj->backend->debug) i_debug("acl vfile: no access to file %s", path); acl_object_remove_all_access(aclobj); - validity->last_mtime = VALIDITY_MTIME_NOACCESS; + validity->last_mtime = ACL_VFILE_VALIDITY_MTIME_NOACCESS; } else { i_error("open(%s) failed: %m", path); return -1; @@ -433,10 +433,10 @@ if (ret < 0) { if (errno == ENOENT || errno == ENOTDIR) { /* if the file used to exist, we have to re-read it */ - return validity->last_mtime != VALIDITY_MTIME_NOTFOUND; + return validity->last_mtime != ACL_VFILE_VALIDITY_MTIME_NOTFOUND; } if (errno == EACCES) - return validity->last_mtime != VALIDITY_MTIME_NOACCESS; + return validity->last_mtime != ACL_VFILE_VALIDITY_MTIME_NOACCESS; i_error("stat(%s) failed: %m", path); return -1; } diff -r 018c66251db6 -r 6018854c8c91 src/plugins/acl/acl-backend-vfile.h --- a/src/plugins/acl/acl-backend-vfile.h Fri Jan 17 17:33:47 2014 -0500 +++ b/src/plugins/acl/acl-backend-vfile.h Fri Jan 17 17:36:29 2014 -0500 @@ -6,8 +6,8 @@ #define ACL_FILENAME "dovecot-acl" #define ACLLIST_FILENAME "dovecot-acl-list" -#define VALIDITY_MTIME_NOTFOUND 0 -#define VALIDITY_MTIME_NOACCESS -1 +#define ACL_VFILE_VALIDITY_MTIME_NOTFOUND 0 +#define ACL_VFILE_VALIDITY_MTIME_NOACCESS -1 struct acl_vfile_validity { time_t last_check; From dovecot at dovecot.org Mon Jan 27 14:25:15 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 27 Jan 2014 14:25:15 +0200 Subject: dovecot-2.2: lib-compression: Assert-crashfix to handling EOF in... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1a54118f4690 changeset: 17117:1a54118f4690 user: Timo Sirainen date: Mon Jan 27 14:25:03 2014 +0200 description: lib-compression: Assert-crashfix to handling EOF in LZ4 compression diffstat: src/lib-compression/istream-lz4.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 6018854c8c91 -r 1a54118f4690 src/lib-compression/istream-lz4.c --- a/src/lib-compression/istream-lz4.c Fri Jan 17 17:36:29 2014 -0500 +++ b/src/lib-compression/istream-lz4.c Mon Jan 27 14:25:03 2014 +0200 @@ -104,7 +104,7 @@ if (ret < 0) { stream->istream.stream_errno = stream->parent->stream_errno; - if (stream->istream.stream_errno != 0) { + if (stream->istream.stream_errno == 0) { stream->istream.eof = TRUE; zstream->stream_size = stream->istream.v_offset + stream->pos - stream->skip; From dovecot at dovecot.org Mon Jan 27 16:36:11 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 27 Jan 2014 16:36:11 +0200 Subject: dovecot-2.2: acl plugin: Added an alternative global ACL file th... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9376bf098692 changeset: 17118:9376bf098692 user: Timo Sirainen date: Mon Jan 27 16:35:46 2014 +0200 description: acl plugin: Added an alternative global ACL file that can contain mailbox patterns. Instead of pointing the global ACL path to a directory use a file instead. The file format is " ". Most importantly this can be used to specify default ACLs for namespaces. The mailbox pattern uses "*" and "?" wildcards currently. I'm not sure if I should still change them to IMAP "*" and "%" wildcards. That would make the behavior more complex ("%" depends on hierarchy separator), slightly slower and quota code is already also using the */? wildcards.. diffstat: src/plugins/acl/Makefile.am | 2 + src/plugins/acl/acl-api-private.h | 6 +- src/plugins/acl/acl-api.c | 28 +++++ src/plugins/acl/acl-api.h | 1 + src/plugins/acl/acl-backend-vfile.c | 114 +++++++++++++++------ src/plugins/acl/acl-backend-vfile.h | 4 +- src/plugins/acl/acl-global-file.c | 191 ++++++++++++++++++++++++++++++++++++ src/plugins/acl/acl-global-file.h | 20 +++ 8 files changed, 330 insertions(+), 36 deletions(-) diffs (truncated from 572 to 300 lines): diff -r 1a54118f4690 -r 9376bf098692 src/plugins/acl/Makefile.am --- a/src/plugins/acl/Makefile.am Mon Jan 27 14:25:03 2014 +0200 +++ b/src/plugins/acl/Makefile.am Mon Jan 27 16:35:46 2014 +0200 @@ -24,6 +24,7 @@ acl-backend-vfile-acllist.c \ acl-backend-vfile-update.c \ acl-cache.c \ + acl-global-file.c \ acl-lookup-dict.c \ acl-mailbox.c \ acl-mailbox-list.c \ @@ -36,6 +37,7 @@ acl-api-private.h \ acl-backend-vfile.h \ acl-cache.h \ + acl-global-file.h \ acl-lookup-dict.h \ acl-plugin.h \ acl-shared-storage.h \ diff -r 1a54118f4690 -r 9376bf098692 src/plugins/acl/acl-api-private.h --- a/src/plugins/acl/acl-api-private.h Mon Jan 27 14:25:03 2014 +0200 +++ b/src/plugins/acl/acl-api-private.h Mon Jan 27 16:35:46 2014 +0200 @@ -49,6 +49,7 @@ struct mailbox_list *list; struct acl_cache *cache; + struct acl_global_file *global_file; struct acl_object *default_aclobj; struct acl_mask *default_aclmask; @@ -69,7 +70,7 @@ char *name; pool_t rights_pool; - ARRAY(struct acl_rights) rights; + ARRAY_TYPE(acl_rights) rights; }; struct acl_object_list_iter { @@ -103,6 +104,8 @@ const char *acl_rights_export(const struct acl_rights *rights); int acl_rights_parse_line(const char *line, pool_t pool, struct acl_rights *rights_r, const char **error_r); +void acl_rights_dup(const struct acl_rights *src, + pool_t pool, struct acl_rights *dest_r); int acl_rights_cmp(const struct acl_rights *r1, const struct acl_rights *r2); void acl_rights_sort(struct acl_object *aclobj); @@ -117,5 +120,6 @@ enum acl_modify_mode modify_mode); void acl_object_rebuild_cache(struct acl_object *aclobj); void acl_object_remove_all_access(struct acl_object *aclobj); +void acl_object_add_global_acls(struct acl_object *aclobj); #endif diff -r 1a54118f4690 -r 9376bf098692 src/plugins/acl/acl-api.c --- a/src/plugins/acl/acl-api.c Mon Jan 27 14:25:03 2014 +0200 +++ b/src/plugins/acl/acl-api.c Mon Jan 27 16:35:46 2014 +0200 @@ -7,6 +7,7 @@ #include "hash.h" #include "mail-user.h" #include "mailbox-list.h" +#include "acl-global-file.h" #include "acl-cache.h" #include "acl-api-private.h" @@ -420,6 +421,19 @@ return 0; } +void acl_rights_dup(const struct acl_rights *src, + pool_t pool, struct acl_rights *dest_r) +{ + memset(dest_r, 0, sizeof(*dest_r)); + dest_r->id_type = src->id_type; + dest_r->identifier = p_strdup(pool, src->identifier); + dest_r->rights = src->rights == NULL ? NULL : + p_strarray_dup(pool, src->rights); + dest_r->neg_rights = src->neg_rights == NULL ? NULL : + p_strarray_dup(pool, src->neg_rights); + dest_r->global = src->global; +} + int acl_rights_cmp(const struct acl_rights *r1, const struct acl_rights *r2) { int ret; @@ -803,3 +817,17 @@ rights.rights = &null; array_append(&aclobj->rights, &rights, 1); } + +void acl_object_add_global_acls(struct acl_object *aclobj) +{ + struct acl_backend *backend = aclobj->backend; + const char *vname, *error; + + if (mailbox_list_is_valid_name(backend->list, aclobj->name, &error)) + vname = mailbox_list_get_vname(backend->list, aclobj->name); + else + vname = ""; + + acl_global_file_get(backend->global_file, vname, + aclobj->rights_pool, &aclobj->rights); +} diff -r 1a54118f4690 -r 9376bf098692 src/plugins/acl/acl-api.h --- a/src/plugins/acl/acl-api.h Mon Jan 27 14:25:03 2014 +0200 +++ b/src/plugins/acl/acl-api.h Mon Jan 27 16:35:46 2014 +0200 @@ -79,6 +79,7 @@ /* These rights are global for all users */ unsigned int global:1; }; +ARRAY_DEFINE_TYPE(acl_rights, struct acl_rights); struct acl_rights_update { struct acl_rights rights; diff -r 1a54118f4690 -r 9376bf098692 src/plugins/acl/acl-backend-vfile.c --- a/src/plugins/acl/acl-backend-vfile.c Mon Jan 27 14:25:03 2014 +0200 +++ b/src/plugins/acl/acl-backend-vfile.c Mon Jan 27 16:35:46 2014 +0200 @@ -6,6 +6,7 @@ #include "istream.h" #include "nfs-workarounds.h" #include "mail-storage-private.h" +#include "acl-global-file.h" #include "acl-cache.h" #include "acl-backend-vfile.h" @@ -32,10 +33,11 @@ { struct acl_backend_vfile *backend = (struct acl_backend_vfile *)_backend; + struct stat st; const char *const *tmp; tmp = t_strsplit(data, ":"); - backend->global_dir = p_strdup_empty(_backend->pool, *tmp); + backend->global_path = p_strdup_empty(_backend->pool, *tmp); backend->cache_secs = ACL_VFILE_DEFAULT_CACHE_SECS; if (*tmp != NULL) @@ -52,10 +54,28 @@ return -1; } } + if (backend->global_path != NULL) { + if (stat(backend->global_path, &st) < 0) { + if (errno != ENOENT) { + i_error("acl vfile: stat(%s) failed: %m", + backend->global_path); + return -1; + } + } else if (!S_ISDIR(st.st_mode)) { + _backend->global_file = + acl_global_file_init(backend->global_path, backend->cache_secs); + } + } if (_backend->debug) { - i_debug("acl vfile: Global ACL directory: %s", - backend->global_dir == NULL ? "(none)" : - backend->global_dir); + if (backend->global_path == NULL) + i_debug("acl vfile: Global ACLs disabled"); + else if (_backend->global_file != NULL) { + i_debug("acl vfile: Global ACL file: %s", + backend->global_path); + } else { + i_debug("acl vfile: Global ACL legacy directory: %s", + backend->global_path); + } } _backend->cache = @@ -73,28 +93,27 @@ array_free(&backend->acllist); pool_unref(&backend->acllist_pool); } + if (_backend->global_file != NULL) + acl_global_file_deinit(&_backend->global_file); pool_unref(&backend->backend.pool); } static const char * acl_backend_vfile_get_local_dir(struct acl_backend *backend, - const char *name) + const char *name, const char *vname) { struct mail_namespace *ns = mailbox_list_get_namespace(backend->list); struct mailbox_list *list = ns->list; struct mail_storage *storage; enum mailbox_list_path_type type; - const char *dir, *inbox, *vname, *error; + const char *dir, *inbox; if (*name == '\0') name = NULL; - else if (!mailbox_list_is_valid_name(list, name, &error)) - return NULL; /* 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. */ - vname = name == NULL ? "" : mailbox_list_get_vname(backend->list, name); if (mailbox_list_get_storage(&list, vname, &storage) < 0) return NULL; i_assert(list == ns->list); @@ -104,7 +123,7 @@ MAILBOX_LIST_PATH_TYPE_CONTROL : MAILBOX_LIST_PATH_TYPE_MAILBOX; if (name == NULL) { if (!mailbox_list_get_root_path(list, type, &dir)) - return FALSE; + return NULL; } else { if (mailbox_list_get_path(list, name, type, &dir) <= 0) return NULL; @@ -129,22 +148,30 @@ struct acl_backend_vfile *backend = (struct acl_backend_vfile *)_backend; struct acl_object_vfile *aclobj; - const char *dir, *vname; + const char *dir, *vname, *error; aclobj = i_new(struct acl_object_vfile, 1); aclobj->aclobj.backend = _backend; aclobj->aclobj.name = i_strdup(name); T_BEGIN { - if (backend->global_dir != NULL) { - vname = mailbox_list_get_vname(backend->backend.list, name); - aclobj->global_path = - i_strconcat(backend->global_dir, "/", vname, NULL); + if (*name == '\0' || + mailbox_list_is_valid_name(_backend->list, name, &error)) { + vname = *name == '\0' ? "" : + mailbox_list_get_vname(_backend->list, name); + + dir = acl_backend_vfile_get_local_dir(_backend, name, vname); + aclobj->local_path = dir == NULL ? NULL : + i_strconcat(dir, "/"ACL_FILENAME, NULL); + if (backend->global_path != NULL && + _backend->global_file == NULL) { + aclobj->global_path = + i_strconcat(backend->global_path, "/", name, NULL); + } + } else { + /* Invalid mailbox name, just use the default + global ACL files */ } - - dir = acl_backend_vfile_get_local_dir(_backend, name); - aclobj->local_path = dir == NULL ? NULL : - i_strconcat(dir, "/"ACL_FILENAME, NULL); } T_END; return &aclobj->aclobj; } @@ -193,7 +220,8 @@ struct acl_backend_vfile *backend = (struct acl_backend_vfile *)_backend; struct acl_backend_vfile_validity *old_validity, new_validity; - const char *path, *local_path, *global_path, *dir; + const char *path, *local_path, *global_path, *dir, *vname = ""; + const char *error; int ret; old_validity = acl_cache_get_validity(_backend->cache, name); @@ -212,16 +240,28 @@ ret = acl_backend_vfile_exists(backend, path, &new_validity.mailbox_validity); } + if (ret == 0 && - (dir = acl_backend_vfile_get_local_dir(_backend, name)) != NULL) { - local_path = t_strconcat(dir, "/", name, NULL); - ret = acl_backend_vfile_exists(backend, local_path, - &new_validity.local_validity); + (*name == '\0' || + mailbox_list_is_valid_name(_backend->list, name, &error))) { + vname = *name == '\0' ? "" : + mailbox_list_get_vname(_backend->list, name); + dir = acl_backend_vfile_get_local_dir(_backend, name, vname); + if (dir != NULL) { + local_path = t_strconcat(dir, "/", name, NULL); + ret = acl_backend_vfile_exists(backend, local_path, + &new_validity.local_validity); + } } - if (ret == 0 && backend->global_dir != NULL) { - global_path = t_strconcat(backend->global_dir, "/", name, NULL); - ret = acl_backend_vfile_exists(backend, global_path, - &new_validity.global_validity); + + if (ret == 0 && backend->global_path != NULL) { + if (_backend->global_file != NULL) + ret = acl_global_file_have_any(_backend->global_file, vname) ? 1 : 0; + else { + global_path = t_strconcat(backend->global_path, "/", name, NULL); + ret = acl_backend_vfile_exists(backend, global_path, + &new_validity.global_validity); + } } acl_cache_set_validity(_backend->cache, name, &new_validity); return ret > 0; From dovecot at dovecot.org Thu Jan 30 04:39:39 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Jan 2014 04:39:39 +0200 Subject: dovecot-2.2: lib-compression: Fixed LZ4 maximum output buffer size Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d9d2d04bb320 changeset: 17119:d9d2d04bb320 user: Teemu Huovila date: Thu Jan 30 03:38:57 2014 +0100 description: lib-compression: Fixed LZ4 maximum output buffer size diffstat: src/lib-compression/ostream-lz4.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 9376bf098692 -r d9d2d04bb320 src/lib-compression/ostream-lz4.c --- a/src/lib-compression/ostream-lz4.c Mon Jan 27 16:35:46 2014 +0200 +++ b/src/lib-compression/ostream-lz4.c Thu Jan 30 03:38:57 2014 +0100 @@ -18,7 +18,7 @@ unsigned int compressbuf_offset; /* chunk size, followed by compressed data */ - unsigned char outbuf[IOSTREAM_LZ4_CHUNK_PREFIX_LEN + CHUNK_SIZE]; + unsigned char outbuf[IOSTREAM_LZ4_CHUNK_PREFIX_LEN + LZ4_COMPRESSBOUND(CHUNK_SIZE)]; unsigned int outbuf_offset, outbuf_used; }; From dovecot at dovecot.org Thu Jan 30 23:04:46 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Jan 2014 23:04:46 +0200 Subject: dovecot-2.2: net_transmit() may have wrongly returned EPIPE error. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/93cf0434dda4 changeset: 17120:93cf0434dda4 user: Timo Sirainen date: Thu Jan 30 22:03:40 2014 +0100 description: net_transmit() may have wrongly returned EPIPE error. If errno was EPIPE before net_transmit() was called and sendto() didn't change it, we still returned error. Also removed the unlikely() call which isn't all that unlikely for non-blocking code. diffstat: src/lib/net.c | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) diffs (22 lines): diff -r d9d2d04bb320 -r 93cf0434dda4 src/lib/net.c --- a/src/lib/net.c Thu Jan 30 03:38:57 2014 +0100 +++ b/src/lib/net.c Thu Jan 30 22:03:40 2014 +0100 @@ -605,12 +605,12 @@ i_assert(len <= SSIZE_T_MAX); ret = send(fd, data, len, 0); - if (unlikely(ret == -1 && (errno == EINTR || errno == EAGAIN))) - return 0; - - if (unlikely(errno == EPIPE)) - return -2; - + if (ret == -1) { + if (errno == EINTR || errno == EAGAIN) + return 0; + if (errno == EPIPE) + return -2; + } return ret; } From dovecot at dovecot.org Thu Jan 30 23:07:07 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Jan 2014 23:07:07 +0200 Subject: dovecot-2.1: net_transmit() may have wrongly returned EPIPE error. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/0eccb40ee3c4 changeset: 15008:0eccb40ee3c4 user: Timo Sirainen date: Thu Jan 30 22:03:40 2014 +0100 description: net_transmit() may have wrongly returned EPIPE error. If errno was EPIPE before net_transmit() was called and sendto() didn't change it, we still returned error. Also removed the unlikely() call which isn't all that unlikely for non-blocking code. diffstat: src/lib/network.c | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) diffs (22 lines): diff -r 7c5172e0c5c7 -r 0eccb40ee3c4 src/lib/network.c --- a/src/lib/network.c Thu Sep 19 22:43:45 2013 +0300 +++ b/src/lib/network.c Thu Jan 30 22:03:40 2014 +0100 @@ -565,12 +565,12 @@ i_assert(len <= SSIZE_T_MAX); ret = send(fd, data, len, 0); - if (unlikely(ret == -1 && (errno == EINTR || errno == EAGAIN))) - return 0; - - if (unlikely(errno == EPIPE)) - return -2; - + if (ret == -1) { + if (errno == EINTR || errno == EAGAIN) + return 0; + if (errno == EPIPE) + return -2; + } return ret; } From dovecot at dovecot.org Fri Jan 31 03:12:44 2014 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 31 Jan 2014 03:12:44 +0200 Subject: dovecot-2.2: doveadm auth cache flush: Fixed broken default auth... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5432b55a2b87 changeset: 17121:5432b55a2b87 user: Timo Sirainen date: Fri Jan 31 02:12:30 2014 +0100 description: doveadm auth cache flush: Fixed broken default auth-master path. Broken by c41700c4a9bb. Patch by Chris Moules. diffstat: src/doveadm/doveadm-auth.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 93cf0434dda4 -r 5432b55a2b87 src/doveadm/doveadm-auth.c --- a/src/doveadm/doveadm-auth.c Thu Jan 30 22:03:40 2014 +0100 +++ b/src/doveadm/doveadm-auth.c Fri Jan 31 02:12:30 2014 +0100 @@ -240,7 +240,7 @@ if (master_socket_path == NULL) { master_socket_path = t_strconcat(doveadm_settings->base_dir, - "auth-master", NULL); + "/auth-master", NULL); } conn = doveadm_get_auth_master_conn(master_socket_path);