From dovecot at dovecot.org Wed Aug 1 14:14:06 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 01 Aug 2012 14:14:06 +0300 Subject: dovecot-2.1: lib-storage: Fixed attempting to delete a non-symli... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/8029f1b4afd0 changeset: 14646:8029f1b4afd0 user: Timo Sirainen date: Wed Aug 01 14:13:40 2012 +0300 description: lib-storage: Fixed attempting to delete a non-symlink with Solaris Also fixed error message to say it's about unlink(), not stat(). diffstat: src/lib-storage/list/mailbox-list-delete.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (18 lines): diff -r a606e9ff1476 -r 8029f1b4afd0 src/lib-storage/list/mailbox-list-delete.c --- a/src/lib-storage/list/mailbox-list-delete.c Tue Jul 31 23:10:53 2012 +0300 +++ b/src/lib-storage/list/mailbox-list-delete.c Wed Aug 01 14:13:40 2012 +0300 @@ -341,11 +341,12 @@ if (errno == ENOENT) { mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); - } else if (errno == EISDIR) { + } else if (errno == EISDIR || + errno == EPERM) { /* Solaris */ mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, "Mailbox isn't a symlink"); } else { - mailbox_list_set_critical(list, "stat(%s) failed: %m", path); + mailbox_list_set_critical(list, "unlink(%s) failed: %m", path); } return -1; } From dovecot at dovecot.org Wed Aug 1 18:30:52 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 01 Aug 2012 18:30:52 +0300 Subject: dovecot-2.2: Moved zlib/bzlib code to lib-compression library. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/378ba560ea9f changeset: 14739:378ba560ea9f user: Timo Sirainen date: Wed Aug 01 18:30:40 2012 +0300 description: Moved zlib/bzlib code to lib-compression library. diffstat: Makefile.am | 1 + configure.in | 16 +- dovecot-config.in.in | 5 +- dovecot.m4 | 8 +- src/Makefile.am | 1 + src/lib-compression/Makefile.am | 25 + src/lib-compression/compression.c | 99 +++++ src/lib-compression/compression.h | 24 + src/lib-compression/istream-bzlib.c | 345 ++++++++++++++++++++ src/lib-compression/istream-zlib.c | 516 +++++++++++++++++++++++++++++++ src/lib-compression/istream-zlib.h | 8 + src/lib-compression/ostream-bzlib.c | 222 +++++++++++++ src/lib-compression/ostream-zlib.c | 325 +++++++++++++++++++ src/lib-compression/ostream-zlib.h | 8 + src/plugins/imap-zlib/Makefile.am | 8 +- src/plugins/imap-zlib/imap-zlib-plugin.c | 11 +- src/plugins/zlib/Makefile.am | 16 +- src/plugins/zlib/istream-bzlib.c | 345 -------------------- src/plugins/zlib/istream-zlib.c | 516 ------------------------------- src/plugins/zlib/istream-zlib.h | 8 - src/plugins/zlib/ostream-bzlib.c | 222 ------------- src/plugins/zlib/ostream-zlib.c | 325 ------------------- src/plugins/zlib/ostream-zlib.h | 8 - src/plugins/zlib/zlib-plugin.c | 107 +----- src/plugins/zlib/zlib-plugin.h | 13 - 25 files changed, 1611 insertions(+), 1571 deletions(-) diffs (truncated from 3535 to 300 lines): diff -r c3a781ef0aeb -r 378ba560ea9f Makefile.am --- a/Makefile.am Tue Jul 31 19:32:03 2012 +0300 +++ b/Makefile.am Wed Aug 01 18:30:40 2012 +0300 @@ -66,6 +66,7 @@ -e "s|^\(LIBDOVECOT_LOGIN\)=.*$$|\1=-ldovecot-login|" \ -e "s|^\(LIBDOVECOT_SQL\)=.*$$|\1=-ldovecot-sql|" \ -e "s|^\(LIBDOVECOT_SSL\)=.*$$|\1=-ldovecot-ssl|" \ + -e "s|^\(LIBDOVECOT_COMPRESS\)=.*$$|\1=-ldovecot-compress|" \ -e "s|^\(LIBDOVECOT_LDA\)=.*$$|\1=-ldovecot-lda|" \ -e "s|^\(LIBDOVECOT_STORAGE\)=.*$$|\1=-ldovecot-storage|" \ -e "s|^\(LIBDOVECOT_INCLUDE\)=.*$$|\1=-I$(pkgincludedir)|" \ diff -r c3a781ef0aeb -r 378ba560ea9f configure.in --- a/configure.in Tue Jul 31 19:32:03 2012 +0300 +++ b/configure.in Wed Aug 01 18:30:40 2012 +0300 @@ -2515,6 +2515,7 @@ LIBDOVECOT_STORAGE_DEPS='$(top_builddir)/src/lib-storage/libdovecot-storage.la $(top_builddir)/src/lib-imap-storage/libimap-storage.la' LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/libdovecot-login.la' LIBDOVECOT_SSL='$(top_builddir)/src/lib-master/libmaster_ssl.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la' + LIBDOVECOT_COMPRESS='$(top_builddir)/src/lib-compression/libcompression.la' LIBDOVECOT_LDA='$(top_builddir)/src/lib-lda/libdovecot-lda.la' else LIBDOVECOT_DEPS='$(top_builddir)/src/lib-master/libmaster.la $(top_builddir)/src/lib-settings/libsettings.la $(top_builddir)/src/lib-dict/libdict.la $(top_builddir)/src/lib-dns/libdns.la $(top_builddir)/src/lib-fs/libfs.la $(top_builddir)/src/lib-imap/libimap.la $(top_builddir)/src/lib-mail/libmail.la $(top_builddir)/src/lib-auth/libauth.la $(top_builddir)/src/lib-charset/libcharset.la $(top_builddir)/src/lib/liblib.la' @@ -2524,6 +2525,7 @@ LIBDOVECOT_STORAGE_DEPS="$LIBDOVECOT_STORAGE_FIRST $LINKED_STORAGE_LIBS $LIBDOVECOT_STORAGE_LAST" LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/liblogin.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la' LIBDOVECOT_SSL='$(top_builddir)/src/lib-master/libmaster_ssl.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la' + LIBDOVECOT_COMPRESS='$(top_builddir)/src/lib-compression/libcompression.la' LIBDOVECOT_LDA='$(top_builddir)/src/lib-lda/liblda.la' fi LIBDOVECOT_STORAGE="$LIBDOVECOT_STORAGE_DEPS $LINKED_STORAGE_LDADD" @@ -2535,6 +2537,7 @@ AC_SUBST(LIBDOVECOT_LOGIN) AC_SUBST(LIBDOVECOT_SQL) AC_SUBST(LIBDOVECOT_SSL) +AC_SUBST(LIBDOVECOT_COMPRESS) AC_SUBST(LIBDOVECOT_LDA) dnl ** @@ -2576,25 +2579,27 @@ dnl ** Plugins dnl ** +COMPRESS_LIBS= if test "$want_zlib" != "no"; then AC_CHECK_HEADER(zlib.h, [ have_zlib=yes - have_zlib_plugin=yes + have_compress_lib=yes AC_DEFINE(HAVE_ZLIB,, Define if you have zlib library) + COMPRESS_LIBS="$COMPRESS_LIBS -lz" ], [ if test "$want_zlib" = "yes"; then AC_ERROR([Can't build with zlib support: zlib.h not found]) fi ]) fi -AM_CONDITIONAL(BUILD_ZLIB, test "$have_zlib" = "yes") if test "$want_bzlib" != "no"; then AC_CHECK_HEADER(bzlib.h, [ AC_CHECK_LIB(bz2, BZ2_bzdopen, [ have_bzlib=yes - have_zlib_plugin=yes + have_compress_lib=yes AC_DEFINE(HAVE_BZLIB,, Define if you have bzlib library) + COMPRESS_LIBS="$COMPRESS_LIBS -lbz2" ], [ if test "$want_bzlib" = "yes"; then AC_ERROR([Can't build with bzlib support: libbz2 not found]) @@ -2606,8 +2611,8 @@ fi ]) fi -AM_CONDITIONAL(BUILD_BZLIB, test "$have_bzlib" = "yes") -AM_CONDITIONAL(BUILD_ZLIB_PLUGIN, test "$have_zlib_plugin" = "yes") +AC_SUBST(COMPRESS_LIBS) +AM_CONDITIONAL(BUILD_ZLIB_PLUGIN, test "$have_compress_lib" = "yes") RPCGEN=${RPCGEN-rpcgen} if ! $RPCGEN -c /dev/null > /dev/null; then @@ -2747,6 +2752,7 @@ src/lib-sql/Makefile src/lib-auth/Makefile src/lib-charset/Makefile +src/lib-compression/Makefile src/lib-dict/Makefile src/lib-dns/Makefile src/lib-fs/Makefile diff -r c3a781ef0aeb -r 378ba560ea9f dovecot-config.in.in --- a/dovecot-config.in.in Tue Jul 31 19:32:03 2012 +0300 +++ b/dovecot-config.in.in Wed Aug 01 18:30:40 2012 +0300 @@ -2,11 +2,13 @@ DOVECOT_LIBS="@LIBS@" DOVECOT_SSL_LIBS="@SSL_LIBS@" DOVECOT_SQL_LIBS="@SQL_LIBS@" +DOVECOT_COMPRESS_LIBS="@COMPRESS_LIBS@" LIBDOVECOT="@LIBDOVECOT@ @MODULE_LIBS@" LIBDOVECOT_LOGIN="@LIBDOVECOT_LOGIN@ @SSL_LIBS@" LIBDOVECOT_SQL="@LIBDOVECOT_SQL@" LIBDOVECOT_SSL="@LIBDOVECOT_SSL@" +LIBDOVECOT_COMPRESS="@LIBDOVECOT_COMPRESS@" LIBDOVECOT_LDA="@LIBDOVECOT_LDA@" LIBDOVECOT_STORAGE="@LIBDOVECOT_STORAGE@" @@ -14,10 +16,11 @@ LIBDOVECOT_LOGIN_DEPS="@LIBDOVECOT_LOGIN@" LIBDOVECOT_SQL_DEPS="@LIBDOVECOT_SQL@" LIBDOVECOT_SSL_DEPS="@LIBDOVECOT_SSL@" +LIBDOVECOT_COMPRESS_DEPS="@LIBDOVECOT_COMPRESS@" LIBDOVECOT_LDA_DEPS="@LIBDOVECOT_LDA@" LIBDOVECOT_STORAGE_DEPS="@LIBDOVECOT_STORAGE_DEPS@" -LIBDOVECOT_INCLUDE="-I$(incdir) -I$(incdir)/src/lib -I$(incdir)/src/lib-dict -I$(incdir)/src/lib-dns -I$(incdir)/src/lib-mail -I$(incdir)/src/lib-imap -I$(incdir)/src/lib-fs -I$(incdir)/src/lib-charset -I$(incdir)/src/lib-auth -I$(incdir)/src/lib-master -I$(incdir)/src/lib-ssl-iostream -I$(incdir)/src/lib-settings" +LIBDOVECOT_INCLUDE="-I$(incdir) -I$(incdir)/src/lib -I$(incdir)/src/lib-dict -I$(incdir)/src/lib-dns -I$(incdir)/src/lib-mail -I$(incdir)/src/lib-imap -I$(incdir)/src/lib-fs -I$(incdir)/src/lib-charset -I$(incdir)/src/lib-auth -I$(incdir)/src/lib-master -I$(incdir)/src/lib-ssl-iostream -I$(incdir)/src/lib-compression -I$(incdir)/src/lib-settings" LIBDOVECOT_LDA_INCLUDE="-I$(incdir)/src/lib-lda -I$(incdir)/src/lda" LIBDOVECOT_STORAGE_INCLUDE="-I$(incdir)/src/lib-index -I$(incdir)/src/lib-storage -I$(incdir)/src/lib-storage/index -I$(incdir)/src/lib-storage/index/raw" LIBDOVECOT_LOGIN_INCLUDE="-I$(incdir)/src/login-common" diff -r c3a781ef0aeb -r 378ba560ea9f dovecot.m4 --- a/dovecot.m4 Tue Jul 31 19:32:03 2012 +0300 +++ b/dovecot.m4 Wed Aug 01 18:30:40 2012 +0300 @@ -6,7 +6,7 @@ # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. -# serial 7 +# serial 8 AC_DEFUN([DC_DOVECOT_MODULEDIR],[ AC_ARG_WITH(moduledir, @@ -84,9 +84,9 @@ fi AX_SUBST_L([DISTCHECK_CONFIGURE_FLAGS], [dovecotdir], [dovecot_moduledir], [dovecot_pkgincludedir], [dovecot_pkglibexecdir], [dovecot_pkglibdir], [dovecot_docdir]) - AX_SUBST_L([DOVECOT_CFLAGS], [DOVECOT_LIBS], [DOVECOT_SSL_LIBS], [DOVECOT_SQL_LIBS]) - AX_SUBST_L([LIBDOVECOT], [LIBDOVECOT_LOGIN], [LIBDOVECOT_SQL], [LIBDOVECOT_SSL], [LIBDOVECOT_LDA], [LIBDOVECOT_STORAGE]) - AX_SUBST_L([LIBDOVECOT_DEPS], [LIBDOVECOT_LOGIN_DEPS], [LIBDOVECOT_SQL_DEPS], [LIBDOVECOT_SSL_DEPS], [LIBDOVECOT_LDA_DEPS], [LIBDOVECOT_STORAGE_DEPS]) + AX_SUBST_L([DOVECOT_CFLAGS], [DOVECOT_LIBS], [DOVECOT_SSL_LIBS], [DOVECOT_SQL_LIBS], [DOVECOT_COMPRESS_LIBS]) + AX_SUBST_L([LIBDOVECOT], [LIBDOVECOT_LOGIN], [LIBDOVECOT_SQL], [LIBDOVECOT_SSL], [LIBDOVECOT_COMPRESS], [LIBDOVECOT_LDA], [LIBDOVECOT_STORAGE]) + AX_SUBST_L([LIBDOVECOT_DEPS], [LIBDOVECOT_LOGIN_DEPS], [LIBDOVECOT_SQL_DEPS], [LIBDOVECOT_SSL_DEPS], [LIBDOVECOT_COMPRESS_DEPS], [LIBDOVECOT_LDA_DEPS], [LIBDOVECOT_STORAGE_DEPS]) AX_SUBST_L([LIBDOVECOT_INCLUDE], [LIBDOVECOT_LDA_INCLUDE], [LIBDOVECOT_SERVICE_INCLUDE], [LIBDOVECOT_STORAGE_INCLUDE], [LIBDOVECOT_LOGIN_INCLUDE], [LIBDOVECOT_CONFIG_INCLUDE], [LIBDOVECOT_IMAP_INCLUDE]) DC_PLUGIN_DEPS diff -r c3a781ef0aeb -r 378ba560ea9f src/Makefile.am --- a/src/Makefile.am Tue Jul 31 19:32:03 2012 +0300 +++ b/src/Makefile.am Wed Aug 01 18:30:40 2012 +0300 @@ -16,6 +16,7 @@ lib-test \ $(LIBDOVECOT_SUBDIRS) \ lib-imap-client \ + lib-compression \ lib-dovecot \ lib-index \ lib-storage \ diff -r c3a781ef0aeb -r 378ba560ea9f src/lib-compression/Makefile.am --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-compression/Makefile.am Wed Aug 01 18:30:40 2012 +0300 @@ -0,0 +1,25 @@ +noinst_LTLIBRARIES = libcompression.la + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-test + +libcompression_la_SOURCES = \ + compression.c \ + istream-zlib.c \ + istream-bzlib.c \ + ostream-zlib.c \ + ostream-bzlib.c +libcompression_la_LIBADD = \ + $(COMPRESS_LIBS) + +pkginc_libdir = $(pkgincludedir) + compression.h \ + istream-zlib.h \ + ostream-zlib.h + +pkglib_LTLIBRARIES = libdovecot-compression.la +libdovecot_compression_la_SOURCES = +libdovecot_compression_la_LIBADD = libcompression.la ../lib/liblib.la $(MODULE_LIBS) $(COMPRESS_LIBS) +libdovecot_compression_la_DEPENDENCIES = libcompression.la +libdovecot_compression_la_LDFLAGS = -export-dynamic diff -r c3a781ef0aeb -r 378ba560ea9f src/lib-compression/compression.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-compression/compression.c Wed Aug 01 18:30:40 2012 +0300 @@ -0,0 +1,99 @@ +/* Copyright (c) 2010-2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "istream.h" +#include "istream-zlib.h" +#include "ostream-zlib.h" +#include "compression.h" + +#ifndef HAVE_ZLIB +# define i_stream_create_gz NULL +# define o_stream_create_gz NULL +#endif +#ifndef HAVE_BZLIB +# define i_stream_create_bz2 NULL +# define o_stream_create_bz2 NULL +#endif + +static bool is_compressed_zlib(struct istream *input) +{ + const unsigned char *data; + size_t size; + + /* Peek in to the stream and see if it looks like it's compressed + (based on its header). This also means that users can try to exploit + security holes in the uncompression library by APPENDing a specially + crafted mail. So let's hope zlib is free of holes. */ + if (i_stream_read_data(input, &data, &size, 1) <= 0) + return FALSE; + i_assert(size >= 2); + + return data[0] == 31 && data[1] == 139; +} + +static bool is_compressed_bzlib(struct istream *input) +{ + const unsigned char *data; + size_t size; + + if (i_stream_read_data(input, &data, &size, 4+6 - 1) <= 0) + return FALSE; + if (data[0] != 'B' || data[1] != 'Z') + return FALSE; + if (data[2] != 'h' && data[2] != '0') + return FALSE; + if (data[3] < '1' || data[3] > '9') + return FALSE; + return memcmp(data + 4, "\x31\x41\x59\x26\x53\x59", 6) == 0; +} + +const struct compression_handler *compression_lookup_handler(const char *name) +{ + unsigned int i; + + for (i = 0; compression_handlers[i].name != NULL; i++) { + if (strcmp(name, compression_handlers[i].name) == 0) + return &compression_handlers[i]; + } + return NULL; +} + +const struct compression_handler * +compression_detect_handler(struct istream *input) +{ + unsigned int i; + + for (i = 0; compression_handlers[i].name != NULL; i++) { + if (compression_handlers[i].is_compressed != NULL && + compression_handlers[i].is_compressed(input)) + return &compression_handlers[i]; + } + return NULL; +} + +const struct compression_handler * +compression_lookup_handler_from_ext(const char *path) +{ + unsigned int i, len, path_len = strlen(path); + + for (i = 0; compression_handlers[i].name != NULL; i++) { + if (compression_handlers[i].ext == NULL) + continue; + + len = strlen(compression_handlers[i].ext); + if (path_len > len && + strcmp(path + path_len - len, compression_handlers[i].ext) == 0) + return &compression_handlers[i]; + } + return NULL; +} + +const struct compression_handler compression_handlers[] = { + { "gz", ".gz", is_compressed_zlib, + i_stream_create_gz, o_stream_create_gz }, + { "bz2", ".bz2", is_compressed_bzlib, + i_stream_create_bz2, o_stream_create_bz2 }, + { "deflate", NULL, NULL, + i_stream_create_deflate, o_stream_create_deflate }, + { NULL, NULL, NULL, NULL, NULL } +}; diff -r c3a781ef0aeb -r 378ba560ea9f src/lib-compression/compression.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-compression/compression.h Wed Aug 01 18:30:40 2012 +0300 @@ -0,0 +1,24 @@ +#ifndef COMPRESSION_H +#define COMPRESSION_H + +struct compression_handler { + const char *name; + const char *ext; + bool (*is_compressed)(struct istream *input); + struct istream *(*create_istream)(struct istream *input, + bool log_errors); + struct ostream *(*create_ostream)(struct ostream *output, int level); From dovecot at dovecot.org Wed Aug 1 18:33:21 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 01 Aug 2012 18:33:21 +0300 Subject: dovecot-2.2: Removed duplicate libdovecot-ssl Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7ece66101bbd changeset: 14740:7ece66101bbd user: Timo Sirainen date: Wed Aug 01 18:33:14 2012 +0300 description: Removed duplicate libdovecot-ssl diffstat: src/lib-dovecot/Makefile.am | 2 ++ src/lib-ssl-iostream/Makefile.am | 9 --------- 2 files changed, 2 insertions(+), 9 deletions(-) diffs (28 lines): diff -r 378ba560ea9f -r 7ece66101bbd src/lib-dovecot/Makefile.am --- a/src/lib-dovecot/Makefile.am Wed Aug 01 18:30:40 2012 +0300 +++ b/src/lib-dovecot/Makefile.am Wed Aug 01 18:33:14 2012 +0300 @@ -25,6 +25,8 @@ $(LTLIBICONV) libdovecot_ssl_la_LIBADD = \ + ../lib/liblib.la \ + $(MODULE_LIBS) \ $(ssl_libs) \ $(SSL_LIBS) diff -r 378ba560ea9f -r 7ece66101bbd src/lib-ssl-iostream/Makefile.am --- a/src/lib-ssl-iostream/Makefile.am Wed Aug 01 18:30:40 2012 +0300 +++ b/src/lib-ssl-iostream/Makefile.am Wed Aug 01 18:33:14 2012 +0300 @@ -24,12 +24,3 @@ headers = \ iostream-openssl.h \ iostream-ssl.h - -pkginc_libdir=$(pkgincludedir) -pkginc_lib_HEADERS = $(headers) - -pkglib_LTLIBRARIES = libdovecot-ssl.la -libdovecot_ssl_la_SOURCES = -libdovecot_ssl_la_LIBADD = libssl_iostream.la ../lib/liblib.la $(MODULE_LIBS) $(SSL_LIBS) -libdovecot_ssl_la_DEPENDENCIES = libssl_iostream.la -libdovecot_ssl_la_LDFLAGS = -export-dynamic From dovecot at dovecot.org Wed Aug 1 18:54:02 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 01 Aug 2012 18:54:02 +0300 Subject: dovecot-2.2: o_stream_ignore_last_errors() / o_stream_nfinish() ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/558db9e46789 changeset: 14741:558db9e46789 user: Timo Sirainen date: Wed Aug 01 18:53:52 2012 +0300 description: o_stream_ignore_last_errors() / o_stream_nfinish() now marks parent streams also as checked. diffstat: src/lib/ostream.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diffs (23 lines): diff -r 7ece66101bbd -r 558db9e46789 src/lib/ostream.c --- a/src/lib/ostream.c Wed Aug 01 18:33:14 2012 +0300 +++ b/src/lib/ostream.c Wed Aug 01 18:53:52 2012 +0300 @@ -241,14 +241,17 @@ int o_stream_nfinish(struct ostream *stream) { o_stream_nflush(stream); - stream->real_stream->last_errors_not_checked = FALSE; + o_stream_ignore_last_errors(stream); errno = stream->last_failed_errno; return stream->last_failed_errno != 0 ? -1 : 0; } void o_stream_ignore_last_errors(struct ostream *stream) { - stream->real_stream->last_errors_not_checked = FALSE; + while (stream != NULL) { + stream->real_stream->last_errors_not_checked = FALSE; + stream = stream->real_stream->parent; + } } void o_stream_set_no_error_handling(struct ostream *stream, bool set) From dovecot at dovecot.org Wed Aug 1 20:24:10 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 01 Aug 2012 20:24:10 +0300 Subject: dovecot-2.1: fts: Fixed crash in fts_lookup_multi() for backends... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/8d59874e02ad changeset: 14647:8d59874e02ad user: Timo Sirainen date: Wed Aug 01 20:24:00 2012 +0300 description: fts: Fixed crash in fts_lookup_multi() for backends that can't handle it (fts-squat) diffstat: src/plugins/fts/fts-api.c | 17 ++++++++++++++++- 1 files changed, 16 insertions(+), 1 deletions(-) diffs (29 lines): diff -r 8029f1b4afd0 -r 8d59874e02ad src/plugins/fts/fts-api.c --- a/src/plugins/fts/fts-api.c Wed Aug 01 14:13:40 2012 +0300 +++ b/src/plugins/fts/fts-api.c Wed Aug 01 20:24:00 2012 +0300 @@ -318,9 +318,24 @@ struct mail_search_arg *args, bool and_args, struct fts_multi_result *result) { + unsigned int i; + i_assert(boxes[0] != NULL); - return backend->v.lookup_multi(backend, boxes, args, and_args, result); + if (backend->v.lookup_multi != NULL) { + return backend->v.lookup_multi(backend, boxes, args, + and_args, result); + } + + for (i = 0; boxes[i] != NULL; i++) ; + result->box_results = p_new(result->pool, struct fts_result, i+1); + + for (i = 0; boxes[i] != NULL; i++) { + if (backend->v.lookup(backend, boxes[i], args, + and_args, &result->box_results[i]) < 0) + return -1; + } + return 0; } void fts_backend_lookup_done(struct fts_backend *backend) From dovecot at dovecot.org Wed Aug 1 20:25:32 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 01 Aug 2012 20:25:32 +0300 Subject: dovecot-2.1: auth: winbind mechanism supports now spaces in file... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/ae4bbcc9612b changeset: 14648:ae4bbcc9612b user: Timo Sirainen date: Wed Aug 01 20:24:58 2012 +0300 description: auth: winbind mechanism supports now spaces in filenames. diffstat: src/auth/mech-winbind.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 8d59874e02ad -r ae4bbcc9612b src/auth/mech-winbind.c --- a/src/auth/mech-winbind.c Wed Aug 01 20:24:00 2012 +0300 +++ b/src/auth/mech-winbind.c Wed Aug 01 20:24:58 2012 +0300 @@ -240,7 +240,7 @@ } else if (strcmp(token[0], "AF") == 0) { const char *user, *p, *error; - user = gss_spnego ? token[2] : token[1]; + user = t_strarray_join(gss_spnego ? token+2 : token+1, " "); i_assert(user != NULL); p = strchr(user, '\\'); From dovecot at dovecot.org Wed Aug 1 20:25:33 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 01 Aug 2012 20:25:33 +0300 Subject: dovecot-2.1: auth: Support empty ldap base (for ldap servers tha... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/fd1cdeef4e2d changeset: 14649:fd1cdeef4e2d user: Timo Sirainen date: Wed Aug 01 20:25:26 2012 +0300 description: auth: Support empty ldap base (for ldap servers that support it). diffstat: src/auth/db-ldap.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r ae4bbcc9612b -r fd1cdeef4e2d src/auth/db-ldap.c --- a/src/auth/db-ldap.c Wed Aug 01 20:24:58 2012 +0300 +++ b/src/auth/db-ldap.c Wed Aug 01 20:25:26 2012 +0300 @@ -314,7 +314,8 @@ i_assert(request->msgid == -1); request->msgid = - ldap_search(conn->ld, srequest->base, conn->set.ldap_scope, + ldap_search(conn->ld, *srequest->base == '\0' ? NULL : + srequest->base, conn->set.ldap_scope, srequest->filter, srequest->attributes, 0); if (request->msgid == -1) { auth_request_log_error(request->auth_request, "ldap", From dovecot at dovecot.org Wed Aug 1 20:59:48 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 01 Aug 2012 20:59:48 +0300 Subject: dovecot-2.1: Released v2.1.9. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/bc86680293d2 changeset: 14650:bc86680293d2 user: Timo Sirainen date: Wed Aug 01 20:36:53 2012 +0300 description: Released v2.1.9. diffstat: NEWS | 24 ++++++++++++++++++++++++ configure.in | 2 +- 2 files changed, 25 insertions(+), 1 deletions(-) diffs (41 lines): diff -r fd1cdeef4e2d -r bc86680293d2 NEWS --- a/NEWS Wed Aug 01 20:25:26 2012 +0300 +++ b/NEWS Wed Aug 01 20:36:53 2012 +0300 @@ -1,3 +1,27 @@ +v2.1.9 2012-08-01 Timo Sirainen + + * mail-log plugin: Log mailbox names with UTF-8 everywhere + (instead of mUTF-7 in some places and UTF-8 in other places) + * director: Changed director_username_hash setting's default from %u + to %Lu (= lowercase usernames). This doesn't break any existing + installations, but might fix some of them. + + + doveadm: Added "auth cache flush []" command. + + Implemented dict passdb/userdb + + Implemented Redis and memcached dict backends, which can be used as + auth backends. Redis can also be used as dict-quota backend. + + Added plugin { quota_ignore_save_errors=yes } setting to allow saving + a mail when quota lookup fails with temporary failure. + - Full text search indexing might have failed for some messages, + always causing indexer-worker process to run out of memory. + - fts-lucene: Fixed handling SEARCH HEADER FROM/TO/SUBJECT/CC/BCC when + the header wasn't lowercased. + - fts-squat: Fixed crash when searching a virtual mailbox. + - pop3: Fixed assert crash when doing UIDL on empty mailbox on some + setups. + - auth: GSSAPI RFC compliancy and error handling fixes. + - Various fixes related to handling shared namespaces + v2.1.8 2012-07-03 Timo Sirainen + pop3c: Added pop3c_master_user setting. diff -r fd1cdeef4e2d -r bc86680293d2 configure.in --- a/configure.in Wed Aug 01 20:25:26 2012 +0300 +++ b/configure.in Wed Aug 01 20:36:53 2012 +0300 @@ -1,5 +1,5 @@ AC_PREREQ([2.59]) -AC_INIT([Dovecot],[2.1.8],[dovecot at dovecot.org]) +AC_INIT([Dovecot],[2.1.9],[dovecot at dovecot.org]) AC_CONFIG_SRCDIR([src]) AM_INIT_AUTOMAKE([foreign]) From dovecot at dovecot.org Wed Aug 1 20:59:48 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 01 Aug 2012 20:59:48 +0300 Subject: dovecot-2.1: Added tag 2.1.9 for changeset bc86680293d2 Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/687906b93914 changeset: 14651:687906b93914 user: Timo Sirainen date: Wed Aug 01 20:36:53 2012 +0300 description: Added tag 2.1.9 for changeset bc86680293d2 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r bc86680293d2 -r 687906b93914 .hgtags --- a/.hgtags Wed Aug 01 20:36:53 2012 +0300 +++ b/.hgtags Wed Aug 01 20:36:53 2012 +0300 @@ -85,3 +85,4 @@ 7c249e2a82a9cd33ae15ead6443c3499e16da623 2.1.6 c92fb8b928f69ca01681a2c2976304b7e4bc3afc 2.1.7 7e5f36fd989d27a2fb48250adbab8fa54ddb6083 2.1.8 +bc86680293d256d5a8009690caeb73ab2e34e359 2.1.9 From dovecot at dovecot.org Wed Aug 1 20:59:48 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 01 Aug 2012 20:59:48 +0300 Subject: dovecot-2.1: Added signature for changeset bc86680293d2 Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/8518f8b5a28b changeset: 14652:8518f8b5a28b user: Timo Sirainen date: Wed Aug 01 20:37:05 2012 +0300 description: Added signature for changeset bc86680293d2 diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 687906b93914 -r 8518f8b5a28b .hgsigs --- a/.hgsigs Wed Aug 01 20:36:53 2012 +0300 +++ b/.hgsigs Wed Aug 01 20:37:05 2012 +0300 @@ -48,3 +48,4 @@ 7c249e2a82a9cd33ae15ead6443c3499e16da623 0 iEYEABECAAYFAk+nX2sACgkQyUhSUUBVisn7uwCbBD3boxBOGEJ8OYsIJ57n5Cr09FAAoIvhxL6EHRB15AMOw4sPaALJ3/bB c92fb8b928f69ca01681a2c2976304b7e4bc3afc 0 iEYEABECAAYFAk/FIeIACgkQyUhSUUBVisk4IgCfUiXVXntqzPjJcALYRpqw4Zc7a/0An3HKWwgb6PBCbmvxBfTezNkqjqVK 7e5f36fd989d27a2fb48250adbab8fa54ddb6083 0 iEYEABECAAYFAk/yVakACgkQyUhSUUBVismekwCfSEVQjd6fwdChjd53LSt03b4UWKoAoIxd/IjLatTISlHm44iiQwzRKByo +bc86680293d256d5a8009690caeb73ab2e34e359 0 iEYEABECAAYFAlAZaTUACgkQyUhSUUBVisnTAACfU1pB34RrXEyLnpnL4Ee/oeNBYcoAnRWxTqx870Efjwf+eBPzafO0C/NU From dovecot at dovecot.org Wed Aug 1 21:14:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 01 Aug 2012 21:14:41 +0300 Subject: dovecot-2.1: auth: Minor code cleanup Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/47ebcf37af3d changeset: 14653:47ebcf37af3d user: Timo Sirainen date: Wed Aug 01 21:14:30 2012 +0300 description: auth: Minor code cleanup diffstat: src/auth/auth-cache.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 8518f8b5a28b -r 47ebcf37af3d src/auth/auth-cache.c --- a/src/auth/auth-cache.c Wed Aug 01 20:37:05 2012 +0300 +++ b/src/auth/auth-cache.c Wed Aug 01 21:14:30 2012 +0300 @@ -305,7 +305,7 @@ for (node = cache->tail; node != NULL; node = next) { next = node->next; if (auth_cache_node_is_one_of_users(node, usernames)) { - auth_cache_node_destroy(cache, cache->tail); + auth_cache_node_destroy(cache, node); ret++; } } From dovecot at dovecot.org Wed Aug 1 22:40:02 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 01 Aug 2012 22:40:02 +0300 Subject: dovecot-2.1: fts: Fixed crash on error handling Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/d499f6d0ca68 changeset: 14654:d499f6d0ca68 user: Timo Sirainen date: Wed Aug 01 22:39:57 2012 +0300 description: fts: Fixed crash on error handling diffstat: src/plugins/fts/fts-search.c | 14 ++++++++------ 1 files changed, 8 insertions(+), 6 deletions(-) diffs (25 lines): diff -r 47ebcf37af3d -r d499f6d0ca68 src/plugins/fts/fts-search.c --- a/src/plugins/fts/fts-search.c Wed Aug 01 21:14:30 2012 +0300 +++ b/src/plugins/fts/fts-search.c Wed Aug 01 22:39:57 2012 +0300 @@ -199,13 +199,15 @@ struct mail_search_arg *args, bool and_args) { - if (!fctx->virtual_mailbox) { - if (fts_search_lookup_level_single(fctx, args, and_args) < 0) - return -1; - } else T_BEGIN { - if (fts_search_lookup_level_multi(fctx, args, and_args) < 0) - return -1; + int ret; + + T_BEGIN { + ret = !fctx->virtual_mailbox ? + fts_search_lookup_level_single(fctx, args, and_args) : + fts_search_lookup_level_multi(fctx, args, and_args); } T_END; + if (ret < 0) + return -1; for (; args != NULL; args = args->next) { if (args->type != SEARCH_OR && args->type != SEARCH_SUB) From dovecot at dovecot.org Wed Aug 1 22:43:55 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 01 Aug 2012 22:43:55 +0300 Subject: dovecot-2.1: fts: Fixed a crash if virtual mailbox search couldn... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/323d6ce62567 changeset: 14655:323d6ce62567 user: Timo Sirainen date: Wed Aug 01 22:43:45 2012 +0300 description: fts: Fixed a crash if virtual mailbox search couldn't be optimized by backend. diffstat: src/plugins/fts/fts-api.c | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) diffs (20 lines): diff -r d499f6d0ca68 -r 323d6ce62567 src/plugins/fts/fts-api.c --- a/src/plugins/fts/fts-api.c Wed Aug 01 22:39:57 2012 +0300 +++ b/src/plugins/fts/fts-api.c Wed Aug 01 22:43:45 2012 +0300 @@ -323,8 +323,14 @@ i_assert(boxes[0] != NULL); if (backend->v.lookup_multi != NULL) { - return backend->v.lookup_multi(backend, boxes, args, - and_args, result); + if (backend->v.lookup_multi(backend, boxes, args, + and_args, result) < 0) + return -1; + if (result->box_results == NULL) { + result->box_results = p_new(result->pool, + struct fts_result, 1); + } + return 0; } for (i = 0; boxes[i] != NULL; i++) ; From dovecot at dovecot.org Wed Aug 1 23:14:33 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 01 Aug 2012 23:14:33 +0300 Subject: dovecot-2.1: doveadm-server: Make sure another command isn't sta... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/476381017ec7 changeset: 14656:476381017ec7 user: Timo Sirainen date: Wed Aug 01 23:14:19 2012 +0300 description: doveadm-server: Make sure another command isn't started before previous one is finished. diffstat: src/doveadm/client-connection.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diffs (32 lines): diff -r 323d6ce62567 -r 476381017ec7 src/doveadm/client-connection.c --- a/src/doveadm/client-connection.c Wed Aug 01 22:43:45 2012 +0300 +++ b/src/doveadm/client-connection.c Wed Aug 01 23:14:19 2012 +0300 @@ -21,6 +21,8 @@ #define MAX_INBUF_SIZE 1024 +static void client_connection_input(struct client_connection *conn); + struct client_connection { pool_t pool; @@ -208,6 +210,10 @@ return FALSE; } + /* make sure client_connection_input() isn't called by the ioloop that + is going to be run by doveadm_mail_cmd_server_run() */ + io_remove(&conn->io); + o_stream_cork(conn->output); ctx = doveadm_mail_cmd_server_parse(cmd_name, conn->set, &input, argc, args); if (ctx == NULL) @@ -220,6 +226,8 @@ net_set_nonblock(conn->fd, FALSE); (void)o_stream_flush(conn->output); net_set_nonblock(conn->fd, TRUE); + + conn->io = io_add(conn->fd, IO_READ, client_connection_input, conn); return TRUE; } From dovecot at dovecot.org Thu Aug 2 23:38:49 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 02 Aug 2012 23:38:49 +0300 Subject: dovecot-2.2: Makefile: Added missing headers to tarball Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/bb0b09793a29 changeset: 14742:bb0b09793a29 user: Timo Sirainen date: Thu Aug 02 23:38:30 2012 +0300 description: Makefile: Added missing headers to tarball diffstat: src/lib-ssl-iostream/Makefile.am | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (11 lines): diff -r 558db9e46789 -r bb0b09793a29 src/lib-ssl-iostream/Makefile.am --- a/src/lib-ssl-iostream/Makefile.am Wed Aug 01 18:53:52 2012 +0300 +++ b/src/lib-ssl-iostream/Makefile.am Thu Aug 02 23:38:30 2012 +0300 @@ -21,6 +21,6 @@ libssl_iostream_la_LIBADD = \ $(SSL_LIBS) -headers = \ +noinst_HEADERS = \ iostream-openssl.h \ iostream-ssl.h From dovecot at dovecot.org Thu Aug 2 23:56:15 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 02 Aug 2012 23:56:15 +0300 Subject: dovecot-2.2: Makefile: Added missing headers Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/95a423729f9c changeset: 14743:95a423729f9c user: Timo Sirainen date: Thu Aug 02 23:56:09 2012 +0300 description: Makefile: Added missing headers diffstat: src/lib-compression/Makefile.am | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r bb0b09793a29 -r 95a423729f9c src/lib-compression/Makefile.am --- a/src/lib-compression/Makefile.am Thu Aug 02 23:38:30 2012 +0300 +++ b/src/lib-compression/Makefile.am Thu Aug 02 23:56:09 2012 +0300 @@ -14,6 +14,7 @@ $(COMPRESS_LIBS) pkginc_libdir = $(pkgincludedir) +pkginc_lib_HEADERS = \ compression.h \ istream-zlib.h \ ostream-zlib.h From dovecot at dovecot.org Fri Aug 3 14:19:16 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 03 Aug 2012 14:19:16 +0300 Subject: dovecot-2.2: Makefile: Fixed -ldovecot-compression name Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5e10caeb5e5d changeset: 14744:5e10caeb5e5d user: Timo Sirainen date: Fri Aug 03 14:19:03 2012 +0300 description: Makefile: Fixed -ldovecot-compression name diffstat: Makefile.am | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 95a423729f9c -r 5e10caeb5e5d Makefile.am --- a/Makefile.am Thu Aug 02 23:56:09 2012 +0300 +++ b/Makefile.am Fri Aug 03 14:19:03 2012 +0300 @@ -66,7 +66,7 @@ -e "s|^\(LIBDOVECOT_LOGIN\)=.*$$|\1=-ldovecot-login|" \ -e "s|^\(LIBDOVECOT_SQL\)=.*$$|\1=-ldovecot-sql|" \ -e "s|^\(LIBDOVECOT_SSL\)=.*$$|\1=-ldovecot-ssl|" \ - -e "s|^\(LIBDOVECOT_COMPRESS\)=.*$$|\1=-ldovecot-compress|" \ + -e "s|^\(LIBDOVECOT_COMPRESS\)=.*$$|\1=-ldovecot-compression|" \ -e "s|^\(LIBDOVECOT_LDA\)=.*$$|\1=-ldovecot-lda|" \ -e "s|^\(LIBDOVECOT_STORAGE\)=.*$$|\1=-ldovecot-storage|" \ -e "s|^\(LIBDOVECOT_INCLUDE\)=.*$$|\1=-I$(pkgincludedir)|" \ From dovecot at dovecot.org Fri Aug 3 17:40:07 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 03 Aug 2012 17:40:07 +0300 Subject: dovecot-2.1: pop3-migration: Avoid disconnection from POP3 serve... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/ab6a4455b27d changeset: 14657:ab6a4455b27d user: Timo Sirainen date: Fri Aug 03 17:39:54 2012 +0300 description: pop3-migration: Avoid disconnection from POP3 server due to idling. diffstat: src/plugins/pop3-migration/pop3-migration-plugin.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diffs (18 lines): diff -r 476381017ec7 -r ab6a4455b27d src/plugins/pop3-migration/pop3-migration-plugin.c --- a/src/plugins/pop3-migration/pop3-migration-plugin.c Wed Aug 01 23:14:19 2012 +0300 +++ b/src/plugins/pop3-migration/pop3-migration-plugin.c Fri Aug 03 17:39:54 2012 +0300 @@ -472,8 +472,13 @@ if (pop3_mailbox_open(box->storage) < 0) return -1; + /* the POP3 server isn't connected to yet. handle all IMAP traffic + first before connecting, so POP3 server won't disconnect us due to + idling. */ + if (imap_map_read(box) < 0) + return -1; - if (pop3_map_read(box->storage) < 0 || imap_map_read(box) < 0) + if (pop3_map_read(box->storage) < 0) return -1; if (!pop3_uidl_assign_by_size(box)) { From pigeonhole at rename-it.nl Fri Aug 3 20:52:46 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 03 Aug 2012 19:52:46 +0200 Subject: dovecot-2.1-pigeonhole: Include: fixed namespace separation of :... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/6a34eda7924e changeset: 1631:6a34eda7924e user: Stephan Bosch date: Fri Aug 03 19:52:36 2012 +0200 description: Include: fixed namespace separation of :global and :personal scripts. Sieve script equality function implementation was wrong. diffstat: src/lib-sieve/sieve-script-dict.c | 29 +++++++++++++-- src/lib-sieve/sieve-script-file.c | 4 +- src/lib-sieve/sieve-script.c | 11 ++--- tests/extensions/include/execute.svtest | 27 ++++++++++++++ tests/extensions/include/included-global/namespace.sieve | 4 ++ tests/extensions/include/included/namespace.sieve | 4 ++ 6 files changed, 67 insertions(+), 12 deletions(-) diffs (162 lines): diff -r c52a0c561311 -r 6a34eda7924e src/lib-sieve/sieve-script-dict.c --- a/src/lib-sieve/sieve-script-dict.c Tue Jul 31 01:18:15 2012 +0200 +++ b/src/lib-sieve/sieve-script-dict.c Fri Aug 03 19:52:36 2012 +0200 @@ -17,7 +17,8 @@ struct sieve_script script; struct dict *dict; - + const char *dict_uri; + pool_t data_pool; const char *data_id; const char *data; @@ -103,8 +104,9 @@ "user=%s, uri=%s, script=%s", username, data, name); } + script->dict_uri = p_strdup(_script->pool, data); script->dict = dict_init - (data, DICT_DATA_TYPE_STRING, username, svinst->base_dir); + (script->dict_uri, DICT_DATA_TYPE_STRING, username, svinst->base_dir); if ( script->dict == NULL ) { sieve_critical(svinst, ehandler, name, "failed to open sieve script", "sieve dict backend: failed to initialize dict with data `%s' " @@ -265,6 +267,24 @@ return sieve_binary_save(sbin, script->binpath, update, 0600, error_r); } +static bool sieve_dict_script_equals +(const struct sieve_script *_script, const struct sieve_script *_other) +{ + struct sieve_dict_script *script = (struct sieve_dict_script *)_script; + struct sieve_dict_script *other = (struct sieve_dict_script *)_other; + + if ( script == NULL || other == NULL ) + return FALSE; + + if ( strcmp(script->dict_uri, other->dict_uri) != 0 ) + return FALSE; + + i_assert( _script->name != NULL && _other->name != NULL ); + + return ( strcmp(_script->name, _other->name) == 0 ); +} + + const struct sieve_script sieve_dict_script = { .driver_name = SIEVE_DICT_SCRIPT_DRIVER_NAME, .v = { @@ -273,13 +293,14 @@ sieve_dict_script_destroy, sieve_dict_script_open, - sieve_dict_script_close, + sieve_dict_script_close, sieve_dict_script_binary_read_metadata, sieve_dict_script_binary_write_metadata, sieve_dict_script_binary_load, sieve_dict_script_binary_save, - NULL, NULL + NULL, + sieve_dict_script_equals } }; diff -r c52a0c561311 -r 6a34eda7924e src/lib-sieve/sieve-script-file.c --- a/src/lib-sieve/sieve-script-file.c Tue Jul 31 01:18:15 2012 +0200 +++ b/src/lib-sieve/sieve-script-file.c Fri Aug 03 19:52:36 2012 +0200 @@ -310,8 +310,8 @@ struct sieve_file_script *script = (struct sieve_file_script *)_script; struct sieve_file_script *other = (struct sieve_file_script *)_other; - if ( script == NULL || other == NULL ) - return -1; + if ( script == NULL || other == NULL ) + return FALSE; return ( script->st.st_ino == other->st.st_ino ); } diff -r c52a0c561311 -r 6a34eda7924e src/lib-sieve/sieve-script.c --- a/src/lib-sieve/sieve-script.c Tue Jul 31 01:18:15 2012 +0200 +++ b/src/lib-sieve/sieve-script.c Fri Aug 03 19:52:36 2012 +0200 @@ -414,18 +414,17 @@ if ( script->script_class != other->script_class ) return FALSE; - if ( script->name != NULL && other->name != NULL && - strcmp(script->name, other->name) == 0 ) - return TRUE; + if ( script->v.equals == NULL ) { + i_assert ( script->location != NULL && other->location != NULL); - if ( script->v.equals == NULL ) - return FALSE; + return ( strcmp(script->location, other->location) == 0 ); + } return script->v.equals(script, other); } unsigned int sieve_script_hash(const struct sieve_script *script) -{ +{ return str_hash(script->name); } diff -r c52a0c561311 -r 6a34eda7924e tests/extensions/include/execute.svtest --- a/tests/extensions/include/execute.svtest Tue Jul 31 01:18:15 2012 +0200 +++ b/tests/extensions/include/execute.svtest Fri Aug 03 19:52:36 2012 +0200 @@ -1,4 +1,6 @@ require "vnd.dovecot.testsuite"; +require "include"; +require "variables"; test_set "message" text: From: idiot at example.com @@ -40,3 +42,28 @@ test_fail "fileinto \"bbbb\" not executed."; } } + +test "Namespace" { + set "global.a" "none"; + include :personal "namespace"; + + if string "${global.a}" "none" { + test_fail "global script not executed"; + } + + if not string "${global.a}" "personal" { + test_fail "executed global instead of personal script: ${global.a}"; + } + + set "global.a" "none"; + include :global "namespace"; + + if string "{global.a}" "none" { + test_fail "global script not executed"; + } + + if not string "${global.a}" "global" { + test_fail "executed personal instead of global script: ${global.a}"; + } +} + diff -r c52a0c561311 -r 6a34eda7924e tests/extensions/include/included-global/namespace.sieve --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/extensions/include/included-global/namespace.sieve Fri Aug 03 19:52:36 2012 +0200 @@ -0,0 +1,4 @@ +require "include"; +require "variables"; + +set "global.a" "global"; diff -r c52a0c561311 -r 6a34eda7924e tests/extensions/include/included/namespace.sieve --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/extensions/include/included/namespace.sieve Fri Aug 03 19:52:36 2012 +0200 @@ -0,0 +1,4 @@ +require "include"; +require "variables"; + +set "global.a" "personal"; From pigeonhole at rename-it.nl Sun Aug 5 01:30:26 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 05 Aug 2012 00:30:26 +0200 Subject: dovecot-2.1-pigeonhole: Testsuite: fixed displaying debug messages. Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/09e393e4274b changeset: 1632:09e393e4274b user: Stephan Bosch date: Sat Aug 04 09:34:21 2012 +0200 description: Testsuite: fixed displaying debug messages. diffstat: src/testsuite/testsuite-log.c | 66 +++++++++++++++++++++--------------------- 1 files changed, 33 insertions(+), 33 deletions(-) diffs (128 lines): diff -r 6a34eda7924e -r 09e393e4274b src/testsuite/testsuite-log.c --- a/src/testsuite/testsuite-log.c Fri Aug 03 19:52:36 2012 +0200 +++ b/src/testsuite/testsuite-log.c Sat Aug 04 09:34:21 2012 +0200 @@ -35,6 +35,23 @@ ARRAY_DEFINE(_testsuite_log_warnings, struct _testsuite_log_message); ARRAY_DEFINE(_testsuite_log_messages, struct _testsuite_log_message); +static inline void ATTR_FORMAT(3, 0) _testsuite_stdout_vlog +(const char *prefix, const char *location, const char *fmt, + va_list args) +{ + if ( _testsuite_log_stdout ) { + va_list args_copy; + VA_COPY(args_copy, args); + + if ( location == NULL || *location == '\0' ) + fprintf(stdout, + "LOG: %s: %s\n", prefix, t_strdup_vprintf(fmt, args_copy)); + else + fprintf(stdout, + "LOG: %s: %s: %s\n", prefix, location, t_strdup_vprintf(fmt, args_copy)); + } +} + static void ATTR_FORMAT(4, 0) _testsuite_log_verror (struct sieve_error_handler *ehandler ATTR_UNUSED, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, @@ -43,17 +60,7 @@ pool_t pool = _testsuite_logmsg_pool; struct _testsuite_log_message msg; - if ( _testsuite_log_stdout ) { - va_list args_copy; - VA_COPY(args_copy, args); - - if ( location == NULL || *location == '\0' ) - fprintf(stdout, - "LOG: error: %s\n", t_strdup_vprintf(fmt, args_copy)); - else - fprintf(stdout, - "LOG: error: %s: %s\n", location, t_strdup_vprintf(fmt, args_copy)); - } + _testsuite_stdout_vlog("error", location, fmt, args); msg.location = p_strdup(pool, location); msg.message = p_strdup_vprintf(pool, fmt, args); @@ -82,17 +89,7 @@ pool_t pool = _testsuite_logmsg_pool; struct _testsuite_log_message msg; - if ( _testsuite_log_stdout ) { - va_list args_copy; - VA_COPY(args_copy, args); - - if ( location == NULL || *location == '\0' ) - fprintf(stdout, - "LOG: warning: %s\n", t_strdup_vprintf(fmt, args_copy)); - else - fprintf(stdout, - "LOG: warning: %s: %s\n", location, t_strdup_vprintf(fmt, args_copy)); - } + _testsuite_stdout_vlog("warning", location, fmt, args); msg.location = p_strdup(pool, location); msg.message = p_strdup_vprintf(pool, fmt, args); @@ -108,17 +105,7 @@ pool_t pool = _testsuite_logmsg_pool; struct _testsuite_log_message msg; - if ( _testsuite_log_stdout ) { - va_list args_copy; - VA_COPY(args_copy, args); - - if ( location == NULL || *location == '\0' ) - fprintf(stdout, - "LOG: info: %s\n", t_strdup_vprintf(fmt, args_copy)); - else - fprintf(stdout, - "LOG: info: %s: %s\n", location, t_strdup_vprintf(fmt, args_copy)); - } + _testsuite_stdout_vlog("info", location, fmt, args); msg.location = p_strdup(pool, location); msg.message = p_strdup_vprintf(pool, fmt, args); @@ -126,6 +113,15 @@ array_append(&_testsuite_log_messages, &msg, 1); } + +static void ATTR_FORMAT(4, 0) _testsuite_log_vdebug +(struct sieve_error_handler *ehandler ATTR_UNUSED, + unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, + va_list args) +{ + _testsuite_stdout_vlog("debug", location, fmt, args); +} + static struct sieve_error_handler *_testsuite_log_ehandler_create(void) { pool_t pool; @@ -139,6 +135,7 @@ ehandler->verror = _testsuite_log_verror; ehandler->vwarning = _testsuite_log_vwarning; ehandler->vinfo = _testsuite_log_vinfo; + ehandler->vdebug = _testsuite_log_vdebug; return ehandler; } @@ -156,6 +153,7 @@ ehandler->verror = _testsuite_log_main_verror; ehandler->vwarning = _testsuite_log_vwarning; ehandler->vinfo = _testsuite_log_vinfo; + ehandler->vdebug = _testsuite_log_vdebug; return ehandler; } @@ -192,9 +190,11 @@ testsuite_log_ehandler = _testsuite_log_ehandler_create(); sieve_error_handler_accept_infolog(testsuite_log_ehandler, TRUE); + sieve_error_handler_accept_debuglog(testsuite_log_ehandler, TRUE); testsuite_log_main_ehandler = _testsuite_log_main_ehandler_create(); sieve_error_handler_accept_infolog(testsuite_log_main_ehandler, TRUE); + sieve_error_handler_accept_debuglog(testsuite_log_main_ehandler, TRUE); sieve_system_ehandler_set(testsuite_log_ehandler); From pigeonhole at rename-it.nl Sun Aug 5 01:30:26 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 05 Aug 2012 00:30:26 +0200 Subject: dovecot-2.1-pigeonhole: Testsuite: added support for executing s... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/e44101914a27 changeset: 1633:e44101914a27 user: Stephan Bosch date: Sun Aug 05 00:30:14 2012 +0200 description: Testsuite: added support for executing sub-scripts and added tst variables namespace. Added test for interaction between include extension and dict script location support. diffstat: src/testsuite/Makefile.am | 3 + src/testsuite/cmd-test-binary.c | 4 +- src/testsuite/ext-testsuite.c | 31 +- src/testsuite/testsuite-common.c | 56 ++++- src/testsuite/testsuite-common.h | 21 +- src/testsuite/testsuite-script.c | 71 ++++-- src/testsuite/testsuite-script.h | 6 +- src/testsuite/testsuite-variables.c | 186 ++++++++++++++++ src/testsuite/testsuite-variables.h | 14 + src/testsuite/testsuite.c | 2 +- tests/extensions/include/execute.svtest | 41 +- tests/extensions/include/execute/namespace.sieve | 26 ++ tests/extensions/include/included-global/namespace.dict | 4 + tests/extensions/include/included/namespace.dict | 4 + 14 files changed, 405 insertions(+), 64 deletions(-) diffs (truncated from 772 to 300 lines): diff -r 09e393e4274b -r e44101914a27 src/testsuite/Makefile.am --- a/src/testsuite/Makefile.am Sat Aug 04 09:34:21 2012 +0200 +++ b/src/testsuite/Makefile.am Sun Aug 05 00:30:14 2012 +0200 @@ -2,6 +2,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib-sieve \ + -I$(top_srcdir)/src/lib-sieve/plugins/variables \ -I$(top_srcdir)/src/lib-sieve-tool \ $(LIBDOVECOT_INCLUDE) \ $(LIBDOVECOT_SERVICE_INCLUDE) @@ -38,6 +39,7 @@ testsuite-settings.c \ testsuite-objects.c \ testsuite-substitutions.c \ + testsuite-variables.c \ testsuite-arguments.c \ testsuite-message.c \ testsuite-log.c \ @@ -56,6 +58,7 @@ testsuite-settings.h \ testsuite-objects.h \ testsuite-substitutions.h \ + testsuite-variables.h \ testsuite-arguments.h \ testsuite-message.h \ testsuite-log.h \ diff -r 09e393e4274b -r e44101914a27 src/testsuite/cmd-test-binary.c --- a/src/testsuite/cmd-test-binary.c Sat Aug 04 09:34:21 2012 +0200 +++ b/src/testsuite/cmd-test-binary.c Sun Aug 05 00:30:14 2012 +0200 @@ -176,7 +176,7 @@ } if ( sbin != NULL ) { - testsuite_script_set_binary(sbin); + testsuite_script_set_binary(renv, sbin); sieve_binary_unref(&sbin); } else { @@ -186,7 +186,7 @@ } } else if ( sieve_operation_is(oprtn, test_binary_save_operation) ) { - struct sieve_binary *sbin = testsuite_script_get_binary(); + struct sieve_binary *sbin = testsuite_script_get_binary(renv); if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { sieve_runtime_trace(renv, 0, "testsuite: test_binary_save command"); diff -r 09e393e4274b -r e44101914a27 src/testsuite/ext-testsuite.c --- a/src/testsuite/ext-testsuite.c Sat Aug 04 09:34:21 2012 +0200 +++ b/src/testsuite/ext-testsuite.c Sun Aug 05 00:30:14 2012 +0200 @@ -45,6 +45,7 @@ #include "sieve-result.h" #include "testsuite-common.h" +#include "testsuite-variables.h" #include "testsuite-arguments.h" /* @@ -76,16 +77,17 @@ &test_binary_save_operation }; -/* - * Operands +/* + * Operands */ -const struct sieve_operand_def *testsuite_operands[] = { +const struct sieve_operand_def *testsuite_operands[] = { &testsuite_object_operand, - &testsuite_substitution_operand + &testsuite_substitution_operand, + &testsuite_namespace_operand }; - -/* + +/* * Extension */ @@ -95,6 +97,9 @@ (const struct sieve_extension *ext, struct sieve_validator *valdtr); static bool ext_testsuite_generator_load (const struct sieve_extension *ext, const struct sieve_codegen_env *cgenv); +static bool ext_testsuite_interpreter_load + (const struct sieve_extension *ext, const struct sieve_runtime_env *renv, + sieve_size_t *address); static bool ext_testsuite_binary_load (const struct sieve_extension *ext, struct sieve_binary *sbin); @@ -105,7 +110,7 @@ NULL, NULL, ext_testsuite_validator_load, ext_testsuite_generator_load, - NULL, + ext_testsuite_interpreter_load, ext_testsuite_binary_load, NULL, NULL, SIEVE_EXT_DEFINE_OPERATIONS(testsuite_operations), @@ -142,6 +147,8 @@ /* sieve_validator_argument_override(valdtr, SAT_VAR_STRING, ext, &testsuite_string_argument);*/ + testsuite_variables_init(ext, valdtr); + return testsuite_validator_context_initialize(valdtr); } @@ -151,9 +158,15 @@ return testsuite_generator_context_initialize(cgenv->gentr, ext); } +static bool ext_testsuite_interpreter_load +(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, + sieve_size_t *address ATTR_UNUSED) +{ + return testsuite_interpreter_context_initialize(renv->interp, ext); +} + static bool ext_testsuite_binary_load -(const struct sieve_extension *ext ATTR_UNUSED, - struct sieve_binary *sbin ATTR_UNUSED) +(const struct sieve_extension *ext ATTR_UNUSED, struct sieve_binary *sbin ATTR_UNUSED) { return TRUE; } diff -r 09e393e4274b -r e44101914a27 src/testsuite/testsuite-common.c --- a/src/testsuite/testsuite-common.c Sat Aug 04 09:34:21 2012 +0200 +++ b/src/testsuite/testsuite-common.c Sun Aug 05 00:30:14 2012 +0200 @@ -17,6 +17,7 @@ #include "sieve-message.h" #include "sieve-commands.h" #include "sieve-extensions.h" +#include "sieve-binary.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" @@ -45,6 +46,7 @@ */ struct sieve_instance *testsuite_sieve_instance = NULL; +char *testsuite_test_path = NULL; /* Test context */ @@ -103,6 +105,48 @@ } /* + * Interpreter context + */ + +static void testsuite_interpreter_free +(const struct sieve_extension *ext ATTR_UNUSED, + struct sieve_interpreter *interp ATTR_UNUSED, void *context) +{ + struct testsuite_interpreter_context *ctx = + (struct testsuite_interpreter_context *)context; + + if ( ctx->compiled_script != NULL ) + sieve_binary_unref(&ctx->compiled_script); +} + +const struct sieve_interpreter_extension testsuite_interpreter_ext = { + &testsuite_extension, + NULL, + testsuite_interpreter_free, +}; + +bool testsuite_interpreter_context_initialize +(struct sieve_interpreter *interp, const struct sieve_extension *this_ext) +{ + pool_t pool = sieve_interpreter_pool(interp); + struct testsuite_interpreter_context *ctx = + p_new(pool, struct testsuite_interpreter_context, 1); + + sieve_interpreter_extension_register + (interp, this_ext, &testsuite_interpreter_ext, ctx); + return TRUE; +} + +struct testsuite_interpreter_context *testsuite_interpreter_context_get +(struct sieve_interpreter *interp, const struct sieve_extension *this_ext) +{ + struct testsuite_interpreter_context *ctx = + sieve_interpreter_extension_get_context(interp, this_ext); + + return ctx; +} + +/* * Test context */ @@ -234,28 +278,34 @@ * Main testsuite init/deinit */ -void testsuite_init(struct sieve_instance *svinst, bool log_stdout) +void testsuite_init +(struct sieve_instance *svinst, const char *test_path, bool log_stdout) { testsuite_sieve_instance = svinst; testsuite_test_context_init(); testsuite_log_init(log_stdout); testsuite_tmp_dir_init(); - + testsuite_script_init(); testsuite_binary_init(); testsuite_smtp_init(); testsuite_ext = sieve_extension_register (svinst, &testsuite_extension, TRUE); + + + testsuite_test_path = i_strdup(test_path); } void testsuite_deinit(void) { + i_free(testsuite_test_path); + testsuite_smtp_deinit(); testsuite_binary_deinit(); testsuite_script_deinit(); - + testsuite_tmp_dir_deinit(); testsuite_log_deinit(); testsuite_test_context_deinit(); diff -r 09e393e4274b -r e44101914a27 src/testsuite/testsuite-common.h --- a/src/testsuite/testsuite-common.h Sat Aug 04 09:34:21 2012 +0200 +++ b/src/testsuite/testsuite-common.h Sun Aug 05 00:30:14 2012 +0200 @@ -20,6 +20,8 @@ extern const struct sieve_script_env *testsuite_scriptenv; +extern char *testsuite_test_path; + /* * Validator context @@ -45,6 +47,19 @@ (struct sieve_generator *gentr, const struct sieve_extension *this_ext); /* + * Interpreter context + */ + +struct testsuite_interpreter_context { + struct sieve_binary *compiled_script; +}; + +bool testsuite_interpreter_context_initialize + (struct sieve_interpreter *interp, const struct sieve_extension *this_ext); +struct testsuite_interpreter_context *testsuite_interpreter_context_get + (struct sieve_interpreter *interp, const struct sieve_extension *this_ext); + +/* * Commands */ @@ -136,7 +151,8 @@ enum testsuite_operand_code { TESTSUITE_OPERAND_OBJECT, - TESTSUITE_OPERAND_SUBSTITUTION + TESTSUITE_OPERAND_SUBSTITUTION, + TESTSUITE_OPERAND_NAMESPACE }; /* @@ -163,7 +179,8 @@ * Testsuite init/deinit */ -void testsuite_init(struct sieve_instance *svinst, bool log_stdout); +void testsuite_init + (struct sieve_instance *svinst, const char *test_path, bool log_stdout); void testsuite_deinit(void); #endif /* __TESTSUITE_COMMON_H */ diff -r 09e393e4274b -r e44101914a27 src/testsuite/testsuite-script.c --- a/src/testsuite/testsuite-script.c Sat Aug 04 09:34:21 2012 +0200 +++ b/src/testsuite/testsuite-script.c Sun Aug 05 00:30:14 2012 +0200 @@ -21,20 +21,14 @@ /* * Tested script environment - */ - -struct sieve_binary *_testsuite_compiled_script; + */ void testsuite_script_init(void) From pigeonhole at rename-it.nl Sun Aug 5 19:42:17 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 05 Aug 2012 18:42:17 +0200 Subject: dovecot-2.1-pigeonhole: Testsuite: fixed compiler warning. Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/bb8a9332e3d5 changeset: 1634:bb8a9332e3d5 user: Stephan Bosch date: Sun Aug 05 18:42:12 2012 +0200 description: Testsuite: fixed compiler warning. diffstat: src/testsuite/testsuite-variables.c | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diffs (17 lines): diff -r e44101914a27 -r bb8a9332e3d5 src/testsuite/testsuite-variables.c --- a/src/testsuite/testsuite-variables.c Sun Aug 05 00:30:14 2012 +0200 +++ b/src/testsuite/testsuite-variables.c Sun Aug 05 18:42:12 2012 +0200 @@ -103,13 +103,10 @@ { const struct sieve_extension *this_ext = SIEVE_OBJECT_EXTENSION(nspc); const char *variable = (const char *) var_data; - struct ext_testsuite_context *ext_data; if ( this_ext == NULL ) return FALSE; - ext_data = (struct ext_testsuite_context *) this_ext->context; - sieve_variables_opr_namespace_variable_emit (cgenv->sblock, testsuite_ext_variables, this_ext, &testsuite_namespace); sieve_binary_emit_cstring(cgenv->sblock, variable); From dovecot at dovecot.org Mon Aug 6 17:01:02 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 06 Aug 2012 17:01:02 +0300 Subject: dovecot-2.2: login: s/succesful/successful/ Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/962215040871 changeset: 14745:962215040871 user: Timo Sirainen date: Mon Aug 06 17:00:47 2012 +0300 description: login: s/succesful/successful/ diffstat: src/login-common/client-common.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 5e10caeb5e5d -r 962215040871 src/login-common/client-common.c --- a/src/login-common/client-common.c Fri Aug 03 14:19:03 2012 +0300 +++ b/src/login-common/client-common.c Mon Aug 06 17:00:47 2012 +0300 @@ -650,7 +650,7 @@ if (client->proxy_auth_failed) return "(proxy dest auth failed)"; if (client->auth_successes > 0) { - return t_strdup_printf("(internal failure, %u succesful auths)", + return t_strdup_printf("(internal failure, %u successful auths)", client->auth_successes); } if (client->auth_user_disabled) From pigeonhole at rename-it.nl Tue Aug 7 00:14:26 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Mon, 06 Aug 2012 23:14:26 +0200 Subject: dovecot-2.1-pigeonhole: lib-sieve: made action limit error messa... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/b25d4208949f changeset: 1635:b25d4208949f user: Stephan Bosch date: Mon Aug 06 23:14:19 2012 +0200 description: lib-sieve: made action limit error messages more verbose. diffstat: src/lib-sieve/sieve-result.c | 12 +++++++----- 1 files changed, 7 insertions(+), 5 deletions(-) diffs (28 lines): diff -r bb8a9332e3d5 -r b25d4208949f src/lib-sieve/sieve-result.c --- a/src/lib-sieve/sieve-result.c Sun Aug 05 18:42:12 2012 +0200 +++ b/src/lib-sieve/sieve-result.c Mon Aug 06 23:14:19 2012 +0200 @@ -554,17 +554,19 @@ } /* Check policy limit on total number of actions */ - if ( svinst->max_actions > 0 && result->action_count >= svinst->max_actions ) + if ( svinst->max_actions > 0 && result->action_count >= svinst->max_actions ) { - sieve_runtime_error(renv, action.location, - "total number of actions exceeds policy limit"); + sieve_runtime_error(renv, action.location, + "total number of actions exceeds policy limit (%u > %u)", + result->action_count+1, svinst->max_actions); return -1; } /* Check policy limit on number of this class of actions */ if ( instance_limit > 0 && instance_count >= instance_limit ) { - sieve_runtime_error(renv, action.location, - "number of %s actions exceeds policy limit", act_def->name); + sieve_runtime_error(renv, action.location, + "number of %s actions exceeds policy limit (%u > %u)", + act_def->name, instance_count+1, instance_limit); return -1; } From pigeonhole at rename-it.nl Tue Aug 7 01:36:24 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 07 Aug 2012 00:36:24 +0200 Subject: dovecot-2.1-pigeonhole: lib-sieve: increase action instance coun... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/9d962388f5f6 changeset: 1637:9d962388f5f6 user: Stephan Bosch date: Tue Aug 07 00:36:11 2012 +0200 description: lib-sieve: increase action instance count (for limit checking) only when an action is actually created. diffstat: src/lib-sieve/sieve-result.c | 34 +++++++++++++++++----------------- 1 files changed, 17 insertions(+), 17 deletions(-) diffs (48 lines): diff -r 837c108f0363 -r 9d962388f5f6 src/lib-sieve/sieve-result.c --- a/src/lib-sieve/sieve-result.c Tue Aug 07 00:34:12 2012 +0200 +++ b/src/lib-sieve/sieve-result.c Tue Aug 07 00:36:11 2012 +0200 @@ -553,27 +553,27 @@ raction = raction->next; } - /* Check policy limit on total number of actions */ - if ( svinst->max_actions > 0 && result->action_count >= svinst->max_actions ) - { - sieve_runtime_error(renv, action.location, - "total number of actions exceeds policy limit (%u > %u)", - result->action_count+1, svinst->max_actions); - return -1; - } - - /* Check policy limit on number of this class of actions */ - if ( instance_limit > 0 && instance_count >= instance_limit ) { - sieve_runtime_error(renv, action.location, - "number of %s actions exceeds policy limit (%u > %u)", - act_def->name, instance_count+1, instance_limit); - return -1; - } - if ( kaction != NULL ) { /* Use existing keep action to define new one */ raction = kaction; } else { + /* Check policy limit on total number of actions */ + if ( svinst->max_actions > 0 && result->action_count >= svinst->max_actions ) + { + sieve_runtime_error(renv, action.location, + "total number of actions exceeds policy limit (%u > %u)", + result->action_count+1, svinst->max_actions); + return -1; + } + + /* Check policy limit on number of this class of actions */ + if ( instance_limit > 0 && instance_count >= instance_limit ) { + sieve_runtime_error(renv, action.location, + "number of %s actions exceeds policy limit (%u > %u)", + act_def->name, instance_count+1, instance_limit); + return -1; + } + /* Create new action object */ raction = p_new(result->pool, struct sieve_result_action, 1); raction->action.executed = FALSE; From pigeonhole at rename-it.nl Tue Aug 7 01:36:24 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 07 Aug 2012 00:36:24 +0200 Subject: dovecot-2.1-pigeonhole: lib-sieve: fixed potential action duplic... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/837c108f0363 changeset: 1636:837c108f0363 user: Stephan Bosch date: Tue Aug 07 00:34:12 2012 +0200 description: lib-sieve: fixed potential action duplication bug. diffstat: src/lib-sieve/sieve-result.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r b25d4208949f -r 837c108f0363 src/lib-sieve/sieve-result.c --- a/src/lib-sieve/sieve-result.c Mon Aug 06 23:14:19 2012 +0200 +++ b/src/lib-sieve/sieve-result.c Tue Aug 07 00:34:12 2012 +0200 @@ -588,7 +588,7 @@ raction->action.location = p_strdup(result->pool, action.location); raction->keep = keep; - if ( raction->prev == NULL ) { + if ( raction->prev == NULL && raction != result->first_action ) { /* Add */ if ( result->first_action == NULL ) { result->first_action = raction; From dovecot at dovecot.org Tue Aug 7 17:56:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 07 Aug 2012 17:56:41 +0300 Subject: dovecot-2.1: lib-master: Settings cache crashed after config_cac... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/2815175a0ffc changeset: 14658:2815175a0ffc user: Timo Sirainen date: Tue Aug 07 17:56:24 2012 +0300 description: lib-master: Settings cache crashed after config_cache_size was reached. This affected login processes when local {} and/or remote {} blocks were specified. Also fixed the cache behavior to be MRU. diffstat: src/lib-master/master-service-settings-cache.c | 18 +++++++++--------- 1 files changed, 9 insertions(+), 9 deletions(-) diffs (51 lines): diff -r ab6a4455b27d -r 2815175a0ffc src/lib-master/master-service-settings-cache.c --- a/src/lib-master/master-service-settings-cache.c Fri Aug 03 17:39:54 2012 +0300 +++ b/src/lib-master/master-service-settings-cache.c Tue Aug 07 17:56:24 2012 +0300 @@ -145,6 +145,8 @@ } if (entry != NULL) { + DLLIST2_REMOVE(&cache->oldest, &cache->newest, entry); + DLLIST2_APPEND(&cache->oldest, &cache->newest, entry); *parser_r = entry->parser; return TRUE; } @@ -195,31 +197,29 @@ /* use global settings, but add local_ip/host to hash tables so we'll find them */ pool = pool_alloconly_create("settings global entry", 256); - entry = p_new(pool, struct settings_entry, 1); } else if (cache->cache_malloc_size >= cache->max_cache_size) { /* free the oldest and reuse its pool */ - entry = cache->oldest; - pool = entry->pool; - setting_entry_detach(cache, entry); - p_clear(pool); + pool = cache->oldest->pool; + setting_entry_detach(cache, cache->oldest); + p_clear(pool); /* note: frees also entry */ } else { pool_size = cache->approx_entry_pool_size != 0 ? cache->approx_entry_pool_size : CACHE_INITIAL_ENTRY_POOL_SIZE; pool = pool_alloconly_create("settings entry", pool_size); - entry = p_new(pool, struct settings_entry, 1); } + entry = p_new(pool, struct settings_entry, 1); entry->pool = pool; entry_local_name = p_strdup(pool, input->local_name); entry->local_name = entry_local_name; entry->local_ip = input->local_ip; if (!output->used_local) { entry->parser = cache->global_parser; - DLLIST2_PREPEND(&cache->oldest_global, &cache->newest_global, - entry); + DLLIST2_APPEND(&cache->oldest_global, &cache->newest_global, + entry); } else { entry->parser = settings_parser_dup(parser, entry->pool); - DLLIST2_PREPEND(&cache->oldest, &cache->newest, entry); + DLLIST2_APPEND(&cache->oldest, &cache->newest, entry); pool_size = pool_alloconly_get_total_used_size(pool); if (pool_size > cache->approx_entry_pool_size) { From dovecot at dovecot.org Wed Aug 8 00:44:56 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 08 Aug 2012 00:44:56 +0300 Subject: dovecot-2.1: fts-solr: Optimized expunging messages: delete more... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/82f59d2139a9 changeset: 14659:82f59d2139a9 user: Timo Sirainen date: Wed Aug 08 00:44:27 2012 +0300 description: fts-solr: Optimized expunging messages: delete more than one ID per request. diffstat: src/plugins/fts-solr/fts-backend-solr.c | 39 ++++++++++++++++++++++---------- 1 files changed, 27 insertions(+), 12 deletions(-) diffs (93 lines): diff -r 2815175a0ffc -r 82f59d2139a9 src/plugins/fts-solr/fts-backend-solr.c --- a/src/plugins/fts-solr/fts-backend-solr.c Tue Aug 07 17:56:24 2012 +0300 +++ b/src/plugins/fts-solr/fts-backend-solr.c Wed Aug 08 00:44:27 2012 +0300 @@ -38,6 +38,7 @@ struct solr_connection_post *post; uint32_t prev_uid; string_t *cmd, *cur_value, *cur_value2; + string_t *cmd_expunge; ARRAY_DEFINE(fields, struct solr_fts_field); uint32_t last_indexed_uid; @@ -240,7 +241,6 @@ ctx = i_new(struct solr_fts_backend_update_context, 1); ctx->ctx.backend = _backend; - ctx->cmd = str_new(default_pool, SOLR_CMDBUF_SIZE); i_array_init(&ctx->fields, 16); return &ctx->ctx; } @@ -326,6 +326,15 @@ return solr_connection_post_end(ctx->post); } +static void +fts_backend_solr_expunge_flush(struct solr_fts_backend_update_context *ctx) +{ + str_append(ctx->cmd_expunge, ""); + (void)solr_connection_post(solr_conn, str_c(ctx->cmd_expunge)); + str_truncate(ctx->cmd_expunge, 0); + str_append(ctx->cmd_expunge, ""); +} + static int fts_backend_solr_update_deinit(struct fts_backend_update_context *_ctx) { @@ -341,6 +350,8 @@ if (ctx->documents_added || ctx->expunges) { /* commit and wait until the documents we just indexed are visible to the following search */ + if (ctx->expunges) + fts_backend_solr_expunge_flush(ctx); str = t_strdup_printf("", ctx->documents_added ? "true" : "false"); @@ -348,7 +359,10 @@ ret = -1; } - str_free(&ctx->cmd); + if (ctx->cmd != NULL) + str_free(&ctx->cmd); + if (ctx->cmd_expunge != NULL) + str_free(&ctx->cmd_expunge); array_foreach_modifiable(&ctx->fields, field) { str_free(&field->value); i_free(field->key); @@ -404,18 +418,18 @@ highly unlikely to be indexed at this time. */ return; } - ctx->expunges = TRUE; + if (!ctx->expunges) { + ctx->expunges = TRUE; + ctx->cmd_expunge = str_new(default_pool, 1024); + str_append(ctx->cmd_expunge, ""); + } - T_BEGIN { - string_t *cmd; + if (str_len(ctx->cmd_expunge) >= SOLR_CMDBUF_FLUSH_SIZE) + fts_backend_solr_expunge_flush(ctx); - cmd = t_str_new(256); - str_append(cmd, ""); - xml_encode_id(ctx, cmd, uid); - str_append(cmd, ""); - - (void)solr_connection_post(solr_conn, str_c(cmd)); - } T_END; + str_append(ctx->cmd_expunge, ""); + xml_encode_id(ctx, ctx->cmd_expunge, uid); + str_append(ctx->cmd_expunge, ""); } static void @@ -425,6 +439,7 @@ if (ctx->post == NULL) { i_assert(ctx->prev_uid == 0); + ctx->cmd = str_new(default_pool, SOLR_CMDBUF_SIZE); ctx->post = solr_connection_post_begin(solr_conn); str_append(ctx->cmd, ""); } else { From dovecot at dovecot.org Wed Aug 8 01:13:16 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 08 Aug 2012 01:13:16 +0300 Subject: dovecot-2.2: Compiler warning fixes Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6de60c6ea713 changeset: 14746:6de60c6ea713 user: Timo Sirainen date: Wed Aug 08 01:13:10 2012 +0300 description: Compiler warning fixes diffstat: src/lib-mail/istream-attachment-extractor.h | 2 +- src/lib-mail/test-istream-attachment.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diffs (25 lines): diff -r 962215040871 -r 6de60c6ea713 src/lib-mail/istream-attachment-extractor.h --- a/src/lib-mail/istream-attachment-extractor.h Mon Aug 06 17:00:47 2012 +0300 +++ b/src/lib-mail/istream-attachment-extractor.h Wed Aug 08 01:13:10 2012 +0300 @@ -49,7 +49,7 @@ struct istream * i_stream_create_attachment_extractor(struct istream *input, struct istream_attachment_settings *set, - void *context); + void *context) ATTR_NULL(3); /* Returns TRUE if the last read returned 0 only because drain_parent_input=FALSE and we didn't have anything to return, but diff -r 962215040871 -r 6de60c6ea713 src/lib-mail/test-istream-attachment.c --- a/src/lib-mail/test-istream-attachment.c Mon Aug 06 17:00:47 2012 +0300 +++ b/src/lib-mail/test-istream-attachment.c Wed Aug 08 01:13:10 2012 +0300 @@ -99,7 +99,8 @@ a->base64_blocks_per_line = info->base64_blocks_per_line; *output_r = o_stream_create_buffer(attachment_data); - o_stream_seek(*output_r, a->buffer_offset); + if (o_stream_seek(*output_r, a->buffer_offset) < 0) + i_unreached(); return 0; } From dovecot at dovecot.org Wed Aug 8 23:40:48 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 08 Aug 2012 23:40:48 +0300 Subject: dovecot-2.2: ioloop-epoll: Allow running ioloop even without any... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/587c5579c598 changeset: 14747:587c5579c598 user: Timo Sirainen date: Wed Aug 08 23:40:37 2012 +0300 description: ioloop-epoll: Allow running ioloop even without any I/Os (only timeouts). diffstat: src/lib/ioloop-epoll.c | 13 ++++++++++--- 1 files changed, 10 insertions(+), 3 deletions(-) diffs (23 lines): diff -r 6de60c6ea713 -r 587c5579c598 src/lib/ioloop-epoll.c --- a/src/lib/ioloop-epoll.c Wed Aug 08 01:13:10 2012 +0300 +++ b/src/lib/ioloop-epoll.c Wed Aug 08 23:40:37 2012 +0300 @@ -178,9 +178,16 @@ msecs = io_loop_get_wait_time(ioloop, &tv); events = array_get_modifiable(&ctx->events, &events_count); - ret = epoll_wait(ctx->epfd, events, events_count, msecs); - if (ret < 0 && errno != EINTR) - i_fatal("epoll_wait(): %m"); + if (events_count > 0) { + ret = epoll_wait(ctx->epfd, events, events_count, msecs); + if (ret < 0 && errno != EINTR) + i_fatal("epoll_wait(): %m"); + } else { + /* no I/Os, but we should have some timeouts. + just wait for them. */ + if (msecs > 0) + usleep(msecs*1000); + } /* execute timeout handlers */ io_loop_handle_timeouts(ioloop); From dovecot at dovecot.org Wed Aug 8 23:42:03 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 08 Aug 2012 23:42:03 +0300 Subject: dovecot-2.2: Added libtest to libdovecot.so Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/84b4459e4dfc changeset: 14748:84b4459e4dfc user: Timo Sirainen date: Wed Aug 08 23:41:40 2012 +0300 description: Added libtest to libdovecot.so diffstat: configure.in | 2 +- dovecot-config.in.in | 2 +- src/Makefile.am | 2 +- src/lib-dovecot/Makefile.am | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diffs (52 lines): diff -r 587c5579c598 -r 84b4459e4dfc configure.in --- a/configure.in Wed Aug 08 23:40:37 2012 +0300 +++ b/configure.in Wed Aug 08 23:41:40 2012 +0300 @@ -2518,7 +2518,7 @@ LIBDOVECOT_COMPRESS='$(top_builddir)/src/lib-compression/libcompression.la' LIBDOVECOT_LDA='$(top_builddir)/src/lib-lda/libdovecot-lda.la' else - LIBDOVECOT_DEPS='$(top_builddir)/src/lib-master/libmaster.la $(top_builddir)/src/lib-settings/libsettings.la $(top_builddir)/src/lib-dict/libdict.la $(top_builddir)/src/lib-dns/libdns.la $(top_builddir)/src/lib-fs/libfs.la $(top_builddir)/src/lib-imap/libimap.la $(top_builddir)/src/lib-mail/libmail.la $(top_builddir)/src/lib-auth/libauth.la $(top_builddir)/src/lib-charset/libcharset.la $(top_builddir)/src/lib/liblib.la' + LIBDOVECOT_DEPS='$(top_builddir)/src/lib-master/libmaster.la $(top_builddir)/src/lib-settings/libsettings.la $(top_builddir)/src/lib-dict/libdict.la $(top_builddir)/src/lib-dns/libdns.la $(top_builddir)/src/lib-fs/libfs.la $(top_builddir)/src/lib-imap/libimap.la $(top_builddir)/src/lib-mail/libmail.la $(top_builddir)/src/lib-auth/libauth.la $(top_builddir)/src/lib-charset/libcharset.la $(top_builddir)/src/lib-test/libtest.la $(top_builddir)/src/lib/liblib.la' LIBDOVECOT="$LIBDOVECOT_DEPS \$(LIBICONV)" LIBDOVECOT_STORAGE_LAST='$(top_builddir)/src/lib-storage/list/libstorage_list.la $(top_builddir)/src/lib-storage/index/libstorage_index.la $(top_builddir)/src/lib-storage/libstorage.la $(top_builddir)/src/lib-index/libindex.la $(top_builddir)/src/lib-imap-storage/libimap-storage.la' LIBDOVECOT_STORAGE_FIRST='$(top_builddir)/src/lib-storage/libstorage_service.la $(top_builddir)/src/lib-storage/register/libstorage_register.la' diff -r 587c5579c598 -r 84b4459e4dfc dovecot-config.in.in --- a/dovecot-config.in.in Wed Aug 08 23:40:37 2012 +0300 +++ b/dovecot-config.in.in Wed Aug 08 23:41:40 2012 +0300 @@ -20,7 +20,7 @@ LIBDOVECOT_LDA_DEPS="@LIBDOVECOT_LDA@" LIBDOVECOT_STORAGE_DEPS="@LIBDOVECOT_STORAGE_DEPS@" -LIBDOVECOT_INCLUDE="-I$(incdir) -I$(incdir)/src/lib -I$(incdir)/src/lib-dict -I$(incdir)/src/lib-dns -I$(incdir)/src/lib-mail -I$(incdir)/src/lib-imap -I$(incdir)/src/lib-fs -I$(incdir)/src/lib-charset -I$(incdir)/src/lib-auth -I$(incdir)/src/lib-master -I$(incdir)/src/lib-ssl-iostream -I$(incdir)/src/lib-compression -I$(incdir)/src/lib-settings" +LIBDOVECOT_INCLUDE="-I$(incdir) -I$(incdir)/src/lib -I$(incdir)/src/lib-dict -I$(incdir)/src/lib-dns -I$(incdir)/src/lib-mail -I$(incdir)/src/lib-imap -I$(incdir)/src/lib-fs -I$(incdir)/src/lib-charset -I$(incdir)/src/lib-auth -I$(incdir)/src/lib-master -I$(incdir)/src/lib-ssl-iostream -I$(incdir)/src/lib-compression -I$(incdir)/src/lib-settings -I$(incdir)/src/lib-test" LIBDOVECOT_LDA_INCLUDE="-I$(incdir)/src/lib-lda -I$(incdir)/src/lda" LIBDOVECOT_STORAGE_INCLUDE="-I$(incdir)/src/lib-index -I$(incdir)/src/lib-storage -I$(incdir)/src/lib-storage/index -I$(incdir)/src/lib-storage/index/raw" LIBDOVECOT_LOGIN_INCLUDE="-I$(incdir)/src/login-common" diff -r 587c5579c598 -r 84b4459e4dfc src/Makefile.am --- a/src/Makefile.am Wed Aug 08 23:40:37 2012 +0300 +++ b/src/Makefile.am Wed Aug 08 23:41:40 2012 +0300 @@ -1,4 +1,5 @@ LIBDOVECOT_SUBDIRS = \ + lib-test \ lib \ lib-auth \ lib-charset \ @@ -13,7 +14,6 @@ lib-ssl-iostream SUBDIRS = \ - lib-test \ $(LIBDOVECOT_SUBDIRS) \ lib-imap-client \ lib-compression \ diff -r 587c5579c598 -r 84b4459e4dfc src/lib-dovecot/Makefile.am --- a/src/lib-dovecot/Makefile.am Wed Aug 08 23:40:37 2012 +0300 +++ b/src/lib-dovecot/Makefile.am Wed Aug 08 23:41:40 2012 +0300 @@ -8,6 +8,7 @@ ../lib-fs/libfs.la \ ../lib-charset/libcharset.la \ ../lib-master/libmaster.la \ + ../lib-test/libtest.la \ ../lib/liblib.la ssl_libs = \ From dovecot at dovecot.org Wed Aug 8 23:46:58 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 08 Aug 2012 23:46:58 +0300 Subject: dovecot-2.2: master: If service's protocol isn't in enabled prot... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/06e98529eac8 changeset: 14749:06e98529eac8 user: Timo Sirainen date: Wed Aug 08 23:46:48 2012 +0300 description: master: If service's protocol isn't in enabled protocols, don't verify its settings. diffstat: src/master/master-settings.c | 11 ++++++++--- 1 files changed, 8 insertions(+), 3 deletions(-) diffs (28 lines): diff -r 84b4459e4dfc -r 06e98529eac8 src/master/master-settings.c --- a/src/master/master-settings.c Wed Aug 08 23:41:40 2012 +0300 +++ b/src/master/master-settings.c Wed Aug 08 23:46:48 2012 +0300 @@ -496,6 +496,13 @@ for (i = 0; i < count; i++) { struct service_settings *service = services[i]; + if (*service->protocol != '\0' && + !str_array_find((const char **)set->protocols_split, + service->protocol)) { + /* protocol not enabled, ignore its settings */ + continue; + } + if (*service->executable == '\0') { *error_r = t_strdup_printf("service(%s): " "executable is empty", service->name); @@ -550,9 +557,7 @@ } #endif - if (*service->protocol != '\0' && - str_array_find((const char **)set->protocols_split, - service->protocol)) { + if (*service->protocol != '\0') { /* each imap/pop3/lmtp process can use up a connection, although if service_count=1 it's only temporary */ if (service->service_count != 1 || From dovecot at dovecot.org Wed Aug 8 23:57:37 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 08 Aug 2012 23:57:37 +0300 Subject: dovecot-2.2: connection API: Don't do error handling by default ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6d626fcbde9e changeset: 14750:6d626fcbde9e user: Timo Sirainen date: Wed Aug 08 23:57:29 2012 +0300 description: connection API: Don't do error handling by default on output stream. For connections the error handling is almost never wanted. diffstat: src/lib/connection.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 06e98529eac8 -r 6d626fcbde9e src/lib/connection.c --- a/src/lib/connection.c Wed Aug 08 23:46:48 2012 +0300 +++ b/src/lib/connection.c Wed Aug 08 23:57:29 2012 +0300 @@ -120,6 +120,7 @@ if (set->output_max_size != 0) { conn->output = o_stream_create_fd(conn->fd_out, set->output_max_size, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); } conn->io = io_add(conn->fd_in, IO_READ, conn->list->v.input, conn); if (set->input_idle_timeout_secs != 0) { From dovecot at dovecot.org Thu Aug 9 18:50:50 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 09 Aug 2012 18:50:50 +0300 Subject: dovecot-2.2: Added file_lock_method_to_str() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1a938b81cc5f changeset: 14751:1a938b81cc5f user: Timo Sirainen date: Thu Aug 09 18:50:31 2012 +0300 description: Added file_lock_method_to_str() diffstat: src/lib/file-lock.c | 13 +++++++++++++ src/lib/file-lock.h | 2 ++ 2 files changed, 15 insertions(+), 0 deletions(-) diffs (35 lines): diff -r 6d626fcbde9e -r 1a938b81cc5f src/lib/file-lock.c --- a/src/lib/file-lock.c Wed Aug 08 23:57:29 2012 +0300 +++ b/src/lib/file-lock.c Thu Aug 09 18:50:31 2012 +0300 @@ -28,6 +28,19 @@ return TRUE; } +const char *file_lock_method_to_str(enum file_lock_method method) +{ + switch (method) { + case FILE_LOCK_METHOD_FCNTL: + return "fcntl"; + case FILE_LOCK_METHOD_FLOCK: + return "flock"; + case FILE_LOCK_METHOD_DOTLOCK: + return "dotlock"; + } + i_unreached(); +} + int file_try_lock(int fd, const char *path, int lock_type, enum file_lock_method lock_method, struct file_lock **lock_r) diff -r 6d626fcbde9e -r 1a938b81cc5f src/lib/file-lock.h --- a/src/lib/file-lock.h Wed Aug 08 23:57:29 2012 +0300 +++ b/src/lib/file-lock.h Thu Aug 09 18:50:31 2012 +0300 @@ -17,6 +17,8 @@ /* Parse lock method from given string. Returns TRUE if ok, FALSE if name is unknown. */ bool file_lock_method_parse(const char *name, enum file_lock_method *method_r); +/* Convert lock method to string. */ +const char *file_lock_method_to_str(enum file_lock_method method); /* Lock the file. Returns 1 if successful, 0 if file is already locked, or -1 if error. lock_type is F_WRLCK or F_RDLCK. */ From pigeonhole at rename-it.nl Thu Aug 9 23:59:01 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 09 Aug 2012 22:59:01 +0200 Subject: dovecot-2.1-pigeonhole: Created specification for the vnd.doveco... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/54a0d0552be7 changeset: 1638:54a0d0552be7 user: Stephan Bosch date: Thu Aug 09 22:58:53 2012 +0200 description: Created specification for the vnd.dovecot.debug extension. Also fixed a small mistake in the spefication for the vnd.dovecot.duplicate extension. diffstat: doc/rfc/spec-bosch-sieve-debug.txt | 224 +++++++++++++++++++++++++++++ doc/rfc/xml/reference.VARIABLES.xml | 15 + doc/rfc/xml/spec-bosch-sieve-debug.xml | 168 +++++++++++++++++++++ doc/rfc/xml/spec-bosch-sieve-duplicate.xml | 2 +- 4 files changed, 408 insertions(+), 1 deletions(-) diffs (truncated from 431 to 300 lines): diff -r 9d962388f5f6 -r 54a0d0552be7 doc/rfc/spec-bosch-sieve-debug.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/rfc/spec-bosch-sieve-debug.txt Thu Aug 09 22:58:53 2012 +0200 @@ -0,0 +1,224 @@ + + + +Pigeonhole Project S. Bosch + August 9, 2012 + + + Sieve Email Filtering: Logging Debug Messages + +Abstract + + This document defines a new vendor-defined test command "debug_log" + for the "Sieve" email filtering language. It provides the means to + debug a Sieve script by logging debug messages. + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2 + 2. Conventions Used in This Document . . . . . . . . . . . . . . . 2 + 3. Command "debug_log" . . . . . . . . . . . . . . . . . . . . . . 2 + 4. Sieve Capability Strings . . . . . . . . . . . . . . . . . . . 2 + 5. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 + 6. Security Considerations . . . . . . . . . . . . . . . . . . . . 3 + 7. Normative References . . . . . . . . . . . . . . . . . . . . . 3 + Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Bosch [Page 1] + + Sieve: Debug Logging August 2012 + + +1. Introduction + + This is an extension to the Sieve filtering language defined by RFC + 5228 [SIEVE]. It adds a command that provides the means to debug a + Sieve script by logging debug messages. + + Much like any other kind of computer program, Sieve scripts are prone + to all kinds of mistakes. Often, there are no real error conditions, + e.g. Sieve language violations, that cause the failure and no error + or warning messages are logged for the user or administrator to + determine what caused the erroneous result. A convenient method of + debugging such issues is printing debug messages to some kind of + logging facility. This way for example, script authors can check + whether specific sections of the script are executed. When combined + with the "variables" [VARIABLES] extension, intermittent results, + message data and status information can be included in those log + messages, further improving the information available for debugging. + + This extension is specific to the Pigeonhole Sieve implementation for + the Dovecot Secure IMAP server. It will therefore most likely not be + supported by web interfaces and GUI-based Sieve editors. + + +2. Conventions Used in This Document + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in [KEYWORDS]. + + Conventions for notations are as in [SIEVE] Section 1.1, including + use of the "Usage:" label for the definition of action and tagged + arguments syntax. + + +3. Command "debug_log" + + Usage: "debug_log" + + The "debug_log" command prints the debug message provided as the + command's "message" argument to an implementation-defined logging + facility. The message MAY contain variable substitutions as provided + by the "variables" [VARIABLES] extension to dynamically compose the + message from information available at runtime. + + +4. Sieve Capability Strings + + A Sieve implementation that defines the "debug_log" action command + + + +Bosch [Page 2] + + Sieve: Debug Logging August 2012 + + + will advertise the capability string "vnd.dovecot.debug". + + +5. Examples + + The following example logs a message when the message's subject + contains the "hello": + + require "vnd.dovecot.debug"; + + if header :contains "subject" "hello" { + debug_log "Subject header contains hello!"; + } + + The next example logs the envelope of the message using the + "variables" [VARIABLES] extension and the "envelope" [SIEVE] + extension: + + require ["variables", "envelope", "vnd.dovecot.debug"]; + + if envelope :matches "to" "*" { set "to" "${1}"; } + if envelope :matches "from" "*" { set "from" "${1}"; } + + debug_log "Received message TO=${to} FROM=${from}"; + + +6. Security Considerations + + If the "vnd.dovecot.debug" extension is used from scripts that are + managed by a user, the log messages SHOULD only be logged to a + personal log file specific to that user. Otherwise, users could + litter system log files with loads of log messages. + + +7. Normative References + + [KEYWORDS] + Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [SIEVE] Guenther, P. and T. Showalter, "Sieve: An Email Filtering + Language", RFC 5228, January 2008. + + [VARIABLES] + Homme, K., "Sieve Email Filtering: Variables Extension", + RFC 5229, January 2008. + + + + + +Bosch [Page 3] + + Sieve: Debug Logging August 2012 + + +Author's Address + + Stephan Bosch + Enschede + NL + + Email: stephan at rename-it.nl + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Bosch [Page 4] + diff -r 9d962388f5f6 -r 54a0d0552be7 doc/rfc/xml/reference.VARIABLES.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/rfc/xml/reference.VARIABLES.xml Thu Aug 09 22:58:53 2012 +0200 @@ -0,0 +1,15 @@ + + + + + +Sieve Email Filtering: Variables Extension + + + + +In advanced mail filtering rule sets, it is useful to keep state or configuration details across rules. This document updates the Sieve filtering language (RFC 5228) with an extension to support variables. The extension changes the interpretation of strings, adds an action to store data in variables, and supplies a new test so that the value of a string can be examined. [STANDARDS-TRACK] + + + + diff -r 9d962388f5f6 -r 54a0d0552be7 doc/rfc/xml/spec-bosch-sieve-debug.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/rfc/xml/spec-bosch-sieve-debug.xml Thu Aug 09 22:58:53 2012 +0200 @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + +Sieve Email Filtering: Logging Debug Messages + + + + +
+ + + Enschede + NL + + stephan at rename-it.nl +
+
+ + + +General +Pigeonhole Project +sieve +debug +logging + + + +This document defines a new vendor-defined test command "debug_log" for the +"Sieve" email filtering language. It provides the means to debug a Sieve script +by logging debug messages. + From pigeonhole at rename-it.nl Fri Aug 10 00:01:49 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 09 Aug 2012 23:01:49 +0200 Subject: dovecot-2.2-pigeonhole: Testsuite: fixed compiler warning. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/bb8a9332e3d5 changeset: 1646:bb8a9332e3d5 user: Stephan Bosch date: Sun Aug 05 18:42:12 2012 +0200 description: Testsuite: fixed compiler warning. diffstat: src/testsuite/testsuite-variables.c | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diffs (17 lines): diff -r e44101914a27 -r bb8a9332e3d5 src/testsuite/testsuite-variables.c --- a/src/testsuite/testsuite-variables.c Sun Aug 05 00:30:14 2012 +0200 +++ b/src/testsuite/testsuite-variables.c Sun Aug 05 18:42:12 2012 +0200 @@ -103,13 +103,10 @@ { const struct sieve_extension *this_ext = SIEVE_OBJECT_EXTENSION(nspc); const char *variable = (const char *) var_data; - struct ext_testsuite_context *ext_data; if ( this_ext == NULL ) return FALSE; - ext_data = (struct ext_testsuite_context *) this_ext->context; - sieve_variables_opr_namespace_variable_emit (cgenv->sblock, testsuite_ext_variables, this_ext, &testsuite_namespace); sieve_binary_emit_cstring(cgenv->sblock, variable); From pigeonhole at rename-it.nl Fri Aug 10 00:01:49 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 09 Aug 2012 23:01:49 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: made action limit error messa... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/b25d4208949f changeset: 1647:b25d4208949f user: Stephan Bosch date: Mon Aug 06 23:14:19 2012 +0200 description: lib-sieve: made action limit error messages more verbose. diffstat: src/lib-sieve/sieve-result.c | 12 +++++++----- 1 files changed, 7 insertions(+), 5 deletions(-) diffs (28 lines): diff -r bb8a9332e3d5 -r b25d4208949f src/lib-sieve/sieve-result.c --- a/src/lib-sieve/sieve-result.c Sun Aug 05 18:42:12 2012 +0200 +++ b/src/lib-sieve/sieve-result.c Mon Aug 06 23:14:19 2012 +0200 @@ -554,17 +554,19 @@ } /* Check policy limit on total number of actions */ - if ( svinst->max_actions > 0 && result->action_count >= svinst->max_actions ) + if ( svinst->max_actions > 0 && result->action_count >= svinst->max_actions ) { - sieve_runtime_error(renv, action.location, - "total number of actions exceeds policy limit"); + sieve_runtime_error(renv, action.location, + "total number of actions exceeds policy limit (%u > %u)", + result->action_count+1, svinst->max_actions); return -1; } /* Check policy limit on number of this class of actions */ if ( instance_limit > 0 && instance_count >= instance_limit ) { - sieve_runtime_error(renv, action.location, - "number of %s actions exceeds policy limit", act_def->name); + sieve_runtime_error(renv, action.location, + "number of %s actions exceeds policy limit (%u > %u)", + act_def->name, instance_count+1, instance_limit); return -1; } From pigeonhole at rename-it.nl Fri Aug 10 00:01:49 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 09 Aug 2012 23:01:49 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: fixed potential action duplic... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/837c108f0363 changeset: 1648:837c108f0363 user: Stephan Bosch date: Tue Aug 07 00:34:12 2012 +0200 description: lib-sieve: fixed potential action duplication bug. diffstat: src/lib-sieve/sieve-result.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r b25d4208949f -r 837c108f0363 src/lib-sieve/sieve-result.c --- a/src/lib-sieve/sieve-result.c Mon Aug 06 23:14:19 2012 +0200 +++ b/src/lib-sieve/sieve-result.c Tue Aug 07 00:34:12 2012 +0200 @@ -588,7 +588,7 @@ raction->action.location = p_strdup(result->pool, action.location); raction->keep = keep; - if ( raction->prev == NULL ) { + if ( raction->prev == NULL && raction != result->first_action ) { /* Add */ if ( result->first_action == NULL ) { result->first_action = raction; From pigeonhole at rename-it.nl Fri Aug 10 00:01:48 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 09 Aug 2012 23:01:48 +0200 Subject: dovecot-2.2-pigeonhole: Include: fixed namespace separation of :... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/6a34eda7924e changeset: 1643:6a34eda7924e user: Stephan Bosch date: Fri Aug 03 19:52:36 2012 +0200 description: Include: fixed namespace separation of :global and :personal scripts. Sieve script equality function implementation was wrong. diffstat: src/lib-sieve/sieve-script-dict.c | 29 +++++++++++++-- src/lib-sieve/sieve-script-file.c | 4 +- src/lib-sieve/sieve-script.c | 11 ++--- tests/extensions/include/execute.svtest | 27 ++++++++++++++ tests/extensions/include/included-global/namespace.sieve | 4 ++ tests/extensions/include/included/namespace.sieve | 4 ++ 6 files changed, 67 insertions(+), 12 deletions(-) diffs (162 lines): diff -r c52a0c561311 -r 6a34eda7924e src/lib-sieve/sieve-script-dict.c --- a/src/lib-sieve/sieve-script-dict.c Tue Jul 31 01:18:15 2012 +0200 +++ b/src/lib-sieve/sieve-script-dict.c Fri Aug 03 19:52:36 2012 +0200 @@ -17,7 +17,8 @@ struct sieve_script script; struct dict *dict; - + const char *dict_uri; + pool_t data_pool; const char *data_id; const char *data; @@ -103,8 +104,9 @@ "user=%s, uri=%s, script=%s", username, data, name); } + script->dict_uri = p_strdup(_script->pool, data); script->dict = dict_init - (data, DICT_DATA_TYPE_STRING, username, svinst->base_dir); + (script->dict_uri, DICT_DATA_TYPE_STRING, username, svinst->base_dir); if ( script->dict == NULL ) { sieve_critical(svinst, ehandler, name, "failed to open sieve script", "sieve dict backend: failed to initialize dict with data `%s' " @@ -265,6 +267,24 @@ return sieve_binary_save(sbin, script->binpath, update, 0600, error_r); } +static bool sieve_dict_script_equals +(const struct sieve_script *_script, const struct sieve_script *_other) +{ + struct sieve_dict_script *script = (struct sieve_dict_script *)_script; + struct sieve_dict_script *other = (struct sieve_dict_script *)_other; + + if ( script == NULL || other == NULL ) + return FALSE; + + if ( strcmp(script->dict_uri, other->dict_uri) != 0 ) + return FALSE; + + i_assert( _script->name != NULL && _other->name != NULL ); + + return ( strcmp(_script->name, _other->name) == 0 ); +} + + const struct sieve_script sieve_dict_script = { .driver_name = SIEVE_DICT_SCRIPT_DRIVER_NAME, .v = { @@ -273,13 +293,14 @@ sieve_dict_script_destroy, sieve_dict_script_open, - sieve_dict_script_close, + sieve_dict_script_close, sieve_dict_script_binary_read_metadata, sieve_dict_script_binary_write_metadata, sieve_dict_script_binary_load, sieve_dict_script_binary_save, - NULL, NULL + NULL, + sieve_dict_script_equals } }; diff -r c52a0c561311 -r 6a34eda7924e src/lib-sieve/sieve-script-file.c --- a/src/lib-sieve/sieve-script-file.c Tue Jul 31 01:18:15 2012 +0200 +++ b/src/lib-sieve/sieve-script-file.c Fri Aug 03 19:52:36 2012 +0200 @@ -310,8 +310,8 @@ struct sieve_file_script *script = (struct sieve_file_script *)_script; struct sieve_file_script *other = (struct sieve_file_script *)_other; - if ( script == NULL || other == NULL ) - return -1; + if ( script == NULL || other == NULL ) + return FALSE; return ( script->st.st_ino == other->st.st_ino ); } diff -r c52a0c561311 -r 6a34eda7924e src/lib-sieve/sieve-script.c --- a/src/lib-sieve/sieve-script.c Tue Jul 31 01:18:15 2012 +0200 +++ b/src/lib-sieve/sieve-script.c Fri Aug 03 19:52:36 2012 +0200 @@ -414,18 +414,17 @@ if ( script->script_class != other->script_class ) return FALSE; - if ( script->name != NULL && other->name != NULL && - strcmp(script->name, other->name) == 0 ) - return TRUE; + if ( script->v.equals == NULL ) { + i_assert ( script->location != NULL && other->location != NULL); - if ( script->v.equals == NULL ) - return FALSE; + return ( strcmp(script->location, other->location) == 0 ); + } return script->v.equals(script, other); } unsigned int sieve_script_hash(const struct sieve_script *script) -{ +{ return str_hash(script->name); } diff -r c52a0c561311 -r 6a34eda7924e tests/extensions/include/execute.svtest --- a/tests/extensions/include/execute.svtest Tue Jul 31 01:18:15 2012 +0200 +++ b/tests/extensions/include/execute.svtest Fri Aug 03 19:52:36 2012 +0200 @@ -1,4 +1,6 @@ require "vnd.dovecot.testsuite"; +require "include"; +require "variables"; test_set "message" text: From: idiot at example.com @@ -40,3 +42,28 @@ test_fail "fileinto \"bbbb\" not executed."; } } + +test "Namespace" { + set "global.a" "none"; + include :personal "namespace"; + + if string "${global.a}" "none" { + test_fail "global script not executed"; + } + + if not string "${global.a}" "personal" { + test_fail "executed global instead of personal script: ${global.a}"; + } + + set "global.a" "none"; + include :global "namespace"; + + if string "{global.a}" "none" { + test_fail "global script not executed"; + } + + if not string "${global.a}" "global" { + test_fail "executed personal instead of global script: ${global.a}"; + } +} + diff -r c52a0c561311 -r 6a34eda7924e tests/extensions/include/included-global/namespace.sieve --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/extensions/include/included-global/namespace.sieve Fri Aug 03 19:52:36 2012 +0200 @@ -0,0 +1,4 @@ +require "include"; +require "variables"; + +set "global.a" "global"; diff -r c52a0c561311 -r 6a34eda7924e tests/extensions/include/included/namespace.sieve --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/extensions/include/included/namespace.sieve Fri Aug 03 19:52:36 2012 +0200 @@ -0,0 +1,4 @@ +require "include"; +require "variables"; + +set "global.a" "personal"; From pigeonhole at rename-it.nl Fri Aug 10 00:01:49 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 09 Aug 2012 23:01:49 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: increase action instance coun... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/9d962388f5f6 changeset: 1649:9d962388f5f6 user: Stephan Bosch date: Tue Aug 07 00:36:11 2012 +0200 description: lib-sieve: increase action instance count (for limit checking) only when an action is actually created. diffstat: src/lib-sieve/sieve-result.c | 34 +++++++++++++++++----------------- 1 files changed, 17 insertions(+), 17 deletions(-) diffs (48 lines): diff -r 837c108f0363 -r 9d962388f5f6 src/lib-sieve/sieve-result.c --- a/src/lib-sieve/sieve-result.c Tue Aug 07 00:34:12 2012 +0200 +++ b/src/lib-sieve/sieve-result.c Tue Aug 07 00:36:11 2012 +0200 @@ -553,27 +553,27 @@ raction = raction->next; } - /* Check policy limit on total number of actions */ - if ( svinst->max_actions > 0 && result->action_count >= svinst->max_actions ) - { - sieve_runtime_error(renv, action.location, - "total number of actions exceeds policy limit (%u > %u)", - result->action_count+1, svinst->max_actions); - return -1; - } - - /* Check policy limit on number of this class of actions */ - if ( instance_limit > 0 && instance_count >= instance_limit ) { - sieve_runtime_error(renv, action.location, - "number of %s actions exceeds policy limit (%u > %u)", - act_def->name, instance_count+1, instance_limit); - return -1; - } - if ( kaction != NULL ) { /* Use existing keep action to define new one */ raction = kaction; } else { + /* Check policy limit on total number of actions */ + if ( svinst->max_actions > 0 && result->action_count >= svinst->max_actions ) + { + sieve_runtime_error(renv, action.location, + "total number of actions exceeds policy limit (%u > %u)", + result->action_count+1, svinst->max_actions); + return -1; + } + + /* Check policy limit on number of this class of actions */ + if ( instance_limit > 0 && instance_count >= instance_limit ) { + sieve_runtime_error(renv, action.location, + "number of %s actions exceeds policy limit (%u > %u)", + act_def->name, instance_count+1, instance_limit); + return -1; + } + /* Create new action object */ raction = p_new(result->pool, struct sieve_result_action, 1); raction->action.executed = FALSE; From pigeonhole at rename-it.nl Fri Aug 10 00:01:49 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 09 Aug 2012 23:01:49 +0200 Subject: dovecot-2.2-pigeonhole: Testsuite: fixed displaying debug messages. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/09e393e4274b changeset: 1644:09e393e4274b user: Stephan Bosch date: Sat Aug 04 09:34:21 2012 +0200 description: Testsuite: fixed displaying debug messages. diffstat: src/testsuite/testsuite-log.c | 66 +++++++++++++++++++++--------------------- 1 files changed, 33 insertions(+), 33 deletions(-) diffs (128 lines): diff -r 6a34eda7924e -r 09e393e4274b src/testsuite/testsuite-log.c --- a/src/testsuite/testsuite-log.c Fri Aug 03 19:52:36 2012 +0200 +++ b/src/testsuite/testsuite-log.c Sat Aug 04 09:34:21 2012 +0200 @@ -35,6 +35,23 @@ ARRAY_DEFINE(_testsuite_log_warnings, struct _testsuite_log_message); ARRAY_DEFINE(_testsuite_log_messages, struct _testsuite_log_message); +static inline void ATTR_FORMAT(3, 0) _testsuite_stdout_vlog +(const char *prefix, const char *location, const char *fmt, + va_list args) +{ + if ( _testsuite_log_stdout ) { + va_list args_copy; + VA_COPY(args_copy, args); + + if ( location == NULL || *location == '\0' ) + fprintf(stdout, + "LOG: %s: %s\n", prefix, t_strdup_vprintf(fmt, args_copy)); + else + fprintf(stdout, + "LOG: %s: %s: %s\n", prefix, location, t_strdup_vprintf(fmt, args_copy)); + } +} + static void ATTR_FORMAT(4, 0) _testsuite_log_verror (struct sieve_error_handler *ehandler ATTR_UNUSED, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, @@ -43,17 +60,7 @@ pool_t pool = _testsuite_logmsg_pool; struct _testsuite_log_message msg; - if ( _testsuite_log_stdout ) { - va_list args_copy; - VA_COPY(args_copy, args); - - if ( location == NULL || *location == '\0' ) - fprintf(stdout, - "LOG: error: %s\n", t_strdup_vprintf(fmt, args_copy)); - else - fprintf(stdout, - "LOG: error: %s: %s\n", location, t_strdup_vprintf(fmt, args_copy)); - } + _testsuite_stdout_vlog("error", location, fmt, args); msg.location = p_strdup(pool, location); msg.message = p_strdup_vprintf(pool, fmt, args); @@ -82,17 +89,7 @@ pool_t pool = _testsuite_logmsg_pool; struct _testsuite_log_message msg; - if ( _testsuite_log_stdout ) { - va_list args_copy; - VA_COPY(args_copy, args); - - if ( location == NULL || *location == '\0' ) - fprintf(stdout, - "LOG: warning: %s\n", t_strdup_vprintf(fmt, args_copy)); - else - fprintf(stdout, - "LOG: warning: %s: %s\n", location, t_strdup_vprintf(fmt, args_copy)); - } + _testsuite_stdout_vlog("warning", location, fmt, args); msg.location = p_strdup(pool, location); msg.message = p_strdup_vprintf(pool, fmt, args); @@ -108,17 +105,7 @@ pool_t pool = _testsuite_logmsg_pool; struct _testsuite_log_message msg; - if ( _testsuite_log_stdout ) { - va_list args_copy; - VA_COPY(args_copy, args); - - if ( location == NULL || *location == '\0' ) - fprintf(stdout, - "LOG: info: %s\n", t_strdup_vprintf(fmt, args_copy)); - else - fprintf(stdout, - "LOG: info: %s: %s\n", location, t_strdup_vprintf(fmt, args_copy)); - } + _testsuite_stdout_vlog("info", location, fmt, args); msg.location = p_strdup(pool, location); msg.message = p_strdup_vprintf(pool, fmt, args); @@ -126,6 +113,15 @@ array_append(&_testsuite_log_messages, &msg, 1); } + +static void ATTR_FORMAT(4, 0) _testsuite_log_vdebug +(struct sieve_error_handler *ehandler ATTR_UNUSED, + unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, + va_list args) +{ + _testsuite_stdout_vlog("debug", location, fmt, args); +} + static struct sieve_error_handler *_testsuite_log_ehandler_create(void) { pool_t pool; @@ -139,6 +135,7 @@ ehandler->verror = _testsuite_log_verror; ehandler->vwarning = _testsuite_log_vwarning; ehandler->vinfo = _testsuite_log_vinfo; + ehandler->vdebug = _testsuite_log_vdebug; return ehandler; } @@ -156,6 +153,7 @@ ehandler->verror = _testsuite_log_main_verror; ehandler->vwarning = _testsuite_log_vwarning; ehandler->vinfo = _testsuite_log_vinfo; + ehandler->vdebug = _testsuite_log_vdebug; return ehandler; } @@ -192,9 +190,11 @@ testsuite_log_ehandler = _testsuite_log_ehandler_create(); sieve_error_handler_accept_infolog(testsuite_log_ehandler, TRUE); + sieve_error_handler_accept_debuglog(testsuite_log_ehandler, TRUE); testsuite_log_main_ehandler = _testsuite_log_main_ehandler_create(); sieve_error_handler_accept_infolog(testsuite_log_main_ehandler, TRUE); + sieve_error_handler_accept_debuglog(testsuite_log_main_ehandler, TRUE); sieve_system_ehandler_set(testsuite_log_ehandler); From pigeonhole at rename-it.nl Fri Aug 10 00:01:49 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 09 Aug 2012 23:01:49 +0200 Subject: dovecot-2.2-pigeonhole: Testsuite: added support for executing s... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/e44101914a27 changeset: 1645:e44101914a27 user: Stephan Bosch date: Sun Aug 05 00:30:14 2012 +0200 description: Testsuite: added support for executing sub-scripts and added tst variables namespace. Added test for interaction between include extension and dict script location support. diffstat: src/testsuite/Makefile.am | 3 + src/testsuite/cmd-test-binary.c | 4 +- src/testsuite/ext-testsuite.c | 31 +- src/testsuite/testsuite-common.c | 56 ++++- src/testsuite/testsuite-common.h | 21 +- src/testsuite/testsuite-script.c | 71 ++++-- src/testsuite/testsuite-script.h | 6 +- src/testsuite/testsuite-variables.c | 186 ++++++++++++++++ src/testsuite/testsuite-variables.h | 14 + src/testsuite/testsuite.c | 2 +- tests/extensions/include/execute.svtest | 41 +- tests/extensions/include/execute/namespace.sieve | 26 ++ tests/extensions/include/included-global/namespace.dict | 4 + tests/extensions/include/included/namespace.dict | 4 + 14 files changed, 405 insertions(+), 64 deletions(-) diffs (truncated from 772 to 300 lines): diff -r 09e393e4274b -r e44101914a27 src/testsuite/Makefile.am --- a/src/testsuite/Makefile.am Sat Aug 04 09:34:21 2012 +0200 +++ b/src/testsuite/Makefile.am Sun Aug 05 00:30:14 2012 +0200 @@ -2,6 +2,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib-sieve \ + -I$(top_srcdir)/src/lib-sieve/plugins/variables \ -I$(top_srcdir)/src/lib-sieve-tool \ $(LIBDOVECOT_INCLUDE) \ $(LIBDOVECOT_SERVICE_INCLUDE) @@ -38,6 +39,7 @@ testsuite-settings.c \ testsuite-objects.c \ testsuite-substitutions.c \ + testsuite-variables.c \ testsuite-arguments.c \ testsuite-message.c \ testsuite-log.c \ @@ -56,6 +58,7 @@ testsuite-settings.h \ testsuite-objects.h \ testsuite-substitutions.h \ + testsuite-variables.h \ testsuite-arguments.h \ testsuite-message.h \ testsuite-log.h \ diff -r 09e393e4274b -r e44101914a27 src/testsuite/cmd-test-binary.c --- a/src/testsuite/cmd-test-binary.c Sat Aug 04 09:34:21 2012 +0200 +++ b/src/testsuite/cmd-test-binary.c Sun Aug 05 00:30:14 2012 +0200 @@ -176,7 +176,7 @@ } if ( sbin != NULL ) { - testsuite_script_set_binary(sbin); + testsuite_script_set_binary(renv, sbin); sieve_binary_unref(&sbin); } else { @@ -186,7 +186,7 @@ } } else if ( sieve_operation_is(oprtn, test_binary_save_operation) ) { - struct sieve_binary *sbin = testsuite_script_get_binary(); + struct sieve_binary *sbin = testsuite_script_get_binary(renv); if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { sieve_runtime_trace(renv, 0, "testsuite: test_binary_save command"); diff -r 09e393e4274b -r e44101914a27 src/testsuite/ext-testsuite.c --- a/src/testsuite/ext-testsuite.c Sat Aug 04 09:34:21 2012 +0200 +++ b/src/testsuite/ext-testsuite.c Sun Aug 05 00:30:14 2012 +0200 @@ -45,6 +45,7 @@ #include "sieve-result.h" #include "testsuite-common.h" +#include "testsuite-variables.h" #include "testsuite-arguments.h" /* @@ -76,16 +77,17 @@ &test_binary_save_operation }; -/* - * Operands +/* + * Operands */ -const struct sieve_operand_def *testsuite_operands[] = { +const struct sieve_operand_def *testsuite_operands[] = { &testsuite_object_operand, - &testsuite_substitution_operand + &testsuite_substitution_operand, + &testsuite_namespace_operand }; - -/* + +/* * Extension */ @@ -95,6 +97,9 @@ (const struct sieve_extension *ext, struct sieve_validator *valdtr); static bool ext_testsuite_generator_load (const struct sieve_extension *ext, const struct sieve_codegen_env *cgenv); +static bool ext_testsuite_interpreter_load + (const struct sieve_extension *ext, const struct sieve_runtime_env *renv, + sieve_size_t *address); static bool ext_testsuite_binary_load (const struct sieve_extension *ext, struct sieve_binary *sbin); @@ -105,7 +110,7 @@ NULL, NULL, ext_testsuite_validator_load, ext_testsuite_generator_load, - NULL, + ext_testsuite_interpreter_load, ext_testsuite_binary_load, NULL, NULL, SIEVE_EXT_DEFINE_OPERATIONS(testsuite_operations), @@ -142,6 +147,8 @@ /* sieve_validator_argument_override(valdtr, SAT_VAR_STRING, ext, &testsuite_string_argument);*/ + testsuite_variables_init(ext, valdtr); + return testsuite_validator_context_initialize(valdtr); } @@ -151,9 +158,15 @@ return testsuite_generator_context_initialize(cgenv->gentr, ext); } +static bool ext_testsuite_interpreter_load +(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, + sieve_size_t *address ATTR_UNUSED) +{ + return testsuite_interpreter_context_initialize(renv->interp, ext); +} + static bool ext_testsuite_binary_load -(const struct sieve_extension *ext ATTR_UNUSED, - struct sieve_binary *sbin ATTR_UNUSED) +(const struct sieve_extension *ext ATTR_UNUSED, struct sieve_binary *sbin ATTR_UNUSED) { return TRUE; } diff -r 09e393e4274b -r e44101914a27 src/testsuite/testsuite-common.c --- a/src/testsuite/testsuite-common.c Sat Aug 04 09:34:21 2012 +0200 +++ b/src/testsuite/testsuite-common.c Sun Aug 05 00:30:14 2012 +0200 @@ -17,6 +17,7 @@ #include "sieve-message.h" #include "sieve-commands.h" #include "sieve-extensions.h" +#include "sieve-binary.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" @@ -45,6 +46,7 @@ */ struct sieve_instance *testsuite_sieve_instance = NULL; +char *testsuite_test_path = NULL; /* Test context */ @@ -103,6 +105,48 @@ } /* + * Interpreter context + */ + +static void testsuite_interpreter_free +(const struct sieve_extension *ext ATTR_UNUSED, + struct sieve_interpreter *interp ATTR_UNUSED, void *context) +{ + struct testsuite_interpreter_context *ctx = + (struct testsuite_interpreter_context *)context; + + if ( ctx->compiled_script != NULL ) + sieve_binary_unref(&ctx->compiled_script); +} + +const struct sieve_interpreter_extension testsuite_interpreter_ext = { + &testsuite_extension, + NULL, + testsuite_interpreter_free, +}; + +bool testsuite_interpreter_context_initialize +(struct sieve_interpreter *interp, const struct sieve_extension *this_ext) +{ + pool_t pool = sieve_interpreter_pool(interp); + struct testsuite_interpreter_context *ctx = + p_new(pool, struct testsuite_interpreter_context, 1); + + sieve_interpreter_extension_register + (interp, this_ext, &testsuite_interpreter_ext, ctx); + return TRUE; +} + +struct testsuite_interpreter_context *testsuite_interpreter_context_get +(struct sieve_interpreter *interp, const struct sieve_extension *this_ext) +{ + struct testsuite_interpreter_context *ctx = + sieve_interpreter_extension_get_context(interp, this_ext); + + return ctx; +} + +/* * Test context */ @@ -234,28 +278,34 @@ * Main testsuite init/deinit */ -void testsuite_init(struct sieve_instance *svinst, bool log_stdout) +void testsuite_init +(struct sieve_instance *svinst, const char *test_path, bool log_stdout) { testsuite_sieve_instance = svinst; testsuite_test_context_init(); testsuite_log_init(log_stdout); testsuite_tmp_dir_init(); - + testsuite_script_init(); testsuite_binary_init(); testsuite_smtp_init(); testsuite_ext = sieve_extension_register (svinst, &testsuite_extension, TRUE); + + + testsuite_test_path = i_strdup(test_path); } void testsuite_deinit(void) { + i_free(testsuite_test_path); + testsuite_smtp_deinit(); testsuite_binary_deinit(); testsuite_script_deinit(); - + testsuite_tmp_dir_deinit(); testsuite_log_deinit(); testsuite_test_context_deinit(); diff -r 09e393e4274b -r e44101914a27 src/testsuite/testsuite-common.h --- a/src/testsuite/testsuite-common.h Sat Aug 04 09:34:21 2012 +0200 +++ b/src/testsuite/testsuite-common.h Sun Aug 05 00:30:14 2012 +0200 @@ -20,6 +20,8 @@ extern const struct sieve_script_env *testsuite_scriptenv; +extern char *testsuite_test_path; + /* * Validator context @@ -45,6 +47,19 @@ (struct sieve_generator *gentr, const struct sieve_extension *this_ext); /* + * Interpreter context + */ + +struct testsuite_interpreter_context { + struct sieve_binary *compiled_script; +}; + +bool testsuite_interpreter_context_initialize + (struct sieve_interpreter *interp, const struct sieve_extension *this_ext); +struct testsuite_interpreter_context *testsuite_interpreter_context_get + (struct sieve_interpreter *interp, const struct sieve_extension *this_ext); + +/* * Commands */ @@ -136,7 +151,8 @@ enum testsuite_operand_code { TESTSUITE_OPERAND_OBJECT, - TESTSUITE_OPERAND_SUBSTITUTION + TESTSUITE_OPERAND_SUBSTITUTION, + TESTSUITE_OPERAND_NAMESPACE }; /* @@ -163,7 +179,8 @@ * Testsuite init/deinit */ -void testsuite_init(struct sieve_instance *svinst, bool log_stdout); +void testsuite_init + (struct sieve_instance *svinst, const char *test_path, bool log_stdout); void testsuite_deinit(void); #endif /* __TESTSUITE_COMMON_H */ diff -r 09e393e4274b -r e44101914a27 src/testsuite/testsuite-script.c --- a/src/testsuite/testsuite-script.c Sat Aug 04 09:34:21 2012 +0200 +++ b/src/testsuite/testsuite-script.c Sun Aug 05 00:30:14 2012 +0200 @@ -21,20 +21,14 @@ /* * Tested script environment - */ - -struct sieve_binary *_testsuite_compiled_script; + */ void testsuite_script_init(void) From pigeonhole at rename-it.nl Fri Aug 10 00:01:49 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 09 Aug 2012 23:01:49 +0200 Subject: dovecot-2.2-pigeonhole: Created specification for the vnd.doveco... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/54a0d0552be7 changeset: 1650:54a0d0552be7 user: Stephan Bosch date: Thu Aug 09 22:58:53 2012 +0200 description: Created specification for the vnd.dovecot.debug extension. Also fixed a small mistake in the spefication for the vnd.dovecot.duplicate extension. diffstat: doc/rfc/spec-bosch-sieve-debug.txt | 224 +++++++++++++++++++++++++++++ doc/rfc/xml/reference.VARIABLES.xml | 15 + doc/rfc/xml/spec-bosch-sieve-debug.xml | 168 +++++++++++++++++++++ doc/rfc/xml/spec-bosch-sieve-duplicate.xml | 2 +- 4 files changed, 408 insertions(+), 1 deletions(-) diffs (truncated from 431 to 300 lines): diff -r 9d962388f5f6 -r 54a0d0552be7 doc/rfc/spec-bosch-sieve-debug.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/rfc/spec-bosch-sieve-debug.txt Thu Aug 09 22:58:53 2012 +0200 @@ -0,0 +1,224 @@ + + + +Pigeonhole Project S. Bosch + August 9, 2012 + + + Sieve Email Filtering: Logging Debug Messages + +Abstract + + This document defines a new vendor-defined test command "debug_log" + for the "Sieve" email filtering language. It provides the means to + debug a Sieve script by logging debug messages. + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2 + 2. Conventions Used in This Document . . . . . . . . . . . . . . . 2 + 3. Command "debug_log" . . . . . . . . . . . . . . . . . . . . . . 2 + 4. Sieve Capability Strings . . . . . . . . . . . . . . . . . . . 2 + 5. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 + 6. Security Considerations . . . . . . . . . . . . . . . . . . . . 3 + 7. Normative References . . . . . . . . . . . . . . . . . . . . . 3 + Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Bosch [Page 1] + + Sieve: Debug Logging August 2012 + + +1. Introduction + + This is an extension to the Sieve filtering language defined by RFC + 5228 [SIEVE]. It adds a command that provides the means to debug a + Sieve script by logging debug messages. + + Much like any other kind of computer program, Sieve scripts are prone + to all kinds of mistakes. Often, there are no real error conditions, + e.g. Sieve language violations, that cause the failure and no error + or warning messages are logged for the user or administrator to + determine what caused the erroneous result. A convenient method of + debugging such issues is printing debug messages to some kind of + logging facility. This way for example, script authors can check + whether specific sections of the script are executed. When combined + with the "variables" [VARIABLES] extension, intermittent results, + message data and status information can be included in those log + messages, further improving the information available for debugging. + + This extension is specific to the Pigeonhole Sieve implementation for + the Dovecot Secure IMAP server. It will therefore most likely not be + supported by web interfaces and GUI-based Sieve editors. + + +2. Conventions Used in This Document + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in [KEYWORDS]. + + Conventions for notations are as in [SIEVE] Section 1.1, including + use of the "Usage:" label for the definition of action and tagged + arguments syntax. + + +3. Command "debug_log" + + Usage: "debug_log" + + The "debug_log" command prints the debug message provided as the + command's "message" argument to an implementation-defined logging + facility. The message MAY contain variable substitutions as provided + by the "variables" [VARIABLES] extension to dynamically compose the + message from information available at runtime. + + +4. Sieve Capability Strings + + A Sieve implementation that defines the "debug_log" action command + + + +Bosch [Page 2] + + Sieve: Debug Logging August 2012 + + + will advertise the capability string "vnd.dovecot.debug". + + +5. Examples + + The following example logs a message when the message's subject + contains the "hello": + + require "vnd.dovecot.debug"; + + if header :contains "subject" "hello" { + debug_log "Subject header contains hello!"; + } + + The next example logs the envelope of the message using the + "variables" [VARIABLES] extension and the "envelope" [SIEVE] + extension: + + require ["variables", "envelope", "vnd.dovecot.debug"]; + + if envelope :matches "to" "*" { set "to" "${1}"; } + if envelope :matches "from" "*" { set "from" "${1}"; } + + debug_log "Received message TO=${to} FROM=${from}"; + + +6. Security Considerations + + If the "vnd.dovecot.debug" extension is used from scripts that are + managed by a user, the log messages SHOULD only be logged to a + personal log file specific to that user. Otherwise, users could + litter system log files with loads of log messages. + + +7. Normative References + + [KEYWORDS] + Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [SIEVE] Guenther, P. and T. Showalter, "Sieve: An Email Filtering + Language", RFC 5228, January 2008. + + [VARIABLES] + Homme, K., "Sieve Email Filtering: Variables Extension", + RFC 5229, January 2008. + + + + + +Bosch [Page 3] + + Sieve: Debug Logging August 2012 + + +Author's Address + + Stephan Bosch + Enschede + NL + + Email: stephan at rename-it.nl + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Bosch [Page 4] + diff -r 9d962388f5f6 -r 54a0d0552be7 doc/rfc/xml/reference.VARIABLES.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/rfc/xml/reference.VARIABLES.xml Thu Aug 09 22:58:53 2012 +0200 @@ -0,0 +1,15 @@ + + + + + +Sieve Email Filtering: Variables Extension + + + + +In advanced mail filtering rule sets, it is useful to keep state or configuration details across rules. This document updates the Sieve filtering language (RFC 5228) with an extension to support variables. The extension changes the interpretation of strings, adds an action to store data in variables, and supplies a new test so that the value of a string can be examined. [STANDARDS-TRACK] + + + + diff -r 9d962388f5f6 -r 54a0d0552be7 doc/rfc/xml/spec-bosch-sieve-debug.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/rfc/xml/spec-bosch-sieve-debug.xml Thu Aug 09 22:58:53 2012 +0200 @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + +Sieve Email Filtering: Logging Debug Messages + + + + +
+ + + Enschede + NL + + stephan at rename-it.nl +
+
+ + + +General +Pigeonhole Project +sieve +debug +logging + + + +This document defines a new vendor-defined test command "debug_log" for the +"Sieve" email filtering language. It provides the means to debug a Sieve script +by logging debug messages. + From pigeonhole at rename-it.nl Fri Aug 10 00:01:49 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 09 Aug 2012 23:01:49 +0200 Subject: dovecot-2.2-pigeonhole: Merged changes from Pigeonhole v0.3 tree. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/368c8f1c0511 changeset: 1651:368c8f1c0511 user: Stephan Bosch date: Thu Aug 09 23:01:43 2012 +0200 description: Merged changes from Pigeonhole v0.3 tree. diffstat: doc/rfc/spec-bosch-sieve-debug.txt | 224 +++++++++++++++ doc/rfc/xml/reference.VARIABLES.xml | 15 + doc/rfc/xml/spec-bosch-sieve-debug.xml | 168 +++++++++++ doc/rfc/xml/spec-bosch-sieve-duplicate.xml | 2 +- src/lib-sieve/sieve-result.c | 34 +- src/lib-sieve/sieve-script-dict.c | 29 +- src/lib-sieve/sieve-script-file.c | 4 +- src/lib-sieve/sieve-script.c | 11 +- src/testsuite/Makefile.am | 3 + src/testsuite/cmd-test-binary.c | 4 +- src/testsuite/ext-testsuite.c | 31 +- src/testsuite/testsuite-common.c | 56 +++- src/testsuite/testsuite-common.h | 21 +- src/testsuite/testsuite-log.c | 66 ++-- src/testsuite/testsuite-script.c | 71 +++- src/testsuite/testsuite-script.h | 6 +- src/testsuite/testsuite-variables.c | 183 ++++++++++++ src/testsuite/testsuite-variables.h | 14 + src/testsuite/testsuite.c | 2 +- tests/extensions/include/execute.svtest | 26 + tests/extensions/include/execute/namespace.sieve | 26 + tests/extensions/include/included-global/namespace.dict | 4 + tests/extensions/include/included-global/namespace.sieve | 4 + tests/extensions/include/included/namespace.dict | 4 + tests/extensions/include/included/namespace.sieve | 4 + 25 files changed, 907 insertions(+), 105 deletions(-) diffs (truncated from 1493 to 300 lines): diff -r bea6fcece21e -r 368c8f1c0511 doc/rfc/spec-bosch-sieve-debug.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/rfc/spec-bosch-sieve-debug.txt Thu Aug 09 23:01:43 2012 +0200 @@ -0,0 +1,224 @@ + + + +Pigeonhole Project S. Bosch + August 9, 2012 + + + Sieve Email Filtering: Logging Debug Messages + +Abstract + + This document defines a new vendor-defined test command "debug_log" + for the "Sieve" email filtering language. It provides the means to + debug a Sieve script by logging debug messages. + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2 + 2. Conventions Used in This Document . . . . . . . . . . . . . . . 2 + 3. Command "debug_log" . . . . . . . . . . . . . . . . . . . . . . 2 + 4. Sieve Capability Strings . . . . . . . . . . . . . . . . . . . 2 + 5. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 + 6. Security Considerations . . . . . . . . . . . . . . . . . . . . 3 + 7. Normative References . . . . . . . . . . . . . . . . . . . . . 3 + Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Bosch [Page 1] + + Sieve: Debug Logging August 2012 + + +1. Introduction + + This is an extension to the Sieve filtering language defined by RFC + 5228 [SIEVE]. It adds a command that provides the means to debug a + Sieve script by logging debug messages. + + Much like any other kind of computer program, Sieve scripts are prone + to all kinds of mistakes. Often, there are no real error conditions, + e.g. Sieve language violations, that cause the failure and no error + or warning messages are logged for the user or administrator to + determine what caused the erroneous result. A convenient method of + debugging such issues is printing debug messages to some kind of + logging facility. This way for example, script authors can check + whether specific sections of the script are executed. When combined + with the "variables" [VARIABLES] extension, intermittent results, + message data and status information can be included in those log + messages, further improving the information available for debugging. + + This extension is specific to the Pigeonhole Sieve implementation for + the Dovecot Secure IMAP server. It will therefore most likely not be + supported by web interfaces and GUI-based Sieve editors. + + +2. Conventions Used in This Document + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in [KEYWORDS]. + + Conventions for notations are as in [SIEVE] Section 1.1, including + use of the "Usage:" label for the definition of action and tagged + arguments syntax. + + +3. Command "debug_log" + + Usage: "debug_log" + + The "debug_log" command prints the debug message provided as the + command's "message" argument to an implementation-defined logging + facility. The message MAY contain variable substitutions as provided + by the "variables" [VARIABLES] extension to dynamically compose the + message from information available at runtime. + + +4. Sieve Capability Strings + + A Sieve implementation that defines the "debug_log" action command + + + +Bosch [Page 2] + + Sieve: Debug Logging August 2012 + + + will advertise the capability string "vnd.dovecot.debug". + + +5. Examples + + The following example logs a message when the message's subject + contains the "hello": + + require "vnd.dovecot.debug"; + + if header :contains "subject" "hello" { + debug_log "Subject header contains hello!"; + } + + The next example logs the envelope of the message using the + "variables" [VARIABLES] extension and the "envelope" [SIEVE] + extension: + + require ["variables", "envelope", "vnd.dovecot.debug"]; + + if envelope :matches "to" "*" { set "to" "${1}"; } + if envelope :matches "from" "*" { set "from" "${1}"; } + + debug_log "Received message TO=${to} FROM=${from}"; + + +6. Security Considerations + + If the "vnd.dovecot.debug" extension is used from scripts that are + managed by a user, the log messages SHOULD only be logged to a + personal log file specific to that user. Otherwise, users could + litter system log files with loads of log messages. + + +7. Normative References + + [KEYWORDS] + Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [SIEVE] Guenther, P. and T. Showalter, "Sieve: An Email Filtering + Language", RFC 5228, January 2008. + + [VARIABLES] + Homme, K., "Sieve Email Filtering: Variables Extension", + RFC 5229, January 2008. + + + + + +Bosch [Page 3] + + Sieve: Debug Logging August 2012 + + +Author's Address + + Stephan Bosch + Enschede + NL + + Email: stephan at rename-it.nl + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Bosch [Page 4] + diff -r bea6fcece21e -r 368c8f1c0511 doc/rfc/xml/reference.VARIABLES.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/rfc/xml/reference.VARIABLES.xml Thu Aug 09 23:01:43 2012 +0200 @@ -0,0 +1,15 @@ + + + + + +Sieve Email Filtering: Variables Extension + + + + +In advanced mail filtering rule sets, it is useful to keep state or configuration details across rules. This document updates the Sieve filtering language (RFC 5228) with an extension to support variables. The extension changes the interpretation of strings, adds an action to store data in variables, and supplies a new test so that the value of a string can be examined. [STANDARDS-TRACK] + + + + diff -r bea6fcece21e -r 368c8f1c0511 doc/rfc/xml/spec-bosch-sieve-debug.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/rfc/xml/spec-bosch-sieve-debug.xml Thu Aug 09 23:01:43 2012 +0200 @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + +Sieve Email Filtering: Logging Debug Messages + + + + +
+ + + Enschede + NL + + stephan at rename-it.nl +
+
+ + + +General +Pigeonhole Project +sieve +debug +logging + + + +This document defines a new vendor-defined test command "debug_log" for the +"Sieve" email filtering language. It provides the means to debug a Sieve script +by logging debug messages. + From dovecot at dovecot.org Fri Aug 10 00:16:19 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 00:16:19 +0300 Subject: dovecot-2.2: lib-storage: Don't save text/* MIME parts to extern... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b1453bc21609 changeset: 14752:b1453bc21609 user: Timo Sirainen date: Fri Aug 10 00:16:08 2012 +0300 description: lib-storage: Don't save text/* MIME parts to external attachments even if they're big enough. diffstat: src/lib-storage/index/index-attachment.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diffs (18 lines): diff -r 1a938b81cc5f -r b1453bc21609 src/lib-storage/index/index-attachment.c --- a/src/lib-storage/index/index-attachment.c Thu Aug 09 18:50:31 2012 +0300 +++ b/src/lib-storage/index/index-attachment.c Fri Aug 10 00:16:08 2012 +0300 @@ -41,8 +41,12 @@ apart.content_type = hdr->content_type; apart.content_disposition = hdr->content_disposition; - return ctx->part_is_attachment == NULL ? TRUE : - ctx->part_is_attachment(ctx, &apart); + if (ctx->part_is_attachment != NULL) + return ctx->part_is_attachment(ctx, &apart); + + /* don't treat text/ parts as attachments */ + return hdr->content_type != NULL && + strncasecmp(hdr->content_type, "text/", 5) != 0; } static int index_attachment_open_temp_fd(void *context) From dovecot at dovecot.org Fri Aug 10 02:33:35 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 02:33:35 +0300 Subject: dovecot-2.1: lib-master: Another settings parser cache fix Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/b082b8260782 changeset: 14660:b082b8260782 user: Timo Sirainen date: Fri Aug 10 02:33:19 2012 +0300 description: lib-master: Another settings parser cache fix diffstat: src/lib-master/master-service-settings-cache.c | 20 +++++++++++--------- 1 files changed, 11 insertions(+), 9 deletions(-) diffs (58 lines): diff -r 82f59d2139a9 -r b082b8260782 src/lib-master/master-service-settings-cache.c --- a/src/lib-master/master-service-settings-cache.c Wed Aug 08 00:44:27 2012 +0300 +++ b/src/lib-master/master-service-settings-cache.c Fri Aug 10 02:33:19 2012 +0300 @@ -168,10 +168,11 @@ settings_parser_deinit(&entry->parser); } -static void cache_add(struct master_service_settings_cache *cache, - const struct master_service_settings_input *input, - const struct master_service_settings_output *output, - struct setting_parser_context *parser) +static struct setting_parser_context * +cache_add(struct master_service_settings_cache *cache, + const struct master_service_settings_input *input, + const struct master_service_settings_output *output, + struct setting_parser_context *parser) { struct settings_entry *entry; pool_t pool; @@ -187,17 +188,17 @@ } if (cache->service_uses_remote) { /* for now we don't try to handle caching remote IPs */ - return; + return parser; } if (input->local_name == NULL && input->local_ip.family == 0) - return; + return parser; if (!output->used_local) { /* use global settings, but add local_ip/host to hash tables so we'll find them */ pool = pool_alloconly_create("settings global entry", 256); - } else if (cache->cache_malloc_size >= cache->max_cache_size) { + } else if (cache->cache_malloc_size >= /*cache->max_cache_size*/1) { /* free the oldest and reuse its pool */ pool = cache->oldest->pool; setting_entry_detach(cache, cache->oldest); @@ -249,6 +250,7 @@ hash_table_insert(cache->local_ip_hash, &entry->local_ip, entry); } + return entry->parser; } int master_service_settings_cache_read(struct master_service_settings_cache *cache, @@ -294,7 +296,7 @@ return -1; } - cache_add(cache, &new_input, &output, cache->service->set_parser); - *parser_r = cache->service->set_parser; + *parser_r = cache_add(cache, &new_input, &output, + cache->service->set_parser); return 0; } From dovecot at dovecot.org Fri Aug 10 02:34:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 02:34:41 +0300 Subject: dovecot-2.1: Removed accidentally committed debug code Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/9d0873cefa08 changeset: 14661:9d0873cefa08 user: Timo Sirainen date: Fri Aug 10 02:34:34 2012 +0300 description: Removed accidentally committed debug code diffstat: src/lib-master/master-service-settings-cache.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r b082b8260782 -r 9d0873cefa08 src/lib-master/master-service-settings-cache.c --- a/src/lib-master/master-service-settings-cache.c Fri Aug 10 02:33:19 2012 +0300 +++ b/src/lib-master/master-service-settings-cache.c Fri Aug 10 02:34:34 2012 +0300 @@ -198,7 +198,7 @@ /* use global settings, but add local_ip/host to hash tables so we'll find them */ pool = pool_alloconly_create("settings global entry", 256); - } else if (cache->cache_malloc_size >= /*cache->max_cache_size*/1) { + } else if (cache->cache_malloc_size >= cache->max_cache_size) { /* free the oldest and reuse its pool */ pool = cache->oldest->pool; setting_entry_detach(cache, cache->oldest); From dovecot at dovecot.org Fri Aug 10 04:57:08 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 04:57:08 +0300 Subject: dovecot-2.2: TODO updated Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/53139f2f2284 changeset: 14753:53139f2f2284 user: Timo Sirainen date: Fri Aug 10 04:56:56 2012 +0300 description: TODO updated diffstat: TODO | 12 ++++++++++-- 1 files changed, 10 insertions(+), 2 deletions(-) diffs (26 lines): diff -r b1453bc21609 -r 53139f2f2284 TODO --- a/TODO Fri Aug 10 00:16:08 2012 +0300 +++ b/TODO Fri Aug 10 04:56:56 2012 +0300 @@ -1,4 +1,13 @@ - - GSSAPI auth patch + - Unfinished extensions: MOVE, NOTIFY, BINARY + - indexer-worker and maybe others (doveadm?) could support dropping privileges + permanently when service_count=1. Note that LMTP can't with multiple RCPT + TOs. + - after reading whole message text, update has_nul-state to cache + - if indexpvt is enabled, mailbox_list_indexes should go there? at least + private flags are otherwise problematic.. possibly only for shared/public + mailboxes?.. + - catenate: {1234} and {1234+} error handling is wrong for both + - index_mail_parse_headers() etc. message_parsers don't check for stream errors - FIFOs maybe should be counted as connections, but unlisten should unlink+reopen it in master? - mailbox list indexes + imaptest test=tests fails @@ -7,7 +16,6 @@ - change proxy TTL so it stops at 1? - istream-concat - lmtp client/proxy: Handle multiline replies better - - lib-ssl-iostream: Support ssl_protocols setting - recreate mailbox -> existing sessions log "indexid changed" error - add message/mime limits - imapc: From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: pop3c: Fixed losing timeout on ioloop change. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/edb8d177bd37 changeset: 14755:edb8d177bd37 user: Timo Sirainen date: Mon Jun 25 00:18:31 2012 +0300 description: pop3c: Fixed losing timeout on ioloop change. diffstat: src/lib-storage/index/pop3c/pop3c-client.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 4edce2f57264 -r edb8d177bd37 src/lib-storage/index/pop3c/pop3c-client.c --- a/src/lib-storage/index/pop3c/pop3c-client.c Sun Jun 24 21:35:18 2012 +0300 +++ b/src/lib-storage/index/pop3c/pop3c-client.c Mon Jun 25 00:18:31 2012 +0300 @@ -166,7 +166,7 @@ static void pop3c_client_ioloop_changed(struct pop3c_client *client) { if (client->to != NULL) - io_loop_move_timeout(&client->to); + client->to = io_loop_move_timeout(&client->to); if (client->io != NULL) client->io = io_loop_move_io(&client->io); if (client->output != NULL) From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: imapc: Fixed crash on saving/copying if remote IMAP... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/20703dbd1168 changeset: 14756:20703dbd1168 user: Timo Sirainen date: Mon Jun 25 19:40:24 2012 +0300 description: imapc: Fixed crash on saving/copying if remote IMAP server didn't support UIDPLUS. diffstat: src/lib-storage/index/imapc/imapc-save.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (23 lines): diff -r edb8d177bd37 -r 20703dbd1168 src/lib-storage/index/imapc/imapc-save.c --- a/src/lib-storage/index/imapc/imapc-save.c Mon Jun 25 00:18:31 2012 +0300 +++ b/src/lib-storage/index/imapc/imapc-save.c Mon Jun 25 19:40:24 2012 +0300 @@ -165,7 +165,8 @@ uint32_t uid = 0; if (reply->state == IMAPC_COMMAND_STATE_OK) { - if (strcasecmp(reply->resp_text_key, "APPENDUID") == 0) + if (reply->resp_text_key != NULL && + strcasecmp(reply->resp_text_key, "APPENDUID") == 0) imapc_save_appenduid(ctx->ctx, reply, &uid); imapc_save_add_to_index(ctx->ctx, uid); ctx->ret = 0; @@ -354,7 +355,8 @@ uint32_t uid = 0; if (reply->state == IMAPC_COMMAND_STATE_OK) { - if (strcasecmp(reply->resp_text_key, "COPYUID") == 0) + if (reply->resp_text_key != NULL && + strcasecmp(reply->resp_text_key, "COPYUID") == 0) imapc_save_copyuid(ctx->ctx, reply, &uid); imapc_save_add_to_index(ctx->ctx, uid); ctx->ret = 0; From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: lib-lda: Duplicate database write failures weren't ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4edce2f57264 changeset: 14754:4edce2f57264 user: Timo Sirainen date: Sun Jun 24 21:35:18 2012 +0300 description: lib-lda: Duplicate database write failures weren't detected. diffstat: src/lib-lda/duplicate.c | 19 +++++++++++++++---- 1 files changed, 15 insertions(+), 4 deletions(-) diffs (38 lines): diff -r c257b9c19915 -r 4edce2f57264 src/lib-lda/duplicate.c --- a/src/lib-lda/duplicate.c Sun Jun 24 20:52:39 2012 +0300 +++ b/src/lib-lda/duplicate.c Sun Jun 24 21:35:18 2012 +0300 @@ -296,7 +296,8 @@ hdr.version = DUPLICATE_VERSION; output = o_stream_create_fd_file(file->new_fd, 0, FALSE); - o_stream_send(output, &hdr, sizeof(hdr)); + o_stream_cork(output); + (void)o_stream_send(output, &hdr, sizeof(hdr)); memset(&rec, 0, sizeof(rec)); iter = hash_table_iterate_init(file->hash); @@ -307,11 +308,21 @@ rec.id_size = d->id_size; rec.user_size = strlen(d->user); - o_stream_send(output, &rec, sizeof(rec)); - o_stream_send(output, d->id, rec.id_size); - o_stream_send(output, d->user, rec.user_size); + (void)o_stream_send(output, &rec, sizeof(rec)); + (void)o_stream_send(output, d->id, rec.id_size); + (void)o_stream_send(output, d->user, rec.user_size); } + o_stream_uncork(output); hash_table_iterate_deinit(&iter); + + if (output->last_failed_errno != 0) { + errno = output->last_failed_errno; + i_error("write(%s) failed: %m", file->path); + o_stream_unref(&output); + file_dotlock_delete(&file->dotlock); + file->new_fd = -1; + return; + } o_stream_unref(&output); file->changed = FALSE; From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: doveadm mailbox status -A -t: Reset vsize counter b... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d8d587bd5a29 changeset: 14758:d8d587bd5a29 user: Timo Sirainen date: Wed Jun 27 12:25:05 2012 +0300 description: doveadm mailbox status -A -t: Reset vsize counter between users. diffstat: src/doveadm/doveadm-mail-mailbox-status.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 0e41d7c48a8b -r d8d587bd5a29 src/doveadm/doveadm-mail-mailbox-status.c --- a/src/doveadm/doveadm-mail-mailbox-status.c Wed Jun 27 12:12:52 2012 +0300 +++ b/src/doveadm/doveadm-mail-mailbox-status.c Wed Jun 27 12:25:05 2012 +0300 @@ -153,6 +153,7 @@ int ret = 0; memset(&ctx->total_status, 0, sizeof(ctx->total_status)); + memset(&ctx->total_metadata, 0, sizeof(ctx->total_metadata)); iter = doveadm_mailbox_list_iter_init(_ctx, user, ctx->search_args, iter_flags); From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: lib-storage: Fixed handling failures when autocreat... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0e41d7c48a8b changeset: 14757:0e41d7c48a8b user: Timo Sirainen date: Wed Jun 27 12:12:52 2012 +0300 description: lib-storage: Fixed handling failures when autocreating mailboxes. diffstat: src/lib-storage/mail-storage.c | 10 +++++++--- 1 files changed, 7 insertions(+), 3 deletions(-) diffs (44 lines): diff -r 20703dbd1168 -r 0e41d7c48a8b src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Mon Jun 25 19:40:24 2012 +0300 +++ b/src/lib-storage/mail-storage.c Wed Jun 27 12:12:52 2012 +0300 @@ -819,17 +819,18 @@ return 0; } -static void mailbox_autocreate(struct mailbox *box) +static int mailbox_autocreate(struct mailbox *box) { const char *errstr; enum mail_error error; if (mailbox_create(box, NULL, FALSE) < 0) { errstr = mailbox_get_last_error(box, &error); - if (error != MAIL_ERROR_NOTFOUND && !box->inbox_user) { + if (error != MAIL_ERROR_NOTFOUND) { mail_storage_set_critical(box->storage, "Failed to autocreate mailbox %s: %s", box->vname, errstr); + return -1; } } else if (box->set != NULL && strcmp(box->set->autocreate, @@ -838,15 +839,18 @@ mail_storage_set_critical(box->storage, "Failed to autosubscribe to mailbox %s: %s", box->vname, mailbox_get_last_error(box, NULL)); + return -1; } } + return 0; } static int mailbox_autocreate_and_reopen(struct mailbox *box) { int ret; - mailbox_autocreate(box); + if (mailbox_autocreate(box) < 0) + return -1; mailbox_close(box); ret = box->v.open(box); From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: pop3c: Added pop3c_master_user setting. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/06ba409a63d3 changeset: 14759:06ba409a63d3 user: Timo Sirainen date: Wed Jun 27 12:29:42 2012 +0300 description: pop3c: Added pop3c_master_user setting. diffstat: src/lib-storage/index/pop3c/pop3c-settings.c | 2 ++ src/lib-storage/index/pop3c/pop3c-settings.h | 1 + src/lib-storage/index/pop3c/pop3c-storage.c | 1 + 3 files changed, 4 insertions(+), 0 deletions(-) diffs (41 lines): diff -r d8d587bd5a29 -r 06ba409a63d3 src/lib-storage/index/pop3c/pop3c-settings.c --- a/src/lib-storage/index/pop3c/pop3c-settings.c Wed Jun 27 12:25:05 2012 +0300 +++ b/src/lib-storage/index/pop3c/pop3c-settings.c Wed Jun 27 12:29:42 2012 +0300 @@ -18,6 +18,7 @@ DEF(SET_UINT, pop3c_port), DEF(SET_STR_VARS, pop3c_user), + DEF(SET_STR_VARS, pop3c_master_user), DEF(SET_STR, pop3c_password), DEF(SET_ENUM, pop3c_ssl), @@ -35,6 +36,7 @@ .pop3c_port = 110, .pop3c_user = "%u", + .pop3c_master_user = "", .pop3c_password = "", .pop3c_ssl = "no:pop3s:starttls", diff -r d8d587bd5a29 -r 06ba409a63d3 src/lib-storage/index/pop3c/pop3c-settings.h --- a/src/lib-storage/index/pop3c/pop3c-settings.h Wed Jun 27 12:25:05 2012 +0300 +++ b/src/lib-storage/index/pop3c/pop3c-settings.h Wed Jun 27 12:29:42 2012 +0300 @@ -6,6 +6,7 @@ unsigned int pop3c_port; const char *pop3c_user; + const char *pop3c_master_user; const char *pop3c_password; const char *pop3c_ssl; diff -r d8d587bd5a29 -r 06ba409a63d3 src/lib-storage/index/pop3c/pop3c-storage.c --- a/src/lib-storage/index/pop3c/pop3c-storage.c Wed Jun 27 12:25:05 2012 +0300 +++ b/src/lib-storage/index/pop3c/pop3c-storage.c Wed Jun 27 12:29:42 2012 +0300 @@ -60,6 +60,7 @@ client_set.host = set->pop3c_host; client_set.port = set->pop3c_port; client_set.username = set->pop3c_user; + client_set.master_user = set->pop3c_master_user; client_set.password = set->pop3c_password; client_set.dns_client_socket_path = t_strconcat(user->set->base_dir, "/", From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: imap: If selected mailbox is DELETEd, disconnect cl... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/81a659ab9183 changeset: 14760:81a659ab9183 user: Timo Sirainen date: Thu Jun 28 06:32:00 2012 +0300 description: imap: If selected mailbox is DELETEd, disconnect client. diffstat: src/imap/cmd-delete.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diffs (30 lines): diff -r 06ba409a63d3 -r 81a659ab9183 src/imap/cmd-delete.c --- a/src/imap/cmd-delete.c Wed Jun 27 12:29:42 2012 +0300 +++ b/src/imap/cmd-delete.c Thu Jun 28 06:32:00 2012 +0300 @@ -10,6 +10,7 @@ struct mailbox *box; const char *name, *errstr; enum mail_error error; + bool disconnect = FALSE; /* */ if (!client_read_string_args(cmd, 1, &name)) @@ -31,6 +32,7 @@ /* deleting selected mailbox. close it first */ client_search_updates_free(client); mailbox_free(&client->mailbox); + disconnect = TRUE; } if (mailbox_delete(box) == 0) @@ -45,5 +47,10 @@ } } mailbox_free(&box); + + if (disconnect) { + client_disconnect_with_error(cmd->client, + "Selected mailbox was deleted, have to disconnect."); + } return TRUE; } From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: dbox: Fixed a potential crash when building message... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3efbc4a8219b changeset: 14761:3efbc4a8219b user: Timo Sirainen date: Fri Jun 29 06:14:51 2012 +0300 description: dbox: Fixed a potential crash when building message stream from external attachments. diffstat: src/lib-storage/index/dbox-common/dbox-attachment.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (14 lines): diff -r 81a659ab9183 -r 3efbc4a8219b src/lib-storage/index/dbox-common/dbox-attachment.c --- a/src/lib-storage/index/dbox-common/dbox-attachment.c Thu Jun 28 06:32:00 2012 +0300 +++ b/src/lib-storage/index/dbox-common/dbox-attachment.c Fri Jun 29 06:14:51 2012 +0300 @@ -212,9 +212,9 @@ input = i_stream_create_limit(*stream, trailer_size); array_append(&streams, &input, 1); - (void)array_append_space(&streams); } } + (void)array_append_space(&streams); inputs = array_idx_modifiable(&streams, 0); i_stream_unref(stream); From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: lib-storage: External mail attachment parsing didn'... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6b08977c4b75 changeset: 14762:6b08977c4b75 user: Timo Sirainen date: Fri Jun 29 08:05:08 2012 +0300 description: lib-storage: External mail attachment parsing didn't handle CRLF linefeeds correctly. This simply meant that if mail_save_crlf=yes was used, base64-encoded attachments weren't saved base64-decoded. diffstat: src/lib-storage/index/index-attachment.c | 44 +++++++++++++++++-------------- 1 files changed, 24 insertions(+), 20 deletions(-) diffs (68 lines): diff -r 3efbc4a8219b -r 6b08977c4b75 src/lib-storage/index/index-attachment.c --- a/src/lib-storage/index/index-attachment.c Fri Jun 29 06:14:51 2012 +0300 +++ b/src/lib-storage/index/index-attachment.c Fri Jun 29 08:05:08 2012 +0300 @@ -448,6 +448,28 @@ } static int +index_attachment_base64_decode_lf(struct mail_save_attachment_part *part) +{ + part->base64_state = BASE64_STATE_0; + if (part->cur_base64_blocks < part->base64_line_blocks) { + /* last line */ + part->base64_state = BASE64_STATE_EOM; + return 0; + } else if (part->base64_line_blocks == 0) { + /* first line */ + if (part->cur_base64_blocks == 0) + return -1; + part->base64_line_blocks = part->cur_base64_blocks; + } else if (part->cur_base64_blocks == part->base64_line_blocks) { + /* line is ok */ + } else { + return -1; + } + part->cur_base64_blocks = 0; + return 1; +} + +static int index_attachment_try_base64_decode_char(struct mail_save_attachment_part *part, size_t pos, char chr) { @@ -458,25 +480,7 @@ else if (chr == '\r') part->base64_state = BASE64_STATE_CR; else if (chr == '\n') { - part->base64_state = BASE64_STATE_0; - if (part->cur_base64_blocks < - part->base64_line_blocks) { - /* last line */ - part->base64_state = BASE64_STATE_EOM; - return 0; - } else if (part->base64_line_blocks == 0) { - /* first line */ - if (part->cur_base64_blocks == 0) - return -1; - part->base64_line_blocks = - part->cur_base64_blocks; - } else if (part->cur_base64_blocks == - part->base64_line_blocks) { - /* line is ok */ - } else { - return -1; - } - part->cur_base64_blocks = 0; + return index_attachment_base64_decode_lf(part); } else { return -1; } @@ -511,7 +515,7 @@ if (chr != '\n') return -1; part->base64_have_crlf = TRUE; - break; + return index_attachment_base64_decode_lf(part); case BASE64_STATE_EOB: if (chr != '=') return -1; From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: config: Fixed IPv6 address handling for parsing v1.... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e009aaf19934 changeset: 14763:e009aaf19934 user: Timo Sirainen date: Mon Jul 02 08:06:19 2012 +0300 description: config: Fixed IPv6 address handling for parsing v1.x style listen/ssl_listen settings. diffstat: src/config/old-set-parser.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 6b08977c4b75 -r e009aaf19934 src/config/old-set-parser.c --- a/src/config/old-set-parser.c Fri Jun 29 08:05:08 2012 +0300 +++ b/src/config/old-set-parser.c Mon Jul 02 08:06:19 2012 +0300 @@ -305,7 +305,7 @@ return TRUE; } p = strrchr(value, ':'); - if (p != NULL) { + if (p != NULL && listen_has_port(value)) { obsolete(ctx, "%s=..:port has been replaced by service { inet_listener { port } }", key); value = t_strdup_until(value, p++); if (config_filter_match(&old_section->filter, &imap_filter)) { From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: lmtp: Don't idle-timeout LMTP client while proxying... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8a97daa8aff6 changeset: 14765:8a97daa8aff6 user: Timo Sirainen date: Mon Jul 02 10:09:15 2012 +0300 description: lmtp: Don't idle-timeout LMTP client while proxying waits for DATA replies. diffstat: src/lmtp/commands.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r 27dccff46fe9 -r 8a97daa8aff6 src/lmtp/commands.c --- a/src/lmtp/commands.c Mon Jul 02 10:05:46 2012 +0300 +++ b/src/lmtp/commands.c Mon Jul 02 10:09:15 2012 +0300 @@ -771,6 +771,9 @@ struct istream *input; bool ret = TRUE; + /* stop handling client input until saving/proxying is finished */ + if (client->to_idle != NULL) + timeout_remove(&client->to_idle); io_remove(&client->io); i_stream_destroy(&client->dot_input); From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: lmtp proxy: Reset timeout each time receiving a rep... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/27dccff46fe9 changeset: 14764:27dccff46fe9 user: Timo Sirainen date: Mon Jul 02 10:05:46 2012 +0300 description: lmtp proxy: Reset timeout each time receiving a reply lin for DATA. This avoids timing out when there are a lot of RCPT TOs. diffstat: src/lmtp/lmtp-proxy.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r e009aaf19934 -r 27dccff46fe9 src/lmtp/lmtp-proxy.c --- a/src/lmtp/lmtp-proxy.c Mon Jul 02 08:06:19 2012 +0300 +++ b/src/lmtp/lmtp-proxy.c Mon Jul 02 10:05:46 2012 +0300 @@ -229,6 +229,9 @@ i_assert(!rcpt->rcpt_to_failed); i_assert(rcpt->reply != NULL); + /* reset timeout in case there are a lot of RCPT TOs */ + timeout_reset(conn->to); + rcpt->reply = p_strdup(conn->proxy->pool, reply); rcpt->data_reply_received = TRUE; From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: lmtp: Fixed previous change to make sure it doesn't... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/569588ff7ef0 changeset: 14766:569588ff7ef0 user: Timo Sirainen date: Mon Jul 02 10:12:59 2012 +0300 description: lmtp: Fixed previous change to make sure it doesn't crash on error handling. diffstat: src/lmtp/lmtp-proxy.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 8a97daa8aff6 -r 569588ff7ef0 src/lmtp/lmtp-proxy.c --- a/src/lmtp/lmtp-proxy.c Mon Jul 02 10:09:15 2012 +0300 +++ b/src/lmtp/lmtp-proxy.c Mon Jul 02 10:12:59 2012 +0300 @@ -230,7 +230,8 @@ i_assert(rcpt->reply != NULL); /* reset timeout in case there are a lot of RCPT TOs */ - timeout_reset(conn->to); + if (conn->to != NULL) + timeout_reset(conn->to); rcpt->reply = p_strdup(conn->proxy->pool, reply); rcpt->data_reply_received = TRUE; From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: imap: Mailbox names in STATUS replies were sent as ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a698fccd37c3 changeset: 14767:a698fccd37c3 user: Timo Sirainen date: Mon Jul 02 14:54:33 2012 +0300 description: imap: Mailbox names in STATUS replies were sent as UTF-8 instead of mUTF-7. diffstat: src/imap/cmd-list.c | 10 ++++++---- src/imap/cmd-status.c | 5 +++-- src/imap/imap-status.c | 4 ++-- src/imap/imap-status.h | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) diffs (96 lines): diff -r 569588ff7ef0 -r a698fccd37c3 src/imap/cmd-list.c --- a/src/imap/cmd-list.c Mon Jul 02 10:12:59 2012 +0300 +++ b/src/imap/cmd-list.c Mon Jul 02 14:54:33 2012 +0300 @@ -364,8 +364,9 @@ client_send_line(ctx->cmd->client, str_c(str)); } -static void list_send_status(struct cmd_list_context *ctx, const char *name, - enum mailbox_info_flags flags) +static void +list_send_status(struct cmd_list_context *ctx, const char *name, + const char *mutf7_name, enum mailbox_info_flags flags) { struct imap_status_result result; struct mail_namespace *ns; @@ -391,7 +392,8 @@ return; } - imap_status_send(ctx->cmd->client, name, &ctx->status_items, &result); + imap_status_send(ctx->cmd->client, mutf7_name, + &ctx->status_items, &result); } static bool list_has_empty_prefix_ns(struct mail_user *user) @@ -481,7 +483,7 @@ ret = client_send_line(ctx->cmd->client, str_c(str)); if (ctx->used_status) T_BEGIN { - list_send_status(ctx, name, flags); + list_send_status(ctx, name, str_c(mutf7_name), flags); } T_END; if (ret == 0) { /* buffer is full, continue later */ diff -r 569588ff7ef0 -r a698fccd37c3 src/imap/cmd-status.c --- a/src/imap/cmd-status.c Mon Jul 02 10:12:59 2012 +0300 +++ b/src/imap/cmd-status.c Mon Jul 02 14:54:33 2012 +0300 @@ -13,7 +13,7 @@ struct imap_status_items items; struct imap_status_result result; struct mail_namespace *ns; - const char *mailbox, *error; + const char *mailbox, *orig_mailbox, *error; bool selected_mailbox; /* */ @@ -30,6 +30,7 @@ if (imap_status_parse_items(cmd, list_args, &items) < 0) return TRUE; + orig_mailbox = mailbox; ns = client_find_namespace(cmd, &mailbox); if (ns == NULL) return TRUE; @@ -42,7 +43,7 @@ return TRUE; } - imap_status_send(client, mailbox, &items, &result); + imap_status_send(client, orig_mailbox, &items, &result); if (!selected_mailbox) client_send_tagline(cmd, "OK Status completed."); else { diff -r 569588ff7ef0 -r a698fccd37c3 src/imap/imap-status.c --- a/src/imap/imap-status.c Mon Jul 02 10:12:59 2012 +0300 +++ b/src/imap/imap-status.c Mon Jul 02 14:54:33 2012 +0300 @@ -96,7 +96,7 @@ return ret; } -void imap_status_send(struct client *client, const char *mailbox, +void imap_status_send(struct client *client, const char *mailbox_mutf7, const struct imap_status_items *items, const struct imap_status_result *result) { @@ -106,7 +106,7 @@ str = t_str_new(128); str_append(str, "* STATUS "); - imap_quote_append_string(str, mailbox, FALSE); + imap_quote_append_string(str, mailbox_mutf7, FALSE); str_append(str, " ("); prefix_len = str_len(str); diff -r 569588ff7ef0 -r a698fccd37c3 src/imap/imap-status.h --- a/src/imap/imap-status.h Mon Jul 02 10:12:59 2012 +0300 +++ b/src/imap/imap-status.h Mon Jul 02 14:54:33 2012 +0300 @@ -18,7 +18,7 @@ struct mail_namespace *ns, const char *mailbox, const struct imap_status_items *items, struct imap_status_result *result_r, const char **error_r); -void imap_status_send(struct client *client, const char *mailbox, +void imap_status_send(struct client *client, const char *mailbox_mutf7, const struct imap_status_items *items, const struct imap_status_result *result); From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: imap-acl: MYRIGHTS command used UTF-8 instead of mU... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/880af3c78df9 changeset: 14768:880af3c78df9 user: Timo Sirainen date: Tue Jul 03 01:06:10 2012 +0300 description: imap-acl: MYRIGHTS command used UTF-8 instead of mUTF-7 encoding for mailbox name. diffstat: src/plugins/imap-acl/imap-acl-plugin.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (27 lines): diff -r a698fccd37c3 -r 880af3c78df9 src/plugins/imap-acl/imap-acl-plugin.c --- a/src/plugins/imap-acl/imap-acl-plugin.c Mon Jul 02 14:54:33 2012 +0300 +++ b/src/plugins/imap-acl/imap-acl-plugin.c Tue Jul 03 01:06:10 2012 +0300 @@ -309,12 +309,13 @@ { struct mail_namespace *ns; struct mailbox *box; - const char *mailbox; + const char *mailbox, *orig_mailbox; const char *const *rights; string_t *str; if (!client_read_string_args(cmd, 1, &mailbox)) return FALSE; + orig_mailbox = mailbox; if (ACL_USER_CONTEXT(cmd->client->user) == NULL) { client_send_command_error(cmd, "ACLs disabled."); @@ -346,7 +347,7 @@ str = t_str_new(128); str_append(str, "* MYRIGHTS "); - imap_quote_append_string(str, mailbox, FALSE); + imap_quote_append_string(str, orig_mailbox, FALSE); str_append_c(str,' '); imap_acl_write_rights_list(str, rights); From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: imap-quota: GETQUOTAROOT command used UTF-8 instead... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/90270c054e1f changeset: 14769:90270c054e1f user: Timo Sirainen date: Tue Jul 03 01:06:24 2012 +0300 description: imap-quota: GETQUOTAROOT command used UTF-8 instead of mUTF-7 encoding for mailbox name. diffstat: src/plugins/imap-quota/imap-quota-plugin.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (27 lines): diff -r 880af3c78df9 -r 90270c054e1f src/plugins/imap-quota/imap-quota-plugin.c --- a/src/plugins/imap-quota/imap-quota-plugin.c Tue Jul 03 01:06:10 2012 +0300 +++ b/src/plugins/imap-quota/imap-quota-plugin.c Tue Jul 03 01:06:24 2012 +0300 @@ -74,12 +74,13 @@ struct mailbox *box; struct quota_root_iter *iter; struct quota_root *root; - const char *mailbox, *name; + const char *mailbox, *orig_mailbox, *name; string_t *quotaroot_reply, *quota_reply; /* */ if (!client_read_string_args(cmd, 1, &mailbox)) return FALSE; + orig_mailbox = mailbox; ns = client_find_namespace(cmd, &mailbox); if (ns == NULL) @@ -101,7 +102,7 @@ quotaroot_reply = t_str_new(128); quota_reply = t_str_new(256); str_append(quotaroot_reply, "* QUOTAROOT "); - imap_quote_append_string(quotaroot_reply, mailbox, FALSE); + imap_quote_append_string(quotaroot_reply, orig_mailbox, FALSE); iter = quota_root_iter_init(box); while ((root = quota_root_iter_next(iter)) != NULL) { From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: layout=fs, mail_shared_explicit_inbox=no: Fixed lis... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a6d59207d9d6 changeset: 14770:a6d59207d9d6 user: Timo Sirainen date: Tue Jul 03 01:52:00 2012 +0300 description: layout=fs, mail_shared_explicit_inbox=no: Fixed listing nonexistent mailboxes in root. diffstat: src/lib-storage/list/mailbox-list-fs-iter.c | 16 ++++++++++++---- 1 files changed, 12 insertions(+), 4 deletions(-) diffs (26 lines): diff -r 90270c054e1f -r a6d59207d9d6 src/lib-storage/list/mailbox-list-fs-iter.c --- a/src/lib-storage/list/mailbox-list-fs-iter.c Tue Jul 03 01:06:24 2012 +0300 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Tue Jul 03 01:52:00 2012 +0300 @@ -404,10 +404,18 @@ we just want to see its contents (not the INBOX's children). */ root = ""; - } else if (*prefix_vname == '\0') { - /* we need to handle "" explicitly here, because getting - storage name with mail_shared_explicit_inbox=no - would return root=INBOX. */ + } else if ((ns->flags & NAMESPACE_FLAG_INBOX_ANY) != 0 && + ns->type == NAMESPACE_SHARED && + !ctx->ctx.list->mail_set->mail_shared_explicit_inbox && + (prefix_vname[0] == '\0' || + (strncmp(ns->prefix, prefix_vname, ns->prefix_len-1) == 0 && + prefix_vname[ns->prefix_len-1] == '\0'))) { + /* we need to handle ns prefix explicitly here, because + getting storage name with + mail_shared_explicit_inbox=no would return + root=INBOX. (e.g. LIST "" shared/user/box has to + return the box when it doesn't exist but + shared/user/box/child exists) */ root = ""; } else { root = mailbox_list_get_storage_name(ctx->ctx.list, From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: lib-sql db cache: Reaching max_unused_connections c... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/955e741ef46a changeset: 14772:955e741ef46a user: Timo Sirainen date: Tue Jul 03 03:27:52 2012 +0300 description: lib-sql db cache: Reaching max_unused_connections caused a crash later. diffstat: src/lib-sql/sql-db-cache.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 668173038ada -r 955e741ef46a src/lib-sql/sql-db-cache.c --- a/src/lib-sql/sql-db-cache.c Tue Jul 03 02:59:53 2012 +0300 +++ b/src/lib-sql/sql-db-cache.c Tue Jul 03 03:27:52 2012 +0300 @@ -75,6 +75,7 @@ db = cache->unused_tail; ctx = SQL_DB_CACHE_CONTEXT(db); sql_db_cache_unlink(ctx); + hash_table_remove(cache->dbs, ctx->key); i_free(ctx->key); ctx->orig_deinit(db); From dovecot at dovecot.org Fri Aug 10 05:24:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:39 +0300 Subject: dovecot-2.2: doveadm server: Keep config socket open while running. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/668173038ada changeset: 14771:668173038ada user: Timo Sirainen date: Tue Jul 03 02:59:53 2012 +0300 description: doveadm server: Keep config socket open while running. diffstat: src/doveadm/main.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (17 lines): diff -r a6d59207d9d6 -r 668173038ada src/doveadm/main.c --- a/src/doveadm/main.c Tue Jul 03 01:52:00 2012 +0300 +++ b/src/doveadm/main.c Tue Jul 03 02:59:53 2012 +0300 @@ -68,9 +68,12 @@ &doveadm_setting_parser_info, NULL }; + enum master_service_flags service_flags = + MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN; const char *error; - master_service = master_service_init("doveadm", 0, &argc, &argv, NULL); + master_service = master_service_init("doveadm", service_flags, + &argc, &argv, NULL); if (master_getopt(master_service) > 0) return FATAL_DEFAULT; From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: Released v2.1.8. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7e5f36fd989d changeset: 14774:7e5f36fd989d user: Timo Sirainen date: Tue Jul 03 05:15:04 2012 +0300 description: Released v2.1.8. diffstat: NEWS | 15 +++++++++++++++ configure.in | 2 +- 2 files changed, 16 insertions(+), 1 deletions(-) diffs (32 lines): diff -r f1509d8eb2c1 -r 7e5f36fd989d NEWS --- a/NEWS Tue Jul 03 04:23:03 2012 +0300 +++ b/NEWS Tue Jul 03 05:15:04 2012 +0300 @@ -1,3 +1,18 @@ +v2.1.8 2012-07-03 Timo Sirainen + + + pop3c: Added pop3c_master_user setting. + - imap: Mailbox names were accidentally sent as UTF-8 instead of mUTF-7 + in previous v2.1.x releases for STATUS, MYRIGHTS and GETQUOTAROOT + commands. + - lmtp proxy: Don't timeout connections too early when mail has a lot + of RCPT TOs. + - director: Don't crash if the director is working alone. + - shared mailboxes: Avoid doing "@domain" userdb lookups. + - doveadm: Fixed crash with proxying some commands. + - fts-squat: Fixed handling multiple SEARCH parameters. + - imapc: Fixed a crash when message had more than 8 keywords. + - imapc: Don't crash on APPEND/COPY if server doesn't support UIDPLUS. + v2.1.7 2012-05-29 Timo Sirainen * LDAP: Compatibility fix for v2.0: ldap: If attributes contain diff -r f1509d8eb2c1 -r 7e5f36fd989d configure.in --- a/configure.in Tue Jul 03 04:23:03 2012 +0300 +++ b/configure.in Tue Jul 03 05:15:04 2012 +0300 @@ -1,5 +1,5 @@ AC_PREREQ([2.59]) -AC_INIT([Dovecot],[2.1.7],[dovecot at dovecot.org]) +AC_INIT([Dovecot],[2.1.8],[dovecot at dovecot.org]) AC_CONFIG_SRCDIR([src]) AM_INIT_AUTOMAKE([foreign]) From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: lmtp: Added lmtp_address_translate setting. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f1509d8eb2c1 changeset: 14773:f1509d8eb2c1 user: Timo Sirainen date: Tue Jul 03 04:23:03 2012 +0300 description: lmtp: Added lmtp_address_translate setting. The idea is that if you need userdb lookup to be done with a special kind of a username like user:domain at extrainfo, you can set lmtp_address_translate=%n:%d@ which translates the address to user at domain after the userdb lookup is done. diffstat: src/lmtp/commands.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ src/lmtp/lmtp-settings.c | 4 ++- src/lmtp/lmtp-settings.h | 1 + 3 files changed, 69 insertions(+), 1 deletions(-) diffs (114 lines): diff -r 955e741ef46a -r f1509d8eb2c1 src/lmtp/commands.c --- a/src/lmtp/commands.c Tue Jul 03 03:27:52 2012 +0300 +++ b/src/lmtp/commands.c Tue Jul 03 04:23:03 2012 +0300 @@ -380,6 +380,69 @@ } } +static void lmtp_address_translate(struct client *client, const char **address) +{ + const char *transpos = client->lmtp_set->lmtp_address_translate; + const char *p, *nextstr, *addrpos = *address; + unsigned int len; + string_t *username, *domain, *dest = NULL; + + if (*transpos == '\0') + return; + + username = t_str_new(64); + domain = t_str_new(64); + + /* check that string matches up to the first '%' */ + p = strchr(transpos, '%'); + if (p == NULL) + len = strlen(transpos); + else + len = p-transpos; + if (strncmp(transpos, addrpos, len) != 0) + return; + transpos += len; + addrpos += len; + + while (*transpos != '\0') { + switch (transpos[1]) { + case 'n': + case 'u': + dest = username; + break; + case 'd': + dest = domain; + break; + default: + return; + } + transpos += 2; + + /* find where the next string starts */ + if (*transpos == '\0') { + str_append(dest, addrpos); + break; + } + p = strchr(transpos, '%'); + if (p == NULL) + nextstr = transpos; + else + nextstr = t_strdup_until(transpos, p); + p = strstr(addrpos, nextstr); + if (p == NULL) + return; + str_append_n(dest, addrpos, p-addrpos); + + len = strlen(nextstr); + transpos += len; + addrpos = p + len; + } + str_append_c(username, '@'); + if (domain != NULL) + str_append_str(username, domain); + *address = str_c(username); +} + int cmd_rcpt(struct client *client, const char *args) { struct mail_recipient rcpt; @@ -449,6 +512,8 @@ return 0; } + lmtp_address_translate(client, &address); + rcpt.address = p_strdup(client->state_pool, address); rcpt.detail = p_strdup(client->state_pool, detail); array_append(&client->state.rcpt_to, &rcpt, 1); diff -r 955e741ef46a -r f1509d8eb2c1 src/lmtp/lmtp-settings.c --- a/src/lmtp/lmtp-settings.c Tue Jul 03 03:27:52 2012 +0300 +++ b/src/lmtp/lmtp-settings.c Tue Jul 03 04:23:03 2012 +0300 @@ -60,6 +60,7 @@ DEF(SET_BOOL, lmtp_proxy), DEF(SET_BOOL, lmtp_save_to_detail_mailbox), DEF(SET_STR_VARS, login_greeting), + DEF(SET_STR, lmtp_address_translate), SETTING_DEFINE_LIST_END }; @@ -67,7 +68,8 @@ static const struct lmtp_settings lmtp_default_settings = { .lmtp_proxy = FALSE, .lmtp_save_to_detail_mailbox = FALSE, - .login_greeting = PACKAGE_NAME" ready." + .login_greeting = PACKAGE_NAME" ready.", + .lmtp_address_translate = "" }; static const struct setting_parser_info *lmtp_setting_dependencies[] = { diff -r 955e741ef46a -r f1509d8eb2c1 src/lmtp/lmtp-settings.h --- a/src/lmtp/lmtp-settings.h Tue Jul 03 03:27:52 2012 +0300 +++ b/src/lmtp/lmtp-settings.h Tue Jul 03 04:23:03 2012 +0300 @@ -8,6 +8,7 @@ bool lmtp_proxy; bool lmtp_save_to_detail_mailbox; const char *login_greeting; + const char *lmtp_address_translate; }; extern const struct setting_parser_info lmtp_setting_parser_info; From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: Added tag 2.1.8 for changeset 7e5f36fd989d Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7e0c247ef1e4 changeset: 14775:7e0c247ef1e4 user: Timo Sirainen date: Tue Jul 03 05:15:04 2012 +0300 description: Added tag 2.1.8 for changeset 7e5f36fd989d diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 7e5f36fd989d -r 7e0c247ef1e4 .hgtags --- a/.hgtags Tue Jul 03 05:15:04 2012 +0300 +++ b/.hgtags Tue Jul 03 05:15:04 2012 +0300 @@ -84,3 +84,4 @@ 469cee314d9c54d2d7101ec9e38579fdc9610eaf 2.1.5 7c249e2a82a9cd33ae15ead6443c3499e16da623 2.1.6 c92fb8b928f69ca01681a2c2976304b7e4bc3afc 2.1.7 +7e5f36fd989d27a2fb48250adbab8fa54ddb6083 2.1.8 From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: Added signature for changeset 7e5f36fd989d Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c1a97e799b43 changeset: 14776:c1a97e799b43 user: Timo Sirainen date: Tue Jul 03 05:15:14 2012 +0300 description: Added signature for changeset 7e5f36fd989d diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 7e0c247ef1e4 -r c1a97e799b43 .hgsigs --- a/.hgsigs Tue Jul 03 05:15:04 2012 +0300 +++ b/.hgsigs Tue Jul 03 05:15:14 2012 +0300 @@ -47,3 +47,4 @@ 469cee314d9c54d2d7101ec9e38579fdc9610eaf 0 iEYEABECAAYFAk+VWqkACgkQyUhSUUBVislnXACfVjPqMmPUvYtXQXwqff0h7N76mZUAn02lPeUCyuyr1TF9e1hGM/sKgmko 7c249e2a82a9cd33ae15ead6443c3499e16da623 0 iEYEABECAAYFAk+nX2sACgkQyUhSUUBVisn7uwCbBD3boxBOGEJ8OYsIJ57n5Cr09FAAoIvhxL6EHRB15AMOw4sPaALJ3/bB c92fb8b928f69ca01681a2c2976304b7e4bc3afc 0 iEYEABECAAYFAk/FIeIACgkQyUhSUUBVisk4IgCfUiXVXntqzPjJcALYRpqw4Zc7a/0An3HKWwgb6PBCbmvxBfTezNkqjqVK +7e5f36fd989d27a2fb48250adbab8fa54ddb6083 0 iEYEABECAAYFAk/yVakACgkQyUhSUUBVismekwCfSEVQjd6fwdChjd53LSt03b4UWKoAoIxd/IjLatTISlHm44iiQwzRKByo From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: auth: Added CACHE-FLUSH command to flush some/all u... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/007bf0047ab0 changeset: 14777:007bf0047ab0 user: Timo Sirainen date: Wed Jul 04 10:56:53 2012 +0300 description: auth: Added CACHE-FLUSH command to flush some/all users from auth cache. diffstat: src/auth/auth-cache.c | 228 +++++++++++++++++++++++++++---------- src/auth/auth-cache.h | 6 +- src/auth/auth-master-connection.c | 27 ++++ src/auth/auth-request.h | 4 + src/auth/auth.c | 9 + src/auth/test-auth-cache.c | 18 ++- 6 files changed, 226 insertions(+), 66 deletions(-) diffs (truncated from 491 to 300 lines): diff -r c1a97e799b43 -r 007bf0047ab0 src/auth/auth-cache.c --- a/src/auth/auth-cache.c Tue Jul 03 05:15:14 2012 +0300 +++ b/src/auth/auth-cache.c Wed Jul 04 10:56:53 2012 +0300 @@ -23,36 +23,72 @@ unsigned long long pos_size, neg_size; }; -static const struct var_expand_table * -auth_request_var_expand_tab_find(const char *key, unsigned int size) +static bool +auth_request_var_expand_tab_find(const char *key, unsigned int size, + unsigned int *idx_r) { const struct var_expand_table *tab = auth_request_var_expand_static_tab; unsigned int i; for (i = 0; tab[i].key != '\0' || tab[i].long_key != NULL; i++) { if (size == 1) { - if (key[0] == tab[i].key) - return &tab[i]; + if (key[0] == tab[i].key) { + *idx_r = i; + return TRUE; + } } else if (tab[i].long_key != NULL) { if (strncmp(key, tab[i].long_key, size) == 0 && - tab[i].long_key[size] == '\0') - return &tab[i]; + tab[i].long_key[size] == '\0') { + *idx_r = i; + return TRUE; + } } } - return NULL; + return FALSE; +} + +static void +auth_cache_key_add_var(string_t *str, const char *data, unsigned int len) +{ + if (str_len(str) > 0) + str_append_c(str, '\t'); + str_append_c(str, '%'); + if (len == 1) + str_append_c(str, data[0]); + else { + str_append_c(str, '{'); + str_append_n(str, data, len); + str_append_c(str, '}'); + } +} + +static void auth_cache_key_add_tab_idx(string_t *str, unsigned int i) +{ + const struct var_expand_table *tab = + &auth_request_var_expand_static_tab[i]; + + if (str_len(str) > 0) + str_append_c(str, '\t'); + str_append_c(str, '%'); + if (tab->key != '\0') + str_append_c(str, tab->key); + else { + str_append_c(str, '{'); + str_append(str, tab->long_key); + str_append_c(str, '}'); + } } char *auth_cache_parse_key(pool_t pool, const char *query) { - const struct var_expand_table *tab; string_t *str; - bool key_seen[100]; - unsigned int idx, size, tab_idx; - bool add_key; + bool key_seen[AUTH_REQUEST_VAR_TAB_COUNT]; + const char *extra_vars; + unsigned int i, idx, size, tab_idx; memset(key_seen, 0, sizeof(key_seen)); - str = str_new(pool, 32); + str = t_str_new(32); for (; *query != '\0'; ) { if (*query != '%') { query++; @@ -66,34 +102,45 @@ } query += idx; - tab = auth_request_var_expand_tab_find(query, size); - if (tab == NULL) { + if (!auth_request_var_expand_tab_find(query, size, &tab_idx)) { /* just add the key. it would be nice to prevent duplicates here as well, but that's just too much trouble and probably very rare. */ - add_key = TRUE; + auth_cache_key_add_var(str, query, size); } else { - tab_idx = tab - auth_request_var_expand_static_tab; i_assert(tab_idx < N_ELEMENTS(key_seen)); - /* @UNSAFE */ - add_key = !key_seen[tab_idx]; key_seen[tab_idx] = TRUE; } - if (add_key) { - if (str_len(str) != 0) - str_append_c(str, '\t'); - str_append_c(str, '%'); - if (size == 1) - str_append_c(str, query[0]); - else { - str_append_c(str, '{'); - str_append_n(str, query, size); - str_append_c(str, '}'); - } - } query += size; } - return str_free_without_data(&str); + + if (key_seen[AUTH_REQUEST_VAR_TAB_USERNAME_IDX] && + key_seen[AUTH_REQUEST_VAR_TAB_DOMAIN_IDX]) { + /* %n and %d both used -> replace with %u */ + key_seen[AUTH_REQUEST_VAR_TAB_USER_IDX] = TRUE; + key_seen[AUTH_REQUEST_VAR_TAB_USERNAME_IDX] = FALSE; + key_seen[AUTH_REQUEST_VAR_TAB_DOMAIN_IDX] = FALSE; + } + + /* we rely on these being at the beginning */ + i_assert(AUTH_REQUEST_VAR_TAB_USER_IDX == 0); + i_assert(AUTH_REQUEST_VAR_TAB_USERNAME_IDX == 1); + i_assert(AUTH_REQUEST_VAR_TAB_DOMAIN_IDX == 2); + + extra_vars = t_strdup(str_c(str)); + str_truncate(str, 0); + for (i = 0; i < N_ELEMENTS(key_seen); i++) { + if (key_seen[i]) + auth_cache_key_add_tab_idx(str, i); + } + + if (*extra_vars != '\0') { + if (str_len(str) > 0) + str_append_c(str, '\t'); + str_append(str, extra_vars); + } + + return p_strdup(pool, str_c(str)); } static void @@ -142,8 +189,8 @@ { struct auth_cache *cache = context; - i_info("SIGHUP received, clearing cache"); - auth_cache_clear(cache); + i_info("SIGHUP received, %u cache entries flushed", + auth_cache_clear(cache)); } static void sig_auth_cache_stats(const siginfo_t *si ATTR_UNUSED, void *context) @@ -200,11 +247,69 @@ i_free(cache); } -void auth_cache_clear(struct auth_cache *cache) +unsigned int auth_cache_clear(struct auth_cache *cache) { + unsigned int ret = hash_table_count(cache->hash); + while (cache->tail != NULL) auth_cache_node_destroy(cache, cache->tail); hash_table_clear(cache->hash, FALSE); + return ret; +} + +static bool auth_cache_node_is_user(struct auth_cache_node *node, + const char *username) +{ + const char *data = node->data; + unsigned int username_len; + + /* The cache nodes begin with "P"/"U", passdb/userdb ID, "/" and + then usually followed by the username. It's too much trouble to + keep track of all the cache keys, so we'll just match it as if it + was the username. If e.g. '%n' is used in the cache key instead of + '%u', it means that cache entries can be removed only when @domain + isn't in the username parameter. */ + if (*data != 'P' && *data != 'U') + return FALSE; + data++; + + while (*data >= '0' && *data <= '9') + data++; + if (*data != '/') + return FALSE; + data++; + + username_len = strlen(username); + return strncmp(data, username, username_len) == 0 && + (data[username_len] == '\t' || data[username_len] == '\0'); +} + +static bool auth_cache_node_is_one_of_users(struct auth_cache_node *node, + const char *const *usernames) +{ + unsigned int i; + + for (i = 0; usernames[i] != NULL; i++) { + if (auth_cache_node_is_user(node, usernames[i])) + return TRUE; + } + return FALSE; +} + +unsigned int auth_cache_clear_users(struct auth_cache *cache, + const char *const *usernames) +{ + struct auth_cache_node *node, *next; + unsigned int ret = 0; + + for (node = cache->tail; node != NULL; node = next) { + next = node->next; + if (auth_cache_node_is_one_of_users(node, usernames)) { + auth_cache_node_destroy(cache, cache->tail); + ret++; + } + } + return ret; } static const char * @@ -216,12 +321,27 @@ return str_tabescape(string); } +static const char * +auth_request_expand_cache_key(const struct auth_request *request, + const char *key) +{ + string_t *str; + + /* Uniquely identify the request's passdb/userdb with the P/U prefix + and by "%!", which expands to the passdb/userdb ID number. */ + key = t_strconcat(request->userdb_lookup ? "U" : "P", "%!/", key, NULL); + + str = t_str_new(256); + var_expand(str, key, + auth_request_get_var_expand_table(request, auth_cache_escape)); + return str_c(str); +} + const char * auth_cache_lookup(struct auth_cache *cache, const struct auth_request *request, const char *key, struct auth_cache_node **node_r, bool *expired_r, bool *neg_expired_r) { - string_t *str; struct auth_cache_node *node; const char *value; unsigned int ttl_secs; @@ -230,13 +350,8 @@ *expired_r = FALSE; *neg_expired_r = FALSE; - /* %! is prepended automatically. it contains the passdb ID number. */ - str = t_str_new(256); - var_expand(str, t_strconcat(request->userdb_lookup ? "U" : "P", - "%!/", key, NULL), - auth_request_get_var_expand_table(request, auth_cache_escape)); - - node = hash_table_lookup(cache->hash, str_c(str)); + key = auth_request_expand_cache_key(request, key); + node = hash_table_lookup(cache->hash, key); if (node == NULL) { cache->miss_count++; return NULL; @@ -269,9 +384,8 @@ void auth_cache_insert(struct auth_cache *cache, struct auth_request *request, const char *key, const char *value, bool last_success) { - string_t *str; struct auth_cache_node *node; - size_t data_size, alloc_size, value_len = strlen(value); + size_t data_size, alloc_size, key_len, value_len = strlen(value); char *current_username; if (*value == '\0' && cache->neg_ttl_secs == 0) { @@ -286,15 +400,12 @@ request->requested_login_user == NULL) request->user = t_strdup_noconst(request->translated_username); - /* %! is prepended automatically. it contains the db ID number. */ - str = t_str_new(256); - var_expand(str, t_strconcat(request->userdb_lookup ? "U" : "P", - "%!/", key, NULL), - auth_request_get_var_expand_table(request, auth_cache_escape)); From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: doveadm: Added "auth cache flush" command. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1093c74f54af changeset: 14778:1093c74f54af user: Timo Sirainen date: Wed Jul 04 10:57:40 2012 +0300 description: doveadm: Added "auth cache flush" command. diffstat: src/doveadm/doveadm-auth.c | 82 +++++++++++++++++++++++++++++++++++++++------ src/doveadm/doveadm.c | 3 +- src/doveadm/doveadm.h | 3 +- src/lib-auth/auth-master.c | 43 ++++++++++++++++++++++++ src/lib-auth/auth-master.h | 4 ++ 5 files changed, 120 insertions(+), 15 deletions(-) diffs (247 lines): diff -r 007bf0047ab0 -r 1093c74f54af src/doveadm/doveadm-auth.c --- a/src/doveadm/doveadm-auth.c Wed Jul 04 10:56:53 2012 +0300 +++ b/src/doveadm/doveadm-auth.c Wed Jul 04 10:57:40 2012 +0300 @@ -27,6 +27,8 @@ bool success; }; +static void auth_cmd_help(doveadm_command_t *cmd); + static int cmd_user_input(const char *auth_socket_path, const struct authtest_input *input, const char *show_field) @@ -214,12 +216,52 @@ auth_master_deinit(&conn); } +static void cmd_auth_cache_flush(int argc, char *argv[]) +{ + const char *auth_socket_path = NULL; + struct auth_master_connection *conn; + unsigned int count; + int c; + + while ((c = getopt(argc, argv, "a:")) > 0) { + switch (c) { + case 'a': + auth_socket_path = optarg; + break; + default: + auth_cmd_help(cmd_auth_cache_flush); + } + } + argv += optind; + + if (auth_socket_path == NULL) { + auth_socket_path = t_strconcat(doveadm_settings->base_dir, + "/auth-master", NULL); + } + + conn = auth_master_init(auth_socket_path, 0); + if (auth_master_cache_flush(conn, (void *)argv, &count) < 0) { + i_error("Cache flush failed"); + doveadm_exit_code = EX_TEMPFAIL; + } else { + printf("%u cache entries flushed\n", count); + } + auth_master_deinit(&conn); +} + static void cmd_auth(int argc, char *argv[]) { const char *auth_socket_path = NULL; struct authtest_input input; int c; + if (null_strcmp(argv[1], "cache") == 0 && + null_strcmp(argv[2], "flush") == 0) { + /* kludgy: handle "doveadm auth cache" command instead */ + cmd_auth_cache_flush(argc-2, argv+2); + return; + } + memset(&input, 0, sizeof(input)); input.info.service = "doveadm"; @@ -232,12 +274,12 @@ auth_user_info_parse(&input.info, optarg); break; default: - help(&doveadm_cmd_auth); + auth_cmd_help(cmd_auth); } } if (optind == argc) - help(&doveadm_cmd_auth); + auth_cmd_help(cmd_auth); input.username = argv[optind++]; input.password = argv[optind] != NULL ? argv[optind++] : @@ -331,12 +373,12 @@ auth_user_info_parse(&input.info, optarg); break; default: - help(&doveadm_cmd_user); + auth_cmd_help(cmd_user); } } if (optind == argc) - help(&doveadm_cmd_user); + auth_cmd_help(cmd_user); have_wildcards = FALSE; for (i = optind; argv[i] != NULL; i++) { @@ -380,12 +422,30 @@ mail_storage_service_deinit(&storage_service); } -struct doveadm_cmd doveadm_cmd_auth = { - cmd_auth, "auth", - "[-a ] [-x ] []" +struct doveadm_cmd doveadm_cmd_auth[] = { + { cmd_auth, "auth", + "[-a ] [-x ] []" }, + { cmd_auth_cache_flush, "auth cache flush", + "[-a ] []" }, + { cmd_user, "user", + "[-a ] [-x ] [-f field] [-m] [...]" } }; -struct doveadm_cmd doveadm_cmd_user = { - cmd_user, "user", - "[-a ] [-x ] [-f field] [-m] [...]" -}; +static void auth_cmd_help(doveadm_command_t *cmd) +{ + unsigned int i; + + for (i = 0; i < N_ELEMENTS(doveadm_cmd_auth); i++) { + if (doveadm_cmd_auth[i].cmd == cmd) + help(&doveadm_cmd_auth[i]); + } + i_unreached(); +} + +void doveadm_register_auth_commands(void) +{ + unsigned int i; + + for (i = 0; i < N_ELEMENTS(doveadm_cmd_auth); i++) + doveadm_register_cmd(&doveadm_cmd_auth[i]); +} diff -r 007bf0047ab0 -r 1093c74f54af src/doveadm/doveadm.c --- a/src/doveadm/doveadm.c Wed Jul 04 10:56:53 2012 +0300 +++ b/src/doveadm/doveadm.c Wed Jul 04 10:57:40 2012 +0300 @@ -271,8 +271,6 @@ &doveadm_cmd_config, &doveadm_cmd_stop, &doveadm_cmd_reload, - &doveadm_cmd_auth, - &doveadm_cmd_user, &doveadm_cmd_dump, &doveadm_cmd_pw, &doveadm_cmd_who, @@ -342,6 +340,7 @@ quick_init = TRUE; } else { quick_init = FALSE; + doveadm_register_auth_commands(); doveadm_register_director_commands(); doveadm_register_instance_commands(); doveadm_register_mount_commands(); diff -r 007bf0047ab0 -r 1093c74f54af src/doveadm/doveadm.h --- a/src/doveadm/doveadm.h Wed Jul 04 10:56:53 2012 +0300 +++ b/src/doveadm/doveadm.h Wed Jul 04 10:57:40 2012 +0300 @@ -22,8 +22,6 @@ extern struct doveadm_cmd doveadm_cmd_stop; extern struct doveadm_cmd doveadm_cmd_reload; -extern struct doveadm_cmd doveadm_cmd_auth; -extern struct doveadm_cmd doveadm_cmd_user; extern struct doveadm_cmd doveadm_cmd_dump; extern struct doveadm_cmd doveadm_cmd_pw; extern struct doveadm_cmd doveadm_cmd_who; @@ -41,6 +39,7 @@ void help(const struct doveadm_cmd *cmd) ATTR_NORETURN; void doveadm_master_send_signal(int signo); +void doveadm_register_auth_commands(void); void doveadm_register_director_commands(void); void doveadm_register_proxy_commands(void); void doveadm_register_log_commands(void); diff -r 007bf0047ab0 -r 1093c74f54af src/lib-auth/auth-master.c --- a/src/lib-auth/auth-master.c Wed Jul 04 10:56:53 2012 +0300 +++ b/src/lib-auth/auth-master.c Wed Jul 04 10:57:40 2012 +0300 @@ -9,6 +9,7 @@ #include "istream.h" #include "ostream.h" #include "str.h" +#include "strescape.h" #include "master-interface.h" #include "auth-master.h" @@ -564,6 +565,48 @@ } static bool +auth_cache_flush_reply_callback(const char *cmd, const char *const *args, + void *context) +{ + unsigned int *countp = context; + + if (strcmp(cmd, "OK") != 0) + *countp = -1U; + else if (args[0] == NULL || str_to_uint(args[0], countp) < 0) + *countp = -1U; + + io_loop_stop(current_ioloop); + return TRUE; +} + +int auth_master_cache_flush(struct auth_master_connection *conn, + const char *const *users, unsigned int *count_r) +{ + string_t *str; + + *count_r = -1U; + + conn->reply_callback = auth_cache_flush_reply_callback; + conn->reply_context = count_r; + + str = t_str_new(128); + str_printfa(str, "CACHE-FLUSH\t%u", auth_master_next_request_id(conn)); + if (users != NULL) { + for (; *users != NULL; users++) { + str_append_c(str, '\t'); + str_tabescape_write(str, *users); + } + } + str_append_c(str, '\n'); + + conn->prefix = "auth cache flush"; + (void)auth_master_run_cmd(conn, str_c(str)); + conn->prefix = DEFAULT_USERDB_LOOKUP_PREFIX; + + return *count_r == -1U ? -1 : 0; +} + +static bool auth_user_list_reply_callback(const char *cmd, const char *const *args, void *context) { diff -r 007bf0047ab0 -r 1093c74f54af src/lib-auth/auth-master.h --- a/src/lib-auth/auth-master.h Wed Jul 04 10:56:53 2012 +0300 +++ b/src/lib-auth/auth-master.h Wed Jul 04 10:57:40 2012 +0300 @@ -38,6 +38,10 @@ int auth_master_pass_lookup(struct auth_master_connection *conn, const char *user, const struct auth_user_info *info, pool_t pool, const char *const **fields_r); +/* Flush authentication cache for everyone (users=NULL) or only for specified + users. Returns number of users flushed from cache. */ +int auth_master_cache_flush(struct auth_master_connection *conn, + const char *const *users, unsigned int *count_r); /* Parse userdb extra fields into auth_user_reply structure. */ void auth_user_fields_parse(const char *const *fields, pool_t pool, From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: file_preallocate() returned wrong value on success ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4b0095f19181 changeset: 14780:4b0095f19181 user: Timo Sirainen date: Sat Jul 07 14:37:54 2012 +0300 description: file_preallocate() returned wrong value on success with OSX. diffstat: src/lib/file-set-size.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r ea18b2ddb67b -r 4b0095f19181 src/lib/file-set-size.c --- a/src/lib/file-set-size.c Sat Jul 07 05:51:37 2012 +0300 +++ b/src/lib/file-set-size.c Sat Jul 07 14:37:54 2012 +0300 @@ -100,7 +100,7 @@ fs.fst_bytesalloc = 0; if (fcntl(fd, F_PREALLOCATE, &fs) < 0) return -1; - return 0; + return fs.fst_bytesalloc > 0 ? 1 : 0; #else return 0; #endif From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: pop3: Fixed assert crash when doing UIDL on empty m... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ea18b2ddb67b changeset: 14779:ea18b2ddb67b user: Timo Sirainen date: Sat Jul 07 05:51:37 2012 +0300 description: pop3: Fixed assert crash when doing UIDL on empty mailbox on some setups. diffstat: src/pop3/pop3-commands.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 1093c74f54af -r ea18b2ddb67b src/pop3/pop3-commands.c --- a/src/pop3/pop3-commands.c Wed Jul 04 10:57:40 2012 +0300 +++ b/src/pop3/pop3-commands.c Sat Jul 07 05:51:37 2012 +0300 @@ -759,7 +759,7 @@ str_hash, (hash_cmp_callback_t *)strcmp); client->uidl_pool = pool_alloconly_create("message uidls", 1024); client->message_uidls = p_new(client->uidl_pool, const char *, - client->messages_count); + client->messages_count+1); str = t_str_new(128); msgnum = 0; while (mailbox_search_next(search_ctx, &mail)) { From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: doveadm auth cache flush usage string updated Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b3e1111e7f49 changeset: 14781:b3e1111e7f49 user: Timo Sirainen date: Wed Jul 04 11:02:58 2012 +0300 description: doveadm auth cache flush usage string updated diffstat: src/doveadm/doveadm-auth.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 4b0095f19181 -r b3e1111e7f49 src/doveadm/doveadm-auth.c --- a/src/doveadm/doveadm-auth.c Sat Jul 07 14:37:54 2012 +0300 +++ b/src/doveadm/doveadm-auth.c Wed Jul 04 11:02:58 2012 +0300 @@ -426,7 +426,7 @@ { cmd_auth, "auth", "[-a ] [-x ] []" }, { cmd_auth_cache_flush, "auth cache flush", - "[-a ] []" }, + "[-a ] [ [...]]" }, { cmd_user, "user", "[-a ] [-x ] [-f field] [-m] [...]" } }; From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: pop3c: Don't get size of TOP output and cache it as... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8ef2b31b125f changeset: 14782:8ef2b31b125f user: Timo Sirainen date: Sat Jul 07 16:27:59 2012 +0300 description: pop3c: Don't get size of TOP output and cache it as message's virtual size. diffstat: src/lib-storage/index/pop3c/pop3c-mail.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) diffs (28 lines): diff -r b3e1111e7f49 -r 8ef2b31b125f src/lib-storage/index/pop3c/pop3c-mail.c --- a/src/lib-storage/index/pop3c/pop3c-mail.c Wed Jul 04 11:02:58 2012 +0300 +++ b/src/lib-storage/index/pop3c/pop3c-mail.c Sat Jul 07 16:27:59 2012 +0300 @@ -110,10 +110,12 @@ if (mail->data.stream == NULL) { capa = pop3c_client_get_capabilities(mbox->client); - if (get_body || (capa & POP3C_CAPABILITY_TOP) == 0) + if (get_body || (capa & POP3C_CAPABILITY_TOP) == 0) { cmd = t_strdup_printf("RETR %u\r\n", _mail->seq); - else + get_body = TRUE; + } else { cmd = t_strdup_printf("TOP %u 0\r\n", _mail->seq); + } if (pop3c_client_cmd_stream(mbox->client, cmd, &input, &error) < 0) { mail_storage_set_error(mbox->box.storage, @@ -130,7 +132,8 @@ } } i_stream_set_name(mail->data.stream, t_strcut(cmd, '\r')); - pop3c_mail_cache_size(mail); + if (get_body) + pop3c_mail_cache_size(mail); } return index_mail_init_stream(mail, hdr_size, body_size, stream_r); } From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: Added a simple JSON parser for parsing an object. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/01cdca5817f2 changeset: 14783:01cdca5817f2 user: Timo Sirainen date: Sun Jul 08 07:37:28 2012 +0300 description: Added a simple JSON parser for parsing an object. diffstat: src/lib/Makefile.am | 2 + src/lib/json-parser.c | 272 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/json-parser.h | 22 ++++ 3 files changed, 296 insertions(+), 0 deletions(-) diffs (truncated from 321 to 300 lines): diff -r 8ef2b31b125f -r 01cdca5817f2 src/lib/Makefile.am --- a/src/lib/Makefile.am Sat Jul 07 16:27:59 2012 +0300 +++ b/src/lib/Makefile.am Sun Jul 08 07:37:28 2012 +0300 @@ -74,6 +74,7 @@ ioloop-select.c \ ioloop-epoll.c \ ioloop-kqueue.c \ + json-parser.c \ lib.c \ lib-signals.c \ md4.c \ @@ -183,6 +184,7 @@ ioloop-iolist.h \ ioloop-private.h \ ioloop-notify-fd.h \ + json-parser.h \ lib.h \ lib-signals.h \ llist.h \ diff -r 8ef2b31b125f -r 01cdca5817f2 src/lib/json-parser.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/json-parser.c Sun Jul 08 07:37:28 2012 +0300 @@ -0,0 +1,272 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "str.h" +#include "hex-dec.h" +#include "unichar.h" +#include "json-parser.h" + +enum json_state { + JSON_STATE_ROOT = 0, + JSON_STATE_OBJECT_KEY, + JSON_STATE_OBJECT_COLON, + JSON_STATE_OBJECT_VALUE, + JSON_STATE_OBJECT_VALUE_NEXT, + JSON_STATE_DONE +}; + +struct json_parser { + const unsigned char *data, *end; + const char *error; + string_t *value; + + enum json_state state; +}; + +struct json_parser * +json_parser_init(const unsigned char *data, unsigned int len) +{ + struct json_parser *parser; + + parser = i_new(struct json_parser, 1); + parser->data = data; + parser->end = data + len; + parser->value = str_new(default_pool, 128); + return parser; +} + +int json_parser_deinit(struct json_parser **_parser, const char **error_r) +{ + struct json_parser *parser = *_parser; + + *_parser = NULL; + + if (parser->error == NULL && parser->data == parser->end && + parser->state != JSON_STATE_ROOT && + parser->state != JSON_STATE_DONE) + parser->error = "Missing '}'"; + + *error_r = parser->error; + str_free(&parser->value); + i_free(parser); + return *error_r != NULL ? -1 : 0; +} + +static bool json_parse_whitespace(struct json_parser *parser) +{ + for (; parser->data != parser->end; parser->data++) { + switch (*parser->data) { + case ' ': + case '\t': + case '\r': + case '\n': + break; + default: + return TRUE; + } + } + return FALSE; +} + +static int json_parse_string(struct json_parser *parser, const char **value_r) +{ + const unsigned char *p; + + if (*parser->data != '"') + return -1; + + str_truncate(parser->value, 0); + for (p = parser->data + 1; p < parser->end; p++) { + if (*p == '"') { + parser->data = p + 1; + *value_r = str_c(parser->value); + return 0; + } + if (*p != '\\') + str_append_c(parser->value, *p); + else { + switch (*++p) { + case '"': + case '\\': + case '/': + str_append_c(parser->value, *p); + break; + case 'b': + str_append_c(parser->value, '\b'); + break; + case 'f': + str_append_c(parser->value, '\f'); + break; + case 'n': + str_append_c(parser->value, '\n'); + break; + case 'r': + str_append_c(parser->value, '\r'); + break; + case 't': + str_append_c(parser->value, '\t'); + break; + case 'u': + if (parser->end - p < 4) + return -1; + uni_ucs4_to_utf8_c(hex2dec(p, 4), + parser->value); + p += 3; + break; + default: + return -1; + } + } + } + return -1; +} + +static int +json_parse_digits(struct json_parser *parser, const unsigned char **_p) +{ + const unsigned char *p = *_p; + + if (p >= parser->end || *p < '0' || *p > '9') + return -1; + + for (; p < parser->end && *p >= '0' && *p <= '9'; p++) + str_append_c(parser->value, *p++); + *_p = p; + return 0; +} + +static int json_parse_int(struct json_parser *parser, const unsigned char **_p) +{ + const unsigned char *p = *_p; + + if (*p == '-') { + str_append_c(parser->value, *p++); + if (p == parser->end) + return -1; + } + if (*p == '0') + str_append_c(parser->value, *p++); + else { + if (json_parse_digits(parser, &p) < 0) + return -1; + } + *_p = p; + return 0; +} + +static int json_parse_number(struct json_parser *parser, const char **value_r) +{ + const unsigned char *p = parser->data; + + str_truncate(parser->value, 0); + if (json_parse_int(parser, &p) < 0) + return -1; + if (p < parser->end && *p == '.') { + /* frac */ + str_append_c(parser->value, *p++); + if (json_parse_digits(parser, &p) < 0) + return -1; + } + if (p < parser->end && (*p == 'e' || *p == 'E')) { + /* exp */ + str_append_c(parser->value, *p++); + if (p == parser->end) + return -1; + if (*p == '+' || *p == '-') + str_append_c(parser->value, *p++); + if (json_parse_digits(parser, &p) < 0) + return -1; + } + *value_r = str_c(parser->value); + return 0; +} + +static int json_parse_atom(struct json_parser *parser, const char *atom) +{ + unsigned int len = strlen(atom); + + if (parser->end - parser->data < len) + return -1; + if (memcmp(parser->data, atom, len) != 0) + return -1; + parser->data += len; + return 0; +} + +bool json_parse_next(struct json_parser *parser, enum json_type *type_r, + const char **value_r) +{ + *value_r = NULL; + + if (!json_parse_whitespace(parser) || parser->error != NULL) + return FALSE; + + switch (parser->state) { + case JSON_STATE_ROOT: + if (*parser->data == '{') { + parser->data++; + parser->state = JSON_STATE_OBJECT_KEY; + return json_parse_next(parser, type_r, value_r); + } + /* fall through */ + case JSON_STATE_OBJECT_VALUE: + if (json_parse_string(parser, value_r) == 0) + *type_r = JSON_TYPE_STRING; + else if (json_parse_number(parser, value_r) == 0) + *type_r = JSON_TYPE_NUMBER; + else if (json_parse_atom(parser, "true") == 0) { + *type_r = JSON_TYPE_TRUE; + *value_r = "true"; + } else if (json_parse_atom(parser, "false") == 0) { + *type_r = JSON_TYPE_FALSE; + *value_r = "false"; + } else if (json_parse_atom(parser, "null") == 0) { + *type_r = JSON_TYPE_NULL; + *value_r = NULL; + } else if (*parser->data == '[') { + parser->error = "Arrays not supported"; + return FALSE; + } else if (*parser->data == '{') { + parser->error = "Nested objects not supported"; + return FALSE; + } else { + parser->error = "Invalid data as value"; + return FALSE; + } + parser->state = parser->state == JSON_STATE_ROOT ? + JSON_STATE_DONE : + JSON_STATE_OBJECT_VALUE_NEXT; + break; + case JSON_STATE_OBJECT_KEY: + *type_r = JSON_TYPE_OBJECT_KEY; + if (json_parse_string(parser, value_r) < 0) { + parser->error = "Expected string as object key"; + return FALSE; + } + parser->state = JSON_STATE_OBJECT_COLON; + break; + case JSON_STATE_OBJECT_COLON: + if (*parser->data != ':') { + parser->error = "Expected ':' after key"; + return FALSE; + } + parser->data++; + parser->state = JSON_STATE_OBJECT_VALUE; + return json_parse_next(parser, type_r, value_r); + case JSON_STATE_OBJECT_VALUE_NEXT: + if (*parser->data == ',') + parser->state = JSON_STATE_OBJECT_KEY; + else if (*parser->data == '}') + parser->state = JSON_STATE_DONE; + else { + parser->error = "Expected ',' or '}' after object value"; + return FALSE; + } + parser->data++; + return json_parse_next(parser, type_r, value_r); + case JSON_STATE_DONE: + parser->error = "Unexpected data at the end"; + return FALSE; + } + return TRUE; +} diff -r 8ef2b31b125f -r 01cdca5817f2 src/lib/json-parser.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/json-parser.h Sun Jul 08 07:37:28 2012 +0300 @@ -0,0 +1,22 @@ +#ifndef JSON_PARSER_H From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: auth: Added "dict" passdb/userdb. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/523c19238a8b changeset: 14784:523c19238a8b user: Timo Sirainen date: Sun Jul 08 07:45:17 2012 +0300 description: auth: Added "dict" passdb/userdb. diffstat: doc/example-config/conf.d/auth-dict.conf.ext | 16 ++ doc/example-config/dovecot-dict-auth.conf.ext | 22 ++ src/auth/Makefile.am | 5 + src/auth/db-dict.c | 177 ++++++++++++++++++++++ src/auth/db-dict.h | 37 ++++ src/auth/main.c | 3 + src/auth/passdb-dict.c | 197 ++++++++++++++++++++++++ src/auth/passdb.c | 2 + src/auth/userdb-dict.c | 207 ++++++++++++++++++++++++++ src/auth/userdb.c | 2 + 10 files changed, 668 insertions(+), 0 deletions(-) diffs (truncated from 788 to 300 lines): diff -r 01cdca5817f2 -r 523c19238a8b doc/example-config/conf.d/auth-dict.conf.ext --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/example-config/conf.d/auth-dict.conf.ext Sun Jul 08 07:45:17 2012 +0300 @@ -0,0 +1,16 @@ +# Authentication via dict backend. Included from auth.conf. +# +# + +passdb { + driver = dict + + # Path for dict configuration file, see + # example-config/dovecot-dict-auth.conf.ext + args = /etc/dovecot/dovecot-dict-auth.conf.ext +} + +userdb { + driver = dict + args = /etc/dovecot/dovecot-dict-auth.conf.ext +} diff -r 01cdca5817f2 -r 523c19238a8b doc/example-config/dovecot-dict-auth.conf.ext --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/example-config/dovecot-dict-auth.conf.ext Sun Jul 08 07:45:17 2012 +0300 @@ -0,0 +1,22 @@ +# Dictionary URI +#uri = + +# Key for passdb lookups +password_key = dovecot/passdb/%u + +# Key for userdb lookups +user_key = dovecot/userdb/%u + +# How to parse the value for key=value pairs. Currently we support only JSON +# format with { "key": "value", ... } object. +#value_format = json + +# Username iteration prefix. Keys under this are assumed to contain usernames. +iterate_prefix = dovecot/userdb/ + +# Should iteration be disabled for this userdb? If this userdb acts only as a +# cache there's no reason to try to iterate the (partial & duplicate) users. +#iterate_disable = no + +# Default password scheme +default_pass_scheme = MD5 diff -r 01cdca5817f2 -r 523c19238a8b src/auth/Makefile.am --- a/src/auth/Makefile.am Sun Jul 08 07:37:28 2012 +0300 +++ b/src/auth/Makefile.am Sun Jul 08 07:45:17 2012 +0300 @@ -25,6 +25,7 @@ -I$(top_srcdir)/src/lib \ -I$(top_srcdir)/src/lib-auth \ -I$(top_srcdir)/src/lib-test \ + -I$(top_srcdir)/src/lib-dict \ -I$(top_srcdir)/src/lib-dns \ -I$(top_srcdir)/src/lib-sql \ -I$(top_srcdir)/src/lib-settings \ @@ -73,6 +74,7 @@ auth-worker-client.c \ auth-worker-server.c \ db-checkpassword.c \ + db-dict.c \ db-sql.c \ db-passwd-file.c \ main.c \ @@ -96,6 +98,7 @@ passdb-bsdauth.c \ passdb-cache.c \ passdb-checkpassword.c \ + passdb-dict.c \ passdb-passwd.c \ passdb-passwd-file.c \ passdb-pam.c \ @@ -108,6 +111,7 @@ userdb.c \ userdb-blocking.c \ userdb-checkpassword.c \ + userdb-dict.c \ userdb-nss.c \ userdb-passwd.c \ userdb-passwd-file.c \ @@ -134,6 +138,7 @@ auth-stream.h \ auth-worker-client.h \ auth-worker-server.h \ + db-dict.h \ db-ldap.h \ db-sql.h \ db-passwd-file.h \ diff -r 01cdca5817f2 -r 523c19238a8b src/auth/db-dict.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/auth/db-dict.c Sun Jul 08 07:45:17 2012 +0300 @@ -0,0 +1,177 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "auth-common.h" + +#include "settings.h" +#include "dict.h" +#include "json-parser.h" +#include "str.h" +#include "auth-request.h" +#include "auth-worker-client.h" +#include "db-dict.h" + +#include +#include + +#define DEF_STR(name) DEF_STRUCT_STR(name, db_dict_settings) +#define DEF_BOOL(name) DEF_STRUCT_BOOL(name, db_dict_settings) + +static struct setting_def setting_defs[] = { + DEF_STR(uri), + DEF_STR(password_key), + DEF_STR(user_key), + DEF_STR(iterate_prefix), + DEF_STR(value_format), + DEF_BOOL(iterate_disable), + DEF_STR(default_pass_scheme), + + { 0, NULL, 0 } +}; + +static struct db_dict_settings default_dict_settings = { + .uri = NULL, + .password_key = "", + .user_key = "", + .iterate_prefix = "", + .iterate_disable = FALSE, + .value_format = "json", + .default_pass_scheme = "MD5" +}; + +static struct dict_connection *connections = NULL; + +static struct dict_connection *dict_conn_find(const char *config_path) +{ + struct dict_connection *conn; + + for (conn = connections; conn != NULL; conn = conn->next) { + if (strcmp(conn->config_path, config_path) == 0) + return conn; + } + + return NULL; +} + +static const char *parse_setting(const char *key, const char *value, + struct dict_connection *conn) +{ + return parse_setting_from_defs(conn->pool, setting_defs, + &conn->set, key, value); +} + +struct dict_connection *db_dict_init(const char *config_path) +{ + struct dict_connection *conn; + pool_t pool; + + conn = dict_conn_find(config_path); + if (conn != NULL) { + conn->refcount++; + return conn; + } + + if (*config_path == '\0') + i_fatal("dict: Configuration file path not given"); + + pool = pool_alloconly_create("dict_connection", 1024); + conn = p_new(pool, struct dict_connection, 1); + conn->pool = pool; + + conn->refcount = 1; + + conn->config_path = p_strdup(pool, config_path); + conn->set = default_dict_settings; + if (!settings_read(config_path, NULL, parse_setting, + null_settings_section_callback, conn)) + exit(FATAL_DEFAULT); + + if (conn->set.uri == NULL) + i_fatal("dict %s: Empty uri setting", config_path); + if (strcmp(conn->set.value_format, "json") != 0) { + i_fatal("dict %s: Unsupported value_format %s in ", + config_path, conn->set.value_format); + } + conn->dict = dict_init(conn->set.uri, DICT_DATA_TYPE_STRING, "", + global_auth_settings->base_dir); + + conn->next = connections; + connections = conn; + return conn; +} + +void db_dict_unref(struct dict_connection **_conn) +{ + struct dict_connection *conn = *_conn; + + *_conn = NULL; + if (--conn->refcount > 0) + return; + + dict_deinit(&conn->dict); + pool_unref(&conn->pool); +} + +struct db_dict_value_iter { + struct json_parser *parser; + string_t *key; + const char *error; +}; + +struct db_dict_value_iter * +db_dict_value_iter_init(struct dict_connection *conn, const char *value) +{ + struct db_dict_value_iter *iter; + + i_assert(strcmp(conn->set.value_format, "json") == 0); + + /* hardcoded for now for JSON value. make it more modular when other + value types are supported. */ + iter = i_new(struct db_dict_value_iter, 1); + iter->key = str_new(default_pool, 64); + iter->parser = json_parser_init((const void *)value, strlen(value)); + return iter; +} + +bool db_dict_value_iter_next(struct db_dict_value_iter *iter, + const char **key_r, const char **value_r) +{ + enum json_type type; + const char *value; + + if (!json_parse_next(iter->parser, &type, &value)) + return FALSE; + if (type != JSON_TYPE_OBJECT_KEY) { + iter->error = "Object expected"; + return FALSE; + } + if (*value == '\0') { + iter->error = "Empty object key"; + return FALSE; + } + str_truncate(iter->key, 0); + str_append(iter->key, value); + + if (!json_parse_next(iter->parser, &type, &value)) { + iter->error = "Missing value"; + return FALSE; + } + *key_r = str_c(iter->key); + *value_r = value; + return TRUE; +} + +int db_dict_value_iter_deinit(struct db_dict_value_iter **_iter, + const char **error_r) +{ + struct db_dict_value_iter *iter = *_iter; + + *_iter = NULL; + + *error_r = iter->error; + if (json_parser_deinit(&iter->parser, &iter->error) < 0 && + *error_r == NULL) + *error_r = iter->error; + str_free(&iter->key); + i_free(iter); + return *error_r != NULL ? -1 : 0; +} diff -r 01cdca5817f2 -r 523c19238a8b src/auth/db-dict.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/auth/db-dict.h Sun Jul 08 07:45:17 2012 +0300 @@ -0,0 +1,37 @@ +#ifndef DB_DICT_H +#define DB_DICT_H + +#include "sql-api.h" + +struct db_dict_settings { + const char *uri; + const char *password_key; + const char *user_key; + const char *iterate_prefix; + bool iterate_disable; + const char *value_format; + const char *default_pass_scheme; +}; + +struct dict_connection { + struct dict_connection *next; + + pool_t pool; + int refcount; + + char *config_path; + struct db_dict_settings set; + struct dict *dict; +}; + From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: Added "connection" API for handling client/server c... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/43b841891c77 changeset: 14785:43b841891c77 user: Timo Sirainen date: Sun Jul 08 08:59:52 2012 +0300 description: Added "connection" API for handling client/server connections more easily. diffstat: src/lib/Makefile.am | 2 + src/lib/connection.c | 341 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/connection.h | 118 +++++++++++++++++ 3 files changed, 461 insertions(+), 0 deletions(-) diffs (truncated from 486 to 300 lines): diff -r 523c19238a8b -r 43b841891c77 src/lib/Makefile.am --- a/src/lib/Makefile.am Sun Jul 08 07:45:17 2012 +0300 +++ b/src/lib/Makefile.am Sun Jul 08 08:59:52 2012 +0300 @@ -22,6 +22,7 @@ child-wait.c \ close-keep-errno.c \ compat.c \ + connection.c \ crc32.c \ data-stack.c \ eacces-error.c \ @@ -140,6 +141,7 @@ child-wait.h \ close-keep-errno.h \ compat.h \ + connection.h \ crc32.h \ data-stack.h \ eacces-error.h \ diff -r 523c19238a8b -r 43b841891c77 src/lib/connection.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/connection.c Sun Jul 08 08:59:52 2012 +0300 @@ -0,0 +1,341 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "ioloop.h" +#include "istream.h" +#include "ostream.h" +#include "network.h" +#include "strescape.h" +#include "llist.h" +#include "connection.h" + +#include + +static void connection_idle_timeout(struct connection *conn) +{ + conn->disconnect_reason = CONNECTION_DISCONNECT_IDLE_TIMEOUT; + conn->list->v.destroy(conn); +} + +static void connection_connect_timeout(struct connection *conn) +{ + conn->disconnect_reason = CONNECTION_DISCONNECT_CONNECT_TIMEOUT; + conn->list->v.destroy(conn); +} + +void connection_input_default(struct connection *conn) +{ + const char *line; + struct istream *input; + int ret = 0; + + switch (connection_input_read(conn)) { + case -1: + case 0: + return; + case 1: + break; + default: + i_unreached(); + } + + input = conn->input; + i_stream_ref(input); + while (!input->closed && (line = i_stream_next_line(input)) != NULL) { + T_BEGIN { + ret = conn->list->v.input_line(conn, line); + } T_END; + if (ret <= 0) + break; + } + if (ret < 0 && !input->closed) { + conn->disconnect_reason = CONNECTION_DISCONNECT_DEINIT; + conn->list->v.destroy(conn); + } + i_stream_unref(&input); +} + +int connection_verify_version(struct connection *conn, + const char *const *args) +{ + unsigned int recv_major_version; + + /* VERSION service_name major version minor version */ + if (str_array_length(args) != 4 || + strcmp(args[0], "VERSION") != 0 || + str_to_uint(args[2], &recv_major_version) < 0 || + str_to_uint(args[3], &conn->minor_version) < 0) { + i_error("%s didn't reply with a valid VERSION line", + conn->name); + return -1; + } + + if (strcmp(args[1], conn->list->set.service_name_in) != 0) { + i_error("%s: Connected to wrong socket type. " + "We want '%s', but received '%s'", conn->name, + conn->list->set.service_name_in, args[1]); + return -1; + } + + if (recv_major_version != conn->list->set.major_version) { + i_error("%s: Socket supports major version %u, " + "but we support only %u (mixed old and new binaries?)", + conn->name, recv_major_version, + conn->list->set.major_version); + return -1; + } + return 0; +} + +int connection_input_line_default(struct connection *conn, const char *line) +{ + const char *const *args; + + args = t_strsplit_tabescaped(line); + if (!conn->version_received) { + if (connection_verify_version(conn, args) < 0) + return -1; + conn->version_received = TRUE; + } + + return conn->list->v.input_args(conn, args); +} + +static void connection_init_streams(struct connection *conn) +{ + const struct connection_settings *set = &conn->list->set; + + i_assert(conn->input == NULL); + i_assert(conn->output == NULL); + i_assert(conn->to == NULL); + + conn->version_received = set->major_version == 0; + + if (set->input_max_size != 0) { + conn->input = i_stream_create_fd(conn->fd_in, + set->input_max_size, FALSE); + } + if (set->output_max_size != 0) { + conn->output = o_stream_create_fd(conn->fd_out, + set->output_max_size, FALSE); + } + if (set->input_idle_timeout_secs != 0) { + conn->to = timeout_add(set->input_idle_timeout_secs*1000, + connection_idle_timeout, conn); + } + if (set->major_version != 0) { + o_stream_send_str(conn->output, t_strdup_printf( + "VERSION\t%s\t%u\t%u\n", set->service_name_out, + set->major_version, set->minor_version)); + } +} + +static void connection_init_io(struct connection *conn) +{ + i_assert(conn->io == NULL); + conn->io = io_add(conn->fd_in, IO_READ, conn->list->v.input, conn); +} + +void connection_init_server(struct connection_list *list, + struct connection *conn, const char *name, + int fd_in, int fd_out) +{ + i_assert(name != NULL); + i_assert(!list->set.client); + + conn->list = list; + conn->name = i_strdup(name); + conn->fd_in = fd_in; + conn->fd_out = fd_out; + connection_init_io(conn); + connection_init_streams(conn); + + DLLIST_PREPEND(&list->connections, conn); +} + +void connection_init_client_ip(struct connection_list *list, + struct connection *conn, + const struct ip_addr *ip, unsigned int port) +{ + i_assert(list->set.client); + + conn->fd_in = conn->fd_out = -1; + conn->list = list; + conn->name = i_strdup_printf("%s:%u", net_ip2addr(ip), port); + + conn->ip = *ip; + conn->port = port; + + DLLIST_PREPEND(&list->connections, conn); +} + +void connection_init_client_unix(struct connection_list *list, + struct connection *conn, const char *path) +{ + i_assert(list->set.client); + + conn->fd_in = conn->fd_out = -1; + conn->list = list; + conn->name = i_strdup(path); + + DLLIST_PREPEND(&list->connections, conn); +} + +static void connection_connected(struct connection *conn) +{ + io_remove(&conn->io); + if (conn->to != NULL) + timeout_remove(&conn->to); + + connection_init_io(conn); +} + +int connection_client_connect(struct connection *conn) +{ + const struct connection_settings *set = &conn->list->set; + int fd; + + i_assert(conn->list->set.client); + i_assert(conn->fd_in == -1); + + if (conn->port != 0) + fd = net_connect_ip(&conn->ip, conn->port, NULL); + else + fd = net_connect_unix(conn->name); + if (fd == -1) + return -1; + conn->fd_in = conn->fd_out = fd; + + if (conn->port != 0) { + conn->io = io_add(conn->fd_out, IO_WRITE, + connection_connected, conn); + if (set->client_connect_timeout_msecs != 0) { + conn->to = timeout_add(set->client_connect_timeout_msecs, + connection_connect_timeout, conn); + } + } else { + connection_init_io(conn); + } + connection_init_streams(conn); + return 0; +} + +void connection_disconnect(struct connection *conn) +{ + if (conn->to != NULL) + timeout_remove(&conn->to); + if (conn->io != NULL) + io_remove(&conn->io); + if (conn->input != NULL) + i_stream_destroy(&conn->input); + if (conn->output != NULL) + o_stream_destroy(&conn->output); + if (conn->fd_in != -1) { + if (close(conn->fd_in) < 0) + i_error("close(%s) failed: %m", conn->name); + if (conn->fd_in != conn->fd_out) + i_error("close(%s/out) failed: %m", conn->name); + conn->fd_in = conn->fd_out = -1; + } +} + +void connection_deinit(struct connection *conn) +{ + DLLIST_REMOVE(&conn->list->connections, conn); + + connection_disconnect(conn); + i_free(conn->name); +} + +int connection_input_read(struct connection *conn) +{ + conn->last_input = ioloop_time; + if (conn->to != NULL) + timeout_reset(conn->to); + + switch (i_stream_read(conn->input)) { + case -2: + /* buffer full */ + switch (conn->list->set.input_full_behavior) { + case CONNECTION_BEHAVIOR_DESTROY: + conn->disconnect_reason = + CONNECTION_DISCONNECT_BUFFER_FULL; + conn->list->v.destroy(conn); + return -1; + case CONNECTION_BEHAVIOR_ALLOW: + return -2; + } + case -1: + /* disconnected */ + conn->disconnect_reason = + CONNECTION_DISCONNECT_CONN_CLOSED; + conn->list->v.destroy(conn); + return -1; + case 0: + /* nothing new read */ + return 0; + default: From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: redis: Fixed connection handling. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/64725ff9c297 changeset: 14787:64725ff9c297 user: Timo Sirainen date: Sun Jul 08 09:18:46 2012 +0300 description: redis: Fixed connection handling. diffstat: src/lib-dict/dict-redis.c | 44 ++++++++++++++++++++++++++++++++------------ src/lib/connection.c | 16 ++++++---------- src/lib/connection.h | 1 + 3 files changed, 39 insertions(+), 22 deletions(-) diffs (163 lines): diff -r 211fbc872ed4 -r 64725ff9c297 src/lib-dict/dict-redis.c --- a/src/lib-dict/dict-redis.c Sun Jul 08 09:00:57 2012 +0300 +++ b/src/lib-dict/dict-redis.c Sun Jul 08 09:18:46 2012 +0300 @@ -28,11 +28,7 @@ struct ioloop *ioloop; struct redis_connection conn; -}; - -struct redis_dict_iterate_context { - struct dict_iterate_context ctx; - struct redis_connection *conn; + bool connected; }; static struct connection_list *redis_connections; @@ -41,6 +37,7 @@ { struct redis_connection *conn = (struct redis_connection *)_conn; + conn->dict->connected = FALSE; connection_disconnect(_conn); if (conn->dict->ioloop != NULL) io_loop_stop(conn->dict->ioloop); @@ -101,6 +98,20 @@ } } +static void redis_conn_connected(struct connection *_conn) +{ + struct redis_connection *conn = (struct redis_connection *)_conn; + + if ((errno = net_geterror(_conn->fd_in)) != 0) { + i_error("redis: connect(%s, %u) failed: %m", + net_ip2addr(&conn->dict->ip), conn->dict->port); + } else { + conn->dict->connected = TRUE; + } + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); +} + static const struct connection_settings redis_conn_set = { .input_max_size = (size_t)-1, .output_max_size = (size_t)-1, @@ -109,7 +120,8 @@ static const struct connection_vfuncs redis_conn_vfuncs = { .destroy = redis_conn_destroy, - .input = redis_conn_input + .input = redis_conn_input, + .connected = redis_conn_connected }; static struct dict * @@ -171,7 +183,8 @@ static void redis_dict_lookup_timeout(struct redis_dict *dict) { - i_error("redis: Lookup timed out in %u secs", dict->timeout_msecs); + i_error("redis: Lookup timed out in %u.%03u secs", + dict->timeout_msecs/1000, dict->timeout_msecs%1000); io_loop_stop(dict->ioloop); } @@ -203,12 +216,19 @@ } else { to = timeout_add(dict->timeout_msecs, redis_dict_lookup_timeout, dict); - cmd = t_strdup_printf("*2\r\n$3\r\nGET\r\n$%d\r\n%s\r\n", - (int)strlen(key), key); - o_stream_send_str(dict->conn.conn.output, cmd); + if (!dict->connected) { + /* wait for connection */ + io_loop_run(dict->ioloop); + } - str_truncate(dict->conn.last_reply, 0); - io_loop_run(dict->ioloop); + if (dict->connected) { + cmd = t_strdup_printf("*2\r\n$3\r\nGET\r\n$%d\r\n%s\r\n", + (int)strlen(key), key); + o_stream_send_str(dict->conn.conn.output, cmd); + + str_truncate(dict->conn.last_reply, 0); + io_loop_run(dict->ioloop); + } timeout_remove(&to); } diff -r 211fbc872ed4 -r 64725ff9c297 src/lib/connection.c --- a/src/lib/connection.c Sun Jul 08 09:00:57 2012 +0300 +++ b/src/lib/connection.c Sun Jul 08 09:18:46 2012 +0300 @@ -105,6 +105,7 @@ { const struct connection_settings *set = &conn->list->set; + i_assert(conn->io == NULL); i_assert(conn->input == NULL); i_assert(conn->output == NULL); i_assert(conn->to == NULL); @@ -119,6 +120,7 @@ conn->output = o_stream_create_fd(conn->fd_out, set->output_max_size, FALSE); } + conn->io = io_add(conn->fd_in, IO_READ, conn->list->v.input, conn); if (set->input_idle_timeout_secs != 0) { conn->to = timeout_add(set->input_idle_timeout_secs*1000, connection_idle_timeout, conn); @@ -128,12 +130,8 @@ "VERSION\t%s\t%u\t%u\n", set->service_name_out, set->major_version, set->minor_version)); } -} - -static void connection_init_io(struct connection *conn) -{ - i_assert(conn->io == NULL); - conn->io = io_add(conn->fd_in, IO_READ, conn->list->v.input, conn); + if (conn->list->v.connected != NULL) + conn->list->v.connected(conn); } void connection_init_server(struct connection_list *list, @@ -147,7 +145,6 @@ conn->name = i_strdup(name); conn->fd_in = fd_in; conn->fd_out = fd_out; - connection_init_io(conn); connection_init_streams(conn); DLLIST_PREPEND(&list->connections, conn); @@ -187,7 +184,7 @@ if (conn->to != NULL) timeout_remove(&conn->to); - connection_init_io(conn); + connection_init_streams(conn); } int connection_client_connect(struct connection *conn) @@ -214,9 +211,8 @@ connection_connect_timeout, conn); } } else { - connection_init_io(conn); + connection_init_streams(conn); } - connection_init_streams(conn); return 0; } diff -r 211fbc872ed4 -r 64725ff9c297 src/lib/connection.h --- a/src/lib/connection.h Sun Jul 08 09:00:57 2012 +0300 +++ b/src/lib/connection.h Sun Jul 08 09:18:46 2012 +0300 @@ -27,6 +27,7 @@ struct connection_vfuncs { void (*destroy)(struct connection *conn); + void (*connected)(struct connection *conn); /* implement one of the input*() methods. They return 0 = ok, -1 = error, disconnect the client */ From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: lib-dict: Added initial version of Redis support. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/211fbc872ed4 changeset: 14786:211fbc872ed4 user: Timo Sirainen date: Sun Jul 08 09:00:57 2012 +0300 description: lib-dict: Added initial version of Redis support. The code is a bit ugly and doesn't handle anything except key lookups. diffstat: src/lib-dict/Makefile.am | 3 +- src/lib-dict/dict-private.h | 3 +- src/lib-dict/dict-redis.c | 250 ++++++++++++++++++++++++++++++++++++++++++++ src/lib-dict/dict.c | 2 + src/lib-dict/test-dict.c | 1 + 5 files changed, 257 insertions(+), 2 deletions(-) diffs (truncated from 309 to 300 lines): diff -r 43b841891c77 -r 211fbc872ed4 src/lib-dict/Makefile.am --- a/src/lib-dict/Makefile.am Sun Jul 08 08:59:52 2012 +0300 +++ b/src/lib-dict/Makefile.am Sun Jul 08 09:00:57 2012 +0300 @@ -13,7 +13,8 @@ base_sources = \ dict.c \ dict-client.c \ - dict-file.c + dict-file.c \ + dict-redis.c libdict_la_SOURCES = \ $(base_sources) diff -r 43b841891c77 -r 211fbc872ed4 src/lib-dict/dict-private.h --- a/src/lib-dict/dict-private.h Sun Jul 08 08:59:52 2012 +0300 +++ b/src/lib-dict/dict-private.h Sun Jul 08 09:00:57 2012 +0300 @@ -51,7 +51,8 @@ unsigned int changed:1; }; +extern struct dict dict_driver_client; extern struct dict dict_driver_file; -extern struct dict dict_driver_client; +extern struct dict dict_driver_redis; #endif diff -r 43b841891c77 -r 211fbc872ed4 src/lib-dict/dict-redis.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-dict/dict-redis.c Sun Jul 08 09:00:57 2012 +0300 @@ -0,0 +1,250 @@ +/* Copyright (c) 2008-2012 Dovecot authors, see the included COPYING redis */ + +#include "lib.h" +#include "str.h" +#include "istream.h" +#include "ostream.h" +#include "connection.h" +#include "dict-private.h" + +#define REDIS_DEFAULT_PORT 6379 +#define REDIS_DEFAULT_LOOKUP_TIMEOUT_MSECS (1000*30) + +struct redis_connection { + struct connection conn; + struct redis_dict *dict; + + string_t *last_reply; + unsigned int bytes_left; + bool value_not_found; + bool value_received; +}; + +struct redis_dict { + struct dict dict; + struct ip_addr ip; + unsigned int port; + unsigned int timeout_msecs; + + struct ioloop *ioloop; + struct redis_connection conn; +}; + +struct redis_dict_iterate_context { + struct dict_iterate_context ctx; + struct redis_connection *conn; +}; + +static struct connection_list *redis_connections; + +static void redis_conn_destroy(struct connection *_conn) +{ + struct redis_connection *conn = (struct redis_connection *)_conn; + + connection_disconnect(_conn); + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); +} + +static void redis_conn_input(struct connection *_conn) +{ + struct redis_connection *conn = (struct redis_connection *)_conn; + const unsigned char *data; + size_t size; + const char *line; + + switch (i_stream_read(_conn->input)) { + case 0: + return; + case -1: + redis_conn_destroy(_conn); + return; + default: + break; + } + + if (conn->bytes_left == 0) { + /* read the size first */ + line = i_stream_next_line(_conn->input); + if (line == NULL) + return; + if (strcmp(line, "$-1") == 0) { + conn->value_received = TRUE; + conn->value_not_found = TRUE; + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); + return; + } + if (line[0] != '$' || str_to_uint(line+1, &conn->bytes_left) < 0) { + i_error("redis: Unexpected input (wanted $size): %s", + line); + redis_conn_destroy(_conn); + return; + } + conn->bytes_left += 2; /* include trailing CRLF */ + } + + data = i_stream_get_data(_conn->input, &size); + if (size > conn->bytes_left) + size = conn->bytes_left; + str_append_n(conn->last_reply, data, size); + + conn->bytes_left -= size; + i_stream_skip(_conn->input, size); + + if (conn->bytes_left == 0) { + /* drop trailing CRLF */ + conn->value_received = TRUE; + str_truncate(conn->last_reply, str_len(conn->last_reply)-2); + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); + } +} + +static const struct connection_settings redis_conn_set = { + .input_max_size = (size_t)-1, + .output_max_size = (size_t)-1, + .client = TRUE +}; + +static const struct connection_vfuncs redis_conn_vfuncs = { + .destroy = redis_conn_destroy, + .input = redis_conn_input +}; + +static struct dict * +redis_dict_init(struct dict *driver, const char *uri, + enum dict_data_type value_type ATTR_UNUSED, + const char *username ATTR_UNUSED, + const char *base_dir ATTR_UNUSED) +{ + struct redis_dict *dict; + const char *const *args; + + if (redis_connections == NULL) { + redis_connections = + connection_list_init(&redis_conn_set, + &redis_conn_vfuncs); + } + + dict = i_new(struct redis_dict, 1); + if (net_addr2ip("127.0.0.1", &dict->ip) < 0) + i_unreached(); + dict->port = REDIS_DEFAULT_PORT; + dict->timeout_msecs = REDIS_DEFAULT_LOOKUP_TIMEOUT_MSECS; + + args = t_strsplit(uri, ":"); + for (; *args != NULL; args++) { + if (strncmp(*args, "host=", 5) == 0) { + if (net_addr2ip(*args+5, &dict->ip) < 0) + i_error("Invalid IP: %s", *args+5); + } else if (strncmp(*args, "port=", 5) == 0) { + if (str_to_uint(*args+5, &dict->port) < 0) + i_error("Invalid port: %s", *args+5); + } else if (strncmp(*args, "timeout_msecs=", 14) == 0) { + if (str_to_uint(*args+14, &dict->timeout_msecs) < 0) + i_error("Invalid timeout_msecs: %s", *args+14); + } else { + i_error("Unknown parameter: %s", *args); + } + } + connection_init_client_ip(redis_connections, &dict->conn.conn, + &dict->ip, dict->port); + + dict->dict = *driver; + dict->conn.last_reply = str_new(default_pool, 256); + dict->conn.dict = dict; + return &dict->dict; +} + +static void redis_dict_deinit(struct dict *_dict) +{ + struct redis_dict *dict = (struct redis_dict *)_dict; + + connection_deinit(&dict->conn.conn); + str_free(&dict->conn.last_reply); + i_free(dict); + + if (redis_connections->connections == NULL) + connection_list_deinit(&redis_connections); +} + +static void redis_dict_lookup_timeout(struct redis_dict *dict) +{ + i_error("redis: Lookup timed out in %u secs", dict->timeout_msecs); + io_loop_stop(dict->ioloop); +} + +static int redis_dict_lookup(struct dict *_dict, pool_t pool, + const char *key, const char **value_r) +{ + struct redis_dict *dict = (struct redis_dict *)_dict; + struct timeout *to; + const char *cmd; + struct ioloop *prev_ioloop = current_ioloop; + + if (strncmp(key, DICT_PATH_SHARED, strlen(DICT_PATH_SHARED)) == 0) + key += strlen(DICT_PATH_SHARED); + else { + i_error("redis: Only shared key lookups supported for now"); + return -1; + } + + dict->conn.value_received = FALSE; + dict->conn.value_not_found = FALSE; + + dict->ioloop = io_loop_create(); + connection_switch_ioloop(&dict->conn.conn); + + if (dict->conn.conn.fd_in == -1 && + connection_client_connect(&dict->conn.conn) < 0) { + i_error("redis: Couldn't connect to %s:%u", + net_ip2addr(&dict->ip), dict->port); + } else { + to = timeout_add(dict->timeout_msecs, + redis_dict_lookup_timeout, dict); + cmd = t_strdup_printf("*2\r\n$3\r\nGET\r\n$%d\r\n%s\r\n", + (int)strlen(key), key); + o_stream_send_str(dict->conn.conn.output, cmd); + + str_truncate(dict->conn.last_reply, 0); + io_loop_run(dict->ioloop); + timeout_remove(&to); + } + + current_ioloop = prev_ioloop; + connection_switch_ioloop(&dict->conn.conn); + current_ioloop = dict->ioloop; + io_loop_destroy(&dict->ioloop); + + if (!dict->conn.value_received) { + /* we failed in some way. make sure we disconnect since the + connection state isn't known anymore */ + redis_conn_destroy(&dict->conn.conn); + return -1; + } + if (dict->conn.value_not_found) + return 0; + + *value_r = p_strdup(pool, str_c(dict->conn.last_reply)); + return 1; +} + +struct dict dict_driver_redis = { + .name = "redis", + { + redis_dict_init, + redis_dict_deinit, + NULL, + redis_dict_lookup, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL + } +}; diff -r 43b841891c77 -r 211fbc872ed4 src/lib-dict/dict.c --- a/src/lib-dict/dict.c Sun Jul 08 08:59:52 2012 +0300 +++ b/src/lib-dict/dict.c Sun Jul 08 09:00:57 2012 +0300 @@ -55,12 +55,14 @@ { dict_driver_register(&dict_driver_client); dict_driver_register(&dict_driver_file); + dict_driver_register(&dict_driver_redis); } void dict_drivers_unregister_builtin(void) { dict_driver_unregister(&dict_driver_client); dict_driver_unregister(&dict_driver_file); + dict_driver_unregister(&dict_driver_redis); } struct dict *dict_init(const char *uri, enum dict_data_type value_type, diff -r 43b841891c77 -r 211fbc872ed4 src/lib-dict/test-dict.c --- a/src/lib-dict/test-dict.c Sun Jul 08 08:59:52 2012 +0300 From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: pop3c: pop3c_master_user setting broke down non-mas... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5b0c88c43929 changeset: 14788:5b0c88c43929 user: Timo Sirainen date: Sun Jul 08 10:28:38 2012 +0300 description: pop3c: pop3c_master_user setting broke down non-master logins. diffstat: src/lib-storage/index/pop3c/pop3c-client.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 64725ff9c297 -r 5b0c88c43929 src/lib-storage/index/pop3c/pop3c-client.c --- a/src/lib-storage/index/pop3c/pop3c-client.c Sun Jul 08 09:18:46 2012 +0300 +++ b/src/lib-storage/index/pop3c/pop3c-client.c Sun Jul 08 10:28:38 2012 +0300 @@ -84,7 +84,7 @@ client->set.debug = set->debug; client->set.host = p_strdup(pool, set->host); client->set.port = set->port; - client->set.master_user = p_strdup(pool, set->master_user); + client->set.master_user = p_strdup_empty(pool, set->master_user); client->set.username = p_strdup(pool, set->username); client->set.password = p_strdup(pool, set->password); client->set.dns_client_socket_path = From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: Debian names libtextcat as libexttextcat. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/558e4205c429 changeset: 14789:558e4205c429 user: Timo Sirainen date: Wed Jul 11 09:32:18 2012 +0200 description: Debian names libtextcat as libexttextcat. Patch by Stephan Bosch. diffstat: configure.in | 6 ++++++ src/plugins/fts-lucene/Makefile.am | 4 ++++ src/plugins/fts-lucene/lucene-wrapper.cc | 4 ++++ 3 files changed, 14 insertions(+), 0 deletions(-) diffs (51 lines): diff -r 5b0c88c43929 -r 558e4205c429 configure.in --- a/configure.in Sun Jul 08 10:28:38 2012 +0300 +++ b/configure.in Wed Jul 11 09:32:18 2012 +0200 @@ -2665,6 +2665,11 @@ AC_CHECK_LIB(textcat, special_textcat_Init, [ have_lucene_textcat=yes AC_DEFINE(HAVE_LUCENE_TEXTCAT,, Define if you want textcat support for CLucene) + ], [ + AC_CHECK_LIB(exttextcat, special_textcat_Init, [ + have_lucene_exttextcat=yes + AC_DEFINE(HAVE_LUCENE_EXTTEXTCAT,, Define if you want textcat (Debian version) support for CLucene) + ]) ]) ], [ if test $want_stemmer = yes; then @@ -2677,6 +2682,7 @@ fi AM_CONDITIONAL(BUILD_LUCENE_STEMMER, test "$have_lucene_stemmer" = "yes") AM_CONDITIONAL(BUILD_LUCENE_TEXTCAT, test "$have_lucene_textcat" = "yes") +AM_CONDITIONAL(BUILD_LUCENE_EXTTEXTCAT, test "$have_lucene_exttextcat" = "yes") if test $have_lucene = no; then not_fts="$not_fts lucene" diff -r 5b0c88c43929 -r 558e4205c429 src/plugins/fts-lucene/Makefile.am --- a/src/plugins/fts-lucene/Makefile.am Sun Jul 08 10:28:38 2012 +0300 +++ b/src/plugins/fts-lucene/Makefile.am Wed Jul 11 09:32:18 2012 +0200 @@ -21,6 +21,10 @@ endif if BUILD_LUCENE_TEXTCAT TEXTCAT_LIBS = -ltextcat +else +if BUILD_LUCENE_EXTTEXTCAT +TEXTCAT_LIBS = -lexttextcat +endif endif lib21_fts_lucene_plugin_la_LIBADD = \ diff -r 5b0c88c43929 -r 558e4205c429 src/plugins/fts-lucene/lucene-wrapper.cc --- a/src/plugins/fts-lucene/lucene-wrapper.cc Sun Jul 08 10:28:38 2012 +0300 +++ b/src/plugins/fts-lucene/lucene-wrapper.cc Wed Jul 11 09:32:18 2012 +0200 @@ -18,6 +18,10 @@ #include #ifdef HAVE_LUCENE_TEXTCAT # include +#else +#ifdef HAVE_LUCENE_EXTTEXTCAT +# include +#endif #endif }; #include From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: mail-log: Log mailbox names with UTF-8 everywhere (... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b4cd382b6606 changeset: 14790:b4cd382b6606 user: Timo Sirainen date: Wed Jul 11 19:15:03 2012 +0200 description: mail-log: Log mailbox names with UTF-8 everywhere (instead of mUTF-7) diffstat: src/plugins/mail-log/mail-log-plugin.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) diffs (41 lines): diff -r 558e4205c429 -r b4cd382b6606 src/plugins/mail-log/mail-log-plugin.c --- a/src/plugins/mail-log/mail-log-plugin.c Wed Jul 11 09:32:18 2012 +0200 +++ b/src/plugins/mail-log/mail-log-plugin.c Wed Jul 11 19:15:03 2012 +0200 @@ -363,7 +363,7 @@ const char *desc; desc = t_strdup_printf("copy from %s", - str_sanitize(mailbox_get_name(src->box), + str_sanitize(mailbox_get_vname(src->box), MAILBOX_NAME_LOG_LEN)); mail_log_append_mail_message(ctx, dst, MAIL_LOG_EVENT_COPY, desc); @@ -466,7 +466,7 @@ return; i_info("Mailbox created: %s", - str_sanitize(box->name, MAILBOX_NAME_LOG_LEN)); + str_sanitize(mailbox_get_vname(box), MAILBOX_NAME_LOG_LEN)); } static void @@ -478,7 +478,7 @@ return; i_info("Mailbox deleted: %s", - str_sanitize(box->name, MAILBOX_NAME_LOG_LEN)); + str_sanitize(mailbox_get_vname(box), MAILBOX_NAME_LOG_LEN)); } static void @@ -491,8 +491,8 @@ return; i_info("Mailbox renamed: %s -> %s", - str_sanitize(src->name, MAILBOX_NAME_LOG_LEN), - str_sanitize(dest->name, MAILBOX_NAME_LOG_LEN)); + str_sanitize(mailbox_get_vname(src), MAILBOX_NAME_LOG_LEN), + str_sanitize(mailbox_get_vname(dest), MAILBOX_NAME_LOG_LEN)); } static const struct notify_vfuncs mail_log_vfuncs = { From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: lib-storage: %h variable didn't necessarily expand ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/abaafe4cc439 changeset: 14792:abaafe4cc439 user: Timo Sirainen date: Mon Jul 16 17:40:45 2012 +0300 description: lib-storage: %h variable didn't necessarily expand correctly for shared users' settings. diffstat: src/lib-storage/mail-user.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (14 lines): diff -r 5bbdfee113a5 -r abaafe4cc439 src/lib-storage/mail-user.c --- a/src/lib-storage/mail-user.c Mon Jul 16 16:49:16 2012 +0300 +++ b/src/lib-storage/mail-user.c Mon Jul 16 17:40:45 2012 +0300 @@ -201,7 +201,9 @@ }; struct var_expand_table *tab; - if (user->var_expand_table != NULL) + /* use a cached table, unless home directory has been set afterwards */ + if (user->var_expand_table != NULL && + user->var_expand_table[4].value == user->_home) return user->var_expand_table; tab = p_malloc(user->pool, sizeof(static_tab)); From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: login: If ssl_key parsing fails, log the reason. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5bbdfee113a5 changeset: 14791:5bbdfee113a5 user: Timo Sirainen date: Mon Jul 16 16:49:16 2012 +0300 description: login: If ssl_key parsing fails, log the reason. diffstat: src/login-common/ssl-proxy-openssl.c | 28 +++++++++++++++------------- 1 files changed, 15 insertions(+), 13 deletions(-) diffs (49 lines): diff -r b4cd382b6606 -r 5bbdfee113a5 src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Wed Jul 11 19:15:03 2012 +0200 +++ b/src/login-common/ssl-proxy-openssl.c Mon Jul 16 16:49:16 2012 +0300 @@ -1026,6 +1026,17 @@ } } +static const char *ssl_key_load_error(void) +{ + unsigned long err = ERR_peek_error(); + + if (ERR_GET_LIB(err) == ERR_LIB_X509 && + ERR_GET_REASON(err) == X509_R_KEY_VALUES_MISMATCH) + return "Key is for a different cert than ssl_cert"; + else + return ssl_last_error(); +} + static EVP_PKEY * ssl_proxy_load_key(const char *key, const char *password) { @@ -1040,23 +1051,14 @@ dup_password = t_strdup_noconst(password); pkey = PEM_read_bio_PrivateKey(bio, NULL, pem_password_callback, dup_password); - if (pkey == NULL) - i_fatal("Couldn't parse private ssl_key"); + if (pkey == NULL) { + i_fatal("Couldn't parse private ssl_key: %s", + ssl_key_load_error()); + } BIO_free(bio); return pkey; } -static const char *ssl_key_load_error(void) -{ - unsigned long err = ERR_peek_error(); - - if (ERR_GET_LIB(err) == ERR_LIB_X509 && - ERR_GET_REASON(err) == X509_R_KEY_VALUES_MISMATCH) - return "Key is for a different cert than ssl_cert"; - else - return ssl_last_error(); -} - static void ssl_proxy_ctx_use_key(SSL_CTX *ctx, const struct login_settings *set) { EVP_PKEY *pkey; From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: quota: ns=PREFIX setting was ignored when accessing... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/30b0d6b1c581 changeset: 14793:30b0d6b1c581 user: Timo Sirainen date: Mon Jul 16 18:00:21 2012 +0300 description: quota: ns=PREFIX setting was ignored when accessing other users' shared mailboxes. diffstat: src/plugins/quota/quota-private.h | 5 ++++- src/plugins/quota/quota.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diffs (27 lines): diff -r abaafe4cc439 -r 30b0d6b1c581 src/plugins/quota/quota-private.h --- a/src/plugins/quota/quota-private.h Mon Jul 16 17:40:45 2012 +0300 +++ b/src/plugins/quota/quota-private.h Mon Jul 16 18:00:21 2012 +0300 @@ -101,7 +101,10 @@ /* this quota root applies only to this namespace. it may also be a public namespace without an owner. */ struct mail_namespace *ns; - /* this is set in quota init(), because namespaces aren't known yet */ + /* this is set in quota init(), because namespaces aren't known yet. + when accessing shared users the ns_prefix may be non-NULL but + ns=NULL, so when checking if quota root applies only to a specific + namespace use the ns_prefix!=NULL check. */ const char *ns_prefix; /* initially the same as set->default_rule.*_limit, but some backends diff -r abaafe4cc439 -r 30b0d6b1c581 src/plugins/quota/quota.c --- a/src/plugins/quota/quota.c Mon Jul 16 17:40:45 2012 +0300 +++ b/src/plugins/quota/quota.c Mon Jul 16 18:00:21 2012 +0300 @@ -769,7 +769,7 @@ (storage->class_flags & MAIL_STORAGE_CLASS_FLAG_NOQUOTA) != 0) return FALSE; - if (root->ns != NULL) { + if (root->ns_prefix != NULL) { if (root->ns != ns) return FALSE; } else { From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: doveconf: When looking up specific settings, ignore... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/892ab0a8ab9c changeset: 14794:892ab0a8ab9c user: Timo Sirainen date: Mon Jul 16 23:15:19 2012 +0300 description: doveconf: When looking up specific settings, ignore errors found by check functions. diffstat: src/config/doveconf.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diffs (24 lines): diff -r 30b0d6b1c581 -r 892ab0a8ab9c src/config/doveconf.c --- a/src/config/doveconf.c Mon Jul 16 18:00:21 2012 +0300 +++ b/src/config/doveconf.c Mon Jul 16 23:15:19 2012 +0300 @@ -451,7 +451,7 @@ unsigned int len; bool dump_section = FALSE; - ctx = config_dump_human_init("", scope, TRUE); + ctx = config_dump_human_init("", scope, FALSE); config_export_by_filter(ctx->export_ctx, filter); if (config_export_finish(&ctx->export_ctx) < 0) return -1; @@ -693,6 +693,11 @@ ret2 = config_export_finish(&ctx); } else if (setting_name_filters != NULL) { ret2 = 0; + /* ignore settings-check failures in configuration. this allows + using doveconf to lookup settings for things like install or + uninstall scripts where the configuration might + (temporarily) not be fully usable */ + ret = 0; for (i = 0; setting_name_filters[i] != NULL; i++) { if (config_dump_one(&filter, hide_key, scope, setting_name_filters[i]) < 0) From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: master: "/X is no longer mounted" warning now point... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9366cfaefdaa changeset: 14795:9366cfaefdaa user: Timo Sirainen date: Tue Jul 17 14:57:44 2012 +0300 description: master: "/X is no longer mounted" warning now points to wiki page. diffstat: src/master/main.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diffs (13 lines): diff -r 892ab0a8ab9c -r 9366cfaefdaa src/master/main.c --- a/src/master/main.c Mon Jul 16 23:15:19 2012 +0300 +++ b/src/master/main.c Tue Jul 17 14:57:44 2012 +0300 @@ -299,8 +299,7 @@ while ((rec = mountpoint_list_iter_next(iter)) != NULL) { if (MOUNTPOINT_WRONGLY_NOT_MOUNTED(rec)) { i_warning("%s is no longer mounted. " - "If this is intentional, " - "remove it with doveadm mount", + "See http://wiki2.dovecot.org/Mountpoints", rec->mount_path); } } From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: lib-mail: mail_user_hash() has now a faster code pa... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5ad46e104c07 changeset: 14796:5ad46e104c07 user: Timo Sirainen date: Tue Jul 17 15:10:35 2012 +0300 description: lib-mail: mail_user_hash() has now a faster code path for format=%Lu diffstat: src/lib-mail/mail-user-hash.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diffs (16 lines): diff -r 9366cfaefdaa -r 5ad46e104c07 src/lib-mail/mail-user-hash.c --- a/src/lib-mail/mail-user-hash.c Tue Jul 17 14:57:44 2012 +0300 +++ b/src/lib-mail/mail-user-hash.c Tue Jul 17 15:10:35 2012 +0300 @@ -21,6 +21,12 @@ if (strcmp(format, "%u") == 0) { /* fast path */ md5_get_digest(username, strlen(username), md5); + } else if (strcmp(format, "%Lu") == 0) { + /* almost as fast path */ + T_BEGIN { + md5_get_digest(t_str_lcase(username), + strlen(username), md5); + } T_END; } else T_BEGIN { string_t *str = t_str_new(128); From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: director: Changed director_username_hash setting's ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/36c3d44a5ba3 changeset: 14798:36c3d44a5ba3 user: Timo Sirainen date: Tue Jul 17 15:14:21 2012 +0300 description: director: Changed director_username_hash setting's default from %u to %Lu This allows potential trouble when username isn't always lowercased. diffstat: src/director/director-settings.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 0722a06a0d9f -r 36c3d44a5ba3 src/director/director-settings.c --- a/src/director/director-settings.c Tue Jul 17 15:13:21 2012 +0300 +++ b/src/director/director-settings.c Tue Jul 17 15:14:21 2012 +0300 @@ -80,7 +80,7 @@ .director_servers = "", .director_mail_servers = "", - .director_username_hash = "%u", + .director_username_hash = "%Lu", .director_user_expire = 60*15, .director_doveadm_port = 0 }; From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: example-config: Added director_username_hash setting. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0722a06a0d9f changeset: 14797:0722a06a0d9f user: Timo Sirainen date: Tue Jul 17 15:13:21 2012 +0300 description: example-config: Added director_username_hash setting. diffstat: doc/example-config/conf.d/10-director.conf | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r 5ad46e104c07 -r 0722a06a0d9f doc/example-config/conf.d/10-director.conf --- a/doc/example-config/conf.d/10-director.conf Tue Jul 17 15:10:35 2012 +0300 +++ b/doc/example-config/conf.d/10-director.conf Tue Jul 17 15:13:21 2012 +0300 @@ -25,6 +25,11 @@ # If you enable this, you'll also need to add inet_listener for the port. #director_doveadm_port = 0 +# How the username is translated before being hashed. Useful values include +# %Ln if user can log in with or without @domain, %Ld if mailboxes are shared +# within domain. +#director_username_hash = %Lu + # To enable director service, uncomment the modes and assign a port. service director { unix_listener login/director { From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: lib-master: Updated default mountpoint ignore prefi... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/77b52599e883 changeset: 14799:77b52599e883 user: Timo Sirainen date: Tue Jul 17 15:21:32 2012 +0300 description: lib-master: Updated default mountpoint ignore prefix list. diffstat: src/lib-master/mountpoint-list.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 36c3d44a5ba3 -r 77b52599e883 src/lib-master/mountpoint-list.c --- a/src/lib-master/mountpoint-list.c Tue Jul 17 15:14:21 2012 +0300 +++ b/src/lib-master/mountpoint-list.c Tue Jul 17 15:21:32 2012 +0300 @@ -55,6 +55,8 @@ "/media", "/sys", "/proc", + "/var/run", + "/run", NULL }; From dovecot at dovecot.org Fri Aug 10 05:24:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:40 +0300 Subject: dovecot-2.2: login: Don't allow STARTTLS if ssl=no in client's s... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/258c2e231357 changeset: 14800:258c2e231357 user: Timo Sirainen date: Tue Jul 17 15:28:24 2012 +0300 description: login: Don't allow STARTTLS if ssl=no in client's settings, even if ssl=yes globally. diffstat: src/imap-login/client.c | 2 +- src/login-common/client-common.c | 7 ++++++- src/login-common/client-common.h | 1 + src/pop3-login/client-authenticate.c | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diffs (59 lines): diff -r 77b52599e883 -r 258c2e231357 src/imap-login/client.c --- a/src/imap-login/client.c Tue Jul 17 15:21:32 2012 +0300 +++ b/src/imap-login/client.c Tue Jul 17 15:28:24 2012 +0300 @@ -62,7 +62,7 @@ str_append(cap_str, imap_client->set->imap_capability + 1); } - if (ssl_initialized && !client->tls) + if (client_is_tls_enabled(client) && !client->tls) str_append(cap_str, " STARTTLS"); if (client->set->disable_plaintext_auth && !client->secured) str_append(cap_str, " LOGINDISABLED"); diff -r 77b52599e883 -r 258c2e231357 src/login-common/client-common.c --- a/src/login-common/client-common.c Tue Jul 17 15:21:32 2012 +0300 +++ b/src/login-common/client-common.c Tue Jul 17 15:28:24 2012 +0300 @@ -346,7 +346,7 @@ return; } - if (!ssl_initialized) { + if (!client_is_tls_enabled(client)) { client_send_line(client, CLIENT_CMD_REPLY_BAD, "TLS support isn't enabled."); return; @@ -591,6 +591,11 @@ return FALSE; } +bool client_is_tls_enabled(struct client *client) +{ + return ssl_initialized && strcmp(client->set->ssl, "no") != 0; +} + const char *client_get_extra_disconnect_reason(struct client *client) { unsigned int auth_secs = client->auth_first_started == 0 ? 0 : diff -r 77b52599e883 -r 258c2e231357 src/login-common/client-common.h --- a/src/login-common/client-common.h Tue Jul 17 15:21:32 2012 +0300 +++ b/src/login-common/client-common.h Tue Jul 17 15:28:24 2012 +0300 @@ -168,6 +168,7 @@ const char *client_get_extra_disconnect_reason(struct client *client); bool client_is_trusted(struct client *client); void client_auth_failed(struct client *client); +bool client_is_tls_enabled(struct client *client); const char *client_get_session_id(struct client *client); bool client_read(struct client *client); diff -r 77b52599e883 -r 258c2e231357 src/pop3-login/client-authenticate.c --- a/src/pop3-login/client-authenticate.c Tue Jul 17 15:21:32 2012 +0300 +++ b/src/pop3-login/client-authenticate.c Tue Jul 17 15:28:24 2012 +0300 @@ -33,7 +33,7 @@ str_append(str, "+OK\r\n"); str_append(str, capability_string); - if (ssl_initialized && !client->common.tls) + if (client_is_tls_enabled(&client->common) && !client->common.tls) str_append(str, "STLS\r\n"); if (!client->common.set->disable_plaintext_auth || client->common.secured) From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: doc: Install mkcert.sh, dovecot-openssl.cnf and sol... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d01a06d821cf changeset: 14801:d01a06d821cf user: Timo Sirainen date: Tue Jul 17 15:31:03 2012 +0300 description: doc: Install mkcert.sh, dovecot-openssl.cnf and solr-schema.xml files. diffstat: doc/Makefile.am | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diffs (23 lines): diff -r 258c2e231357 -r d01a06d821cf doc/Makefile.am --- a/doc/Makefile.am Tue Jul 17 15:28:24 2012 +0300 +++ b/doc/Makefile.am Tue Jul 17 15:31:03 2012 +0300 @@ -7,7 +7,10 @@ docfiles = \ documentation.txt \ securecoding.txt \ - thread-refs.txt + thread-refs.txt \ + mkcert.sh \ + dovecot-openssl.cnf \ + solr-schema.xml if BUILD_DOCS doc_DATA = $(docfiles) @@ -15,7 +18,4 @@ EXTRA_DIST = \ dovecot-initd.sh \ - mkcert.sh \ - dovecot-openssl.cnf \ - solr-schema.xml \ $(docfiles) From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: config: Fixed error reporting when reloading settin... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/56ef4e70b1a9 changeset: 14802:56ef4e70b1a9 user: Timo Sirainen date: Tue Jul 17 15:44:36 2012 +0300 description: config: Fixed error reporting when reloading settings for master process fails. diffstat: src/config/config-connection.c | 2 +- src/lib-settings/settings-parser.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletions(-) diffs (24 lines): diff -r d01a06d821cf -r 56ef4e70b1a9 src/config/config-connection.c --- a/src/config/config-connection.c Tue Jul 17 15:31:03 2012 +0300 +++ b/src/config/config-connection.c Tue Jul 17 15:44:36 2012 +0300 @@ -100,7 +100,7 @@ path = master_service_get_config_path(master_service); if (config_parse_file(path, TRUE, "", &error) <= 0) { o_stream_send_str(conn->output, - t_strconcat("ERROR ", error, "\n", NULL)); + t_strconcat("\nERROR ", error, "\n", NULL)); config_connection_destroy(conn); return -1; } diff -r d01a06d821cf -r 56ef4e70b1a9 src/lib-settings/settings-parser.c --- a/src/lib-settings/settings-parser.c Tue Jul 17 15:31:03 2012 +0300 +++ b/src/lib-settings/settings-parser.c Tue Jul 17 15:44:36 2012 +0300 @@ -945,6 +945,8 @@ switch (ret) { case -1: + if (ctx->error != NULL) + break; if (input->stream_errno != 0) { ctx->error = p_strdup_printf(ctx->parser_pool, "read() failed: %m"); From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: auth: GSSAPI RFC compliancy fixes. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ced6a796f56d changeset: 14803:ced6a796f56d user: Timo Sirainen date: Tue Jul 17 16:17:40 2012 +0300 description: auth: GSSAPI RFC compliancy fixes. Patch by Ben Morrow: The first problem is that, because of the way the client invokes libsasl, it sends a GSSAPI request which does not ask for mutual authentication. This means that on the server gss_accept_sec_context returns GSS_S_COMPLETE with a zero-length output token. Dovecot currently sends this to the client as a zero-length continuation response, but this is incorrect according to RFC 4752: what it ought to do instead is proceed straight to the security layer negotiations, and send a gss_wrap packet. The second is that Cyrus sends an empty authz identity; that is, the security layer negotiation packet, when gss_unwrapped, is exactly 4 bytes long. Dovecot objects to this, but in RFC 4422 this is explicitly allowed, and means the authz identity is identical to the authn identity. diffstat: src/auth/mech-gssapi.c | 58 +++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 46 insertions(+), 12 deletions(-) diffs (96 lines): diff -r 56ef4e70b1a9 -r ced6a796f56d src/auth/mech-gssapi.c --- a/src/auth/mech-gssapi.c Tue Jul 17 15:44:36 2012 +0300 +++ b/src/auth/mech-gssapi.c Tue Jul 17 16:17:40 2012 +0300 @@ -78,6 +78,9 @@ static gss_OID_desc mech_gssapi_krb5_oid = { 9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" }; +static int +mech_gssapi_wrap(struct gssapi_auth_request *request, gss_buffer_desc inbuf); + static void mech_gssapi_log_error(struct auth_request *request, OM_uint32 status_value, int status_type, const char *description) @@ -214,6 +217,21 @@ return name; } +static gss_name_t +duplicate_name(struct auth_request *request, gss_name_t old) +{ + OM_uint32 major_status, minor_status; + gss_name_t new; + + major_status = gss_duplicate_name(&minor_status, old, &new); + if (GSS_ERROR(major_status)) { + mech_gssapi_log_error(request, major_status, GSS_C_GSS_CODE, + "gss_duplicate_name"); + return GSS_C_NO_NAME; + } + return new; +} + static bool data_has_nuls(const void *data, unsigned int len) { const unsigned char *c = data; @@ -328,9 +346,15 @@ } if (ret == 0) { - auth_request_handler_reply_continue(auth_request, - output_token.value, - output_token.length); + if (output_token.length > 0) { + auth_request_handler_reply_continue(auth_request, + output_token.value, + output_token.length); + } else { + /* If there is no output token, go straight to wrap, + which is expecting an empty input token. */ + ret = mech_gssapi_wrap(request, output_token); + } } (void)gss_release_buffer(&minor_status, &output_token); return ret; @@ -510,22 +534,32 @@ /* outbuf[0] contains bitmask for selected security layer, outbuf[1..3] contains maximum output_message size */ - if (outbuf.length <= 4) { + if (outbuf.length < 4) { auth_request_log_error(auth_request, "gssapi", "Invalid response length"); return -1; } - name = (unsigned char *)outbuf.value + 4; - name_len = outbuf.length - 4; - if (data_has_nuls(name, name_len)) { - auth_request_log_info(auth_request, "gssapi", - "authz_name has NULs"); - return -1; + if (outbuf.length > 4) { + name = (unsigned char *)outbuf.value + 4; + name_len = outbuf.length - 4; + + if (data_has_nuls(name, name_len)) { + auth_request_log_info(auth_request, "gssapi", + "authz_name has NULs"); + return -1; + } + + login_user = p_strndup(auth_request->pool, name, name_len); + request->authz_name = import_name(auth_request, name, name_len); + } else { + request->authz_name = duplicate_name(auth_request, + request->authn_name); + if (get_display_name(auth_request, request->authz_name, + NULL, &login_user) < 0) + return -1; } - login_user = p_strndup(auth_request->pool, name, name_len); - request->authz_name = import_name(auth_request, name, name_len); if (request->authz_name == GSS_C_NO_NAME) { auth_request_log_info(auth_request, "gssapi", "no authz_name"); return -1; From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: auth: Fixed error handling in GSSAPI when __gss_use... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/35ae9569de5a changeset: 14804:35ae9569de5a user: Timo Sirainen date: Tue Jul 17 16:20:20 2012 +0300 description: auth: Fixed error handling in GSSAPI when __gss_userok() was used. An invalid username would have been treated as successful and auth process probably would have crashed. diffstat: src/auth/mech-gssapi.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r ced6a796f56d -r 35ae9569de5a src/auth/mech-gssapi.c --- a/src/auth/mech-gssapi.c Tue Jul 17 16:17:40 2012 +0300 +++ b/src/auth/mech-gssapi.c Tue Jul 17 16:20:20 2012 +0300 @@ -416,8 +416,8 @@ bool ret = FALSE; /* Parse out the principal's username */ - if (!get_display_name(&request->auth_request, name, &name_type, - &princ_display_name) < 0) + if (get_display_name(&request->auth_request, name, &name_type, + &princ_display_name) < 0) return FALSE; if (!mech_gssapi_oid_cmp(name_type, GSS_KRB5_NT_PRINCIPAL_NAME) && From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: quota: Added quota_ignore_save_errors plugin setting. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a946a37af082 changeset: 14805:a946a37af082 user: Timo Sirainen date: Mon Jul 23 14:23:32 2012 +0300 description: quota: Added quota_ignore_save_errors plugin setting. If mail is being saved but current quota usage lookup fails with internal error, save the mail anyway instead of failing. diffstat: src/plugins/quota/quota-private.h | 1 + src/plugins/quota/quota-storage.c | 5 +++-- src/plugins/quota/quota.c | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diffs (45 lines): diff -r 35ae9569de5a -r a946a37af082 src/plugins/quota/quota-private.h --- a/src/plugins/quota/quota-private.h Tue Jul 17 16:20:20 2012 +0300 +++ b/src/plugins/quota/quota-private.h Mon Jul 23 14:23:32 2012 +0300 @@ -25,6 +25,7 @@ uoff_t size, bool *too_large_r); const char *quota_exceeded_msg; + unsigned int ignore_save_errors:1; unsigned int debug:1; }; diff -r 35ae9569de5a -r a946a37af082 src/plugins/quota/quota-storage.c --- a/src/plugins/quota/quota-storage.c Tue Jul 17 16:20:20 2012 +0300 +++ b/src/plugins/quota/quota-storage.c Mon Jul 23 14:23:32 2012 +0300 @@ -147,7 +147,7 @@ } else { mail_storage_set_critical(t->box->storage, "Internal quota calculation error"); - return -1; + return qt->quota->set->ignore_save_errors ? 0 : -1; } } @@ -204,7 +204,8 @@ } else if (ret < 0) { mail_storage_set_critical(t->box->storage, "Internal quota calculation error"); - return -1; + if (!qt->quota->set->ignore_save_errors) + return -1; } } diff -r 35ae9569de5a -r a946a37af082 src/plugins/quota/quota.c --- a/src/plugins/quota/quota.c Tue Jul 17 16:20:20 2012 +0300 +++ b/src/plugins/quota/quota.c Mon Jul 23 14:23:32 2012 +0300 @@ -195,6 +195,8 @@ quota_set->debug = user->mail_debug; quota_set->quota_exceeded_msg = mail_user_plugin_getenv(user, "quota_exceeded_message"); + quota_set->ignore_save_errors = + mail_user_plugin_getenv(user, "quota_ignore_save_errors") != NULL; if (quota_set->quota_exceeded_msg == NULL) quota_set->quota_exceeded_msg = DEFAULT_QUOTA_EXCEEDED_MSG; From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: lib-dict: Allow backends to have iteration methods ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/522e03dd4268 changeset: 14806:522e03dd4268 user: Timo Sirainen date: Mon Jul 23 17:23:37 2012 +0300 description: lib-dict: Allow backends to have iteration methods as NULL if they don't support it. diffstat: src/lib-dict/dict.c | 12 ++++++++++-- 1 files changed, 10 insertions(+), 2 deletions(-) diffs (42 lines): diff -r a946a37af082 -r 522e03dd4268 src/lib-dict/dict.c --- a/src/lib-dict/dict.c Mon Jul 23 14:23:32 2012 +0300 +++ b/src/lib-dict/dict.c Mon Jul 23 17:23:37 2012 +0300 @@ -7,6 +7,7 @@ #include "dict-private.h" static ARRAY_DEFINE(dict_drivers, struct dict *); +static struct dict_iterate_context dict_iter_unsupported; static struct dict *dict_driver_lookup(const char *name) { @@ -136,13 +137,19 @@ i_assert(paths[0] != NULL); for (i = 0; paths[i] != NULL; i++) i_assert(dict_key_prefix_is_valid(paths[i])); + if (dict->v.iterate_init == NULL) { + /* not supported by backend */ + i_error("%s: dict iteration not supported", dict->name); + return &dict_iter_unsupported; + } return dict->v.iterate_init(dict, paths, flags); } bool dict_iterate(struct dict_iterate_context *ctx, const char **key_r, const char **value_r) { - return ctx->dict->v.iterate(ctx, key_r, value_r); + return ctx == &dict_iter_unsupported ? FALSE : + ctx->dict->v.iterate(ctx, key_r, value_r); } int dict_iterate_deinit(struct dict_iterate_context **_ctx) @@ -150,7 +157,8 @@ struct dict_iterate_context *ctx = *_ctx; *_ctx = NULL; - return ctx->dict->v.iterate_deinit(ctx); + return ctx == &dict_iter_unsupported ? -1 : + ctx->dict->v.iterate_deinit(ctx); } struct dict_transaction_context *dict_transaction_begin(struct dict *dict) From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: redis dict: Added support for set/unset/atomic_inc. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/54e2556f87ea changeset: 14807:54e2556f87ea user: Timo Sirainen date: Mon Jul 23 17:24:13 2012 +0300 description: redis dict: Added support for set/unset/atomic_inc. This allows using Redis as dict quota backend. diffstat: src/lib-dict/dict-redis.c | 504 +++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 451 insertions(+), 53 deletions(-) diffs (truncated from 632 to 300 lines): diff -r 522e03dd4268 -r 54e2556f87ea src/lib-dict/dict-redis.c --- a/src/lib-dict/dict-redis.c Mon Jul 23 17:23:37 2012 +0300 +++ b/src/lib-dict/dict-redis.c Mon Jul 23 17:24:13 2012 +0300 @@ -1,6 +1,7 @@ /* Copyright (c) 2008-2012 Dovecot authors, see the included COPYING redis */ #include "lib.h" +#include "array.h" #include "str.h" #include "istream.h" #include "ostream.h" @@ -9,6 +10,20 @@ #define REDIS_DEFAULT_PORT 6379 #define REDIS_DEFAULT_LOOKUP_TIMEOUT_MSECS (1000*30) +#define DICT_USERNAME_SEPARATOR '/' + +enum redis_input_state { + /* expecting $-1 / $ followed by GET reply */ + REDIS_INPUT_STATE_GET, + /* expecting +QUEUED */ + REDIS_INPUT_STATE_MULTI, + /* expecting +OK reply for DISCARD */ + REDIS_INPUT_STATE_DISCARD, + /* expecting * */ + REDIS_INPUT_STATE_EXEC, + /* expecting EXEC reply */ + REDIS_INPUT_STATE_EXEC_REPLY +}; struct redis_connection { struct connection conn; @@ -20,35 +35,208 @@ bool value_received; }; +struct redis_dict_reply { + unsigned int reply_count; + dict_transaction_commit_callback_t *callback; + void *context; +}; + struct redis_dict { struct dict dict; struct ip_addr ip; + char *username, *key_prefix; unsigned int port; unsigned int timeout_msecs; struct ioloop *ioloop; struct redis_connection conn; + + ARRAY_DEFINE(input_states, enum redis_input_state); + ARRAY_DEFINE(replies, struct redis_dict_reply); + bool connected; + bool transaction_open; +}; + +struct redis_dict_transaction_context { + struct dict_transaction_context ctx; + unsigned int cmd_count; + bool failed; }; static struct connection_list *redis_connections; +static void +redis_input_state_add(struct redis_dict *dict, enum redis_input_state state) +{ + array_append(&dict->input_states, &state, 1); +} + +static void redis_input_state_remove(struct redis_dict *dict) +{ + array_delete(&dict->input_states, 0, 1); +} + static void redis_conn_destroy(struct connection *_conn) { struct redis_connection *conn = (struct redis_connection *)_conn; + const struct redis_dict_reply *reply; conn->dict->connected = FALSE; connection_disconnect(_conn); + + array_foreach(&conn->dict->replies, reply) { + if (reply->callback != NULL) + reply->callback(-1, reply->context); + } + array_clear(&conn->dict->replies); + array_clear(&conn->dict->input_states); + if (conn->dict->ioloop != NULL) io_loop_stop(conn->dict->ioloop); } +static void redis_wait(struct redis_dict *dict) +{ + struct ioloop *prev_ioloop = current_ioloop; + + i_assert(dict->ioloop == NULL); + + dict->ioloop = io_loop_create(); + connection_switch_ioloop(&dict->conn.conn); + + do { + io_loop_run(dict->ioloop); + } while (array_count(&dict->input_states) > 0); + + current_ioloop = prev_ioloop; + connection_switch_ioloop(&dict->conn.conn); + current_ioloop = dict->ioloop; + io_loop_destroy(&dict->ioloop); +} + +static void redis_input_get(struct redis_connection *conn) +{ + const unsigned char *data; + size_t size; + const char *line; + + if (conn->bytes_left == 0) { + /* read the size first */ + line = i_stream_next_line(conn->conn.input); + if (line == NULL) + return; + if (strcmp(line, "$-1") == 0) { + conn->value_received = TRUE; + conn->value_not_found = TRUE; + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); + redis_input_state_remove(conn->dict); + return; + } + if (line[0] != '$' || str_to_uint(line+1, &conn->bytes_left) < 0) { + i_error("redis: Unexpected input (wanted $size): %s", + line); + redis_conn_destroy(&conn->conn); + return; + } + conn->bytes_left += 2; /* include trailing CRLF */ + } + + data = i_stream_get_data(conn->conn.input, &size); + if (size > conn->bytes_left) + size = conn->bytes_left; + str_append_n(conn->last_reply, data, size); + + conn->bytes_left -= size; + i_stream_skip(conn->conn.input, size); + + if (conn->bytes_left == 0) { + /* reply fully read - drop trailing CRLF */ + conn->value_received = TRUE; + str_truncate(conn->last_reply, str_len(conn->last_reply)-2); + + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); + redis_input_state_remove(conn->dict); + } +} + +static int redis_conn_input_more(struct redis_connection *conn) +{ + struct redis_dict *dict = conn->dict; + struct redis_dict_reply *reply; + const enum redis_input_state *states; + enum redis_input_state state; + unsigned int count, num_replies; + const char *line; + + states = array_get(&dict->input_states, &count); + if (count == 0) { + line = i_stream_next_line(conn->conn.input); + if (line == NULL) line = ""; + i_error("redis: Unexpected input (expected nothing): %s", + line); + return -1; + } + state = states[0]; + if (state == REDIS_INPUT_STATE_GET) { + redis_input_get(conn); + return 1; + } + + line = i_stream_next_line(conn->conn.input); + if (line == NULL) + return 0; + + redis_input_state_remove(dict); + switch (state) { + case REDIS_INPUT_STATE_GET: + i_unreached(); + case REDIS_INPUT_STATE_MULTI: + case REDIS_INPUT_STATE_DISCARD: + if (line[0] != '+') + break; + return 1; + case REDIS_INPUT_STATE_EXEC: + if (line[0] != '*' || str_to_uint(line+1, &num_replies) < 0) + break; + + reply = array_idx_modifiable(&dict->replies, 0); + i_assert(reply->reply_count > 0); + if (reply->reply_count != num_replies) { + i_error("redis: EXEC expected %u replies, not %u", + reply->reply_count, num_replies); + return -1; + } + return 1; + case REDIS_INPUT_STATE_EXEC_REPLY: + if (*line != '+' && *line != ':') + break; + /* success, just ignore the actual reply */ + reply = array_idx_modifiable(&dict->replies, 0); + i_assert(reply->reply_count > 0); + if (--reply->reply_count == 0) { + if (reply->callback != NULL) + reply->callback(1, reply->context); + array_delete(&dict->replies, 0, 1); + /* if we're running in a dict-ioloop, we're handling a + synchronous commit and need to stop now */ + if (array_count(&dict->replies) == 0 && + conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); + } + return 1; + } + i_error("redis: Unexpected input (state=%d): %s", state, line); + return -1; +} + static void redis_conn_input(struct connection *_conn) { struct redis_connection *conn = (struct redis_connection *)_conn; - const unsigned char *data; size_t size; - const char *line; + int ret; switch (i_stream_read(_conn->input)) { case 0: @@ -60,42 +248,13 @@ break; } - if (conn->bytes_left == 0) { - /* read the size first */ - line = i_stream_next_line(_conn->input); - if (line == NULL) - return; - if (strcmp(line, "$-1") == 0) { - conn->value_received = TRUE; - conn->value_not_found = TRUE; - if (conn->dict->ioloop != NULL) - io_loop_stop(conn->dict->ioloop); - return; - } - if (line[0] != '$' || str_to_uint(line+1, &conn->bytes_left) < 0) { - i_error("redis: Unexpected input (wanted $size): %s", - line); - redis_conn_destroy(_conn); - return; - } - conn->bytes_left += 2; /* include trailing CRLF */ + while ((ret = redis_conn_input_more(conn)) > 0) { + i_stream_get_data(_conn->input, &size); + if (size == 0) + break; } - - data = i_stream_get_data(_conn->input, &size); - if (size > conn->bytes_left) - size = conn->bytes_left; - str_append_n(conn->last_reply, data, size); - - conn->bytes_left -= size; - i_stream_skip(_conn->input, size); - - if (conn->bytes_left == 0) { - /* drop trailing CRLF */ - conn->value_received = TRUE; - str_truncate(conn->last_reply, str_len(conn->last_reply)-2); - if (conn->dict->ioloop != NULL) - io_loop_stop(conn->dict->ioloop); - } + if (ret < 0) + redis_conn_destroy(_conn); } static void redis_conn_connected(struct connection *_conn) @@ -124,10 +283,30 @@ .connected = redis_conn_connected }; +static const char *redis_escape_username(const char *username) +{ + const char *p; + string_t *str = t_str_new(64); From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: lib-dict: Added memcached backend using its binary ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b6df5871632a changeset: 14808:b6df5871632a user: Timo Sirainen date: Mon Jul 23 21:43:39 2012 +0300 description: lib-dict: Added memcached backend using its binary protocol. diffstat: src/lib-dict/Makefile.am | 1 + src/lib-dict/dict-memcached.c | 376 ++++++++++++++++++++++++++++++++++++++++++ src/lib-dict/dict-private.h | 1 + src/lib-dict/dict.c | 2 + src/lib-dict/test-dict.c | 1 + 5 files changed, 381 insertions(+), 0 deletions(-) diffs (truncated from 432 to 300 lines): diff -r 54e2556f87ea -r b6df5871632a src/lib-dict/Makefile.am --- a/src/lib-dict/Makefile.am Mon Jul 23 17:24:13 2012 +0300 +++ b/src/lib-dict/Makefile.am Mon Jul 23 21:43:39 2012 +0300 @@ -14,6 +14,7 @@ dict.c \ dict-client.c \ dict-file.c \ + dict-memcached.c \ dict-redis.c libdict_la_SOURCES = \ diff -r 54e2556f87ea -r b6df5871632a src/lib-dict/dict-memcached.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-dict/dict-memcached.c Mon Jul 23 21:43:39 2012 +0300 @@ -0,0 +1,376 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING memcached */ + +#include "lib.h" +#include "array.h" +#include "str.h" +#include "istream.h" +#include "ostream.h" +#include "connection.h" +#include "dict-private.h" + +#define MEMCACHED_DEFAULT_PORT 11211 +#define MEMCACHED_DEFAULT_LOOKUP_TIMEOUT_MSECS (1000*30) + +/* we need only very limited memcached functionality, so just define the binary + protocol ourself instead requiring protocol_binary.h */ +#define MEMCACHED_REQUEST_HDR_MAGIC 0x80 +#define MEMCACHED_REPLY_HDR_MAGIC 0x81 + +#define MEMCACHED_REQUEST_HDR_LENGTH 24 +#define MEMCACHED_REPLY_HDR_LENGTH 24 + +#define MEMCACHED_CMD_GET 0x00 + +#define MEMCACHED_DATA_TYPE_RAW 0x00 + +enum memcached_response { + MEMCACHED_RESPONSE_OK = 0x0000, + MEMCACHED_RESPONSE_NOTFOUND = 0x0001, + MEMCACHED_RESPONSE_INTERNALERROR= 0x0084, + MEMCACHED_RESPONSE_BUSY = 0x0085, + MEMCACHED_RESPONSE_TEMPFAILURE = 0x0086 +}; + +struct memcached_connection { + struct connection conn; + struct memcached_dict *dict; + + buffer_t *cmd; + struct { + const unsigned char *value; + unsigned int value_len; + enum memcached_response status; + bool reply_received; + } reply; +}; + +struct memcached_dict { + struct dict dict; + struct ip_addr ip; + char *key_prefix; + unsigned int port; + unsigned int timeout_msecs; + + struct ioloop *ioloop; + struct memcached_connection conn; + + bool connected; +}; + +static struct connection_list *memcached_connections; + +static void memcached_conn_destroy(struct connection *_conn) +{ + struct memcached_connection *conn = (struct memcached_connection *)_conn; + + conn->dict->connected = FALSE; + connection_disconnect(_conn); + + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); +} + +static int memcached_input_get(struct memcached_connection *conn) +{ + const unsigned char *data; + size_t size; + uint32_t body_len, value_pos; + uint16_t key_len, key_pos, status; + uint8_t extras_len, data_type; + + data = i_stream_get_data(conn->conn.input, &size); + if (size < MEMCACHED_REPLY_HDR_LENGTH) + return 0; + + if (data[0] != MEMCACHED_REPLY_HDR_MAGIC) { + i_error("memcached: Invalid reply magic: %u != %u", + data[0], MEMCACHED_REPLY_HDR_MAGIC); + return -1; + } + memcpy(&body_len, data+8, 4); body_len = ntohl(body_len); + body_len += MEMCACHED_REPLY_HDR_LENGTH; + if (size < body_len) { + /* we haven't read the whole response yet */ + return 0; + } + + memcpy(&key_len, data+2, 2); key_len = ntohs(key_len); + extras_len = data[4]; + data_type = data[5]; + memcpy(&status, data+6, 2); status = ntohs(status); + if (data_type != MEMCACHED_DATA_TYPE_RAW) { + i_error("memcached: Unsupported data type: %u != %u", + data[0], MEMCACHED_DATA_TYPE_RAW); + return -1; + } + + key_pos = MEMCACHED_REPLY_HDR_LENGTH + extras_len; + value_pos = key_pos + key_len; + if (value_pos > body_len) { + i_error("memcached: Invalid key/extras lengths"); + return -1; + } + conn->reply.value = data + value_pos; + conn->reply.value_len = body_len - value_pos; + conn->reply.status = status; + + i_stream_skip(conn->conn.input, body_len); + conn->reply.reply_received = TRUE; + + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); + return 1; +} + +static void memcached_conn_input(struct connection *_conn) +{ + struct memcached_connection *conn = (struct memcached_connection *)_conn; + + switch (i_stream_read(_conn->input)) { + case 0: + return; + case -1: + memcached_conn_destroy(_conn); + return; + default: + break; + } + + if (memcached_input_get(conn) < 0) + memcached_conn_destroy(_conn); +} + +static void memcached_conn_connected(struct connection *_conn) +{ + struct memcached_connection *conn = (struct memcached_connection *)_conn; + + if ((errno = net_geterror(_conn->fd_in)) != 0) { + i_error("memcached: connect(%s, %u) failed: %m", + net_ip2addr(&conn->dict->ip), conn->dict->port); + } else { + conn->dict->connected = TRUE; + } + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); +} + +static const struct connection_settings memcached_conn_set = { + .input_max_size = (size_t)-1, + .output_max_size = (size_t)-1, + .client = TRUE +}; + +static const struct connection_vfuncs memcached_conn_vfuncs = { + .destroy = memcached_conn_destroy, + .input = memcached_conn_input, + .connected = memcached_conn_connected +}; + +static struct dict * +memcached_dict_init(struct dict *driver, const char *uri, + enum dict_data_type value_type ATTR_UNUSED, + const char *username ATTR_UNUSED, + const char *base_dir ATTR_UNUSED) +{ + struct memcached_dict *dict; + const char *const *args; + + if (memcached_connections == NULL) { + memcached_connections = + connection_list_init(&memcached_conn_set, + &memcached_conn_vfuncs); + } + + dict = i_new(struct memcached_dict, 1); + if (net_addr2ip("127.0.0.1", &dict->ip) < 0) + i_unreached(); + dict->port = MEMCACHED_DEFAULT_PORT; + dict->timeout_msecs = MEMCACHED_DEFAULT_LOOKUP_TIMEOUT_MSECS; + dict->key_prefix = i_strdup(""); + + args = t_strsplit(uri, ":"); + for (; *args != NULL; args++) { + if (strncmp(*args, "host=", 5) == 0) { + if (net_addr2ip(*args+5, &dict->ip) < 0) + i_error("Invalid IP: %s", *args+5); + } else if (strncmp(*args, "port=", 5) == 0) { + if (str_to_uint(*args+5, &dict->port) < 0) + i_error("Invalid port: %s", *args+5); + } else if (strncmp(*args, "prefix=", 7) == 0) { + i_free(dict->key_prefix); + dict->key_prefix = i_strdup(*args + 7); + } else if (strncmp(*args, "timeout_msecs=", 14) == 0) { + if (str_to_uint(*args+14, &dict->timeout_msecs) < 0) + i_error("Invalid timeout_msecs: %s", *args+14); + } else { + i_error("Unknown parameter: %s", *args); + } + } + connection_init_client_ip(memcached_connections, &dict->conn.conn, + &dict->ip, dict->port); + + dict->dict = *driver; + dict->conn.cmd = buffer_create_dynamic(default_pool, 256); + dict->conn.dict = dict; + return &dict->dict; +} + +static void memcached_dict_deinit(struct dict *_dict) +{ + struct memcached_dict *dict = (struct memcached_dict *)_dict; + + connection_deinit(&dict->conn.conn); + buffer_free(&dict->conn.cmd); + i_free(dict->key_prefix); + i_free(dict); + + if (memcached_connections->connections == NULL) + connection_list_deinit(&memcached_connections); +} + +static void memcached_dict_lookup_timeout(struct memcached_dict *dict) +{ + i_error("memcached: Lookup timed out in %u.%03u secs", + dict->timeout_msecs/1000, dict->timeout_msecs%1000); + io_loop_stop(dict->ioloop); +} + +static void memcached_add_header(buffer_t *buf, unsigned int key_len) +{ + uint32_t body_len = htonl(key_len); + + i_assert(key_len <= 0xffff); + + buffer_append_c(buf, MEMCACHED_REQUEST_HDR_MAGIC); + buffer_append_c(buf, MEMCACHED_CMD_GET); + buffer_append_c(buf, (key_len >> 8) & 0xff); + buffer_append_c(buf, key_len & 0xff); + buffer_append_c(buf, 0); /* extras length */ + buffer_append_c(buf, MEMCACHED_DATA_TYPE_RAW); + buffer_append_zero(buf, 2); /* vbucket id - we probably don't care? */ + buffer_append(buf, &body_len, sizeof(body_len)); + buffer_append_zero(buf, 4+8); /* opaque + cas */ + i_assert(buf->used == MEMCACHED_REQUEST_HDR_LENGTH); +} + +static int +memcached_dict_lookup_real(struct memcached_dict *dict, pool_t pool, + const char *key, const char **value_r) +{ + struct ioloop *prev_ioloop = current_ioloop; + struct timeout *to; + unsigned int key_len; + + if (strncmp(key, DICT_PATH_SHARED, strlen(DICT_PATH_SHARED)) == 0) + key += strlen(DICT_PATH_SHARED); + else { + i_error("memcached: Only shared keys supported currently"); + return -1; + } + if (*dict->key_prefix != '\0') + key = t_strconcat(dict->key_prefix, key, NULL); + key_len = strlen(key); + if (key_len > 0xffff) { + i_error("memcached: Key is too long (%u bytes): %s", + key_len, key); + return -1; + } + + i_assert(dict->ioloop == NULL); + + dict->ioloop = io_loop_create(); + connection_switch_ioloop(&dict->conn.conn); + + if (dict->conn.conn.fd_in == -1 && + connection_client_connect(&dict->conn.conn) < 0) { From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: lib-charset: Removed unnecessary buffer size increa... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cbd2b321a68f changeset: 14810:cbd2b321a68f user: Timo Sirainen date: Sat Jul 28 19:33:14 2012 +0300 description: lib-charset: Removed unnecessary buffer size increases, which only caused out-of-memory errors. diffstat: src/lib-charset/charset-iconv.c | 13 +------------ 1 files changed, 1 insertions(+), 12 deletions(-) diffs (31 lines): diff -r 4b505b1c4c5b -r cbd2b321a68f src/lib-charset/charset-iconv.c --- a/src/lib-charset/charset-iconv.c Wed Jul 25 15:39:14 2012 +0300 +++ b/src/lib-charset/charset-iconv.c Sat Jul 28 19:33:14 2012 +0300 @@ -120,9 +120,8 @@ charset_to_utf8(struct charset_translation *t, const unsigned char *src, size_t *src_size, buffer_t *dest) { - bool dtcase = (t->flags & CHARSET_FLAG_DECOMP_TITLECASE) != 0; enum charset_result result; - size_t pos, used, size, prev_pos = 0, prev_used = 0; + size_t pos, size; size_t prev_invalid_pos = (size_t)-1; bool ret; @@ -141,16 +140,6 @@ prev_invalid_pos = dest->used; } pos++; - } else if (!dtcase) { - /* force buffer to grow */ - used = dest->used; - size = buffer_get_size(dest) - used + 1; - (void)buffer_append_space_unsafe(dest, size); - buffer_set_used_size(dest, used); - } else { - i_assert(dest->used != prev_used || pos != prev_pos); - prev_pos = pos; - prev_used = dest->used; } } From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: pop3c: If POP3 server doesn't support CAPA command,... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4b505b1c4c5b changeset: 14809:4b505b1c4c5b user: Timo Sirainen date: Wed Jul 25 15:39:14 2012 +0300 description: pop3c: If POP3 server doesn't support CAPA command, try to use UIDL anyway. diffstat: src/lib-storage/index/pop3c/pop3c-client.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diffs (19 lines): diff -r b6df5871632a -r 4b505b1c4c5b src/lib-storage/index/pop3c/pop3c-client.c --- a/src/lib-storage/index/pop3c/pop3c-client.c Mon Jul 23 21:43:39 2012 +0300 +++ b/src/lib-storage/index/pop3c/pop3c-client.c Wed Jul 25 15:39:14 2012 +0300 @@ -348,8 +348,13 @@ client->state = POP3C_CLIENT_STATE_CAPA; break; case POP3C_CLIENT_STATE_CAPA: - if (strncasecmp(line, "-ERR", 4) == 0 || - strcmp(line, ".") == 0) { + if (strncasecmp(line, "-ERR", 4) == 0) { + /* CAPA command not supported. some commands still + support UIDL though. */ + client->capabilities |= POP3C_CAPABILITY_UIDL; + pop3c_client_login_finished(client); + break; + } else if (strcmp(line, ".") == 0) { pop3c_client_login_finished(client); break; } From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: verbose_ssl=yes: Log debug messages with debug leve... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/eec5e1f03fff changeset: 14811:eec5e1f03fff user: Timo Sirainen date: Sat Jul 28 19:56:07 2012 +0300 description: verbose_ssl=yes: Log debug messages with debug level instead of as warnings. diffstat: src/lib-ssl-iostream/iostream-openssl.c | 6 +++--- src/login-common/ssl-proxy-openssl.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diffs (32 lines): diff -r cbd2b321a68f -r eec5e1f03fff src/lib-ssl-iostream/iostream-openssl.c --- a/src/lib-ssl-iostream/iostream-openssl.c Sat Jul 28 19:33:14 2012 +0300 +++ b/src/lib-ssl-iostream/iostream-openssl.c Sat Jul 28 19:56:07 2012 +0300 @@ -24,9 +24,9 @@ i_warning("%s: SSL failed: where=0x%x: %s", ssl_io->source, where, SSL_state_string_long(ssl)); } else { - i_warning("%s: SSL: where=0x%x, ret=%d: %s", - ssl_io->source, where, ret, - SSL_state_string_long(ssl)); + i_debug("%s: SSL: where=0x%x, ret=%d: %s", + ssl_io->source, where, ret, + SSL_state_string_long(ssl)); } } diff -r cbd2b321a68f -r eec5e1f03fff src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Sat Jul 28 19:33:14 2012 +0300 +++ b/src/login-common/ssl-proxy-openssl.c Sat Jul 28 19:56:07 2012 +0300 @@ -846,9 +846,9 @@ where, SSL_state_string_long(ssl), net_ip2addr(&proxy->ip)); } else { - i_warning("SSL: where=0x%x, ret=%d: %s [%s]", - where, ret, SSL_state_string_long(ssl), - net_ip2addr(&proxy->ip)); + i_info("SSL: where=0x%x, ret=%d: %s [%s]", + where, ret, SSL_state_string_long(ssl), + net_ip2addr(&proxy->ip)); } } From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: fts-lucene: Fixed handling non-lowercase SEARCH HEA... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/77f2510bb009 changeset: 14813:77f2510bb009 user: Timo Sirainen date: Sat Jul 28 20:00:32 2012 +0300 description: fts-lucene: Fixed handling non-lowercase SEARCH HEADER FROM/TO/SUBJECT/CC/BCC Based on patch by Matthew Powell. diffstat: src/plugins/fts-lucene/lucene-wrapper.cc | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 4ddb9117a178 -r 77f2510bb009 src/plugins/fts-lucene/lucene-wrapper.cc --- a/src/plugins/fts-lucene/lucene-wrapper.cc Sat Jul 28 19:57:10 2012 +0300 +++ b/src/plugins/fts-lucene/lucene-wrapper.cc Sat Jul 28 20:00:32 2012 +0300 @@ -1098,7 +1098,7 @@ return false; q = lucene_get_query(index, - t_lucene_utf8_to_tchar(index, arg->hdr_field_name, FALSE), + t_lucene_utf8_to_tchar(index, t_str_lcase(arg->hdr_field_name), FALSE), arg); break; default: @@ -1141,7 +1141,7 @@ if (*arg->value.str == '\0') { /* checking potential existence of the header name */ q = lucene_get_query_str(index, _T("hdr"), - arg->hdr_field_name, FALSE); + t_str_lcase(arg->hdr_field_name), FALSE); break; } From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: lib-storage: When copying a mail, use a new timesta... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b13b8267999d changeset: 14814:b13b8267999d user: Timo Sirainen date: Sat Jul 28 20:31:13 2012 +0300 description: lib-storage: When copying a mail, use a new timestamp for date.save instead of preserving it. diffstat: src/lib-storage/index/index-storage.c | 13 +++++++++++-- 1 files changed, 11 insertions(+), 2 deletions(-) diffs (30 lines): diff -r 77f2510bb009 -r b13b8267999d src/lib-storage/index/index-storage.c --- a/src/lib-storage/index/index-storage.c Sat Jul 28 20:00:32 2012 +0300 +++ b/src/lib-storage/index/index-storage.c Sat Jul 28 20:31:13 2012 +0300 @@ -625,6 +625,7 @@ struct mailbox_transaction_context *dest_trans = ctx->transaction; const struct mail_cache_field *dest_field; unsigned int src_field_idx, dest_field_idx; + uint32_t t; src_field_idx = mail_cache_register_lookup(src_mail->box->cache, name); i_assert(src_field_idx != -1U); @@ -643,8 +644,16 @@ } buffer_set_used_size(buf, 0); - if (mail_cache_lookup_field(src_mail->transaction->cache_view, buf, - src_mail->seq, src_field_idx) > 0) { + if (strcmp(name, "date.save") == 0) { + /* save date must update when mail is copied */ + t = ioloop_time; + buffer_append(buf, &t, sizeof(t)); + } else { + if (mail_cache_lookup_field(src_mail->transaction->cache_view, buf, + src_mail->seq, src_field_idx) <= 0) + buffer_set_used_size(buf, 0); + } + if (buf->used > 0) { mail_cache_add(dest_trans->cache_trans, dest_seq, dest_field_idx, buf->data, buf->used); } From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: lib-storage: When saving a mail, set date.save to c... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c598f76eeeed changeset: 14815:c598f76eeeed user: Timo Sirainen date: Sat Jul 28 20:31:30 2012 +0300 description: lib-storage: When saving a mail, set date.save to cache immediately. diffstat: src/lib-storage/index/index-mail.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r b13b8267999d -r c598f76eeeed src/lib-storage/index/index-mail.c --- a/src/lib-storage/index/index-mail.c Sat Jul 28 20:31:13 2012 +0300 +++ b/src/lib-storage/index/index-mail.c Sat Jul 28 20:31:30 2012 +0300 @@ -731,7 +731,8 @@ uint32_t t; dates[0] = mail->data.received_date; - dates[1] = mail->data.save_date; + dates[1] = mail->mail.mail.saving ? ioloop_time : + mail->data.save_date; for (i = 0; i < N_ELEMENTS(date_fields); i++) { if (dates[i] != (time_t)-1 && From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: verbose_ssl=yes: Log debug messages with debug leve... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4ddb9117a178 changeset: 14812:4ddb9117a178 user: Timo Sirainen date: Sat Jul 28 19:57:10 2012 +0300 description: verbose_ssl=yes: Log debug messages with debug level instead of as info... diffstat: src/login-common/ssl-proxy-openssl.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (16 lines): diff -r eec5e1f03fff -r 4ddb9117a178 src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Sat Jul 28 19:56:07 2012 +0300 +++ b/src/login-common/ssl-proxy-openssl.c Sat Jul 28 19:57:10 2012 +0300 @@ -846,9 +846,9 @@ where, SSL_state_string_long(ssl), net_ip2addr(&proxy->ip)); } else { - i_info("SSL: where=0x%x, ret=%d: %s [%s]", - where, ret, SSL_state_string_long(ssl), - net_ip2addr(&proxy->ip)); + i_debug("SSL: where=0x%x, ret=%d: %s [%s]", + where, ret, SSL_state_string_long(ssl), + net_ip2addr(&proxy->ip)); } } From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: lib-storage: Avoid creating shared user for an empt... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ec5c630012cd changeset: 14816:ec5c630012cd user: Timo Sirainen date: Tue Jul 31 18:33:45 2012 +0300 description: lib-storage: Avoid creating shared user for an empty username. diffstat: src/lib-storage/index/shared/shared-list.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r c598f76eeeed -r ec5c630012cd src/lib-storage/index/shared/shared-list.c --- a/src/lib-storage/index/shared/shared-list.c Sat Jul 28 20:31:30 2012 +0300 +++ b/src/lib-storage/index/shared/shared-list.c Tue Jul 31 18:33:45 2012 +0300 @@ -135,7 +135,8 @@ else ns_ref = NULL; - if (ns_ref != NULL && shared_storage_get_namespace(&ns, &ns_ref) == 0) + if (ns_ref != NULL && *ns_ref != '\0' && + shared_storage_get_namespace(&ns, &ns_ref) == 0) return mailbox_list_join_refpattern(ns->list, ref, pattern); /* fallback to default behavior */ From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: imap: Fixed LIST handling with reference parameter. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fac6b994e869 changeset: 14817:fac6b994e869 user: Timo Sirainen date: Tue Jul 31 18:34:53 2012 +0300 description: imap: Fixed LIST handling with reference parameter. For example "LIST shared/ %" failed to list shared/user namespace prefix. diffstat: src/imap/cmd-list.c | 28 +++++++++++++++------------- 1 files changed, 15 insertions(+), 13 deletions(-) diffs (72 lines): diff -r ec5c630012cd -r fac6b994e869 src/imap/cmd-list.c --- a/src/imap/cmd-list.c Tue Jul 31 18:33:45 2012 +0300 +++ b/src/imap/cmd-list.c Tue Jul 31 18:34:53 2012 +0300 @@ -236,17 +236,22 @@ enum imap_match_result match; const char *ns_prefix, *p; bool inboxcase; + unsigned int skip_len; + + skip_len = strlen(ctx->ref); + if (strncmp(ctx->ns->prefix, ctx->ref, skip_len) != 0) + skip_len = 0; inboxcase = strncasecmp(ctx->ns->prefix, "INBOX", 5) == 0 && ctx->ns->prefix[5] == mail_namespace_get_sep(ctx->ns); glob = imap_match_init_multiple(pool_datastack_create(), ctx->patterns, inboxcase, mail_namespace_get_sep(ctx->ns)); - ns_prefix = ctx->ns->prefix; + ns_prefix = ctx->ns->prefix + skip_len; match = imap_match(glob, ns_prefix); if (match == IMAP_MATCH_YES) { - return !ctx->cur_ns_skip_trailing_sep ? ns_prefix : - t_strndup(ns_prefix, strlen(ns_prefix)-1); + return !ctx->cur_ns_skip_trailing_sep ? ctx->ns->prefix : + t_strndup(ctx->ns->prefix, strlen(ctx->ns->prefix)-1); } while ((match & IMAP_MATCH_PARENT) != 0) { @@ -256,7 +261,8 @@ match = imap_match(glob, ns_prefix); } i_assert(match == IMAP_MATCH_YES); - return ns_prefix; + return t_strconcat(t_strndup(ctx->ns->prefix, skip_len), + ns_prefix, NULL); } static void list_reply_append_ns_sep_param(string_t *str, char sep) @@ -510,18 +516,14 @@ skip_namespace_prefix(const char **prefix, const char **pattern, bool inbox_check, char sep) { - size_t pattern_len, prefix_len; + size_t pattern_len, prefix_len, min_len; bool match; prefix_len = strlen(*prefix); pattern_len = strlen(*pattern); + min_len = I_MIN(prefix_len, pattern_len); - if (pattern_len < prefix_len) { - /* eg. namespace prefix = "INBOX.", pattern = "INBOX" */ - return; - } - - match = strncmp(*prefix, *pattern, prefix_len) == 0; + match = strncmp(*prefix, *pattern, min_len) == 0; if (!match && inbox_check) { /* try INBOX check. */ match = prefix_len >= 5 && @@ -533,8 +535,8 @@ } if (match) { - *prefix += prefix_len; - *pattern += prefix_len; + *prefix += min_len; + *pattern += min_len; } } From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: fts-solr: Log a better error if Solr sends invalid ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/817b69b2b21f changeset: 14819:817b69b2b21f user: Timo Sirainen date: Tue Jul 31 22:03:00 2012 +0300 description: fts-solr: Log a better error if Solr sends invalid XML input. diffstat: src/plugins/fts-solr/solr-connection.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-) diffs (25 lines): diff -r f74557336910 -r 817b69b2b21f src/plugins/fts-solr/solr-connection.c --- a/src/plugins/fts-solr/solr-connection.c Tue Jul 31 20:59:22 2012 +0300 +++ b/src/plugins/fts-solr/solr-connection.c Tue Jul 31 22:03:00 2012 +0300 @@ -88,7 +88,7 @@ const void *data, size_t size, bool done) { enum XML_Error err; - int line; + int line, col; if (conn->xml_failed) return -1; @@ -99,8 +99,10 @@ err = XML_GetErrorCode(conn->xml_parser); if (err != XML_ERROR_FINISHED) { line = XML_GetCurrentLineNumber(conn->xml_parser); - i_error("fts_solr: Invalid XML input at line %d: %s", - line, XML_ErrorString(err)); + col = XML_GetCurrentColumnNumber(conn->xml_parser); + i_error("fts_solr: Invalid XML input at %d:%d: %s " + "(near: %.*s)", line, col, XML_ErrorString(err), + (int)I_MIN(size, 128), data); conn->xml_failed = TRUE; return -1; } From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: auth: if passwd-file isn't the only userdb, don't c... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f74557336910 changeset: 14818:f74557336910 user: Timo Sirainen date: Tue Jul 31 20:59:22 2012 +0300 description: auth: if passwd-file isn't the only userdb, don't complain about missing userdb fields diffstat: src/auth/db-passwd-file.c | 18 +++++++++++++++--- src/auth/db-passwd-file.h | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diffs (65 lines): diff -r fac6b994e869 -r f74557336910 src/auth/db-passwd-file.c --- a/src/auth/db-passwd-file.c Tue Jul 31 18:34:53 2012 +0300 +++ b/src/auth/db-passwd-file.c Tue Jul 31 20:59:22 2012 +0300 @@ -7,6 +7,7 @@ #include "userdb.h" #include "db-passwd-file.h" +#include "array.h" #include "buffer.h" #include "istream.h" #include "hash.h" @@ -90,7 +91,7 @@ } if (*args == NULL) { - if (pw->db->userdb) { + if (pw->db->userdb_warn_missing) { i_error("passwd-file %s: User %s is missing " "userdb info", pw->path, username); } @@ -290,6 +291,15 @@ return NULL; } +static void db_passwd_file_set_userdb(struct db_passwd_file *db) +{ + db->userdb = TRUE; + /* warn about missing userdb fields only when there aren't any other + userdbs. */ + db->userdb_warn_missing = + array_count(&global_auth_settings->userdbs) == 1; +} + struct db_passwd_file * db_passwd_file_init(const char *path, bool userdb, bool debug) { @@ -300,13 +310,15 @@ db = db_passwd_file_find(path); if (db != NULL) { db->refcount++; - db->userdb = TRUE; + if (userdb) + db_passwd_file_set_userdb(db); return db; } db = i_new(struct db_passwd_file, 1); db->refcount = 1; - db->userdb = userdb; + if (userdb) + db_passwd_file_set_userdb(db); db->debug = debug; for (p = path; *p != '\0'; p++) { diff -r fac6b994e869 -r f74557336910 src/auth/db-passwd-file.h --- a/src/auth/db-passwd-file.h Tue Jul 31 18:34:53 2012 +0300 +++ b/src/auth/db-passwd-file.h Tue Jul 31 20:59:22 2012 +0300 @@ -37,6 +37,7 @@ unsigned int vars:1; unsigned int userdb:1; + unsigned int userdb_warn_missing:1; unsigned int debug:1; }; From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: script: Don't add an empty parameter to executed co... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1d9d799a2efc changeset: 14820:1d9d799a2efc user: Timo Sirainen date: Tue Jul 31 22:30:19 2012 +0300 description: script: Don't add an empty parameter to executed command line Also fixed an error check diffstat: src/util/script.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (23 lines): diff -r 817b69b2b21f -r 1d9d799a2efc src/util/script.c --- a/src/util/script.c Tue Jul 31 22:03:00 2012 +0300 +++ b/src/util/script.c Tue Jul 31 22:30:19 2012 +0300 @@ -133,8 +133,8 @@ } alarm(0); - /* drop the last LF */ - buffer_set_used_size(input, scanpos-1); + /* drop the last two LFs */ + buffer_set_used_size(input, scanpos-2); args = t_strsplit(str_c(input), "\n"); script_verify_version(*args); args++; @@ -148,7 +148,7 @@ exec_child(conn, args + 1); i_unreached(); } - if (*args == '\0') + if (**args == '\0') i_fatal("empty options"); args++; } From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: lib-storage: Improved missing namespace error messa... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0abb9b0a54db changeset: 14821:0abb9b0a54db user: Timo Sirainen date: Tue Jul 31 22:33:21 2012 +0300 description: lib-storage: Improved missing namespace error messages. diffstat: src/lib-storage/mail-namespace.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (22 lines): diff -r 1d9d799a2efc -r 0abb9b0a54db src/lib-storage/mail-namespace.c --- a/src/lib-storage/mail-namespace.c Tue Jul 31 22:30:19 2012 +0300 +++ b/src/lib-storage/mail-namespace.c Tue Jul 31 22:33:21 2012 +0300 @@ -249,15 +249,15 @@ return FALSE; } if (list_sep == '\0') { - *error_r = "no list=yes namespaces"; + *error_r = "list=yes namespace missing"; return FALSE; } if (!visible_namespaces) { - *error_r = "no hidden=no namespaces"; + *error_r = "hidden=no namespace missing"; return FALSE; } if (subscriptions_count == 0) { - *error_r = "no subscriptions=yes namespaces"; + *error_r = "subscriptions=yes namespace missing"; return FALSE; } return TRUE; From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: imapc: Fixed crashes during mailbox close. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/afa918d1c1eb changeset: 14822:afa918d1c1eb user: Timo Sirainen date: Tue Jul 31 23:02:22 2012 +0300 description: imapc: Fixed crashes during mailbox close. diffstat: src/lib-imap-client/imapc-client.c | 2 +- src/lib-imap-client/imapc-connection.c | 29 +++++++++++++++-------------- src/lib-imap-client/imapc-connection.h | 3 ++- 3 files changed, 18 insertions(+), 16 deletions(-) diffs (104 lines): diff -r 0abb9b0a54db -r afa918d1c1eb src/lib-imap-client/imapc-client.c --- a/src/lib-imap-client/imapc-client.c Tue Jul 31 22:33:21 2012 +0300 +++ b/src/lib-imap-client/imapc-client.c Tue Jul 31 23:02:22 2012 +0300 @@ -270,7 +270,7 @@ /* reopen the mailbox */ box->reopen_callback(box->reopen_context); } else { - imapc_connection_abort_commands(box->conn, TRUE, FALSE); + imapc_connection_abort_commands(box->conn, NULL, FALSE); } } diff -r 0abb9b0a54db -r afa918d1c1eb src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Tue Jul 31 22:33:21 2012 +0300 +++ b/src/lib-imap-client/imapc-connection.c Tue Jul 31 23:02:22 2012 +0300 @@ -212,6 +212,7 @@ static void imapc_connection_abort_commands_array(ARRAY_TYPE(imapc_command) *cmd_array, ARRAY_TYPE(imapc_command) *dest_array, + struct imapc_client_mailbox *only_box, bool keep_retriable) { struct imapc_command *const *cmdp, *cmd; @@ -221,8 +222,10 @@ cmdp = array_idx(cmd_array, i); cmd = *cmdp; - if (keep_retriable && - (cmd->flags & IMAPC_COMMAND_FLAG_RETRIABLE) != 0) { + if (cmd->box != only_box && only_box != NULL) + i++; + else if (keep_retriable && + (cmd->flags & IMAPC_COMMAND_FLAG_RETRIABLE) != 0) { cmd->send_pos = 0; cmd->wait_for_literal = 0; i++; @@ -234,22 +237,20 @@ } void imapc_connection_abort_commands(struct imapc_connection *conn, - bool disconnected, bool keep_retriable) + struct imapc_client_mailbox *only_box, + bool keep_retriable) { struct imapc_command *const *cmdp, *cmd; ARRAY_TYPE(imapc_command) tmp_array; struct imapc_command_reply reply; t_array_init(&tmp_array, 8); - if (disconnected) { - imapc_connection_abort_commands_array(&conn->cmd_wait_list, - &tmp_array, - keep_retriable); - } - imapc_connection_abort_commands_array(&conn->cmd_send_queue, - &tmp_array, keep_retriable); + imapc_connection_abort_commands_array(&conn->cmd_wait_list, &tmp_array, + only_box, keep_retriable); + imapc_connection_abort_commands_array(&conn->cmd_send_queue, &tmp_array, + only_box, keep_retriable); - if (array_count(&conn->cmd_wait_list) > 0 && disconnected) { + if (array_count(&conn->cmd_wait_list) > 0 && only_box == NULL) { /* need to move all the waiting commands to send queue */ array_append_array(&conn->cmd_wait_list, &conn->cmd_send_queue); @@ -368,13 +369,13 @@ conn->fd = -1; imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED); - imapc_connection_abort_commands(conn, TRUE, reconnecting); + imapc_connection_abort_commands(conn, NULL, reconnecting); } static void imapc_connection_set_disconnected(struct imapc_connection *conn) { imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED); - imapc_connection_abort_commands(conn, TRUE, FALSE); + imapc_connection_abort_commands(conn, NULL, FALSE); } static void imapc_connection_reconnect(struct imapc_connection *conn) @@ -1852,7 +1853,7 @@ conn->selecting_box = NULL; } imapc_connection_send_idle_done(conn); - imapc_connection_abort_commands(conn, FALSE, FALSE); + imapc_connection_abort_commands(conn, box, FALSE); } struct imapc_client_mailbox * diff -r 0abb9b0a54db -r afa918d1c1eb src/lib-imap-client/imapc-connection.h --- a/src/lib-imap-client/imapc-connection.h Tue Jul 31 22:33:21 2012 +0300 +++ b/src/lib-imap-client/imapc-connection.h Tue Jul 31 23:02:22 2012 +0300 @@ -26,7 +26,8 @@ void *login_context); void imapc_connection_disconnect(struct imapc_connection *conn); void imapc_connection_abort_commands(struct imapc_connection *conn, - bool disconnected, bool keep_retriable); + struct imapc_client_mailbox *only_box, + bool keep_retriable); void imapc_connection_ioloop_changed(struct imapc_connection *conn); void imapc_connection_input_pending(struct imapc_connection *conn); From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: fts-solr: Compiler warning fix Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a606e9ff1476 changeset: 14823:a606e9ff1476 user: Timo Sirainen date: Tue Jul 31 23:10:53 2012 +0300 description: fts-solr: Compiler warning fix diffstat: src/plugins/fts-solr/solr-connection.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r afa918d1c1eb -r a606e9ff1476 src/plugins/fts-solr/solr-connection.c --- a/src/plugins/fts-solr/solr-connection.c Tue Jul 31 23:02:22 2012 +0300 +++ b/src/plugins/fts-solr/solr-connection.c Tue Jul 31 23:10:53 2012 +0300 @@ -102,7 +102,7 @@ col = XML_GetCurrentColumnNumber(conn->xml_parser); i_error("fts_solr: Invalid XML input at %d:%d: %s " "(near: %.*s)", line, col, XML_ErrorString(err), - (int)I_MIN(size, 128), data); + (int)I_MIN(size, 128), (const char *)data); conn->xml_failed = TRUE; return -1; } From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: lib-storage: Fixed attempting to delete a non-symli... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8029f1b4afd0 changeset: 14824:8029f1b4afd0 user: Timo Sirainen date: Wed Aug 01 14:13:40 2012 +0300 description: lib-storage: Fixed attempting to delete a non-symlink with Solaris Also fixed error message to say it's about unlink(), not stat(). diffstat: src/lib-storage/list/mailbox-list-delete.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (18 lines): diff -r a606e9ff1476 -r 8029f1b4afd0 src/lib-storage/list/mailbox-list-delete.c --- a/src/lib-storage/list/mailbox-list-delete.c Tue Jul 31 23:10:53 2012 +0300 +++ b/src/lib-storage/list/mailbox-list-delete.c Wed Aug 01 14:13:40 2012 +0300 @@ -341,11 +341,12 @@ if (errno == ENOENT) { mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); - } else if (errno == EISDIR) { + } else if (errno == EISDIR || + errno == EPERM) { /* Solaris */ mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, "Mailbox isn't a symlink"); } else { - mailbox_list_set_critical(list, "stat(%s) failed: %m", path); + mailbox_list_set_critical(list, "unlink(%s) failed: %m", path); } return -1; } From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: fts: Fixed crash in fts_lookup_multi() for backends... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8d59874e02ad changeset: 14825:8d59874e02ad user: Timo Sirainen date: Wed Aug 01 20:24:00 2012 +0300 description: fts: Fixed crash in fts_lookup_multi() for backends that can't handle it (fts-squat) diffstat: src/plugins/fts/fts-api.c | 17 ++++++++++++++++- 1 files changed, 16 insertions(+), 1 deletions(-) diffs (29 lines): diff -r 8029f1b4afd0 -r 8d59874e02ad src/plugins/fts/fts-api.c --- a/src/plugins/fts/fts-api.c Wed Aug 01 14:13:40 2012 +0300 +++ b/src/plugins/fts/fts-api.c Wed Aug 01 20:24:00 2012 +0300 @@ -318,9 +318,24 @@ struct mail_search_arg *args, bool and_args, struct fts_multi_result *result) { + unsigned int i; + i_assert(boxes[0] != NULL); - return backend->v.lookup_multi(backend, boxes, args, and_args, result); + if (backend->v.lookup_multi != NULL) { + return backend->v.lookup_multi(backend, boxes, args, + and_args, result); + } + + for (i = 0; boxes[i] != NULL; i++) ; + result->box_results = p_new(result->pool, struct fts_result, i+1); + + for (i = 0; boxes[i] != NULL; i++) { + if (backend->v.lookup(backend, boxes[i], args, + and_args, &result->box_results[i]) < 0) + return -1; + } + return 0; } void fts_backend_lookup_done(struct fts_backend *backend) From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: auth: winbind mechanism supports now spaces in file... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ae4bbcc9612b changeset: 14826:ae4bbcc9612b user: Timo Sirainen date: Wed Aug 01 20:24:58 2012 +0300 description: auth: winbind mechanism supports now spaces in filenames. diffstat: src/auth/mech-winbind.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 8d59874e02ad -r ae4bbcc9612b src/auth/mech-winbind.c --- a/src/auth/mech-winbind.c Wed Aug 01 20:24:00 2012 +0300 +++ b/src/auth/mech-winbind.c Wed Aug 01 20:24:58 2012 +0300 @@ -240,7 +240,7 @@ } else if (strcmp(token[0], "AF") == 0) { const char *user, *p, *error; - user = gss_spnego ? token[2] : token[1]; + user = t_strarray_join(gss_spnego ? token+2 : token+1, " "); i_assert(user != NULL); p = strchr(user, '\\'); From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: auth: Support empty ldap base (for ldap servers tha... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fd1cdeef4e2d changeset: 14827:fd1cdeef4e2d user: Timo Sirainen date: Wed Aug 01 20:25:26 2012 +0300 description: auth: Support empty ldap base (for ldap servers that support it). diffstat: src/auth/db-ldap.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r ae4bbcc9612b -r fd1cdeef4e2d src/auth/db-ldap.c --- a/src/auth/db-ldap.c Wed Aug 01 20:24:58 2012 +0300 +++ b/src/auth/db-ldap.c Wed Aug 01 20:25:26 2012 +0300 @@ -314,7 +314,8 @@ i_assert(request->msgid == -1); request->msgid = - ldap_search(conn->ld, srequest->base, conn->set.ldap_scope, + ldap_search(conn->ld, *srequest->base == '\0' ? NULL : + srequest->base, conn->set.ldap_scope, srequest->filter, srequest->attributes, 0); if (request->msgid == -1) { auth_request_log_error(request->auth_request, "ldap", From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: Released v2.1.9. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/bc86680293d2 changeset: 14828:bc86680293d2 user: Timo Sirainen date: Wed Aug 01 20:36:53 2012 +0300 description: Released v2.1.9. diffstat: NEWS | 24 ++++++++++++++++++++++++ configure.in | 2 +- 2 files changed, 25 insertions(+), 1 deletions(-) diffs (41 lines): diff -r fd1cdeef4e2d -r bc86680293d2 NEWS --- a/NEWS Wed Aug 01 20:25:26 2012 +0300 +++ b/NEWS Wed Aug 01 20:36:53 2012 +0300 @@ -1,3 +1,27 @@ +v2.1.9 2012-08-01 Timo Sirainen + + * mail-log plugin: Log mailbox names with UTF-8 everywhere + (instead of mUTF-7 in some places and UTF-8 in other places) + * director: Changed director_username_hash setting's default from %u + to %Lu (= lowercase usernames). This doesn't break any existing + installations, but might fix some of them. + + + doveadm: Added "auth cache flush []" command. + + Implemented dict passdb/userdb + + Implemented Redis and memcached dict backends, which can be used as + auth backends. Redis can also be used as dict-quota backend. + + Added plugin { quota_ignore_save_errors=yes } setting to allow saving + a mail when quota lookup fails with temporary failure. + - Full text search indexing might have failed for some messages, + always causing indexer-worker process to run out of memory. + - fts-lucene: Fixed handling SEARCH HEADER FROM/TO/SUBJECT/CC/BCC when + the header wasn't lowercased. + - fts-squat: Fixed crash when searching a virtual mailbox. + - pop3: Fixed assert crash when doing UIDL on empty mailbox on some + setups. + - auth: GSSAPI RFC compliancy and error handling fixes. + - Various fixes related to handling shared namespaces + v2.1.8 2012-07-03 Timo Sirainen + pop3c: Added pop3c_master_user setting. diff -r fd1cdeef4e2d -r bc86680293d2 configure.in --- a/configure.in Wed Aug 01 20:25:26 2012 +0300 +++ b/configure.in Wed Aug 01 20:36:53 2012 +0300 @@ -1,5 +1,5 @@ AC_PREREQ([2.59]) -AC_INIT([Dovecot],[2.1.8],[dovecot at dovecot.org]) +AC_INIT([Dovecot],[2.1.9],[dovecot at dovecot.org]) AC_CONFIG_SRCDIR([src]) AM_INIT_AUTOMAKE([foreign]) From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: Added tag 2.1.9 for changeset bc86680293d2 Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/687906b93914 changeset: 14829:687906b93914 user: Timo Sirainen date: Wed Aug 01 20:36:53 2012 +0300 description: Added tag 2.1.9 for changeset bc86680293d2 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r bc86680293d2 -r 687906b93914 .hgtags --- a/.hgtags Wed Aug 01 20:36:53 2012 +0300 +++ b/.hgtags Wed Aug 01 20:36:53 2012 +0300 @@ -85,3 +85,4 @@ 7c249e2a82a9cd33ae15ead6443c3499e16da623 2.1.6 c92fb8b928f69ca01681a2c2976304b7e4bc3afc 2.1.7 7e5f36fd989d27a2fb48250adbab8fa54ddb6083 2.1.8 +bc86680293d256d5a8009690caeb73ab2e34e359 2.1.9 From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: Added signature for changeset bc86680293d2 Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8518f8b5a28b changeset: 14830:8518f8b5a28b user: Timo Sirainen date: Wed Aug 01 20:37:05 2012 +0300 description: Added signature for changeset bc86680293d2 diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 687906b93914 -r 8518f8b5a28b .hgsigs --- a/.hgsigs Wed Aug 01 20:36:53 2012 +0300 +++ b/.hgsigs Wed Aug 01 20:37:05 2012 +0300 @@ -48,3 +48,4 @@ 7c249e2a82a9cd33ae15ead6443c3499e16da623 0 iEYEABECAAYFAk+nX2sACgkQyUhSUUBVisn7uwCbBD3boxBOGEJ8OYsIJ57n5Cr09FAAoIvhxL6EHRB15AMOw4sPaALJ3/bB c92fb8b928f69ca01681a2c2976304b7e4bc3afc 0 iEYEABECAAYFAk/FIeIACgkQyUhSUUBVisk4IgCfUiXVXntqzPjJcALYRpqw4Zc7a/0An3HKWwgb6PBCbmvxBfTezNkqjqVK 7e5f36fd989d27a2fb48250adbab8fa54ddb6083 0 iEYEABECAAYFAk/yVakACgkQyUhSUUBVismekwCfSEVQjd6fwdChjd53LSt03b4UWKoAoIxd/IjLatTISlHm44iiQwzRKByo +bc86680293d256d5a8009690caeb73ab2e34e359 0 iEYEABECAAYFAlAZaTUACgkQyUhSUUBVisnTAACfU1pB34RrXEyLnpnL4Ee/oeNBYcoAnRWxTqx870Efjwf+eBPzafO0C/NU From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: auth: Minor code cleanup Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/47ebcf37af3d changeset: 14831:47ebcf37af3d user: Timo Sirainen date: Wed Aug 01 21:14:30 2012 +0300 description: auth: Minor code cleanup diffstat: src/auth/auth-cache.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 8518f8b5a28b -r 47ebcf37af3d src/auth/auth-cache.c --- a/src/auth/auth-cache.c Wed Aug 01 20:37:05 2012 +0300 +++ b/src/auth/auth-cache.c Wed Aug 01 21:14:30 2012 +0300 @@ -305,7 +305,7 @@ for (node = cache->tail; node != NULL; node = next) { next = node->next; if (auth_cache_node_is_one_of_users(node, usernames)) { - auth_cache_node_destroy(cache, cache->tail); + auth_cache_node_destroy(cache, node); ret++; } } From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: fts: Fixed crash on error handling Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d499f6d0ca68 changeset: 14832:d499f6d0ca68 user: Timo Sirainen date: Wed Aug 01 22:39:57 2012 +0300 description: fts: Fixed crash on error handling diffstat: src/plugins/fts/fts-search.c | 14 ++++++++------ 1 files changed, 8 insertions(+), 6 deletions(-) diffs (25 lines): diff -r 47ebcf37af3d -r d499f6d0ca68 src/plugins/fts/fts-search.c --- a/src/plugins/fts/fts-search.c Wed Aug 01 21:14:30 2012 +0300 +++ b/src/plugins/fts/fts-search.c Wed Aug 01 22:39:57 2012 +0300 @@ -199,13 +199,15 @@ struct mail_search_arg *args, bool and_args) { - if (!fctx->virtual_mailbox) { - if (fts_search_lookup_level_single(fctx, args, and_args) < 0) - return -1; - } else T_BEGIN { - if (fts_search_lookup_level_multi(fctx, args, and_args) < 0) - return -1; + int ret; + + T_BEGIN { + ret = !fctx->virtual_mailbox ? + fts_search_lookup_level_single(fctx, args, and_args) : + fts_search_lookup_level_multi(fctx, args, and_args); } T_END; + if (ret < 0) + return -1; for (; args != NULL; args = args->next) { if (args->type != SEARCH_OR && args->type != SEARCH_SUB) From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: fts: Fixed a crash if virtual mailbox search couldn... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/323d6ce62567 changeset: 14833:323d6ce62567 user: Timo Sirainen date: Wed Aug 01 22:43:45 2012 +0300 description: fts: Fixed a crash if virtual mailbox search couldn't be optimized by backend. diffstat: src/plugins/fts/fts-api.c | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) diffs (20 lines): diff -r d499f6d0ca68 -r 323d6ce62567 src/plugins/fts/fts-api.c --- a/src/plugins/fts/fts-api.c Wed Aug 01 22:39:57 2012 +0300 +++ b/src/plugins/fts/fts-api.c Wed Aug 01 22:43:45 2012 +0300 @@ -323,8 +323,14 @@ i_assert(boxes[0] != NULL); if (backend->v.lookup_multi != NULL) { - return backend->v.lookup_multi(backend, boxes, args, - and_args, result); + if (backend->v.lookup_multi(backend, boxes, args, + and_args, result) < 0) + return -1; + if (result->box_results == NULL) { + result->box_results = p_new(result->pool, + struct fts_result, 1); + } + return 0; } for (i = 0; boxes[i] != NULL; i++) ; From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: doveadm-server: Make sure another command isn't sta... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/476381017ec7 changeset: 14834:476381017ec7 user: Timo Sirainen date: Wed Aug 01 23:14:19 2012 +0300 description: doveadm-server: Make sure another command isn't started before previous one is finished. diffstat: src/doveadm/client-connection.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diffs (32 lines): diff -r 323d6ce62567 -r 476381017ec7 src/doveadm/client-connection.c --- a/src/doveadm/client-connection.c Wed Aug 01 22:43:45 2012 +0300 +++ b/src/doveadm/client-connection.c Wed Aug 01 23:14:19 2012 +0300 @@ -21,6 +21,8 @@ #define MAX_INBUF_SIZE 1024 +static void client_connection_input(struct client_connection *conn); + struct client_connection { pool_t pool; @@ -208,6 +210,10 @@ return FALSE; } + /* make sure client_connection_input() isn't called by the ioloop that + is going to be run by doveadm_mail_cmd_server_run() */ + io_remove(&conn->io); + o_stream_cork(conn->output); ctx = doveadm_mail_cmd_server_parse(cmd_name, conn->set, &input, argc, args); if (ctx == NULL) @@ -220,6 +226,8 @@ net_set_nonblock(conn->fd, FALSE); (void)o_stream_flush(conn->output); net_set_nonblock(conn->fd, TRUE); + + conn->io = io_add(conn->fd, IO_READ, client_connection_input, conn); return TRUE; } From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: pop3-migration: Avoid disconnection from POP3 serve... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ab6a4455b27d changeset: 14835:ab6a4455b27d user: Timo Sirainen date: Fri Aug 03 17:39:54 2012 +0300 description: pop3-migration: Avoid disconnection from POP3 server due to idling. diffstat: src/plugins/pop3-migration/pop3-migration-plugin.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diffs (18 lines): diff -r 476381017ec7 -r ab6a4455b27d src/plugins/pop3-migration/pop3-migration-plugin.c --- a/src/plugins/pop3-migration/pop3-migration-plugin.c Wed Aug 01 23:14:19 2012 +0300 +++ b/src/plugins/pop3-migration/pop3-migration-plugin.c Fri Aug 03 17:39:54 2012 +0300 @@ -472,8 +472,13 @@ if (pop3_mailbox_open(box->storage) < 0) return -1; + /* the POP3 server isn't connected to yet. handle all IMAP traffic + first before connecting, so POP3 server won't disconnect us due to + idling. */ + if (imap_map_read(box) < 0) + return -1; - if (pop3_map_read(box->storage) < 0 || imap_map_read(box) < 0) + if (pop3_map_read(box->storage) < 0) return -1; if (!pop3_uidl_assign_by_size(box)) { From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: lib-master: Settings cache crashed after config_cac... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2815175a0ffc changeset: 14836:2815175a0ffc user: Timo Sirainen date: Tue Aug 07 17:56:24 2012 +0300 description: lib-master: Settings cache crashed after config_cache_size was reached. This affected login processes when local {} and/or remote {} blocks were specified. Also fixed the cache behavior to be MRU. diffstat: src/lib-master/master-service-settings-cache.c | 18 +++++++++--------- 1 files changed, 9 insertions(+), 9 deletions(-) diffs (51 lines): diff -r ab6a4455b27d -r 2815175a0ffc src/lib-master/master-service-settings-cache.c --- a/src/lib-master/master-service-settings-cache.c Fri Aug 03 17:39:54 2012 +0300 +++ b/src/lib-master/master-service-settings-cache.c Tue Aug 07 17:56:24 2012 +0300 @@ -145,6 +145,8 @@ } if (entry != NULL) { + DLLIST2_REMOVE(&cache->oldest, &cache->newest, entry); + DLLIST2_APPEND(&cache->oldest, &cache->newest, entry); *parser_r = entry->parser; return TRUE; } @@ -195,31 +197,29 @@ /* use global settings, but add local_ip/host to hash tables so we'll find them */ pool = pool_alloconly_create("settings global entry", 256); - entry = p_new(pool, struct settings_entry, 1); } else if (cache->cache_malloc_size >= cache->max_cache_size) { /* free the oldest and reuse its pool */ - entry = cache->oldest; - pool = entry->pool; - setting_entry_detach(cache, entry); - p_clear(pool); + pool = cache->oldest->pool; + setting_entry_detach(cache, cache->oldest); + p_clear(pool); /* note: frees also entry */ } else { pool_size = cache->approx_entry_pool_size != 0 ? cache->approx_entry_pool_size : CACHE_INITIAL_ENTRY_POOL_SIZE; pool = pool_alloconly_create("settings entry", pool_size); - entry = p_new(pool, struct settings_entry, 1); } + entry = p_new(pool, struct settings_entry, 1); entry->pool = pool; entry_local_name = p_strdup(pool, input->local_name); entry->local_name = entry_local_name; entry->local_ip = input->local_ip; if (!output->used_local) { entry->parser = cache->global_parser; - DLLIST2_PREPEND(&cache->oldest_global, &cache->newest_global, - entry); + DLLIST2_APPEND(&cache->oldest_global, &cache->newest_global, + entry); } else { entry->parser = settings_parser_dup(parser, entry->pool); - DLLIST2_PREPEND(&cache->oldest, &cache->newest, entry); + DLLIST2_APPEND(&cache->oldest, &cache->newest, entry); pool_size = pool_alloconly_get_total_used_size(pool); if (pool_size > cache->approx_entry_pool_size) { From dovecot at dovecot.org Fri Aug 10 05:24:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:41 +0300 Subject: dovecot-2.2: fts-solr: Optimized expunging messages: delete more... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/82f59d2139a9 changeset: 14837:82f59d2139a9 user: Timo Sirainen date: Wed Aug 08 00:44:27 2012 +0300 description: fts-solr: Optimized expunging messages: delete more than one ID per request. diffstat: src/plugins/fts-solr/fts-backend-solr.c | 39 ++++++++++++++++++++++---------- 1 files changed, 27 insertions(+), 12 deletions(-) diffs (93 lines): diff -r 2815175a0ffc -r 82f59d2139a9 src/plugins/fts-solr/fts-backend-solr.c --- a/src/plugins/fts-solr/fts-backend-solr.c Tue Aug 07 17:56:24 2012 +0300 +++ b/src/plugins/fts-solr/fts-backend-solr.c Wed Aug 08 00:44:27 2012 +0300 @@ -38,6 +38,7 @@ struct solr_connection_post *post; uint32_t prev_uid; string_t *cmd, *cur_value, *cur_value2; + string_t *cmd_expunge; ARRAY_DEFINE(fields, struct solr_fts_field); uint32_t last_indexed_uid; @@ -240,7 +241,6 @@ ctx = i_new(struct solr_fts_backend_update_context, 1); ctx->ctx.backend = _backend; - ctx->cmd = str_new(default_pool, SOLR_CMDBUF_SIZE); i_array_init(&ctx->fields, 16); return &ctx->ctx; } @@ -326,6 +326,15 @@ return solr_connection_post_end(ctx->post); } +static void +fts_backend_solr_expunge_flush(struct solr_fts_backend_update_context *ctx) +{ + str_append(ctx->cmd_expunge, "
"); + (void)solr_connection_post(solr_conn, str_c(ctx->cmd_expunge)); + str_truncate(ctx->cmd_expunge, 0); + str_append(ctx->cmd_expunge, ""); +} + static int fts_backend_solr_update_deinit(struct fts_backend_update_context *_ctx) { @@ -341,6 +350,8 @@ if (ctx->documents_added || ctx->expunges) { /* commit and wait until the documents we just indexed are visible to the following search */ + if (ctx->expunges) + fts_backend_solr_expunge_flush(ctx); str = t_strdup_printf("", ctx->documents_added ? "true" : "false"); @@ -348,7 +359,10 @@ ret = -1; } - str_free(&ctx->cmd); + if (ctx->cmd != NULL) + str_free(&ctx->cmd); + if (ctx->cmd_expunge != NULL) + str_free(&ctx->cmd_expunge); array_foreach_modifiable(&ctx->fields, field) { str_free(&field->value); i_free(field->key); @@ -404,18 +418,18 @@ highly unlikely to be indexed at this time. */ return; } - ctx->expunges = TRUE; + if (!ctx->expunges) { + ctx->expunges = TRUE; + ctx->cmd_expunge = str_new(default_pool, 1024); + str_append(ctx->cmd_expunge, ""); + } - T_BEGIN { - string_t *cmd; + if (str_len(ctx->cmd_expunge) >= SOLR_CMDBUF_FLUSH_SIZE) + fts_backend_solr_expunge_flush(ctx); - cmd = t_str_new(256); - str_append(cmd, ""); - xml_encode_id(ctx, cmd, uid); - str_append(cmd, ""); - - (void)solr_connection_post(solr_conn, str_c(cmd)); - } T_END; + str_append(ctx->cmd_expunge, ""); + xml_encode_id(ctx, ctx->cmd_expunge, uid); + str_append(ctx->cmd_expunge, ""); } static void @@ -425,6 +439,7 @@ if (ctx->post == NULL) { i_assert(ctx->prev_uid == 0); + ctx->cmd = str_new(default_pool, SOLR_CMDBUF_SIZE); ctx->post = solr_connection_post_begin(solr_conn); str_append(ctx->cmd, ""); } else { From dovecot at dovecot.org Fri Aug 10 05:24:42 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:42 +0300 Subject: dovecot-2.2: lib-master: Another settings parser cache fix Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b082b8260782 changeset: 14838:b082b8260782 user: Timo Sirainen date: Fri Aug 10 02:33:19 2012 +0300 description: lib-master: Another settings parser cache fix diffstat: src/lib-master/master-service-settings-cache.c | 20 +++++++++++--------- 1 files changed, 11 insertions(+), 9 deletions(-) diffs (58 lines): diff -r 82f59d2139a9 -r b082b8260782 src/lib-master/master-service-settings-cache.c --- a/src/lib-master/master-service-settings-cache.c Wed Aug 08 00:44:27 2012 +0300 +++ b/src/lib-master/master-service-settings-cache.c Fri Aug 10 02:33:19 2012 +0300 @@ -168,10 +168,11 @@ settings_parser_deinit(&entry->parser); } -static void cache_add(struct master_service_settings_cache *cache, - const struct master_service_settings_input *input, - const struct master_service_settings_output *output, - struct setting_parser_context *parser) +static struct setting_parser_context * +cache_add(struct master_service_settings_cache *cache, + const struct master_service_settings_input *input, + const struct master_service_settings_output *output, + struct setting_parser_context *parser) { struct settings_entry *entry; pool_t pool; @@ -187,17 +188,17 @@ } if (cache->service_uses_remote) { /* for now we don't try to handle caching remote IPs */ - return; + return parser; } if (input->local_name == NULL && input->local_ip.family == 0) - return; + return parser; if (!output->used_local) { /* use global settings, but add local_ip/host to hash tables so we'll find them */ pool = pool_alloconly_create("settings global entry", 256); - } else if (cache->cache_malloc_size >= cache->max_cache_size) { + } else if (cache->cache_malloc_size >= /*cache->max_cache_size*/1) { /* free the oldest and reuse its pool */ pool = cache->oldest->pool; setting_entry_detach(cache, cache->oldest); @@ -249,6 +250,7 @@ hash_table_insert(cache->local_ip_hash, &entry->local_ip, entry); } + return entry->parser; } int master_service_settings_cache_read(struct master_service_settings_cache *cache, @@ -294,7 +296,7 @@ return -1; } - cache_add(cache, &new_input, &output, cache->service->set_parser); - *parser_r = cache->service->set_parser; + *parser_r = cache_add(cache, &new_input, &output, + cache->service->set_parser); return 0; } From dovecot at dovecot.org Fri Aug 10 05:24:42 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:42 +0300 Subject: dovecot-2.2: Removed accidentally committed debug code Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9d0873cefa08 changeset: 14839:9d0873cefa08 user: Timo Sirainen date: Fri Aug 10 02:34:34 2012 +0300 description: Removed accidentally committed debug code diffstat: src/lib-master/master-service-settings-cache.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r b082b8260782 -r 9d0873cefa08 src/lib-master/master-service-settings-cache.c --- a/src/lib-master/master-service-settings-cache.c Fri Aug 10 02:33:19 2012 +0300 +++ b/src/lib-master/master-service-settings-cache.c Fri Aug 10 02:34:34 2012 +0300 @@ -198,7 +198,7 @@ /* use global settings, but add local_ip/host to hash tables so we'll find them */ pool = pool_alloconly_create("settings global entry", 256); - } else if (cache->cache_malloc_size >= /*cache->max_cache_size*/1) { + } else if (cache->cache_malloc_size >= cache->max_cache_size) { /* free the oldest and reuse its pool */ pool = cache->oldest->pool; setting_entry_detach(cache, cache->oldest); From dovecot at dovecot.org Fri Aug 10 05:24:42 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:24:42 +0300 Subject: dovecot-2.2: Merged changes from v2.1 tree. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6a0954d0ce09 changeset: 14840:6a0954d0ce09 user: Timo Sirainen date: Fri Aug 10 05:24:07 2012 +0300 description: Merged changes from v2.1 tree. diffstat: .hgsigs | 2 + .hgtags | 2 + NEWS | 39 + configure.in | 6 + doc/Makefile.am | 8 +- doc/example-config/conf.d/10-director.conf | 5 + doc/example-config/conf.d/auth-dict.conf.ext | 16 + doc/example-config/dovecot-dict-auth.conf.ext | 22 + src/auth/Makefile.am | 5 + src/auth/auth-cache.c | 228 +++++- src/auth/auth-cache.h | 7 +- src/auth/auth-master-connection.c | 27 + src/auth/auth-request.h | 4 + src/auth/auth.c | 9 + src/auth/db-dict.c | 177 +++++ src/auth/db-dict.h | 37 + src/auth/db-ldap.c | 3 +- src/auth/db-passwd-file.c | 18 +- src/auth/db-passwd-file.h | 1 + src/auth/main.c | 3 + src/auth/mech-gssapi.c | 62 +- src/auth/mech-winbind.c | 2 +- src/auth/passdb-dict.c | 197 ++++++ src/auth/passdb.c | 2 + src/auth/test-auth-cache.c | 18 +- src/auth/userdb-dict.c | 207 ++++++ src/auth/userdb.c | 2 + src/config/config-connection.c | 2 +- src/config/doveconf.c | 7 +- src/config/old-set-parser.c | 2 +- src/director/director-settings.c | 2 +- src/doveadm/client-connection.c | 8 + src/doveadm/doveadm-auth.c | 82 ++- src/doveadm/doveadm-mail-mailbox-status.c | 1 + src/doveadm/doveadm.c | 3 +- src/doveadm/doveadm.h | 3 +- src/doveadm/main.c | 5 +- src/imap-login/client.c | 2 +- src/imap/cmd-delete.c | 7 + src/imap/cmd-list.c | 38 +- src/imap/cmd-status.c | 5 +- src/imap/imap-status.c | 4 +- src/imap/imap-status.h | 2 +- src/lib-auth/auth-master.c | 43 + src/lib-auth/auth-master.h | 4 + src/lib-charset/charset-iconv.c | 13 +- src/lib-dict/Makefile.am | 4 +- src/lib-dict/dict-memcached.c | 376 +++++++++++ src/lib-dict/dict-private.h | 4 +- src/lib-dict/dict-redis.c | 666 +++++++++++++++++++++ src/lib-dict/dict.c | 16 +- src/lib-dict/test-dict.c | 2 + src/lib-imap-client/imapc-client.c | 2 +- src/lib-imap-client/imapc-connection.c | 29 +- src/lib-imap-client/imapc-connection.h | 3 +- src/lib-mail/mail-user-hash.c | 6 + src/lib-master/master-service-settings-cache.c | 36 +- src/lib-master/mountpoint-list.c | 2 + src/lib-settings/settings-parser.c | 2 + src/lib-sql/sql-db-cache.c | 1 + src/lib-ssl-iostream/iostream-openssl.c | 6 +- src/lib-storage/index/imapc/imapc-save.c | 6 +- src/lib-storage/index/index-mail.c | 3 +- src/lib-storage/index/index-storage.c | 13 +- src/lib-storage/index/pop3c/pop3c-client.c | 11 +- src/lib-storage/index/pop3c/pop3c-mail.c | 9 +- src/lib-storage/index/pop3c/pop3c-settings.c | 2 + src/lib-storage/index/pop3c/pop3c-settings.h | 1 + src/lib-storage/index/pop3c/pop3c-storage.c | 1 + src/lib-storage/index/shared/shared-list.c | 3 +- src/lib-storage/list/mailbox-list-delete.c | 5 +- src/lib-storage/list/mailbox-list-fs-iter.c | 16 +- src/lib-storage/mail-namespace.c | 6 +- src/lib-storage/mail-storage.c | 10 +- src/lib-storage/mail-user.c | 4 +- src/lib/Makefile.am | 2 + src/lib/file-set-size.c | 2 +- src/lib/json-parser.c | 272 ++++++++ src/lib/json-parser.h | 22 + src/lmtp/commands.c | 68 ++ src/lmtp/lmtp-proxy.c | 4 + src/lmtp/lmtp-settings.c | 2 + src/lmtp/lmtp-settings.h | 1 + src/login-common/client-common.c | 8 +- src/login-common/client-common.h | 1 + src/login-common/ssl-proxy-openssl.c | 34 +- src/master/main.c | 3 +- src/plugins/fts-lucene/Makefile.am | 4 + src/plugins/fts-lucene/lucene-wrapper.cc | 8 +- src/plugins/fts-solr/fts-backend-solr.c | 39 +- src/plugins/fts-solr/solr-connection.c | 8 +- src/plugins/fts/fts-api.c | 23 +- src/plugins/fts/fts-search.c | 14 +- src/plugins/imap-acl/imap-acl-plugin.c | 5 +- src/plugins/imap-quota/imap-quota-plugin.c | 5 +- src/plugins/mail-log/mail-log-plugin.c | 10 +- src/plugins/pop3-migration/pop3-migration-plugin.c | 7 +- src/plugins/quota/quota-private.h | 6 +- src/plugins/quota/quota-storage.c | 5 +- src/plugins/quota/quota.c | 4 +- src/pop3-login/client-authenticate.c | 2 +- src/pop3/pop3-commands.c | 2 +- src/util/script.c | 6 +- 103 files changed, 2882 insertions(+), 272 deletions(-) diffs (truncated from 4961 to 300 lines): diff -r 53139f2f2284 -r 6a0954d0ce09 .hgsigs --- a/.hgsigs Fri Aug 10 04:56:56 2012 +0300 +++ b/.hgsigs Fri Aug 10 05:24:07 2012 +0300 @@ -47,3 +47,5 @@ 469cee314d9c54d2d7101ec9e38579fdc9610eaf 0 iEYEABECAAYFAk+VWqkACgkQyUhSUUBVislnXACfVjPqMmPUvYtXQXwqff0h7N76mZUAn02lPeUCyuyr1TF9e1hGM/sKgmko 7c249e2a82a9cd33ae15ead6443c3499e16da623 0 iEYEABECAAYFAk+nX2sACgkQyUhSUUBVisn7uwCbBD3boxBOGEJ8OYsIJ57n5Cr09FAAoIvhxL6EHRB15AMOw4sPaALJ3/bB c92fb8b928f69ca01681a2c2976304b7e4bc3afc 0 iEYEABECAAYFAk/FIeIACgkQyUhSUUBVisk4IgCfUiXVXntqzPjJcALYRpqw4Zc7a/0An3HKWwgb6PBCbmvxBfTezNkqjqVK +7e5f36fd989d27a2fb48250adbab8fa54ddb6083 0 iEYEABECAAYFAk/yVakACgkQyUhSUUBVismekwCfSEVQjd6fwdChjd53LSt03b4UWKoAoIxd/IjLatTISlHm44iiQwzRKByo +bc86680293d256d5a8009690caeb73ab2e34e359 0 iEYEABECAAYFAlAZaTUACgkQyUhSUUBVisnTAACfU1pB34RrXEyLnpnL4Ee/oeNBYcoAnRWxTqx870Efjwf+eBPzafO0C/NU diff -r 53139f2f2284 -r 6a0954d0ce09 .hgtags --- a/.hgtags Fri Aug 10 04:56:56 2012 +0300 +++ b/.hgtags Fri Aug 10 05:24:07 2012 +0300 @@ -84,3 +84,5 @@ 469cee314d9c54d2d7101ec9e38579fdc9610eaf 2.1.5 7c249e2a82a9cd33ae15ead6443c3499e16da623 2.1.6 c92fb8b928f69ca01681a2c2976304b7e4bc3afc 2.1.7 +7e5f36fd989d27a2fb48250adbab8fa54ddb6083 2.1.8 +bc86680293d256d5a8009690caeb73ab2e34e359 2.1.9 diff -r 53139f2f2284 -r 6a0954d0ce09 NEWS --- a/NEWS Fri Aug 10 04:56:56 2012 +0300 +++ b/NEWS Fri Aug 10 05:24:07 2012 +0300 @@ -1,3 +1,42 @@ +v2.1.9 2012-08-01 Timo Sirainen + + * mail-log plugin: Log mailbox names with UTF-8 everywhere + (instead of mUTF-7 in some places and UTF-8 in other places) + * director: Changed director_username_hash setting's default from %u + to %Lu (= lowercase usernames). This doesn't break any existing + installations, but might fix some of them. + + + doveadm: Added "auth cache flush []" command. + + Implemented dict passdb/userdb + + Implemented Redis and memcached dict backends, which can be used as + auth backends. Redis can also be used as dict-quota backend. + + Added plugin { quota_ignore_save_errors=yes } setting to allow saving + a mail when quota lookup fails with temporary failure. + - Full text search indexing might have failed for some messages, + always causing indexer-worker process to run out of memory. + - fts-lucene: Fixed handling SEARCH HEADER FROM/TO/SUBJECT/CC/BCC when + the header wasn't lowercased. + - fts-squat: Fixed crash when searching a virtual mailbox. + - pop3: Fixed assert crash when doing UIDL on empty mailbox on some + setups. + - auth: GSSAPI RFC compliancy and error handling fixes. + - Various fixes related to handling shared namespaces + +v2.1.8 2012-07-03 Timo Sirainen + + + pop3c: Added pop3c_master_user setting. + - imap: Mailbox names were accidentally sent as UTF-8 instead of mUTF-7 + in previous v2.1.x releases for STATUS, MYRIGHTS and GETQUOTAROOT + commands. + - lmtp proxy: Don't timeout connections too early when mail has a lot + of RCPT TOs. + - director: Don't crash if the director is working alone. + - shared mailboxes: Avoid doing "@domain" userdb lookups. + - doveadm: Fixed crash with proxying some commands. + - fts-squat: Fixed handling multiple SEARCH parameters. + - imapc: Fixed a crash when message had more than 8 keywords. + - imapc: Don't crash on APPEND/COPY if server doesn't support UIDPLUS. + v2.1.7 2012-05-29 Timo Sirainen * LDAP: Compatibility fix for v2.0: ldap: If attributes contain diff -r 53139f2f2284 -r 6a0954d0ce09 configure.in --- a/configure.in Fri Aug 10 04:56:56 2012 +0300 +++ b/configure.in Fri Aug 10 05:24:07 2012 +0300 @@ -2675,6 +2675,11 @@ AC_CHECK_LIB(textcat, special_textcat_Init, [ have_lucene_textcat=yes AC_DEFINE(HAVE_LUCENE_TEXTCAT,, Define if you want textcat support for CLucene) + ], [ + AC_CHECK_LIB(exttextcat, special_textcat_Init, [ + have_lucene_exttextcat=yes + AC_DEFINE(HAVE_LUCENE_EXTTEXTCAT,, Define if you want textcat (Debian version) support for CLucene) + ]) ]) ], [ if test $want_stemmer = yes; then @@ -2687,6 +2692,7 @@ fi AM_CONDITIONAL(BUILD_LUCENE_STEMMER, test "$have_lucene_stemmer" = "yes") AM_CONDITIONAL(BUILD_LUCENE_TEXTCAT, test "$have_lucene_textcat" = "yes") +AM_CONDITIONAL(BUILD_LUCENE_EXTTEXTCAT, test "$have_lucene_exttextcat" = "yes") if test $have_lucene = no; then not_fts="$not_fts lucene" diff -r 53139f2f2284 -r 6a0954d0ce09 doc/Makefile.am --- a/doc/Makefile.am Fri Aug 10 04:56:56 2012 +0300 +++ b/doc/Makefile.am Fri Aug 10 05:24:07 2012 +0300 @@ -7,7 +7,10 @@ docfiles = \ documentation.txt \ securecoding.txt \ - thread-refs.txt + thread-refs.txt \ + mkcert.sh \ + dovecot-openssl.cnf \ + solr-schema.xml if BUILD_DOCS doc_DATA = $(docfiles) @@ -15,7 +18,4 @@ EXTRA_DIST = \ dovecot-initd.sh \ - mkcert.sh \ - dovecot-openssl.cnf \ - solr-schema.xml \ $(docfiles) diff -r 53139f2f2284 -r 6a0954d0ce09 doc/example-config/conf.d/10-director.conf --- a/doc/example-config/conf.d/10-director.conf Fri Aug 10 04:56:56 2012 +0300 +++ b/doc/example-config/conf.d/10-director.conf Fri Aug 10 05:24:07 2012 +0300 @@ -25,6 +25,11 @@ # If you enable this, you'll also need to add inet_listener for the port. #director_doveadm_port = 0 +# How the username is translated before being hashed. Useful values include +# %Ln if user can log in with or without @domain, %Ld if mailboxes are shared +# within domain. +#director_username_hash = %Lu + # To enable director service, uncomment the modes and assign a port. service director { unix_listener login/director { diff -r 53139f2f2284 -r 6a0954d0ce09 doc/example-config/conf.d/auth-dict.conf.ext --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/example-config/conf.d/auth-dict.conf.ext Fri Aug 10 05:24:07 2012 +0300 @@ -0,0 +1,16 @@ +# Authentication via dict backend. Included from auth.conf. +# +# + +passdb { + driver = dict + + # Path for dict configuration file, see + # example-config/dovecot-dict-auth.conf.ext + args = /etc/dovecot/dovecot-dict-auth.conf.ext +} + +userdb { + driver = dict + args = /etc/dovecot/dovecot-dict-auth.conf.ext +} diff -r 53139f2f2284 -r 6a0954d0ce09 doc/example-config/dovecot-dict-auth.conf.ext --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/example-config/dovecot-dict-auth.conf.ext Fri Aug 10 05:24:07 2012 +0300 @@ -0,0 +1,22 @@ +# Dictionary URI +#uri = + +# Key for passdb lookups +password_key = dovecot/passdb/%u + +# Key for userdb lookups +user_key = dovecot/userdb/%u + +# How to parse the value for key=value pairs. Currently we support only JSON +# format with { "key": "value", ... } object. +#value_format = json + +# Username iteration prefix. Keys under this are assumed to contain usernames. +iterate_prefix = dovecot/userdb/ + +# Should iteration be disabled for this userdb? If this userdb acts only as a +# cache there's no reason to try to iterate the (partial & duplicate) users. +#iterate_disable = no + +# Default password scheme +default_pass_scheme = MD5 diff -r 53139f2f2284 -r 6a0954d0ce09 src/auth/Makefile.am --- a/src/auth/Makefile.am Fri Aug 10 04:56:56 2012 +0300 +++ b/src/auth/Makefile.am Fri Aug 10 05:24:07 2012 +0300 @@ -25,6 +25,7 @@ -I$(top_srcdir)/src/lib \ -I$(top_srcdir)/src/lib-auth \ -I$(top_srcdir)/src/lib-test \ + -I$(top_srcdir)/src/lib-dict \ -I$(top_srcdir)/src/lib-dns \ -I$(top_srcdir)/src/lib-sql \ -I$(top_srcdir)/src/lib-settings \ @@ -73,6 +74,7 @@ auth-worker-client.c \ auth-worker-server.c \ db-checkpassword.c \ + db-dict.c \ db-sql.c \ db-passwd-file.c \ main.c \ @@ -96,6 +98,7 @@ passdb-bsdauth.c \ passdb-cache.c \ passdb-checkpassword.c \ + passdb-dict.c \ passdb-passwd.c \ passdb-passwd-file.c \ passdb-pam.c \ @@ -108,6 +111,7 @@ userdb.c \ userdb-blocking.c \ userdb-checkpassword.c \ + userdb-dict.c \ userdb-nss.c \ userdb-passwd.c \ userdb-passwd-file.c \ @@ -134,6 +138,7 @@ auth-stream.h \ auth-worker-client.h \ auth-worker-server.h \ + db-dict.h \ db-ldap.h \ db-sql.h \ db-passwd-file.h \ diff -r 53139f2f2284 -r 6a0954d0ce09 src/auth/auth-cache.c --- a/src/auth/auth-cache.c Fri Aug 10 04:56:56 2012 +0300 +++ b/src/auth/auth-cache.c Fri Aug 10 05:24:07 2012 +0300 @@ -23,36 +23,72 @@ unsigned long long pos_size, neg_size; }; -static const struct var_expand_table * -auth_request_var_expand_tab_find(const char *key, unsigned int size) +static bool +auth_request_var_expand_tab_find(const char *key, unsigned int size, + unsigned int *idx_r) { const struct var_expand_table *tab = auth_request_var_expand_static_tab; unsigned int i; for (i = 0; tab[i].key != '\0' || tab[i].long_key != NULL; i++) { if (size == 1) { - if (key[0] == tab[i].key) - return &tab[i]; + if (key[0] == tab[i].key) { + *idx_r = i; + return TRUE; + } } else if (tab[i].long_key != NULL) { if (strncmp(key, tab[i].long_key, size) == 0 && - tab[i].long_key[size] == '\0') - return &tab[i]; + tab[i].long_key[size] == '\0') { + *idx_r = i; + return TRUE; + } } } - return NULL; + return FALSE; +} + +static void +auth_cache_key_add_var(string_t *str, const char *data, unsigned int len) +{ + if (str_len(str) > 0) + str_append_c(str, '\t'); + str_append_c(str, '%'); + if (len == 1) + str_append_c(str, data[0]); + else { + str_append_c(str, '{'); + str_append_n(str, data, len); + str_append_c(str, '}'); + } +} + +static void auth_cache_key_add_tab_idx(string_t *str, unsigned int i) +{ + const struct var_expand_table *tab = + &auth_request_var_expand_static_tab[i]; + + if (str_len(str) > 0) + str_append_c(str, '\t'); + str_append_c(str, '%'); + if (tab->key != '\0') + str_append_c(str, tab->key); + else { + str_append_c(str, '{'); + str_append(str, tab->long_key); + str_append_c(str, '}'); + } } char *auth_cache_parse_key(pool_t pool, const char *query) { - const struct var_expand_table *tab; string_t *str; - bool key_seen[100]; - unsigned int idx, size, tab_idx; - bool add_key; + bool key_seen[AUTH_REQUEST_VAR_TAB_COUNT]; + const char *extra_vars; + unsigned int i, idx, size, tab_idx; memset(key_seen, 0, sizeof(key_seen)); - str = str_new(pool, 32); + str = t_str_new(32); for (; *query != '\0'; ) { From dovecot at dovecot.org Fri Aug 10 05:29:48 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:29:48 +0300 Subject: dovecot-2.2: doveadm: Renamed "auth" command to "auth test". Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/19b6a8c025e4 changeset: 14841:19b6a8c025e4 user: Timo Sirainen date: Fri Aug 10 05:27:45 2012 +0300 description: doveadm: Renamed "auth" command to "auth test". diffstat: src/doveadm/doveadm-auth.c | 15 ++++----------- 1 files changed, 4 insertions(+), 11 deletions(-) diffs (48 lines): diff -r 6a0954d0ce09 -r 19b6a8c025e4 src/doveadm/doveadm-auth.c --- a/src/doveadm/doveadm-auth.c Fri Aug 10 05:24:07 2012 +0300 +++ b/src/doveadm/doveadm-auth.c Fri Aug 10 05:27:45 2012 +0300 @@ -249,19 +249,12 @@ auth_master_deinit(&conn); } -static void cmd_auth(int argc, char *argv[]) +static void cmd_auth_test(int argc, char *argv[]) { const char *auth_socket_path = NULL; struct authtest_input input; int c; - if (null_strcmp(argv[1], "cache") == 0 && - null_strcmp(argv[2], "flush") == 0) { - /* kludgy: handle "doveadm auth cache" command instead */ - cmd_auth_cache_flush(argc-2, argv+2); - return; - } - memset(&input, 0, sizeof(input)); input.info.service = "doveadm"; @@ -274,12 +267,12 @@ auth_user_info_parse(&input.info, optarg); break; default: - auth_cmd_help(cmd_auth); + auth_cmd_help(cmd_auth_test); } } if (optind == argc) - auth_cmd_help(cmd_auth); + auth_cmd_help(cmd_auth_test); input.username = argv[optind++]; input.password = argv[optind] != NULL ? argv[optind++] : @@ -423,7 +416,7 @@ } struct doveadm_cmd doveadm_cmd_auth[] = { - { cmd_auth, "auth", + { cmd_auth_test, "auth test", "[-a ] [-x ] []" }, { cmd_auth_cache_flush, "auth cache flush", "[-a ] [ [...]]" }, From dovecot at dovecot.org Fri Aug 10 05:34:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 05:34:41 +0300 Subject: dovecot-2.2: ioloop-epoll: Fix for running with zero I/Os. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/17fb07dea309 changeset: 14842:17fb07dea309 user: Timo Sirainen date: Fri Aug 10 05:34:35 2012 +0300 description: ioloop-epoll: Fix for running with zero I/Os. diffstat: src/lib/ioloop-epoll.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 19b6a8c025e4 -r 17fb07dea309 src/lib/ioloop-epoll.c --- a/src/lib/ioloop-epoll.c Fri Aug 10 05:27:45 2012 +0300 +++ b/src/lib/ioloop-epoll.c Fri Aug 10 05:34:35 2012 +0300 @@ -187,6 +187,7 @@ just wait for them. */ if (msecs > 0) usleep(msecs*1000); + ret = 0; } /* execute timeout handlers */ From dovecot at dovecot.org Fri Aug 10 06:51:22 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 06:51:22 +0300 Subject: dovecot-2.2: istream-base64-encoder: Minor fix to require only 3... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f31916c173d1 changeset: 14843:f31916c173d1 user: Timo Sirainen date: Fri Aug 10 05:55:13 2012 +0300 description: istream-base64-encoder: Minor fix to require only 3 bytes instead of 4 per input block. Base64 encoder reads 3 bytes and outputs 4 bytes, so it's ok to read only 3 bytes. diffstat: src/lib/istream-base64-encoder.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 17fb07dea309 -r f31916c173d1 src/lib/istream-base64-encoder.c --- a/src/lib/istream-base64-encoder.c Fri Aug 10 05:34:35 2012 +0300 +++ b/src/lib/istream-base64-encoder.c Fri Aug 10 05:55:13 2012 +0300 @@ -22,7 +22,7 @@ ssize_t ret; size = i_stream_get_data_size(stream->parent); - if (size >= 4) + if (size >= 3) return 1; /* we have less than one base64 block. @@ -104,7 +104,7 @@ if (ret <= 0) return ret; size = i_stream_get_data_size(stream->parent); - } while (size < 4 && !stream->parent->eof); + } while (size < 3 && !stream->parent->eof); /* encode as many lines as fits into destination buffer */ pre_count = stream->pos - stream->skip; From dovecot at dovecot.org Fri Aug 10 06:51:22 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 06:51:22 +0300 Subject: dovecot-2.2: istreams: When reading invalid data, fail with EINV... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/51a9846bb2bd changeset: 14844:51a9846bb2bd user: Timo Sirainen date: Fri Aug 10 06:03:11 2012 +0300 description: istreams: When reading invalid data, fail with EINVAL instead of EIO. EINVAL was already used more. diffstat: src/lib-mail/istream-attachment-extractor.c | 4 ++-- src/lib-storage/index/istream-mail.c | 2 +- src/lib/istream-sized.c | 2 +- src/lib/istream-sized.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diffs (57 lines): diff -r f31916c173d1 -r 51a9846bb2bd src/lib-mail/istream-attachment-extractor.c --- a/src/lib-mail/istream-attachment-extractor.c Fri Aug 10 05:55:13 2012 +0300 +++ b/src/lib-mail/istream-attachment-extractor.c Fri Aug 10 06:03:11 2012 +0300 @@ -575,7 +575,7 @@ stream->istream.stream_errno = stream->parent->stream_errno; if (ret < 0) - stream->istream.stream_errno = EIO; + stream->istream.stream_errno = EINVAL; astream->cur_part = NULL; return -1; case 0: @@ -588,7 +588,7 @@ if (block.part != astream->cur_part && astream->cur_part != NULL) { /* end of a MIME part */ if (astream_end_of_part(astream) < 0) { - stream->istream.stream_errno = EIO; + stream->istream.stream_errno = EINVAL; return -1; } } diff -r f31916c173d1 -r 51a9846bb2bd src/lib-storage/index/istream-mail.c --- a/src/lib-storage/index/istream-mail.c Fri Aug 10 05:55:13 2012 +0300 +++ b/src/lib-storage/index/istream-mail.c Fri Aug 10 06:03:11 2012 +0300 @@ -51,7 +51,7 @@ "(%"PRIuUOFF_T" %c %"PRIuUOFF_T")", str, mstream->expected_size, chr, cur_size); mail_set_cache_corrupted(mstream->mail, MAIL_FETCH_PHYSICAL_SIZE); - mstream->istream.istream.stream_errno = EIO; + mstream->istream.istream.stream_errno = EINVAL; } static ssize_t diff -r f31916c173d1 -r 51a9846bb2bd src/lib/istream-sized.c --- a/src/lib/istream-sized.c Fri Aug 10 05:55:13 2012 +0300 +++ b/src/lib/istream-sized.c Fri Aug 10 06:03:11 2012 +0300 @@ -59,7 +59,7 @@ "(%"PRIuUOFF_T" < %"PRIuUOFF_T")", i_stream_get_name(stream->parent), stream->istream.v_offset, sstream->size); - stream->istream.stream_errno = EIO; + stream->istream.stream_errno = EINVAL; } ret = pos > stream->pos ? (ssize_t)(pos - stream->pos) : diff -r f31916c173d1 -r 51a9846bb2bd src/lib/istream-sized.h --- a/src/lib/istream-sized.h Fri Aug 10 05:55:13 2012 +0300 +++ b/src/lib/istream-sized.h Fri Aug 10 06:03:11 2012 +0300 @@ -2,7 +2,7 @@ #define ISTREAM_SIZED_H /* Assume that input is exactly the given size. If it's smaller, log an error - and fail with EIO error. If it's larger, log an error but don't fail. */ + and fail with EINVAL error. If it's larger, log an error but don't fail. */ struct istream *i_stream_create_sized(struct istream *input, uoff_t size); #endif From dovecot at dovecot.org Fri Aug 10 06:51:22 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 06:51:22 +0300 Subject: dovecot-2.2: Added istream-base64-decoder. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/39b1b519c033 changeset: 14845:39b1b519c033 user: Timo Sirainen date: Fri Aug 10 06:45:25 2012 +0300 description: Added istream-base64-decoder. diffstat: src/lib/Makefile.am | 4 +- src/lib/istream-base64-decoder.c | 131 ++++++++++++++++++++++++++++++++++ src/lib/istream-base64-encoder.c | 2 +- src/lib/istream-base64-encoder.h | 8 -- src/lib/istream-base64.h | 10 ++ src/lib/test-istream-base64-decoder.c | 69 +++++++++++++++++ src/lib/test-istream-base64-encoder.c | 2 +- src/lib/test-lib.c | 1 + src/lib/test-lib.h | 1 + 9 files changed, 217 insertions(+), 11 deletions(-) diffs (truncated from 308 to 300 lines): diff -r 51a9846bb2bd -r 39b1b519c033 src/lib/Makefile.am --- a/src/lib/Makefile.am Fri Aug 10 06:03:11 2012 +0300 +++ b/src/lib/Makefile.am Fri Aug 10 06:45:25 2012 +0300 @@ -54,6 +54,7 @@ iostream-rawlog.c \ iso8601-date.c \ istream.c \ + istream-base64-decoder.c \ istream-base64-encoder.c \ istream-chain.c \ istream-concat.c \ @@ -178,7 +179,7 @@ iostream-rawlog-private.h \ iso8601-date.h \ istream.h \ - istream-base64-encoder.h \ + istream-base64.h \ istream-chain.h \ istream-concat.h \ istream-crlf.h \ @@ -263,6 +264,7 @@ test-hash-format.c \ test-hex-binary.c \ test-iso8601-date.c \ + test-istream-base64-decoder.c \ test-istream-base64-encoder.c \ test-istream-concat.c \ test-istream-crlf.c \ diff -r 51a9846bb2bd -r 39b1b519c033 src/lib/istream-base64-decoder.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/istream-base64-decoder.c Fri Aug 10 06:45:25 2012 +0300 @@ -0,0 +1,131 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "buffer.h" +#include "base64.h" +#include "istream-private.h" +#include "istream-base64.h" + +struct base64_decoder_istream { + struct istream_private istream; +}; + +static int i_stream_read_parent(struct istream_private *stream) +{ + size_t size; + ssize_t ret; + + size = i_stream_get_data_size(stream->parent); + if (size >= 4) + return 1; + + /* we have less than one base64 block. + see if there is more data available. */ + ret = i_stream_read(stream->parent); + if (ret <= 0) { + stream->istream.stream_errno = stream->parent->stream_errno; + stream->istream.eof = stream->parent->eof; + return ret; + } + size = i_stream_get_data_size(stream->parent); + i_assert(size != 0); + return 1; +} + +static int +i_stream_base64_try_decode_block(struct base64_decoder_istream *bstream) +{ + struct istream_private *stream = &bstream->istream; + const unsigned char *data; + size_t size, avail, buffer_avail, pos; + buffer_t buf; + + data = i_stream_get_data(stream->parent, &size); + if (size == 0) + return 0; + + i_stream_try_alloc(stream, (size+3)/4*3, &avail); + buffer_avail = stream->buffer_size - stream->pos; + + if ((size + 3) / 4 * 3 > buffer_avail) { + /* can't fit everything to destination buffer. + write as much as we can. */ + size = (buffer_avail / 3) * 4; + if (size == 0) + return -2; + } + + buffer_create_data(&buf, stream->w_buffer + stream->pos, buffer_avail); + if (base64_decode(data, size, &pos, &buf) < 0) { + stream->istream.stream_errno = EINVAL; + return -1; + } + + stream->pos += buf.used; + i_stream_skip(stream->parent, pos); + return pos > 0 ? 1 : 0; +} + +static ssize_t i_stream_base64_decoder_read(struct istream_private *stream) +{ + struct base64_decoder_istream *bstream = + (struct base64_decoder_istream *)stream; + size_t pre_count, post_count; + int ret; + + do { + ret = i_stream_read_parent(stream); + if (ret <= 0) { + if (ret < 0 && stream->istream.stream_errno == 0 && + i_stream_get_data_size(stream->parent) > 0) { + /* base64 input with a partial block */ + stream->istream.stream_errno = EINVAL; + } + return ret; + } + + /* encode as many blocks as fits into destination buffer */ + pre_count = stream->pos - stream->skip; + while ((ret = i_stream_base64_try_decode_block(bstream)) > 0) ; + post_count = stream->pos - stream->skip; + } while (ret == 0); + + if (ret < 0) + return ret; + + i_assert(post_count > pre_count); + return post_count - pre_count; +} + +static void +i_stream_base64_decoder_seek(struct istream_private *stream, + uoff_t v_offset, bool mark) +{ + if (v_offset < stream->istream.v_offset) { + /* seeking backwards - go back to beginning and seek + forward from there. */ + stream->parent_expected_offset = stream->parent_start_offset; + stream->skip = stream->pos = 0; + stream->istream.v_offset = 0; + i_stream_seek(stream->parent, 0); + } + i_stream_default_seek_nonseekable(stream, v_offset, mark); +} + +struct istream * +i_stream_create_base64_decoder(struct istream *input) +{ + struct base64_decoder_istream *bstream; + + bstream = i_new(struct base64_decoder_istream, 1); + bstream->istream.max_buffer_size = input->real_stream->max_buffer_size; + + bstream->istream.read = i_stream_base64_decoder_read; + bstream->istream.seek = i_stream_base64_decoder_seek; + + bstream->istream.istream.readable_fd = FALSE; + bstream->istream.istream.blocking = input->blocking; + bstream->istream.istream.seekable = input->seekable; + return i_stream_create(&bstream->istream, input, + i_stream_get_fd(input)); +} diff -r 51a9846bb2bd -r 39b1b519c033 src/lib/istream-base64-encoder.c --- a/src/lib/istream-base64-encoder.c Fri Aug 10 06:03:11 2012 +0300 +++ b/src/lib/istream-base64-encoder.c Fri Aug 10 06:45:25 2012 +0300 @@ -4,7 +4,7 @@ #include "buffer.h" #include "base64.h" #include "istream-private.h" -#include "istream-base64-encoder.h" +#include "istream-base64.h" struct base64_encoder_istream { struct istream_private istream; diff -r 51a9846bb2bd -r 39b1b519c033 src/lib/istream-base64-encoder.h --- a/src/lib/istream-base64-encoder.h Fri Aug 10 06:03:11 2012 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -#ifndef ISTREAM_BASE64_H -#define ISTREAM_BASE64_H - -struct istream * -i_stream_create_base64_encoder(struct istream *input, - unsigned int chars_per_line, bool crlf); - -#endif diff -r 51a9846bb2bd -r 39b1b519c033 src/lib/istream-base64.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/istream-base64.h Fri Aug 10 06:45:25 2012 +0300 @@ -0,0 +1,10 @@ +#ifndef ISTREAM_BASE64_H +#define ISTREAM_BASE64_H + +struct istream * +i_stream_create_base64_encoder(struct istream *input, + unsigned int chars_per_line, bool crlf); +struct istream * +i_stream_create_base64_decoder(struct istream *input); + +#endif diff -r 51a9846bb2bd -r 39b1b519c033 src/lib/test-istream-base64-decoder.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/test-istream-base64-decoder.c Fri Aug 10 06:45:25 2012 +0300 @@ -0,0 +1,69 @@ +/* Copyright (c) 2010-2012 Dovecot authors, see the included COPYING file */ + +#include "test-lib.h" +#include "str.h" +#include "istream-private.h" +#include "istream-base64.h" + +struct { + const char *input; + const char *output; +} tests[] = { + { "aGVsbG8gd29ybGQ=", "hello world" }, + { "\naGVs\nbG8g\nd29y\nbGQ=\n", "hello world" }, + { " aGVs \r\n bG8g \r\n d29y \t \r\n bGQ= \r\n\r\n", "hello world" }, +}; + +static void +decode_test(const char *base64_input, const char *output, bool broken_input) +{ + unsigned int base64_input_len = strlen(base64_input); + struct istream *input_data, *input; + const unsigned char *data; + size_t i, size; + int ret = 0; + + input_data = test_istream_create_data(base64_input, base64_input_len); + test_istream_set_allow_eof(input_data, FALSE); + input = i_stream_create_base64_decoder(input_data); + + for (i = 1; i <= base64_input_len; i++) { + test_istream_set_size(input_data, i); + while ((ret = i_stream_read(input)) > 0) ; + if (ret == -1 && broken_input) + break; + test_assert(ret == 0); + } + if (ret == 0) { + test_istream_set_allow_eof(input_data, TRUE); + while ((ret = i_stream_read(input)) > 0) ; + } + test_assert(ret == -1); + test_assert((input->stream_errno == 0 && !broken_input) || + (input->stream_errno == EINVAL && broken_input)); + + data = i_stream_get_data(input, &size); + test_assert(size == strlen(output) && memcmp(data, output, size) == 0); + i_stream_unref(&input); + i_stream_unref(&input_data); +} + +void test_istream_base64_decoder(void) +{ + unsigned int i; + + for (i = 0; i < N_ELEMENTS(tests); i++) { + test_begin(t_strdup_printf("istream base64 decoder %u", i+1)); + decode_test(tests[i].input, tests[i].output, FALSE); + test_end(); + } + test_begin("istream base64 decoder error"); + decode_test("foo", "", TRUE); + decode_test("Zm9vC", "foo", TRUE); + decode_test("Zm9v!", "foo", TRUE); + decode_test("Zm9!v", "", TRUE); + decode_test("Zm9 v", "", TRUE); + decode_test("Zm 9v", "", TRUE); + decode_test("Z m9v", "", TRUE); + test_end(); +} diff -r 51a9846bb2bd -r 39b1b519c033 src/lib/test-istream-base64-encoder.c --- a/src/lib/test-istream-base64-encoder.c Fri Aug 10 06:03:11 2012 +0300 +++ b/src/lib/test-istream-base64-encoder.c Fri Aug 10 06:45:25 2012 +0300 @@ -3,7 +3,7 @@ #include "test-lib.h" #include "str.h" #include "istream-private.h" -#include "istream-base64-encoder.h" +#include "istream-base64.h" static const char *hello = "hello world"; diff -r 51a9846bb2bd -r 39b1b519c033 src/lib/test-lib.c --- a/src/lib/test-lib.c Fri Aug 10 06:03:11 2012 +0300 +++ b/src/lib/test-lib.c Fri Aug 10 06:45:25 2012 +0300 @@ -14,6 +14,7 @@ test_hash_format, test_hex_binary, test_iso8601_date, + test_istream_base64_decoder, test_istream_base64_encoder, test_istream_concat, test_istream_crlf, diff -r 51a9846bb2bd -r 39b1b519c033 src/lib/test-lib.h --- a/src/lib/test-lib.h Fri Aug 10 06:03:11 2012 +0300 +++ b/src/lib/test-lib.h Fri Aug 10 06:45:25 2012 +0300 From dovecot at dovecot.org Fri Aug 10 07:00:26 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 07:00:26 +0300 Subject: dovecot-2.2: Various fixes to istream-base64-encoder/decoder Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4d13da5c571b changeset: 14846:4d13da5c571b user: Timo Sirainen date: Fri Aug 10 07:00:20 2012 +0300 description: Various fixes to istream-base64-encoder/decoder diffstat: src/lib/istream-base64-decoder.c | 2 +- src/lib/istream-base64-encoder.c | 45 ++++++++++++++++++---------------- src/lib/test-istream-base64-encoder.c | 43 +++++++++++++++++++++++++------- 3 files changed, 58 insertions(+), 32 deletions(-) diffs (191 lines): diff -r 39b1b519c033 -r 4d13da5c571b src/lib/istream-base64-decoder.c --- a/src/lib/istream-base64-decoder.c Fri Aug 10 06:45:25 2012 +0300 +++ b/src/lib/istream-base64-decoder.c Fri Aug 10 07:00:20 2012 +0300 @@ -88,7 +88,7 @@ pre_count = stream->pos - stream->skip; while ((ret = i_stream_base64_try_decode_block(bstream)) > 0) ; post_count = stream->pos - stream->skip; - } while (ret == 0); + } while (ret == 0 && pre_count == post_count); if (ret < 0) return ret; diff -r 39b1b519c033 -r 4d13da5c571b src/lib/istream-base64-encoder.c --- a/src/lib/istream-base64-encoder.c Fri Aug 10 06:45:25 2012 +0300 +++ b/src/lib/istream-base64-encoder.c Fri Aug 10 07:00:20 2012 +0300 @@ -31,14 +31,14 @@ if (ret <= 0) { stream->istream.stream_errno = stream->parent->stream_errno; stream->istream.eof = stream->parent->eof; - return size > 0 ? 1 : ret; + return ret; } size = i_stream_get_data_size(stream->parent); i_assert(size != 0); return 1; } -static bool +static int i_stream_base64_try_encode_line(struct base64_encoder_istream *bstream) { struct istream_private *stream = &bstream->istream; @@ -47,13 +47,13 @@ buffer_t buf; data = i_stream_get_data(stream->parent, &size); - if (size == 0) - return FALSE; + if (size == 0 || (size < 3 && !stream->parent->eof)) + return 0; if (bstream->cur_line_len == bstream->chars_per_line) { /* @UNSAFE: end of line, add newline */ if (!i_stream_try_alloc(stream, bstream->crlf ? 2 : 1, &avail)) - return FALSE; + return -2; if (bstream->crlf) stream->w_buffer[stream->pos++] = '\r'; @@ -68,13 +68,14 @@ /* can't fit everything to destination buffer. write as much as we can. */ size = (buffer_avail / 4) * 3; + if (size == 0) + return -2; } else if (!stream->parent->eof && size % 3 != 0) { /* encode 3 chars at a time, so base64_encode() doesn't add '=' characters in the middle of the stream */ size -= (size % 3); } - if (size == 0) - return FALSE; + i_assert(size != 0); if (bstream->cur_line_len + (size+2)/3*4 > bstream->chars_per_line) { size = (bstream->chars_per_line - bstream->cur_line_len)/4 * 3; @@ -89,32 +90,34 @@ i_assert(bstream->cur_line_len <= bstream->chars_per_line); stream->pos += buf.used; i_stream_skip(stream->parent, size); - return TRUE; + return 1; } static ssize_t i_stream_base64_encoder_read(struct istream_private *stream) { struct base64_encoder_istream *bstream = (struct base64_encoder_istream *)stream; - size_t pre_count, post_count, size; + size_t pre_count, post_count; int ret; do { ret = i_stream_read_parent(stream); - if (ret <= 0) - return ret; - size = i_stream_get_data_size(stream->parent); - } while (size < 3 && !stream->parent->eof); + if (ret == 0) + return 0; + if (ret < 0) { + if (i_stream_get_data_size(stream->parent) == 0) + return -1; + /* add the final partial block */ + } - /* encode as many lines as fits into destination buffer */ - pre_count = stream->pos - stream->skip; - while (i_stream_base64_try_encode_line(bstream)) ; - post_count = stream->pos - stream->skip; + /* encode as many lines as fits into destination buffer */ + pre_count = stream->pos - stream->skip; + while ((ret = i_stream_base64_try_encode_line(bstream)) > 0) ; + post_count = stream->pos - stream->skip; + } while (ret == 0 && pre_count == post_count); - if (pre_count == post_count) { - i_assert(stream->buffer_size - stream->pos < 4); - return -2; - } + if (ret < 0) + return ret; i_assert(post_count > pre_count); return post_count - pre_count; diff -r 39b1b519c033 -r 4d13da5c571b src/lib/test-istream-base64-encoder.c --- a/src/lib/test-istream-base64-encoder.c Fri Aug 10 06:45:25 2012 +0300 +++ b/src/lib/test-istream-base64-encoder.c Fri Aug 10 07:00:20 2012 +0300 @@ -5,28 +5,46 @@ #include "istream-private.h" #include "istream-base64.h" +static struct test { + const char *input; + unsigned int chars_per_line; + bool crlf; + const char *output; +} tests[] = { + { "hello world", 80, FALSE, "aGVsbG8gd29ybGQ=" }, + { "hello world", 4, FALSE, "aGVs\nbG8g\nd29y\nbGQ=" }, + { "hello world", 4, TRUE, "aGVs\r\nbG8g\r\nd29y\r\nbGQ=", }, +}; + static const char *hello = "hello world"; -static const char * -encode(const char *text, unsigned int chars_per_line, bool crlf) +static void encode_test(const char *text, unsigned int chars_per_line, + bool crlf, const char *output) { + unsigned int i, text_len = strlen(text); struct istream *input, *input_data; - const char *reply; const unsigned char *data; size_t size; ssize_t ret; - input_data = i_stream_create_from_data(text, strlen(text)); + input_data = test_istream_create_data(text, text_len); + test_istream_set_allow_eof(input_data, FALSE); input = i_stream_create_base64_encoder(input_data, chars_per_line, crlf); + + for (i = 1; i <= text_len; i++) { + test_istream_set_size(input_data, i); + while ((ret = i_stream_read(input)) > 0) ; + test_assert(ret == 0); + } + test_istream_set_allow_eof(input_data, TRUE); while ((ret = i_stream_read(input)) > 0) ; test_assert(ret == -1); data = i_stream_get_data(input, &size); - reply = t_strndup(data, size); + test_assert(size == strlen(output) && memcmp(data, output, size) == 0); i_stream_unref(&input); i_stream_unref(&input_data); - return reply; } static void @@ -61,10 +79,15 @@ void test_istream_base64_encoder(void) { - test_begin("istream base64 encoder"); - test_assert(strcmp(encode(hello, 80, FALSE), "aGVsbG8gd29ybGQ=") == 0); - test_assert(strcmp(encode(hello, 4, FALSE), "aGVs\nbG8g\nd29y\nbGQ=") == 0); - test_assert(strcmp(encode(hello, 4, TRUE), "aGVs\r\nbG8g\r\nd29y\r\nbGQ=") == 0); + unsigned int i; + + for (i = 0; i < N_ELEMENTS(tests); i++) { + test_begin(t_strdup_printf("istream base64 decoder %u", i+1)); + encode_test(tests[i].input, tests[i].chars_per_line, + tests[i].crlf, tests[i].output); + test_end(); + } + test_begin("istream base64 encoder seek"); test_istream_base64_encoder_seek(hello, "aGVs\r\nbG8g\r\nd29y\r\nbGQ="); test_end(); } From dovecot at dovecot.org Fri Aug 10 07:01:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 07:01:41 +0300 Subject: dovecot-2.2: Previous istream-base64 changes broke compilation Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b3567ec85f9e changeset: 14847:b3567ec85f9e user: Timo Sirainen date: Fri Aug 10 07:01:34 2012 +0300 description: Previous istream-base64 changes broke compilation diffstat: src/lib-mail/istream-attachment-connector.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 4d13da5c571b -r b3567ec85f9e src/lib-mail/istream-attachment-connector.c --- a/src/lib-mail/istream-attachment-connector.c Fri Aug 10 07:00:20 2012 +0300 +++ b/src/lib-mail/istream-attachment-connector.c Fri Aug 10 07:01:34 2012 +0300 @@ -5,7 +5,7 @@ #include "istream.h" #include "istream-concat.h" #include "istream-sized.h" -#include "istream-base64-encoder.h" +#include "istream-base64.h" #include "istream-attachment-connector.h" struct istream_attachment_connector { From dovecot at dovecot.org Fri Aug 10 07:32:01 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 07:32:01 +0300 Subject: dovecot-2.1: quoted-printable decode didn't ignore whitespace at... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/cc5f888d466a changeset: 14662:cc5f888d466a user: Timo Sirainen date: Fri Aug 10 07:31:28 2012 +0300 description: quoted-printable decode didn't ignore whitespace at the end of soft line break. diffstat: src/lib-mail/quoted-printable.c | 42 +++++++++++++++++++++++------------ src/lib-mail/test-quoted-printable.c | 6 ++-- 2 files changed, 30 insertions(+), 18 deletions(-) diffs (85 lines): diff -r 9d0873cefa08 -r cc5f888d466a src/lib-mail/quoted-printable.c --- a/src/lib-mail/quoted-printable.c Fri Aug 10 02:34:34 2012 +0300 +++ b/src/lib-mail/quoted-printable.c Fri Aug 10 07:31:28 2012 +0300 @@ -8,11 +8,31 @@ #define QP_IS_TRAILING_SPACE(c) \ ((c) == ' ' || (c) == '\t') +static int +qp_is_end_of_line(const unsigned char *src, size_t *src_pos, size_t size) +{ + size_t i = *src_pos; + + i_assert(src[i] == '='); + for (i++; i < size; i++) { + if (QP_IS_TRAILING_SPACE(src[i]) || src[i] == '\r') + continue; + + if (src[i] != '\n') + return 0; + + *src_pos = i; + return 1; + } + return -1; +} + void quoted_printable_decode(const unsigned char *src, size_t src_size, size_t *src_pos_r, buffer_t *dest) { char hexbuf[3]; size_t src_pos, pos, next; + int ret; hexbuf[2] = '\0'; @@ -38,26 +58,18 @@ buffer_append(dest, src + next, src_pos - next); next = src_pos; - if (src_pos+1 >= src_size) - break; - - if (src[src_pos+1] == '\n') { - /* =\n -> skip both */ - src_pos++; - next += 2; + if ((ret = qp_is_end_of_line(src, &src_pos, src_size)) > 0) { + /* =[whitespace][\r]\n */ + next = src_pos+1; continue; } - + if (ret < 0) { + /* unknown yet if this is end of line */ + break; + } if (src_pos+2 >= src_size) break; - if (src[src_pos+1] == '\r' && src[src_pos+2] == '\n') { - /* =\r\n -> skip both */ - src_pos += 2; - next += 3; - continue; - } - /* = */ hexbuf[0] = src[src_pos+1]; hexbuf[1] = src[src_pos+2]; diff -r 9d0873cefa08 -r cc5f888d466a src/lib-mail/test-quoted-printable.c --- a/src/lib-mail/test-quoted-printable.c Fri Aug 10 02:34:34 2012 +0300 +++ b/src/lib-mail/test-quoted-printable.c Fri Aug 10 07:31:28 2012 +0300 @@ -16,9 +16,9 @@ { static struct test_quoted_printable_decode_data data[] = { { "foo \r\nbar=", "foo\r\nbar", 1 }, - { "foo =\nbar", "foo bar", 0 }, - { "foo =\n=01", "foo \001", 0 }, - { "foo =\r\nbar", "foo bar", 0 }, + { "foo\t=\nbar", "foo\tbar", 0 }, + { "foo = \n=01", "foo \001", 0 }, + { "foo =\t\r\nbar", "foo bar", 0 }, { "foo =\r\n=01", "foo \001", 0 }, { "foo \nbar=", "foo\r\nbar", 1 }, { "=0A=0D ", "\n\r", 2 }, From dovecot at dovecot.org Fri Aug 10 07:32:20 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 07:32:20 +0300 Subject: dovecot-2.2: quoted-printable decode didn't ignore whitespace at... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9195486cb5c2 changeset: 14848:9195486cb5c2 user: Timo Sirainen date: Fri Aug 10 07:31:28 2012 +0300 description: quoted-printable decode didn't ignore whitespace at the end of soft line break. diffstat: src/lib-mail/quoted-printable.c | 42 +++++++++++++++++++++++------------ src/lib-mail/test-quoted-printable.c | 6 ++-- 2 files changed, 30 insertions(+), 18 deletions(-) diffs (85 lines): diff -r b3567ec85f9e -r 9195486cb5c2 src/lib-mail/quoted-printable.c --- a/src/lib-mail/quoted-printable.c Fri Aug 10 07:01:34 2012 +0300 +++ b/src/lib-mail/quoted-printable.c Fri Aug 10 07:31:28 2012 +0300 @@ -8,11 +8,31 @@ #define QP_IS_TRAILING_SPACE(c) \ ((c) == ' ' || (c) == '\t') +static int +qp_is_end_of_line(const unsigned char *src, size_t *src_pos, size_t size) +{ + size_t i = *src_pos; + + i_assert(src[i] == '='); + for (i++; i < size; i++) { + if (QP_IS_TRAILING_SPACE(src[i]) || src[i] == '\r') + continue; + + if (src[i] != '\n') + return 0; + + *src_pos = i; + return 1; + } + return -1; +} + void quoted_printable_decode(const unsigned char *src, size_t src_size, size_t *src_pos_r, buffer_t *dest) { char hexbuf[3]; size_t src_pos, pos, next; + int ret; hexbuf[2] = '\0'; @@ -38,26 +58,18 @@ buffer_append(dest, src + next, src_pos - next); next = src_pos; - if (src_pos+1 >= src_size) - break; - - if (src[src_pos+1] == '\n') { - /* =\n -> skip both */ - src_pos++; - next += 2; + if ((ret = qp_is_end_of_line(src, &src_pos, src_size)) > 0) { + /* =[whitespace][\r]\n */ + next = src_pos+1; continue; } - + if (ret < 0) { + /* unknown yet if this is end of line */ + break; + } if (src_pos+2 >= src_size) break; - if (src[src_pos+1] == '\r' && src[src_pos+2] == '\n') { - /* =\r\n -> skip both */ - src_pos += 2; - next += 3; - continue; - } - /* = */ hexbuf[0] = src[src_pos+1]; hexbuf[1] = src[src_pos+2]; diff -r b3567ec85f9e -r 9195486cb5c2 src/lib-mail/test-quoted-printable.c --- a/src/lib-mail/test-quoted-printable.c Fri Aug 10 07:01:34 2012 +0300 +++ b/src/lib-mail/test-quoted-printable.c Fri Aug 10 07:31:28 2012 +0300 @@ -16,9 +16,9 @@ { static struct test_quoted_printable_decode_data data[] = { { "foo \r\nbar=", "foo\r\nbar", 1 }, - { "foo =\nbar", "foo bar", 0 }, - { "foo =\n=01", "foo \001", 0 }, - { "foo =\r\nbar", "foo bar", 0 }, + { "foo\t=\nbar", "foo\tbar", 0 }, + { "foo = \n=01", "foo \001", 0 }, + { "foo =\t\r\nbar", "foo bar", 0 }, { "foo =\r\n=01", "foo \001", 0 }, { "foo \nbar=", "foo\r\nbar", 1 }, { "=0A=0D ", "\n\r", 2 }, From dovecot at dovecot.org Fri Aug 10 07:32:20 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 10 Aug 2012 07:32:20 +0300 Subject: dovecot-2.2: Added istream-qp-decoder Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b26aa0641080 changeset: 14849:b26aa0641080 user: Timo Sirainen date: Fri Aug 10 07:32:14 2012 +0300 description: Added istream-qp-decoder diffstat: src/lib-mail/Makefile.am | 7 + src/lib-mail/istream-qp-decoder.c | 130 +++++++++++++++++++++++++++++++++ src/lib-mail/istream-qp.h | 6 + src/lib-mail/test-istream-qp-decoder.c | 69 +++++++++++++++++ 4 files changed, 212 insertions(+), 0 deletions(-) diffs (255 lines): diff -r 9195486cb5c2 -r b26aa0641080 src/lib-mail/Makefile.am --- a/src/lib-mail/Makefile.am Fri Aug 10 07:31:28 2012 +0300 +++ b/src/lib-mail/Makefile.am Fri Aug 10 07:32:14 2012 +0300 @@ -12,6 +12,7 @@ istream-dot.c \ istream-header-filter.c \ istream-nonuls.c \ + istream-qp-decoder.c \ mail-user-hash.c \ mbox-from.c \ message-address.c \ @@ -37,6 +38,7 @@ istream-dot.h \ istream-header-filter.h \ istream-nonuls.h \ + istream-qp.h \ mail-user-hash.h \ mbox-from.h \ mail-types.h \ @@ -64,6 +66,7 @@ test-istream-attachment \ test-istream-binary-converter \ test-istream-header-filter \ + test-istream-qp-decoder \ test-mbox-from \ test-message-address \ test-message-date \ @@ -86,6 +89,10 @@ test_istream_dot_LDADD = istream-dot.lo $(test_libs) test_istream_dot_DEPENDENCIES = istream-dot.lo $(test_libs) +test_istream_qp_decoder_SOURCES = test-istream-qp-decoder.c +test_istream_qp_decoder_LDADD = istream-qp-decoder.lo quoted-printable.lo $(test_libs) +test_istream_qp_decoder_DEPENDENCIES = istream-qp-decoder.lo quoted-printable.lo $(test_libs) + message_parser_objects = \ message-parser.lo \ message-header-parser.lo \ diff -r 9195486cb5c2 -r b26aa0641080 src/lib-mail/istream-qp-decoder.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-mail/istream-qp-decoder.c Fri Aug 10 07:32:14 2012 +0300 @@ -0,0 +1,130 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "buffer.h" +#include "istream-private.h" +#include "quoted-printable.h" +#include "istream-qp.h" + +struct qp_decoder_istream { + struct istream_private istream; +}; + +static int +i_stream_read_parent(struct istream_private *stream, size_t *prev_size) +{ + size_t size; + ssize_t ret; + + size = i_stream_get_data_size(stream->parent); + if (size >= 4 && size != *prev_size) { + *prev_size = size; + return 1; + } + + /* we have less than one qp block. + see if there is more data available. */ + ret = i_stream_read(stream->parent); + if (ret <= 0) { + stream->istream.stream_errno = stream->parent->stream_errno; + stream->istream.eof = stream->parent->eof; + return ret; + } + *prev_size = i_stream_get_data_size(stream->parent); + return 1; +} + +static int +i_stream_qp_try_decode_block(struct qp_decoder_istream *bstream) +{ + struct istream_private *stream = &bstream->istream; + const unsigned char *data; + size_t size, avail, buffer_avail, pos; + buffer_t buf; + + data = i_stream_get_data(stream->parent, &size); + if (size == 0) + return 0; + + i_stream_try_alloc(stream, (size+3)/4*3, &avail); + buffer_avail = stream->buffer_size - stream->pos; + + if ((size + 3) / 4 * 3 > buffer_avail) { + /* can't fit everything to destination buffer. + write as much as we can. */ + size = (buffer_avail / 3) * 4; + if (size == 0) + return -2; + } + + buffer_create_data(&buf, stream->w_buffer + stream->pos, buffer_avail); + quoted_printable_decode(data, size, &pos, &buf); + + stream->pos += buf.used; + i_stream_skip(stream->parent, pos); + return pos > 0 ? 1 : 0; +} + +static ssize_t i_stream_qp_decoder_read(struct istream_private *stream) +{ + struct qp_decoder_istream *bstream = + (struct qp_decoder_istream *)stream; + size_t pre_count, post_count; + int ret; + size_t prev_size = 0; + + do { + ret = i_stream_read_parent(stream, &prev_size); + if (ret <= 0) { + if (ret < 0 && stream->istream.stream_errno == 0 && + i_stream_get_data_size(stream->parent) > 0) { + /* qp input with a partial block */ + stream->istream.stream_errno = EINVAL; + } + return ret; + } + + /* encode as many blocks as fits into destination buffer */ + pre_count = stream->pos - stream->skip; + while ((ret = i_stream_qp_try_decode_block(bstream)) > 0) ; + post_count = stream->pos - stream->skip; + } while (ret == 0 && pre_count == post_count); + + if (ret < 0) + return ret; + + i_assert(post_count > pre_count); + return post_count - pre_count; +} + +static void +i_stream_qp_decoder_seek(struct istream_private *stream, + uoff_t v_offset, bool mark) +{ + if (v_offset < stream->istream.v_offset) { + /* seeking backwards - go back to beginning and seek + forward from there. */ + stream->parent_expected_offset = stream->parent_start_offset; + stream->skip = stream->pos = 0; + stream->istream.v_offset = 0; + i_stream_seek(stream->parent, 0); + } + i_stream_default_seek_nonseekable(stream, v_offset, mark); +} + +struct istream *i_stream_create_qp_decoder(struct istream *input) +{ + struct qp_decoder_istream *bstream; + + bstream = i_new(struct qp_decoder_istream, 1); + bstream->istream.max_buffer_size = input->real_stream->max_buffer_size; + + bstream->istream.read = i_stream_qp_decoder_read; + bstream->istream.seek = i_stream_qp_decoder_seek; + + bstream->istream.istream.readable_fd = FALSE; + bstream->istream.istream.blocking = input->blocking; + bstream->istream.istream.seekable = input->seekable; + return i_stream_create(&bstream->istream, input, + i_stream_get_fd(input)); +} diff -r 9195486cb5c2 -r b26aa0641080 src/lib-mail/istream-qp.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-mail/istream-qp.h Fri Aug 10 07:32:14 2012 +0300 @@ -0,0 +1,6 @@ +#ifndef ISTREAM_QP_H +#define ISTREAM_QP_H + +struct istream *i_stream_create_qp_decoder(struct istream *input); + +#endif diff -r 9195486cb5c2 -r b26aa0641080 src/lib-mail/test-istream-qp-decoder.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-mail/test-istream-qp-decoder.c Fri Aug 10 07:32:14 2012 +0300 @@ -0,0 +1,69 @@ +/* Copyright (c) 2010-2012 Dovecot authors, see the included COPYING file */ + +#include "test-lib.h" +#include "str.h" +#include "istream-private.h" +#include "istream-qp.h" + +struct { + const char *input; + const char *output; +} tests[] = { + { "p=C3=A4=C3=A4t=C3=B6s", "p??t?s" }, + { "p=c3=a4=c3=a4t=c3=b6s", "p??t?s" }, + { "p=c3=a4= \t \n=c3=\r\n=a4t= \r\n=c3=b6s", "p??t?s" }, +}; + +static void +decode_test(const char *qp_input, const char *output, bool broken_input) +{ + unsigned int qp_input_len = strlen(qp_input); + struct istream *input_data, *input; + const unsigned char *data; + size_t i, size; + int ret = 0; + + input_data = test_istream_create_data(qp_input, qp_input_len); + test_istream_set_allow_eof(input_data, FALSE); + input = i_stream_create_qp_decoder(input_data); + + for (i = 1; i <= qp_input_len; i++) { + test_istream_set_size(input_data, i); + while ((ret = i_stream_read(input)) > 0) ; + if (ret == -1 && broken_input) + break; + test_assert(ret == 0); + } + if (ret == 0) { + test_istream_set_allow_eof(input_data, TRUE); + while ((ret = i_stream_read(input)) > 0) ; + } + test_assert(ret == -1); + test_assert((input->stream_errno == 0 && !broken_input) || + (input->stream_errno == EINVAL && broken_input)); + + data = i_stream_get_data(input, &size); + test_assert(size == strlen(output) && memcmp(data, output, size) == 0); + i_stream_unref(&input); + i_stream_unref(&input_data); +} + +static void test_istream_qp_decoder(void) +{ + unsigned int i; + + for (i = 0; i < N_ELEMENTS(tests); i++) { + test_begin(t_strdup_printf("istream qp decoder %u", i+1)); + decode_test(tests[i].input, tests[i].output, FALSE); + test_end(); + } +} + +int main(void) +{ + static void (*test_functions[])(void) = { + test_istream_qp_decoder, + NULL + }; + return test_run(test_functions); +} From dovecot at dovecot.org Sat Aug 11 02:16:19 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 11 Aug 2012 02:16:19 +0300 Subject: dovecot-2.2: Makefile: Removed mountpoint.o from unused_objects,... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6008a36cb36c changeset: 14850:6008a36cb36c user: Timo Sirainen date: Sat Aug 11 02:16:07 2012 +0300 description: Makefile: Removed mountpoint.o from unused_objects, since it's now included via lib-master. diffstat: src/doveadm/Makefile.am | 1 - src/imap/Makefile.am | 7 ------- src/indexer/Makefile.am | 1 - src/lda/Makefile.am | 1 - src/lmtp/Makefile.am | 1 - src/pop3/Makefile.am | 1 - 6 files changed, 0 insertions(+), 12 deletions(-) diffs (77 lines): diff -r b26aa0641080 -r 6008a36cb36c src/doveadm/Makefile.am --- a/src/doveadm/Makefile.am Fri Aug 10 07:32:14 2012 +0300 +++ b/src/doveadm/Makefile.am Sat Aug 11 02:16:07 2012 +0300 @@ -27,7 +27,6 @@ if !BUILD_SHARED_LIBS unused_objects = \ - ../lib/mountpoint.o \ ../lib-imap/imap-util.o \ ../lib-storage/mail-search-parser-imap.o endif diff -r b26aa0641080 -r 6008a36cb36c src/imap/Makefile.am --- a/src/imap/Makefile.am Fri Aug 10 07:32:14 2012 +0300 +++ b/src/imap/Makefile.am Sat Aug 11 02:16:07 2012 +0300 @@ -15,18 +15,11 @@ imap_LDFLAGS = -export-dynamic -if !BUILD_SHARED_LIBS -unused_objects = \ - ../lib/mountpoint.o -endif - imap_LDADD = \ - $(unused_objects) \ $(LIBDOVECOT_STORAGE) \ $(LIBDOVECOT) \ $(MODULE_LIBS) imap_DEPENDENCIES = \ - $(unused_objects) \ $(LIBDOVECOT_STORAGE_DEPS) \ $(LIBDOVECOT_DEPS) diff -r b26aa0641080 -r 6008a36cb36c src/indexer/Makefile.am --- a/src/indexer/Makefile.am Fri Aug 10 07:32:14 2012 +0300 +++ b/src/indexer/Makefile.am Sat Aug 11 02:16:07 2012 +0300 @@ -22,7 +22,6 @@ if !BUILD_SHARED_LIBS unused_objects = \ - ../lib/mountpoint.o \ ../lib-imap/imap-util.o \ ../lib-storage/mail-search-parser-imap.o endif diff -r b26aa0641080 -r 6008a36cb36c src/lda/Makefile.am --- a/src/lda/Makefile.am Fri Aug 10 07:32:14 2012 +0300 +++ b/src/lda/Makefile.am Sat Aug 11 02:16:07 2012 +0300 @@ -18,7 +18,6 @@ if !BUILD_SHARED_LIBS unused_objects = \ - ../lib/mountpoint.o \ ../lib-mail/message-header-encode.o \ ../lib-imap/imap-util.o \ ../lib-storage/mail-search-parser-imap.o diff -r b26aa0641080 -r 6008a36cb36c src/lmtp/Makefile.am --- a/src/lmtp/Makefile.am Fri Aug 10 07:32:14 2012 +0300 +++ b/src/lmtp/Makefile.am Sat Aug 11 02:16:07 2012 +0300 @@ -19,7 +19,6 @@ if !BUILD_SHARED_LIBS unused_objects = \ - ../lib/mountpoint.o \ ../lib-mail/message-header-encode.o \ ../lib-imap/imap-util.o \ ../lib-storage/mail-search-parser-imap.o \ diff -r b26aa0641080 -r 6008a36cb36c src/pop3/Makefile.am --- a/src/pop3/Makefile.am Fri Aug 10 07:32:14 2012 +0300 +++ b/src/pop3/Makefile.am Sat Aug 11 02:16:07 2012 +0300 @@ -14,7 +14,6 @@ if !BUILD_SHARED_LIBS unused_objects = \ - ../lib/mountpoint.o \ ../lib-imap/imap-util.o \ ../lib-storage/mail-search-parser-imap.o endif From dovecot at dovecot.org Sat Aug 11 02:54:03 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 11 Aug 2012 02:54:03 +0300 Subject: dovecot-2.2: Added o_stream_get_fd(). Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4bcd507e8907 changeset: 14851:4bcd507e8907 user: Timo Sirainen date: Sat Aug 11 02:53:49 2012 +0300 description: Added o_stream_get_fd(). diffstat: src/lib-compression/ostream-bzlib.c | 3 ++- src/lib-compression/ostream-zlib.c | 3 ++- src/lib-fs/ostream-cmp.c | 3 ++- src/lib-ssl-iostream/ostream-openssl.c | 3 ++- src/lib/ostream-buffer.c | 2 +- src/lib/ostream-file.c | 4 ++-- src/lib/ostream-private.h | 3 ++- src/lib/ostream-rawlog.c | 2 +- src/lib/ostream.c | 8 +++++++- src/lib/ostream.h | 3 +++ 10 files changed, 24 insertions(+), 10 deletions(-) diffs (151 lines): diff -r 6008a36cb36c -r 4bcd507e8907 src/lib-compression/ostream-bzlib.c --- a/src/lib-compression/ostream-bzlib.c Sat Aug 11 02:16:07 2012 +0300 +++ b/src/lib-compression/ostream-bzlib.c Sat Aug 11 02:53:49 2012 +0300 @@ -217,6 +217,7 @@ zstream->zs.next_out = zstream->outbuf; zstream->zs.avail_out = sizeof(zstream->outbuf); - return o_stream_create(&zstream->ostream, output); + return o_stream_create(&zstream->ostream, output, + o_stream_get_fd(output)); } #endif diff -r 6008a36cb36c -r 4bcd507e8907 src/lib-compression/ostream-zlib.c --- a/src/lib-compression/ostream-zlib.c Sat Aug 11 02:16:07 2012 +0300 +++ b/src/lib-compression/ostream-zlib.c Sat Aug 11 02:53:49 2012 +0300 @@ -310,7 +310,8 @@ zstream->zs.next_out = zstream->outbuf; zstream->zs.avail_out = sizeof(zstream->outbuf); - return o_stream_create(&zstream->ostream, output); + return o_stream_create(&zstream->ostream, output, + o_stream_get_fd(output)); } struct ostream *o_stream_create_gz(struct ostream *output, int level) diff -r 6008a36cb36c -r 4bcd507e8907 src/lib-fs/ostream-cmp.c --- a/src/lib-fs/ostream-cmp.c Sat Aug 11 02:16:07 2012 +0300 +++ b/src/lib-fs/ostream-cmp.c Sat Aug 11 02:53:49 2012 +0300 @@ -80,7 +80,8 @@ cstream->equals = TRUE; i_stream_ref(input); - return o_stream_create(&cstream->ostream, output); + return o_stream_create(&cstream->ostream, output, + o_stream_get_fd(output)); } bool o_stream_cmp_equals(struct ostream *_output) diff -r 6008a36cb36c -r 4bcd507e8907 src/lib-ssl-iostream/ostream-openssl.c --- a/src/lib-ssl-iostream/ostream-openssl.c Sat Aug 11 02:16:07 2012 +0300 +++ b/src/lib-ssl-iostream/ostream-openssl.c Sat Aug 11 02:53:49 2012 +0300 @@ -256,5 +256,6 @@ o_stream_set_flush_callback(ssl_io->plain_output, plain_flush_callback, sstream); - return o_stream_create(&sstream->ostream, NULL); + return o_stream_create(&sstream->ostream, NULL, + o_stream_get_fd(ssl_io->plain_output)); } diff -r 6008a36cb36c -r 4bcd507e8907 src/lib/ostream-buffer.c --- a/src/lib/ostream-buffer.c Sat Aug 11 02:16:07 2012 +0300 +++ b/src/lib/ostream-buffer.c Sat Aug 11 02:53:49 2012 +0300 @@ -60,7 +60,7 @@ bstream->ostream.write_at = o_stream_buffer_write_at; bstream->buf = buf; - output = o_stream_create(&bstream->ostream, NULL); + output = o_stream_create(&bstream->ostream, NULL, -1); o_stream_set_name(output, "(buffer)"); return output; } diff -r 6008a36cb36c -r 4bcd507e8907 src/lib/ostream-file.c --- a/src/lib/ostream-file.c Sat Aug 11 02:16:07 2012 +0300 +++ b/src/lib/ostream-file.c Sat Aug 11 02:53:49 2012 +0300 @@ -933,7 +933,7 @@ fstream = o_stream_create_fd_common(fd, autoclose_fd); fstream->ostream.max_buffer_size = max_buffer_size; - ostream = o_stream_create(&fstream->ostream, NULL); + ostream = o_stream_create(&fstream->ostream, NULL, fd); offset = lseek(fd, 0, SEEK_CUR); if (offset >= 0) { @@ -969,7 +969,7 @@ fstream->real_offset = offset; fstream->buffer_offset = offset; - ostream = o_stream_create(&fstream->ostream, NULL); + ostream = o_stream_create(&fstream->ostream, NULL, fd); ostream->offset = offset; return ostream; } diff -r 6008a36cb36c -r 4bcd507e8907 src/lib/ostream-private.h --- a/src/lib/ostream-private.h Sat Aug 11 02:16:07 2012 +0300 +++ b/src/lib/ostream-private.h Sat Aug 11 02:53:49 2012 +0300 @@ -32,6 +32,7 @@ struct ostream *parent; /* for filter streams */ + int fd; stream_flush_callback_t *callback; void *context; @@ -41,7 +42,7 @@ }; struct ostream * -o_stream_create(struct ostream_private *_stream, struct ostream *parent) +o_stream_create(struct ostream_private *_stream, struct ostream *parent, int fd) ATTR_NULL(2); off_t io_stream_copy(struct ostream *outstream, struct istream *instream, diff -r 6008a36cb36c -r 4bcd507e8907 src/lib/ostream-rawlog.c --- a/src/lib/ostream-rawlog.c Sat Aug 11 02:16:07 2012 +0300 +++ b/src/lib/ostream-rawlog.c Sat Aug 11 02:53:49 2012 +0300 @@ -58,5 +58,5 @@ rstream->riostream.autoclose_fd = autoclose_fd; rstream->riostream.write_timestamp = TRUE; - return o_stream_create(&rstream->ostream, output); + return o_stream_create(&rstream->ostream, output, -1); } diff -r 6008a36cb36c -r 4bcd507e8907 src/lib/ostream.c --- a/src/lib/ostream.c Sat Aug 11 02:16:07 2012 +0300 +++ b/src/lib/ostream.c Sat Aug 11 02:53:49 2012 +0300 @@ -20,6 +20,11 @@ return stream->real_stream->iostream.name; } +int o_stream_get_fd(struct ostream *stream) +{ + return stream->real_stream->fd; +} + void o_stream_destroy(struct ostream **stream) { o_stream_close(*stream); @@ -459,8 +464,9 @@ } struct ostream * -o_stream_create(struct ostream_private *_stream, struct ostream *parent) +o_stream_create(struct ostream_private *_stream, struct ostream *parent, int fd) { + _stream->fd = fd; _stream->ostream.real_stream = _stream; if (parent != NULL) { _stream->parent = parent; diff -r 6008a36cb36c -r 4bcd507e8907 src/lib/ostream.h --- a/src/lib/ostream.h Sat Aug 11 02:16:07 2012 +0300 +++ b/src/lib/ostream.h Sat Aug 11 02:53:49 2012 +0300 @@ -42,6 +42,9 @@ /* Get output stream's name. Returns "" if stream has no name. */ const char *o_stream_get_name(struct ostream *stream); +/* Return file descriptor for stream, or -1 if none is available. */ +int o_stream_get_fd(struct ostream *stream); + /* o_stream_close() + o_stream_unref() */ void o_stream_destroy(struct ostream **stream); /* Reference counting. References start from 1, so calling o_stream_unref() From dovecot at dovecot.org Sat Aug 11 03:14:56 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 11 Aug 2012 03:14:56 +0300 Subject: dovecot-2.2: istream-header-filter: Added i_stream_header_filter... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/04abd58abf7a changeset: 14852:04abd58abf7a user: Timo Sirainen date: Sat Aug 11 03:14:43 2012 +0300 description: istream-header-filter: Added i_stream_header_filter_add() to add extra headers. diffstat: src/lib-mail/istream-header-filter.c | 14 +++++++++++--- src/lib-mail/istream-header-filter.h | 12 ++++++++++-- src/lib-mail/test-istream-header-filter.c | 3 ++- src/lib-storage/index/index-mail-headers.c | 6 ++++-- src/lib-storage/index/mbox/mbox-save.c | 6 ++++-- 5 files changed, 31 insertions(+), 10 deletions(-) diffs (128 lines): diff -r 4bcd507e8907 -r 04abd58abf7a src/lib-mail/istream-header-filter.c --- a/src/lib-mail/istream-header-filter.c Sat Aug 11 02:53:49 2012 +0300 +++ b/src/lib-mail/istream-header-filter.c Sat Aug 11 03:14:43 2012 +0300 @@ -177,7 +177,7 @@ matched = TRUE; if (!mstream->header_parsed && mstream->callback != NULL) { - mstream->callback(hdr, &matched, + mstream->callback(mstream, hdr, &matched, mstream->context); } @@ -200,7 +200,8 @@ bool orig_matched = matched; mstream->parsed_lines = mstream->cur_line; - mstream->callback(hdr, &matched, mstream->context); + mstream->callback(mstream, hdr, &matched, + mstream->context); if (matched != orig_matched) { i_array_init(&mstream->match_change_lines, 8); array_append(&mstream->match_change_lines, @@ -275,7 +276,8 @@ mstream->hdr_ctx = NULL; if (!mstream->header_parsed && mstream->callback != NULL) - mstream->callback(NULL, &matched, mstream->context); + mstream->callback(mstream, NULL, + &matched, mstream->context); mstream->header_parsed = TRUE; mstream->header_read = TRUE; @@ -548,3 +550,9 @@ return i_stream_create(&mstream->istream, input, -1); } + +void i_stream_header_filter_add(struct header_filter_istream *input, + const void *data, size_t size) +{ + buffer_append(input->hdr_buf, data, size); +} diff -r 4bcd507e8907 -r 04abd58abf7a src/lib-mail/istream-header-filter.h --- a/src/lib-mail/istream-header-filter.h Sat Aug 11 02:53:49 2012 +0300 +++ b/src/lib-mail/istream-header-filter.h Sat Aug 11 03:14:43 2012 +0300 @@ -1,6 +1,8 @@ #ifndef ISTREAM_HEADER_FILTER_H #define ISTREAM_HEADER_FILTER_H +struct header_filter_istream; + enum header_filter_flags { /* Include only specified headers in output.*/ HEADER_FILTER_INCLUDE = 0x01, @@ -19,7 +21,8 @@ struct message_header_line; -typedef void header_filter_callback(struct message_header_line *hdr, +typedef void header_filter_callback(struct header_filter_istream *input, + struct message_header_line *hdr, bool *matched, void *context); extern header_filter_callback *null_header_filter_callback; @@ -35,7 +38,8 @@ #ifdef CONTEXT_TYPE_SAFETY # define i_stream_create_header_filter(input, flags, headers, headers_count, \ callback, context) \ - ({(void)(1 ? 0 : callback((struct message_header_line *)0, \ + ({(void)(1 ? 0 : callback((struct header_filter_istream *)0, \ + (struct message_header_line *)0, \ (bool *)0, context)); \ i_stream_create_header_filter(input, flags, headers, headers_count, \ (header_filter_callback *)callback, context); }) @@ -46,4 +50,8 @@ (header_filter_callback *)callback, context) #endif +/* Add more data to headers. Should called from the filter callback. */ +void i_stream_header_filter_add(struct header_filter_istream *input, + const void *data, size_t size); + #endif diff -r 4bcd507e8907 -r 04abd58abf7a src/lib-mail/test-istream-header-filter.c --- a/src/lib-mail/test-istream-header-filter.c Sat Aug 11 02:53:49 2012 +0300 +++ b/src/lib-mail/test-istream-header-filter.c Sat Aug 11 03:14:43 2012 +0300 @@ -8,7 +8,8 @@ #include "test-common.h" static void ATTR_NULL(3) -filter_callback(struct message_header_line *hdr, +filter_callback(struct header_filter_istream *input ATTR_UNUSED, + struct message_header_line *hdr, bool *matched, void *context ATTR_UNUSED) { if (hdr != NULL && hdr->name_offset == 0) { diff -r 4bcd507e8907 -r 04abd58abf7a src/lib-storage/index/index-mail-headers.c --- a/src/lib-storage/index/index-mail-headers.c Sat Aug 11 02:53:49 2012 +0300 +++ b/src/lib-storage/index/index-mail-headers.c Sat Aug 11 03:14:43 2012 +0300 @@ -779,8 +779,10 @@ return ret < 0 ? -1 : (list[0] != NULL ? 1 : 0); } -static void header_cache_callback(struct message_header_line *hdr, - bool *matched, struct index_mail *mail) +static void +header_cache_callback(struct header_filter_istream *input ATTR_UNUSED, + struct message_header_line *hdr, + bool *matched, struct index_mail *mail) { if (hdr != NULL && hdr->eoh) *matched = FALSE; diff -r 4bcd507e8907 -r 04abd58abf7a src/lib-storage/index/mbox/mbox-save.c --- a/src/lib-storage/index/mbox/mbox-save.c Sat Aug 11 02:53:49 2012 +0300 +++ b/src/lib-storage/index/mbox/mbox-save.c Sat Aug 11 03:14:43 2012 +0300 @@ -341,8 +341,10 @@ return 0; } -static void save_header_callback(struct message_header_line *hdr, - bool *matched, struct mbox_save_context *ctx) +static void +save_header_callback(struct header_filter_istream *input ATTR_UNUSED, + struct message_header_line *hdr, + bool *matched, struct mbox_save_context *ctx) { if (hdr != NULL) { if (strncmp(hdr->name, "From ", 5) == 0) { From dovecot at dovecot.org Sat Aug 11 04:09:55 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 11 Aug 2012 04:09:55 +0300 Subject: dovecot-2.2: imap: FETCH BODY[n] shouldn't include MIME headers Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5ceeb25ed337 changeset: 14853:5ceeb25ed337 user: Timo Sirainen date: Sat Aug 11 04:09:41 2012 +0300 description: imap: FETCH BODY[n] shouldn't include MIME headers diffstat: src/lib-imap-storage/imap-msgpart.c | 16 ++++++++++++---- 1 files changed, 12 insertions(+), 4 deletions(-) diffs (66 lines): diff -r 04abd58abf7a -r 5ceeb25ed337 src/lib-imap-storage/imap-msgpart.c --- a/src/lib-imap-storage/imap-msgpart.c Sat Aug 11 03:14:43 2012 +0300 +++ b/src/lib-imap-storage/imap-msgpart.c Sat Aug 11 04:09:41 2012 +0300 @@ -15,6 +15,7 @@ enum fetch_type { FETCH_FULL, FETCH_MIME, + FETCH_MIME_BODY, FETCH_HEADER, FETCH_HEADER_FIELDS, FETCH_HEADER_FIELDS_NOT, @@ -230,10 +231,13 @@ if (*section == '\0') { /* full message/MIME part */ - msgpart->fetch_type = FETCH_FULL; msgpart->wanted_fields |= MAIL_FETCH_STREAM_BODY; - if (*msgpart->section_number == '\0') + if (*msgpart->section_number == '\0') { + msgpart->fetch_type = FETCH_FULL; msgpart->wanted_fields |= MAIL_FETCH_STREAM_HEADER; + } else { + msgpart->fetch_type = FETCH_MIME_BODY; + } return 0; } section = t_str_ucase(section); @@ -242,11 +246,11 @@ msgpart->fetch_type = FETCH_MIME; msgpart->wanted_fields |= MAIL_FETCH_STREAM_BODY; } else if (strcmp(section, "TEXT") == 0) { - /* message body */ + /* body (for root or for message/rfc822) */ msgpart->fetch_type = FETCH_BODY; msgpart->wanted_fields |= MAIL_FETCH_STREAM_BODY; } else if (strncmp(section, "HEADER", 6) == 0) { - /* header */ + /* header (for root or for message/rfc822) */ if (section[6] == '\0') { msgpart->fetch_type = FETCH_HEADER; ret = 0; @@ -272,6 +276,8 @@ msgpart->wanted_fields |= MAIL_FETCH_STREAM_HEADER; else msgpart->wanted_fields |= MAIL_FETCH_STREAM_BODY; + } else { + i_unreached(); } return 0; } @@ -529,6 +535,7 @@ result_r->size_field = MAIL_FETCH_VIRTUAL_SIZE; break; case FETCH_MIME: + case FETCH_MIME_BODY: i_unreached(); case FETCH_HEADER: case FETCH_HEADER_FIELDS_NOT: @@ -577,6 +584,7 @@ case FETCH_HEADER_FIELDS_NOT: i_unreached(); case FETCH_BODY: + case FETCH_MIME_BODY: i_stream_skip(input, hdr_size.physical_size); part_size.physical_size += body_size.physical_size; part_size.virtual_size += body_size.virtual_size; From dovecot at dovecot.org Sat Aug 11 05:15:13 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 11 Aug 2012 05:15:13 +0300 Subject: dovecot-2.2: istream-seekable: Minor code cleanup. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/928b099a63cb changeset: 14854:928b099a63cb user: Timo Sirainen date: Sat Aug 11 05:15:00 2012 +0300 description: istream-seekable: Minor code cleanup. stream->buffer and sstream->buffer being two different things was a bit confusing. diffstat: src/lib/istream-seekable.c | 44 ++++++++++++++++++++++---------------------- 1 files changed, 22 insertions(+), 22 deletions(-) diffs (155 lines): diff -r 5ceeb25ed337 -r 928b099a63cb src/lib/istream-seekable.c --- a/src/lib/istream-seekable.c Sat Aug 11 04:09:41 2012 +0300 +++ b/src/lib/istream-seekable.c Sat Aug 11 05:15:00 2012 +0300 @@ -22,7 +22,7 @@ int (*fd_callback)(const char **path_r, void *context); void *context; - buffer_t *buffer; + buffer_t *membuf; struct istream **input, *cur_input; struct istream *fd_input; unsigned int cur_idx; @@ -46,8 +46,8 @@ struct seekable_istream *sstream = (struct seekable_istream *)stream; unsigned int i; - if (sstream->buffer != NULL) - buffer_free(&sstream->buffer); + if (sstream->membuf != NULL) + buffer_free(&sstream->membuf); if (sstream->fd_input != NULL) i_stream_unref(&sstream->fd_input); for (i = 0; sstream->input[i] != NULL; i++) @@ -84,14 +84,14 @@ return -1; /* copy our currently read buffer to it */ - if (write_full(fd, sstream->buffer->data, sstream->buffer->used) < 0) { + if (write_full(fd, sstream->membuf->data, sstream->membuf->used) < 0) { if (!ENOSPACE(errno)) i_error("write_full(%s) failed: %m", path); i_close_fd(&fd); return -1; } sstream->temp_path = i_strdup(path); - sstream->write_peak = sstream->buffer->used; + sstream->write_peak = sstream->membuf->used; sstream->fd = fd; sstream->fd_input = @@ -114,7 +114,7 @@ } stream->buffer = buffer; stream->pos = size; - buffer_free(&sstream->buffer); + buffer_free(&sstream->membuf); return 0; } @@ -161,9 +161,9 @@ i_assert(stream->skip == 0); - if (stream->istream.v_offset + stream->pos >= sstream->buffer->used) { + if (stream->istream.v_offset + stream->pos >= sstream->membuf->used) { /* need to read more */ - if (sstream->buffer->used >= stream->max_buffer_size) + if (sstream->membuf->used >= stream->max_buffer_size) return FALSE; size = sstream->cur_input == NULL ? 0 : @@ -178,13 +178,13 @@ /* we should have more now. */ data = i_stream_get_data(sstream->cur_input, &size); i_assert(size > 0); - buffer_append(sstream->buffer, data, size); + buffer_append(sstream->membuf, data, size); i_stream_skip(sstream->cur_input, size); } offset = stream->istream.v_offset; - stream->buffer = CONST_PTR_OFFSET(sstream->buffer->data, offset); - pos = sstream->buffer->used - offset; + stream->buffer = CONST_PTR_OFFSET(sstream->membuf->data, offset); + pos = sstream->membuf->used - offset; *ret_r = pos - stream->pos; i_assert(*ret_r > 0); @@ -197,15 +197,15 @@ struct istream_private *stream = &sstream->istream; void *data; - i_assert(sstream->buffer == NULL); + i_assert(sstream->membuf == NULL); - sstream->buffer = + sstream->membuf = buffer_create_dynamic(default_pool, sstream->write_peak); - data = buffer_append_space_unsafe(sstream->buffer, sstream->write_peak); + data = buffer_append_space_unsafe(sstream->membuf, sstream->write_peak); if (pread_full(sstream->fd, data, sstream->write_peak, 0) < 0) { i_error("read(%s) failed: %m", sstream->temp_path); - buffer_free(&sstream->buffer); + buffer_free(&sstream->membuf); return -1; } i_stream_destroy(&sstream->fd_input); @@ -227,7 +227,7 @@ stream->pos -= stream->skip; stream->skip = 0; - if (sstream->buffer != NULL) { + if (sstream->membuf != NULL) { if (read_from_buffer(sstream, &ret)) return ret; @@ -238,7 +238,7 @@ i_unreached(); return ret; } - i_assert(sstream->buffer == NULL); + i_assert(sstream->membuf == NULL); } i_assert(stream->istream.v_offset + stream->pos <= sstream->write_peak); @@ -299,7 +299,7 @@ return &stream->statbuf; } - if (sstream->buffer != NULL) { + if (sstream->membuf != NULL) { /* we want to know the full size of the file, so read until we're finished */ old_offset = stream->istream.v_offset; @@ -323,9 +323,9 @@ return i_stream_stat(sstream->fd_input, exact); } else { /* buffer is completely in memory */ - i_assert(sstream->buffer != NULL); + i_assert(sstream->membuf != NULL); - stream->statbuf.st_size = sstream->buffer->used; + stream->statbuf.st_size = sstream->membuf->used; return &stream->statbuf; } } @@ -361,7 +361,7 @@ sstream = i_new(struct seekable_istream, 1); sstream->fd_callback = fd_callback; sstream->context = context; - sstream->buffer = buffer_create_dynamic(default_pool, BUF_INITIAL_SIZE); + sstream->membuf = buffer_create_dynamic(default_pool, BUF_INITIAL_SIZE); sstream->istream.max_buffer_size = max_buffer_size; sstream->fd = -1; sstream->size = (uoff_t)-1; @@ -372,7 +372,7 @@ /* initialize our buffer from first stream's pending data */ data = i_stream_get_data(sstream->cur_input, &size); - buffer_append(sstream->buffer, data, size); + buffer_append(sstream->membuf, data, size); i_stream_skip(sstream->cur_input, size); sstream->istream.iostream.close = i_stream_seekable_close; From dovecot at dovecot.org Sat Aug 11 05:17:25 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 11 Aug 2012 05:17:25 +0300 Subject: dovecot-2.2: istream-seekable: When we reach EOF, unreference al... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2a973e6c25f8 changeset: 14855:2a973e6c25f8 user: Timo Sirainen date: Sat Aug 11 05:17:19 2012 +0300 description: istream-seekable: When we reach EOF, unreference all the input streams. diffstat: src/lib/istream-seekable.c | 20 +++++++++++--------- 1 files changed, 11 insertions(+), 9 deletions(-) diffs (66 lines): diff -r 928b099a63cb -r 2a973e6c25f8 src/lib/istream-seekable.c --- a/src/lib/istream-seekable.c Sat Aug 11 05:15:00 2012 +0300 +++ b/src/lib/istream-seekable.c Sat Aug 11 05:17:19 2012 +0300 @@ -41,17 +41,23 @@ i_stream_close(sstream->input[i]); } +static void unref_streams(struct seekable_istream *sstream) +{ + unsigned int i; + + for (i = 0; sstream->input[i] != NULL; i++) + i_stream_unref(&sstream->input[i]); +} + static void i_stream_seekable_destroy(struct iostream_private *stream) { struct seekable_istream *sstream = (struct seekable_istream *)stream; - unsigned int i; if (sstream->membuf != NULL) buffer_free(&sstream->membuf); if (sstream->fd_input != NULL) i_stream_unref(&sstream->fd_input); - for (i = 0; sstream->input[i] != NULL; i++) - i_stream_unref(&sstream->input[i]); + unref_streams(sstream); i_free(sstream->temp_path); i_free(sstream->input); @@ -159,8 +165,6 @@ const unsigned char *data; size_t size, pos, offset; - i_assert(stream->skip == 0); - if (stream->istream.v_offset + stream->pos >= sstream->membuf->used) { /* need to read more */ if (sstream->membuf->used >= stream->max_buffer_size) @@ -189,6 +193,7 @@ *ret_r = pos - stream->pos; i_assert(*ret_r > 0); stream->pos = pos; + stream->skip = 0; return TRUE; } @@ -223,10 +228,6 @@ size_t size, pos; ssize_t ret; - stream->buffer = CONST_PTR_OFFSET(stream->buffer, stream->skip); - stream->pos -= stream->skip; - stream->skip = 0; - if (sstream->membuf != NULL) { if (read_from_buffer(sstream, &ret)) return ret; @@ -316,6 +317,7 @@ } i_stream_skip(&stream->istream, stream->pos - stream->skip); i_stream_seek(&stream->istream, old_offset); + unref_streams(sstream); } if (sstream->fd_input != NULL) { From dovecot at dovecot.org Sat Aug 11 05:19:35 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 11 Aug 2012 05:19:35 +0300 Subject: dovecot-2.2: Added istreams_merge(), which forces istream-seekab... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/39f23dcb9e18 changeset: 14856:39f23dcb9e18 user: Timo Sirainen date: Sat Aug 11 05:17:58 2012 +0300 description: Added istreams_merge(), which forces istream-seekable to be created. diffstat: src/lib/istream-seekable.c | 34 ++++++++++++++++++++++------------ src/lib/istream-seekable.h | 7 +++++++ 2 files changed, 29 insertions(+), 12 deletions(-) diffs (72 lines): diff -r 2a973e6c25f8 -r 39f23dcb9e18 src/lib/istream-seekable.c --- a/src/lib/istream-seekable.c Sat Aug 11 05:17:19 2012 +0300 +++ b/src/lib/istream-seekable.c Sat Aug 11 05:17:58 2012 +0300 @@ -333,10 +333,9 @@ } struct istream * -i_stream_create_seekable(struct istream *input[], - size_t max_buffer_size, - int (*fd_callback)(const char **path_r, void *context), - void *context) +i_streams_merge(struct istream *input[], size_t max_buffer_size, + int (*fd_callback)(const char **path_r, void *context), + void *context) ATTR_NULL(4) { struct seekable_istream *sstream; const unsigned char *data; @@ -344,14 +343,6 @@ size_t size; bool blocking = TRUE; - /* If all input streams are seekable, use concat istream instead */ - for (count = 0; input[count] != NULL; count++) { - if (!input[count]->seekable) - break; - } - if (input[count] == NULL) - return i_stream_create_concat(input); - /* if any of the streams isn't blocking, set ourself also nonblocking */ for (count = 0; input[count] != NULL; count++) { if (!input[count]->blocking) @@ -390,3 +381,22 @@ sstream->istream.istream.seekable = TRUE; return i_stream_create(&sstream->istream, NULL, -1); } + +struct istream * +i_stream_create_seekable(struct istream *input[], + size_t max_buffer_size, + int (*fd_callback)(const char **path_r, void *context), + void *context) +{ + unsigned int count; + + /* If all input streams are seekable, use concat istream instead */ + for (count = 0; input[count] != NULL; count++) { + if (!input[count]->seekable) + break; + } + if (input[count] == NULL) + return i_stream_create_concat(input); + + return i_streams_merge(input, max_buffer_size, fd_callback, context); +} diff -r 2a973e6c25f8 -r 39f23dcb9e18 src/lib/istream-seekable.h --- a/src/lib/istream-seekable.h Sat Aug 11 05:17:19 2012 +0300 +++ b/src/lib/istream-seekable.h Sat Aug 11 05:17:58 2012 +0300 @@ -8,6 +8,13 @@ the fd and path of the created file. Typically the callback would also unlink the file before returning. */ struct istream * +i_streams_merge(struct istream *input[], size_t max_buffer_size, + int (*fd_callback)(const char **path_r, void *context), + void *context) ATTR_NULL(4); + +/* Same as i_streams_merge(), but if all of the inputs are seekable already, + create a concat stream instead. */ +struct istream * i_stream_create_seekable(struct istream *input[], size_t max_buffer_size, int (*fd_callback)(const char **path_r, void *context), From dovecot at dovecot.org Sat Aug 11 05:20:05 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 11 Aug 2012 05:20:05 +0300 Subject: dovecot-2.2: lib-mail: Added message_decoder_parse_cte() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/624107158354 changeset: 14857:624107158354 user: Timo Sirainen date: Sat Aug 11 05:19:58 2012 +0300 description: lib-mail: Added message_decoder_parse_cte() diffstat: src/lib-mail/message-decoder.c | 40 +++++++++++++++++----------------------- src/lib-mail/message-decoder.h | 13 +++++++++++++ 2 files changed, 30 insertions(+), 23 deletions(-) diffs (148 lines): diff -r 39f23dcb9e18 -r 624107158354 src/lib-mail/message-decoder.c --- a/src/lib-mail/message-decoder.c Sat Aug 11 05:17:58 2012 +0300 +++ b/src/lib-mail/message-decoder.c Sat Aug 11 05:19:58 2012 +0300 @@ -13,13 +13,6 @@ #include "message-header-decode.h" #include "message-decoder.h" -enum content_type { - CONTENT_TYPE_UNKNOWN = 0, - CONTENT_TYPE_BINARY, - CONTENT_TYPE_QP, - CONTENT_TYPE_BASE64 -}; - /* base64 takes max 4 bytes per character, q-p takes max 3. */ #define MAX_ENCODING_BUF_SIZE 3 @@ -42,7 +35,7 @@ buffer_t *encoding_buf; char *content_charset; - enum content_type content_type; + enum message_cte message_cte; unsigned int charset_utf8:1; unsigned int binary_input:1; @@ -92,11 +85,10 @@ message_decode_body_init_charset(ctx, ctx->prev_part); } -static void -parse_content_transfer_encoding(struct message_decoder_context *ctx, - struct message_header_line *hdr) +enum message_cte message_decoder_parse_cte(struct message_header_line *hdr) { struct rfc822_parser_context parser; + enum message_cte message_cte; string_t *value; value = t_str_new(64); @@ -105,24 +97,25 @@ rfc822_skip_lwsp(&parser); (void)rfc822_parse_mime_token(&parser, value); - ctx->content_type = CONTENT_TYPE_UNKNOWN; + message_cte = MESSAGE_CTE_UNKNOWN; switch (str_len(value)) { case 4: if (i_memcasecmp(str_data(value), "7bit", 4) == 0 || i_memcasecmp(str_data(value), "8bit", 4) == 0) - ctx->content_type = CONTENT_TYPE_BINARY; + message_cte = MESSAGE_CTE_78BIT; break; case 6: if (i_memcasecmp(str_data(value), "base64", 6) == 0) - ctx->content_type = CONTENT_TYPE_BASE64; + message_cte = MESSAGE_CTE_BASE64; else if (i_memcasecmp(str_data(value), "binary", 6) == 0) - ctx->content_type = CONTENT_TYPE_BINARY; + message_cte = MESSAGE_CTE_BINARY; break; case 16: if (i_memcasecmp(str_data(value), "quoted-printable", 16) == 0) - ctx->content_type = CONTENT_TYPE_QP; + message_cte = MESSAGE_CTE_QP; break; } + return message_cte; } static void @@ -170,7 +163,7 @@ parse_content_type(ctx, hdr); if (hdr->name_len == 25 && strcasecmp(hdr->name, "Content-Transfer-Encoding") == 0) - parse_content_transfer_encoding(ctx, hdr); + ctx->message_cte = message_decoder_parse_cte(hdr); } T_END; buffer_set_used_size(ctx->buf, 0); @@ -278,16 +271,17 @@ buffer_append(ctx->encoding_buf, input->data, input->size); } - switch (ctx->content_type) { - case CONTENT_TYPE_UNKNOWN: + switch (ctx->message_cte) { + case MESSAGE_CTE_UNKNOWN: /* just skip this body */ return FALSE; - case CONTENT_TYPE_BINARY: + case MESSAGE_CTE_78BIT: + case MESSAGE_CTE_BINARY: data = input->data; size = pos = input->size; break; - case CONTENT_TYPE_QP: + case MESSAGE_CTE_QP: buffer_set_used_size(ctx->buf, 0); if (ctx->encoding_buf->used != 0) { quoted_printable_decode(ctx->encoding_buf->data, @@ -300,7 +294,7 @@ data = ctx->buf->data; size = ctx->buf->used; break; - case CONTENT_TYPE_BASE64: + case MESSAGE_CTE_BASE64: buffer_set_used_size(ctx->buf, 0); if (ctx->encoding_buf->used != 0) { ret = base64_decode(ctx->encoding_buf->data, @@ -409,7 +403,7 @@ void message_decoder_decode_reset(struct message_decoder_context *ctx) { i_free_and_null(ctx->content_charset); - ctx->content_type = CONTENT_TYPE_BINARY; + ctx->message_cte = MESSAGE_CTE_78BIT; ctx->charset_utf8 = TRUE; buffer_set_used_size(ctx->encoding_buf, 0); } diff -r 39f23dcb9e18 -r 624107158354 src/lib-mail/message-decoder.h --- a/src/lib-mail/message-decoder.h Sat Aug 11 05:17:58 2012 +0300 +++ b/src/lib-mail/message-decoder.h Sat Aug 11 05:19:58 2012 +0300 @@ -1,6 +1,16 @@ #ifndef MESSAGE_DECODER_H #define MESSAGE_DECODER_H +struct message_header_line; + +enum message_cte { + MESSAGE_CTE_UNKNOWN = 0, + MESSAGE_CTE_78BIT, + MESSAGE_CTE_BINARY, + MESSAGE_CTE_QP, + MESSAGE_CTE_BASE64 +}; + enum message_decoder_flags { /* Return all headers and parts through uni_utf8_to_decomposed_titlecase() */ @@ -33,4 +43,7 @@ /* Call whenever message changes */ void message_decoder_decode_reset(struct message_decoder_context *ctx); +/* Decode Content-Transfer-Encoding header. */ +enum message_cte message_decoder_parse_cte(struct message_header_line *hdr); + #endif From dovecot at dovecot.org Sat Aug 11 05:29:13 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 11 Aug 2012 05:29:13 +0300 Subject: dovecot-2.2: istream-seekable: Reverted unnecessary/broken chang... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ae5ad2935674 changeset: 14858:ae5ad2935674 user: Timo Sirainen date: Sat Aug 11 05:29:05 2012 +0300 description: istream-seekable: Reverted unnecessary/broken changes from the previous patch. diffstat: src/lib/istream-seekable.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diffs (31 lines): diff -r 624107158354 -r ae5ad2935674 src/lib/istream-seekable.c --- a/src/lib/istream-seekable.c Sat Aug 11 05:19:58 2012 +0300 +++ b/src/lib/istream-seekable.c Sat Aug 11 05:29:05 2012 +0300 @@ -165,6 +165,8 @@ const unsigned char *data; size_t size, pos, offset; + i_assert(stream->skip == 0); + if (stream->istream.v_offset + stream->pos >= sstream->membuf->used) { /* need to read more */ if (sstream->membuf->used >= stream->max_buffer_size) @@ -193,7 +195,6 @@ *ret_r = pos - stream->pos; i_assert(*ret_r > 0); stream->pos = pos; - stream->skip = 0; return TRUE; } @@ -228,6 +229,10 @@ size_t size, pos; ssize_t ret; + stream->buffer = CONST_PTR_OFFSET(stream->buffer, stream->skip); + stream->pos -= stream->skip; + stream->skip = 0; + if (sstream->membuf != NULL) { if (read_from_buffer(sstream, &ret)) return ret; From dovecot at dovecot.org Sat Aug 11 05:31:53 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 11 Aug 2012 05:31:53 +0300 Subject: dovecot-2.2: IMAP BINARY extension supports now FETCH BINARY com... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f3ef88e19cd5 changeset: 14859:f3ef88e19cd5 user: Timo Sirainen date: Sat Aug 11 05:31:46 2012 +0300 description: IMAP BINARY extension supports now FETCH BINARY command. diffstat: src/doveadm/doveadm-mail.c | 1 + src/imap/cmd-fetch.c | 18 +- src/imap/imap-commands-util.c | 2 + src/imap/imap-fetch-body.c | 108 ++++++++- src/imap/imap-fetch.c | 1 + src/imap/imap-fetch.h | 1 + src/lib-imap-storage/imap-msgpart.c | 197 ++++++++++++--- src/lib-imap-storage/imap-msgpart.h | 14 + src/lib-storage/fail-mail.c | 12 + src/lib-storage/index/Makefile.am | 1 + src/lib-storage/index/cydir/cydir-mail.c | 1 + src/lib-storage/index/dbox-multi/mdbox-mail.c | 1 + src/lib-storage/index/dbox-single/sdbox-mail.c | 1 + src/lib-storage/index/imapc/imapc-mail.c | 1 + src/lib-storage/index/index-mail-binary.c | 313 +++++++++++++++++++++++++ src/lib-storage/index/index-mail.h | 4 + src/lib-storage/index/maildir/maildir-mail.c | 1 + src/lib-storage/index/mbox/mbox-mail.c | 1 + src/lib-storage/index/pop3c/pop3c-mail.c | 1 + src/lib-storage/index/raw/raw-mail.c | 1 + src/lib-storage/mail-error.h | 5 +- src/lib-storage/mail-storage-private.h | 18 + src/lib-storage/mail-storage.c | 12 + src/lib-storage/mail-storage.h | 12 + src/lib-storage/mail-user.c | 1 + src/lib-storage/mail.c | 24 + src/plugins/virtual/virtual-mail.c | 1 + 27 files changed, 701 insertions(+), 52 deletions(-) diffs (truncated from 1199 to 300 lines): diff -r ae5ad2935674 -r f3ef88e19cd5 src/doveadm/doveadm-mail.c --- a/src/doveadm/doveadm-mail.c Sat Aug 11 05:29:05 2012 +0300 +++ b/src/doveadm/doveadm-mail.c Sat Aug 11 05:31:46 2012 +0300 @@ -46,6 +46,7 @@ break; case MAIL_ERROR_NOTPOSSIBLE: case MAIL_ERROR_EXISTS: + case MAIL_ERROR_CONVERSION: exit_code = DOVEADM_EX_NOTPOSSIBLE; break; case MAIL_ERROR_PARAMS: diff -r ae5ad2935674 -r f3ef88e19cd5 src/imap/cmd-fetch.c --- a/src/imap/cmd-fetch.c Sat Aug 11 05:29:05 2012 +0300 +++ b/src/imap/cmd-fetch.c Sat Aug 11 05:31:46 2012 +0300 @@ -143,6 +143,7 @@ { static const char *ok_message = "OK Fetch completed."; const char *tagged_reply = ok_message; + enum mail_error error; if (ctx->skipped_expunged_msgs) { tagged_reply = "OK ["IMAP_RESP_CODE_EXPUNGEISSUED"] " @@ -160,12 +161,17 @@ return TRUE; } - errstr = mailbox_get_last_error(cmd->client->mailbox, NULL); - - /* We never want to reply NO to FETCH requests, - BYE is preferrable (see imap-ml for reasons). */ - client_disconnect_with_error(cmd->client, errstr); - return TRUE; + errstr = mailbox_get_last_error(cmd->client->mailbox, &error); + if (error == MAIL_ERROR_CONVERSION) { + /* BINARY found unsupported Content-Transfer-Encoding */ + tagged_reply = "NO ["IMAP_RESP_CODE_UNKNOWN_CTE"] " + "Unknown Content-Transfer-Encoding."; + } else { + /* We never want to reply NO to FETCH requests, + BYE is preferrable (see imap-ml for reasons). */ + client_disconnect_with_error(cmd->client, errstr); + return TRUE; + } } return cmd_sync(cmd, diff -r ae5ad2935674 -r f3ef88e19cd5 src/imap/imap-commands-util.c --- a/src/imap/imap-commands-util.c Sat Aug 11 05:29:05 2012 +0300 +++ b/src/imap/imap-commands-util.c Sat Aug 11 05:31:46 2012 +0300 @@ -134,6 +134,8 @@ case MAIL_ERROR_INUSE: resp_code = IMAP_RESP_CODE_INUSE; break; + case MAIL_ERROR_CONVERSION: + break; } if (resp_code == NULL || *error_string == '[') return t_strconcat("NO ", error_string, NULL); diff -r ae5ad2935674 -r f3ef88e19cd5 src/imap/imap-fetch-body.c --- a/src/imap/imap-fetch-body.c Sat Aug 11 05:29:05 2012 +0300 +++ b/src/imap/imap-fetch-body.c Sat Aug 11 05:31:46 2012 +0300 @@ -24,6 +24,8 @@ struct imap_msgpart *msgpart; unsigned int partial:1; + unsigned int binary:1; + unsigned int binary_size:1; }; static void fetch_read_error(struct imap_fetch_context *ctx) @@ -40,7 +42,13 @@ string_t *str; str = t_str_new(128); - str_printfa(str, "BODY[%s]", body->section); + if (body->binary_size) + str_append(str, "BINARY.SIZE"); + else if (body->binary) + str_append(str, "BINARY"); + else + str_append(str, "BODY"); + str_printfa(str, "[%s]", body->section); if (body->partial) { str_printfa(str, "<%"PRIuUOFF_T">", imap_msgpart_get_partial_offset(body->msgpart)); @@ -130,6 +138,27 @@ return ctx->cont_handler(ctx); } +static int fetch_binary_size(struct imap_fetch_context *ctx, struct mail *mail, + const struct imap_fetch_body_data *body) +{ + string_t *str; + size_t size; + + if (imap_msgpart_size(mail, body->msgpart, &size) < 0) + return -1; + + str = t_str_new(128); + if (ctx->first) + ctx->first = FALSE; + else + str_append_c(str, ' '); + str_printfa(str, "%s %"PRIuUOFF_T, get_body_name(body), size); + + if (o_stream_send(ctx->client->output, str_data(str), str_len(str)) < 0) + return -1; + return 1; +} + /* Parse next digits in string into integer. Returns -1 if the integer becomes too big and wraps. */ static int read_uoff_t(const char **p, uoff_t *value) @@ -294,6 +323,83 @@ return TRUE; } +bool imap_fetch_binary_init(struct imap_fetch_init_context *ctx) +{ + struct imap_fetch_body_data *body; + const struct imap_arg *list_args; + unsigned int list_count; + const char *str, *p, *error; + + i_assert(strncmp(ctx->name, "BINARY", 6) == 0); + p = ctx->name + 6; + + body = p_new(ctx->fetch_ctx->pool, struct imap_fetch_body_data, 1); + body->binary = TRUE; + + if (strncmp(p, ".SIZE", 5) == 0) { + /* fetch decoded size of the section */ + p += 5; + body->binary_size = TRUE; + } else if (strncmp(p, ".PEEK", 5) == 0) { + p += 5; + } else { + ctx->fetch_ctx->flags_update_seen = TRUE; + } + if (*p != '[') { + ctx->error = "Invalid BINARY[..] parameter: Missing '['"; + return FALSE; + } + + if (imap_arg_get_list_full(&ctx->args[0], &list_args, &list_count)) { + /* BINARY[HEADER.FIELDS.. (headers list)] */ + if (!imap_arg_get_atom(&ctx->args[1], &str) || + str[0] != ']') { + ctx->error = "Invalid BINARY[..] parameter: Missing ']'"; + return FALSE; + } + if (body_header_fields_parse(ctx, body, p+1, + list_args, list_count) < 0) + return FALSE; + p = str+1; + ctx->args += 2; + } else { + /* no headers list */ + body->section = p+1; + p = strchr(body->section, ']'); + if (p == NULL) { + ctx->error = "Invalid BINARY[..] parameter: Missing ']'"; + return FALSE; + } + body->section = p_strdup_until(ctx->fetch_ctx->pool, + body->section, p); + p++; + } + if (imap_msgpart_parse(ctx->fetch_ctx->box, body->section, + &body->msgpart) < 0) { + ctx->error = "Invalid BINARY[..] section"; + return -1; + } + imap_msgpart_set_decode_to_binary(body->msgpart); + ctx->fetch_ctx->fetch_data |= + imap_msgpart_get_fetch_data(body->msgpart); + + if (!body->binary_size) { + if (body_parse_partial(body, p, &error) < 0) { + ctx->error = p_strdup_printf(ctx->fetch_ctx->pool, + "Invalid BINARY[..] parameter: %s", error); + return FALSE; + } + } + + /* update the section name for the imap_fetch_add_handler() */ + ctx->name = p_strdup(ctx->fetch_ctx->pool, get_body_name(body)); + if (body->binary_size) + imap_fetch_add_handler(ctx, 0, "NIL", fetch_binary_size, body); + else + imap_fetch_add_handler(ctx, 0, "NIL", fetch_body_msgpart, body); + return TRUE; +} + static int ATTR_NULL(3) fetch_rfc822_size(struct imap_fetch_context *ctx, struct mail *mail, void *context ATTR_UNUSED) diff -r ae5ad2935674 -r f3ef88e19cd5 src/imap/imap-fetch.c --- a/src/imap/imap-fetch.c Sat Aug 11 05:29:05 2012 +0300 +++ b/src/imap/imap-fetch.c Sat Aug 11 05:31:46 2012 +0300 @@ -860,6 +860,7 @@ static const struct imap_fetch_handler imap_fetch_default_handlers[] = { + { "BINARY", imap_fetch_binary_init }, { "BODY", fetch_body_init }, { "BODYSTRUCTURE", fetch_bodystructure_init }, { "ENVELOPE", fetch_envelope_init }, diff -r ae5ad2935674 -r f3ef88e19cd5 src/imap/imap-fetch.h --- a/src/imap/imap-fetch.h Sat Aug 11 05:29:05 2012 +0300 +++ b/src/imap/imap-fetch.h Sat Aug 11 05:31:46 2012 +0300 @@ -125,6 +125,7 @@ bool imap_fetch_body_section_init(struct imap_fetch_init_context *ctx); bool imap_fetch_rfc822_init(struct imap_fetch_init_context *ctx); +bool imap_fetch_binary_init(struct imap_fetch_init_context *ctx); void imap_fetch_handlers_init(void); void imap_fetch_handlers_deinit(void); diff -r ae5ad2935674 -r f3ef88e19cd5 src/lib-imap-storage/imap-msgpart.c --- a/src/lib-imap-storage/imap-msgpart.c Sat Aug 11 05:29:05 2012 +0300 +++ b/src/lib-imap-storage/imap-msgpart.c Sat Aug 11 05:31:46 2012 +0300 @@ -5,8 +5,12 @@ #include "istream.h" #include "istream-crlf.h" #include "istream-nonuls.h" +#include "istream-base64.h" #include "istream-header-filter.h" +#include "istream-qp.h" +#include "ostream.h" #include "message-parser.h" +#include "message-decoder.h" #include "mail-storage-private.h" #include "mail-namespace.h" #include "imap-parser.h" @@ -37,6 +41,8 @@ /* which part of the message part to fetch (default: 0..(uoff_t)-1) */ uoff_t partial_offset, partial_size; + + unsigned int decode_cte_to_binary:1; }; struct imap_msgpart_open_ctx { @@ -293,6 +299,11 @@ pool_unref(&msgpart->pool); } +void imap_msgpart_set_decode_to_binary(struct imap_msgpart *msgpart) +{ + msgpart->decode_cte_to_binary = TRUE; +} + void imap_msgpart_set_partial(struct imap_msgpart *msgpart, uoff_t offset, uoff_t size) { @@ -394,7 +405,7 @@ const struct imap_msgpart *msgpart) { struct mail_msgpart_partial_cache *cache = &mail->box->partial_cache; - struct istream *nul_input, *crlf_input; + struct istream *crlf_input; const unsigned char *data; size_t size; uoff_t physical_start = input->v_offset; @@ -415,11 +426,6 @@ message parts. */ skip_using_parts(mail, input, &virtual_skip); } - if (!mail->has_no_nuls) { - nul_input = i_stream_create_nonuls(input, 0x80); - i_stream_unref(&input); - input = nul_input; - } crlf_input = i_stream_create_crlf(input); i_stream_unref(&input); input = crlf_input; @@ -445,6 +451,7 @@ static void imap_msgpart_get_partial(struct mail *mail, const struct imap_msgpart *msgpart, + bool convert_nuls, bool use_partial_cache, const struct message_size *part_size, struct imap_msgpart_open_result *result) { @@ -468,6 +475,7 @@ } else { /* input has LF linefeeds. it can be slow to seek to wanted position, so try to do caching whenever possible */ + i_assert(use_partial_cache); result->input = imap_msgpart_crlf_seek(mail, result->input, msgpart); } @@ -480,49 +488,73 @@ /* send all bytes */ result->size = bytes_left; } + + if (!mail->has_no_nuls && convert_nuls) { + /* IMAP literals must not contain NULs. change them to From dovecot at dovecot.org Sat Aug 11 05:47:13 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 11 Aug 2012 05:47:13 +0300 Subject: dovecot-2.2: imap: Send FETCH BINARY output using literal8. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f0feae227c60 changeset: 14860:f0feae227c60 user: Timo Sirainen date: Sat Aug 11 05:47:03 2012 +0300 description: imap: Send FETCH BINARY output using literal8. diffstat: src/imap/imap-fetch-body.c | 13 ++++++++----- src/lib-imap-storage/imap-msgpart.c | 3 +++ 2 files changed, 11 insertions(+), 5 deletions(-) diffs (51 lines): diff -r f3ef88e19cd5 -r f0feae227c60 src/imap/imap-fetch-body.c --- a/src/imap/imap-fetch-body.c Sat Aug 11 05:31:46 2012 +0300 +++ b/src/imap/imap-fetch-body.c Sat Aug 11 05:47:03 2012 +0300 @@ -58,7 +58,7 @@ static string_t *get_prefix(struct imap_fetch_context *ctx, const struct imap_fetch_body_data *body, - uoff_t size) + uoff_t size, bool has_nuls) { string_t *str; @@ -70,10 +70,12 @@ str_append(str, get_body_name(body)); - if (size != (uoff_t)-1) + if (size == (uoff_t)-1) + str_append(str, " NIL"); + else if (has_nuls && body->binary) + str_printfa(str, " ~{%"PRIuUOFF_T"}\r\n", size); + else str_printfa(str, " {%"PRIuUOFF_T"}\r\n", size); - else - str_append(str, " NIL"); return str; } @@ -131,7 +133,8 @@ ctx->cur_size_field = result.size_field; ctx->cur_name = p_strconcat(ctx->pool, "[", body->section, "]", NULL); - str = get_prefix(ctx, body, ctx->cur_size); + str = get_prefix(ctx, body, ctx->cur_size, + result.binary_decoded_input_has_nuls); o_stream_nsend(ctx->client->output, str_data(str), str_len(str)); ctx->cont_handler = fetch_stream_continue; diff -r f3ef88e19cd5 -r f0feae227c60 src/lib-imap-storage/imap-msgpart.c --- a/src/lib-imap-storage/imap-msgpart.c Sat Aug 11 05:31:46 2012 +0300 +++ b/src/lib-imap-storage/imap-msgpart.c Sat Aug 11 05:47:03 2012 +0300 @@ -665,6 +665,9 @@ use_partial_cache = TRUE; } + if (binary && msgpart->decode_cte_to_binary) + result_r->binary_decoded_input_has_nuls = TRUE; + imap_msgpart_get_partial(mail, msgpart, !binary, use_partial_cache, &part_size, result_r); return 0; From dovecot at dovecot.org Sat Aug 11 07:47:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 11 Aug 2012 07:47:40 +0300 Subject: dovecot-2.2: liblib: Added "number packing" API. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b45d968adff8 changeset: 14861:b45d968adff8 user: Timo Sirainen date: Sat Aug 11 07:46:42 2012 +0300 description: liblib: Added "number packing" API. diffstat: src/lib/Makefile.am | 3 +++ src/lib/numpack.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/lib/numpack.h | 10 ++++++++++ src/lib/test-lib.c | 1 + src/lib/test-lib.h | 1 + src/lib/test-numpack.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 104 insertions(+), 0 deletions(-) diffs (160 lines): diff -r f0feae227c60 -r b45d968adff8 src/lib/Makefile.am --- a/src/lib/Makefile.am Sat Aug 11 05:47:03 2012 +0300 +++ b/src/lib/Makefile.am Sat Aug 11 07:46:42 2012 +0300 @@ -95,6 +95,7 @@ mountpoint.c \ network.c \ nfs-workarounds.c \ + numpack.c \ ostream.c \ ostream-file.c \ ostream-buffer.c \ @@ -207,6 +208,7 @@ mountpoint.h \ network.h \ nfs-workarounds.h \ + numpack.h \ ostream.h \ ostream-private.h \ ostream-rawlog.h \ @@ -273,6 +275,7 @@ test-llist.c \ test-mempool-alloconly.c \ test-network.c \ + test-numpack.c \ test-ostream-file.c \ test-primes.c \ test-priorityq.c \ diff -r f0feae227c60 -r b45d968adff8 src/lib/numpack.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/numpack.c Sat Aug 11 07:46:42 2012 +0300 @@ -0,0 +1,45 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "buffer.h" +#include "numpack.h" + +void numpack_encode(buffer_t *buf, uint64_t num) +{ + /* number continues as long as the highest bit is set */ + while (num >= 0x80) { + buffer_append_c(buf, (num & 0x7f) | 0x80); + num >>= 7; + } + + buffer_append_c(buf, num); +} + +int numpack_decode(const uint8_t **p, const uint8_t *end, uint64_t *num_r) +{ + const uint8_t *c = *p; + uint64_t value = 0; + unsigned int bits = 0; + + for (;;) { + if (c == end) + return -1; + + value |= (uint64_t)(*c & 0x7f) << bits; + if (*c < 0x80) + break; + + bits += 7; + c++; + } + + if (bits >= 64) { + /* overflow */ + *p = end; + return -1; + } + + *p = c + 1; + *num_r = value; + return 0; +} diff -r f0feae227c60 -r b45d968adff8 src/lib/numpack.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/numpack.h Sat Aug 11 07:46:42 2012 +0300 @@ -0,0 +1,10 @@ +#ifndef NUMPACK_H +#define NUMPACK_H + +/* Numbers are stored by 7 bits at a time. The highest bit specifies if the + number continues to next byte. */ + +void numpack_encode(buffer_t *buf, uint64_t num); +int numpack_decode(const uint8_t **p, const uint8_t *end, uint64_t *num_r); + +#endif diff -r f0feae227c60 -r b45d968adff8 src/lib/test-lib.c --- a/src/lib/test-lib.c Sat Aug 11 05:47:03 2012 +0300 +++ b/src/lib/test-lib.c Sat Aug 11 07:46:42 2012 +0300 @@ -23,6 +23,7 @@ test_llist, test_mempool_alloconly, test_network, + test_numpack, test_ostream_file, test_primes, test_priorityq, diff -r f0feae227c60 -r b45d968adff8 src/lib/test-lib.h --- a/src/lib/test-lib.h Sat Aug 11 05:47:03 2012 +0300 +++ b/src/lib/test-lib.h Sat Aug 11 07:46:42 2012 +0300 @@ -22,6 +22,7 @@ void test_llist(void); void test_mempool_alloconly(void); void test_network(void); +void test_numpack(void); void test_ostream_file(void); void test_primes(void); void test_priorityq(void); diff -r f0feae227c60 -r b45d968adff8 src/lib/test-numpack.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/test-numpack.c Sat Aug 11 07:46:42 2012 +0300 @@ -0,0 +1,44 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "test-lib.h" +#include "buffer.h" +#include "numpack.h" + +#include + +static struct test { + uint64_t input; + uint8_t output[10]; + unsigned int output_size; +} tests[] = { + { 0xffffffff, { 0xff, 0xff, 0xff, 0xff, 0xf }, 5 }, + { 0, { 0 }, 1 }, + { 0x7f, { 0x7f }, 1 }, + { 0x80, { 0x80, 1 }, 2 }, + { 0x81, { 0x81, 1 }, 2 }, + { 0xdeadbeefcafe, { 0xfe, 0x95, 0xbf, 0xf7, 0xdb, 0xd5, 0x37 }, 7 }, + { 0xffffffffffffffff, { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1 }, 10 }, + { 0xfffffffe, { 0xfe, 0xff, 0xff, 0xff, 0xf }, 5 }, +}; + +void test_numpack(void) +{ + buffer_t *buf = buffer_create_dynamic(pool_datastack_create(), 32); + unsigned int i; + const uint8_t *p, *end; + uint64_t num; + + test_begin("numpack"); + for (i = 0; i < N_ELEMENTS(tests); i++) { + buffer_set_used_size(buf, 0); + numpack_encode(buf, tests[i].input); + test_assert(buf->used == tests[i].output_size && + memcmp(buf->data, tests[i].output, + tests[i].output_size) == 0); + + p = buf->data; end = p + buf->used; + test_assert(numpack_decode(&p, end, &num) == 0); + test_assert(num == tests[i].input); + } + test_end(); +} From dovecot at dovecot.org Sat Aug 11 07:47:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 11 Aug 2012 07:47:40 +0300 Subject: dovecot-2.2: lib-storage: Added caching for mail_get_binary_size() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f75d5a2eddcb changeset: 14862:f75d5a2eddcb user: Timo Sirainen date: Sat Aug 11 07:47:29 2012 +0300 description: lib-storage: Added caching for mail_get_binary_size() diffstat: src/lib-mail/Makefile.am | 2 + src/lib-mail/message-binary-part.c | 40 +++ src/lib-mail/message-binary-part.h | 26 ++ src/lib-storage/index/index-mail-binary.c | 356 ++++++++++++++++++++++------- src/lib-storage/index/index-mail.c | 6 +- src/lib-storage/index/index-mail.h | 2 + src/lib-storage/mail.c | 28 +- 7 files changed, 364 insertions(+), 96 deletions(-) diffs (truncated from 689 to 300 lines): diff -r b45d968adff8 -r f75d5a2eddcb src/lib-mail/Makefile.am --- a/src/lib-mail/Makefile.am Sat Aug 11 07:46:42 2012 +0300 +++ b/src/lib-mail/Makefile.am Sat Aug 11 07:47:29 2012 +0300 @@ -16,6 +16,7 @@ mail-user-hash.c \ mbox-from.c \ message-address.c \ + message-binary-part.c \ message-date.c \ message-decoder.c \ message-header-decode.c \ @@ -43,6 +44,7 @@ mbox-from.h \ mail-types.h \ message-address.h \ + message-binary-part.h \ message-date.h \ message-decoder.h \ message-header-decode.h \ diff -r b45d968adff8 -r f75d5a2eddcb src/lib-mail/message-binary-part.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-mail/message-binary-part.c Sat Aug 11 07:47:29 2012 +0300 @@ -0,0 +1,40 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "numpack.h" +#include "message-binary-part.h" + +void message_binary_part_serialize(const struct message_binary_part *parts, + buffer_t *dest) +{ + const struct message_binary_part *part; + + for (part = parts; part != NULL; part = part->next) { + numpack_encode(dest, part->physical_pos); + numpack_encode(dest, part->binary_hdr_size); + numpack_encode(dest, part->binary_body_size); + } +} + +int message_binary_part_deserialize(pool_t pool, const void *data, size_t size, + struct message_binary_part **parts_r) +{ + const uint8_t *p = data, *end = p + size; + uint64_t n1, n2, n3; + struct message_binary_part *part = NULL, *prev_part = NULL; + + while (p != end) { + part = p_new(pool, struct message_binary_part, 1); + part->next = prev_part; + prev_part = part; + if (numpack_decode(&p, end, &n1) < 0 || + numpack_decode(&p, end, &n2) < 0 || + numpack_decode(&p, end, &n3) < 0) + return -1; + part->physical_pos = n1; + part->binary_hdr_size = n2; + part->binary_body_size = n3; + } + *parts_r = part; + return 0; +} diff -r b45d968adff8 -r f75d5a2eddcb src/lib-mail/message-binary-part.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-mail/message-binary-part.h Sat Aug 11 07:47:29 2012 +0300 @@ -0,0 +1,26 @@ +#ifndef MESSAGE_BINARY_PART_H +#define MESSAGE_BINARY_PART_H + +struct message_binary_part { + struct message_binary_part *next; + + /* Absolute position from beginning of message. This can be used to + match the part to struct message_part. */ + uoff_t physical_pos; + /* Decoded binary header/body size. The binary header size may differ + from message_part's, because Content-Transfer-Encoding is changed to + "binary". */ + uoff_t binary_hdr_size; + uoff_t binary_body_size; +}; + +/* Serialize message binary_part. */ +void message_binary_part_serialize(const struct message_binary_part *parts, + buffer_t *dest); + +/* Generate struct message_binary_part from serialized data. Returns 0 if ok, + -1 if any problems are detected. */ +int message_binary_part_deserialize(pool_t pool, const void *data, size_t size, + struct message_binary_part **parts_r); + +#endif diff -r b45d968adff8 -r f75d5a2eddcb src/lib-storage/index/index-mail-binary.c --- a/src/lib-storage/index/index-mail-binary.c Sat Aug 11 07:46:42 2012 +0300 +++ b/src/lib-storage/index/index-mail-binary.c Sat Aug 11 07:47:29 2012 +0300 @@ -10,24 +10,36 @@ #include "istream-qp.h" #include "istream-header-filter.h" #include "ostream.h" +#include "message-binary-part.h" #include "message-parser.h" #include "message-decoder.h" #include "mail-user.h" +#include "index-storage.h" #include "index-mail.h" #define MAIL_BINARY_CACHE_EXPIRE_MSECS (60*1000) +#define IS_CONVERTED_CTE(cte) \ + ((cte) == MESSAGE_CTE_QP || (cte) == MESSAGE_CTE_BASE64) + +struct binary_block { + struct istream *input; + struct message_binary_part bin_part; + bool converted, converted_hdr; +}; + struct binary_ctx { struct mail *mail; struct istream *input; bool has_nuls, converted; - ARRAY_DEFINE(streams, struct istream *); + ARRAY_DEFINE(blocks, struct binary_block); uoff_t copy_start_offset; }; static void binary_copy_to(struct binary_ctx *ctx, uoff_t end_offset) { + struct binary_block *block; struct istream *linput, *cinput; uoff_t orig_offset, size; @@ -43,7 +55,9 @@ linput = i_stream_create_limit(ctx->input, size); cinput = i_stream_create_crlf(linput); i_stream_unref(&linput); - array_append(&ctx->streams, &cinput, 1); + + block = array_append_space(&ctx->blocks); + block->input = cinput; i_stream_seek(ctx->input, orig_offset); } @@ -72,7 +86,8 @@ struct message_header_line *hdr; struct message_part *child; struct message_size hdr_size; - struct istream *linput, *cinput; + struct istream *linput; + struct binary_block *block; enum message_cte cte; int ret; @@ -109,17 +124,21 @@ i_stream_seek(ctx->input, part->physical_pos); if (!include_hdr) { /* body only */ - } else if (cte == MESSAGE_CTE_QP || cte == MESSAGE_CTE_BASE64) { + } else if (IS_CONVERTED_CTE(cte)) { /* write header with modified content-type */ if (ctx->copy_start_offset != 0) binary_copy_to(ctx, part->physical_pos); + block = array_append_space(&ctx->blocks); + block->bin_part.physical_pos = part->physical_pos; + block->converted = TRUE; + block->converted_hdr = TRUE; + linput = i_stream_create_limit(ctx->input, (uoff_t)-1); - cinput = i_stream_create_header_filter(linput, + block->input = i_stream_create_header_filter(linput, HEADER_FILTER_EXCLUDE | HEADER_FILTER_HIDE_BODY, filter_headers, N_ELEMENTS(filter_headers), binary_cte_filter_callback, ctx); i_stream_unref(&linput); - array_append(&ctx->streams, &cinput, 1); } else { /* copy everything as-is until the end of this header */ binary_copy_to(ctx, part->physical_pos + @@ -141,6 +160,9 @@ } /* single part - write decoded data */ + block = array_append_space(&ctx->blocks); + block->bin_part.physical_pos = part->physical_pos; + i_stream_seek(ctx->input, part->physical_pos + part->header_size.physical_size); linput = i_stream_create_limit(ctx->input, part->body_size.physical_size); @@ -152,20 +174,18 @@ /* no conversion necessary */ if ((part->flags & MESSAGE_PART_FLAG_HAS_NULS) != 0) ctx->has_nuls = TRUE; - cinput = linput; - i_stream_ref(cinput); + block->input = i_stream_create_crlf(linput); break; case MESSAGE_CTE_QP: - cinput = i_stream_create_qp_decoder(linput); - ctx->converted = TRUE; + block->input = i_stream_create_qp_decoder(linput); + ctx->converted = block->converted = TRUE; break; case MESSAGE_CTE_BASE64: - cinput = i_stream_create_base64_decoder(linput); - ctx->converted = TRUE; + block->input = i_stream_create_base64_decoder(linput); + ctx->converted = block->converted = TRUE; break; } i_stream_unref(&linput); - array_append(&ctx->streams, &cinput, 1); ctx->copy_start_offset = part->physical_pos + part->header_size.physical_size + @@ -200,14 +220,225 @@ static void binary_streams_free(struct binary_ctx *ctx) { - struct istream **input; + struct binary_block *block; - array_foreach_modifiable(&ctx->streams, input) { - if (*input != NULL) - i_stream_unref(input); + array_foreach_modifiable(&ctx->blocks, block) + i_stream_unref(&block->input); +} + +static void +binary_parts_update(struct binary_ctx *ctx, const struct message_part *part, + struct message_binary_part **msg_bin_parts) +{ + struct index_mail *mail = (struct index_mail *)ctx->mail; + struct binary_block *blocks; + struct message_binary_part bin_part; + unsigned int i, count; + uoff_t size; + bool found; + + blocks = array_get_modifiable(&ctx->blocks, &count); + for (; part != NULL; part = part->next) { + binary_parts_update(ctx, part->children, msg_bin_parts); + + memset(&bin_part, 0, sizeof(bin_part)); + /* default to unchanged header */ + bin_part.binary_hdr_size = part->header_size.virtual_size; + bin_part.physical_pos = part->physical_pos; + found = FALSE; + for (i = 0; i < count; i++) { + if (blocks[i].bin_part.physical_pos != part->physical_pos || + !blocks[i].converted) + continue; + + size = blocks[i].input->v_offset; + if (blocks[i].converted_hdr) + bin_part.binary_hdr_size = size; + else + bin_part.binary_body_size = size; + found = TRUE; + } + if (found) { + bin_part.next = *msg_bin_parts; + *msg_bin_parts = p_new(mail->data_pool, + struct message_binary_part, 1); + **msg_bin_parts = bin_part; + } } } +static void binary_parts_cache(struct binary_ctx *ctx) +{ + struct index_mail *mail = (struct index_mail *)ctx->mail; + buffer_t *buf; + + buf = buffer_create_dynamic(pool_datastack_create(), 128); + message_binary_part_serialize(mail->data.bin_parts, buf); + index_mail_cache_add(mail, MAIL_CACHE_BINARY_PARTS, + buf->data, buf->used); +} + +static struct istream **blocks_get_streams(struct binary_ctx *ctx) +{ + struct istream **streams; + const struct binary_block *blocks; + unsigned int i, count; + + blocks = array_get(&ctx->blocks, &count); + streams = t_new(struct istream *, count+1); + for (i = 0; i < count; i++) + streams[i] = blocks[i].input; + return streams; +} + +static int +index_mail_read_binary_to_cache(struct mail *_mail, + const struct message_part *part, + bool include_hdr, bool *binary_r, + bool *converted_r) From dovecot at dovecot.org Sat Aug 11 07:48:09 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 11 Aug 2012 07:48:09 +0300 Subject: dovecot-2.2: Added BINARY to IMAP capabilities. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/621c0e2d7efc changeset: 14863:621c0e2d7efc user: Timo Sirainen date: Sat Aug 11 07:48:04 2012 +0300 description: Added BINARY to IMAP capabilities. diffstat: configure.in | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r f75d5a2eddcb -r 621c0e2d7efc configure.in --- a/configure.in Sat Aug 11 07:47:29 2012 +0300 +++ b/configure.in Sat Aug 11 07:48:04 2012 +0300 @@ -2718,7 +2718,7 @@ dnl IDLE doesn't really belong to banner. It's there just to make Blackberries dnl happy, because otherwise BIS server disables push email. capability_banner="IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE" -capability="$capability_banner SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE" +capability="$capability_banner SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE BINARY" AC_DEFINE_UNQUOTED(CAPABILITY_STRING, "$capability", IMAP capabilities) AC_DEFINE_UNQUOTED(CAPABILITY_BANNER_STRING, "$capability_banner", IMAP capabilities advertised in banner) From dovecot at dovecot.org Sat Aug 11 08:03:16 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 11 Aug 2012 08:03:16 +0300 Subject: dovecot-2.2: imap: Fixed FETCHing nonexistent parts. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ec5346eb7d60 changeset: 14864:ec5346eb7d60 user: Timo Sirainen date: Sat Aug 11 08:03:05 2012 +0300 description: imap: Fixed FETCHing nonexistent parts. diffstat: src/lib-imap-storage/imap-msgpart.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (20 lines): diff -r 621c0e2d7efc -r ec5346eb7d60 src/lib-imap-storage/imap-msgpart.c --- a/src/lib-imap-storage/imap-msgpart.c Sat Aug 11 07:48:04 2012 +0300 +++ b/src/lib-imap-storage/imap-msgpart.c Sat Aug 11 08:03:05 2012 +0300 @@ -544,7 +544,6 @@ struct message_size hdr_size, body_size; struct istream *input = NULL; - memset(result_r, 0, sizeof(*result_r)); memset(&hdr_size, 0, sizeof(hdr_size)); memset(&body_size, 0, sizeof(body_size)); memset(part_size_r, 0, sizeof(*part_size_r)); @@ -633,6 +632,8 @@ bool include_hdr, binary, use_partial_cache; int ret; + memset(result_r, 0, sizeof(*result_r)); + if ((ret = imap_msgpart_find_part(mail, msgpart, &part)) < 0) return -1; if (ret == 0) { From dovecot at dovecot.org Sat Aug 11 08:10:43 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 11 Aug 2012 08:10:43 +0300 Subject: dovecot-2.2: Renamed struct mailbox_info.name to vname. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e852d1fbf40a changeset: 14865:e852d1fbf40a user: Timo Sirainen date: Sat Aug 11 08:10:32 2012 +0300 description: Renamed struct mailbox_info.name to vname. diffstat: TODO | 5 +-- src/doveadm/doveadm-mail-altmove.c | 2 +- src/doveadm/doveadm-mail-expunge.c | 2 +- src/doveadm/doveadm-mail-import.c | 2 +- src/doveadm/doveadm-mail-index.c | 8 ++-- src/doveadm/doveadm-mail-iter.c | 4 +- src/doveadm/doveadm-mail-mailbox-status.c | 2 +- src/doveadm/doveadm-mail-mailbox.c | 6 +- src/doveadm/doveadm-mail-move.c | 2 +- src/doveadm/doveadm-mail.c | 6 +- src/doveadm/doveadm-mailbox-list-iter.c | 6 +- src/doveadm/dsync/dsync-mailbox-tree-fill.c | 8 ++-- src/imap/cmd-list.c | 4 +- src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c | 2 +- src/lib-storage/index/imapc/imapc-list.c | 10 ++-- src/lib-storage/list/mailbox-list-fs-iter.c | 14 ++++---- src/lib-storage/list/mailbox-list-index-iter.c | 10 ++-- src/lib-storage/list/mailbox-list-index-sync.c | 2 +- src/lib-storage/list/mailbox-list-maildir-iter.c | 4 +- src/lib-storage/list/mailbox-list-maildir.c | 6 +- src/lib-storage/list/mailbox-list-none.c | 2 +- src/lib-storage/list/mailbox-list-subscriptions.c | 2 +- src/lib-storage/mailbox-guid-cache.c | 6 +- src/lib-storage/mailbox-list-iter.c | 28 ++++++++-------- src/lib-storage/mailbox-list.h | 2 +- src/plugins/acl/acl-backend-vfile-acllist.c | 2 +- src/plugins/acl/acl-mailbox-list.c | 24 ++++++------ src/plugins/fts-lucene/lucene-wrapper.cc | 2 +- src/plugins/fts-solr/fts-backend-solr.c | 2 +- src/plugins/quota/quota-count.c | 2 +- src/plugins/quota/quota-maildir.c | 4 +- src/plugins/virtual/virtual-config.c | 8 ++-- 32 files changed, 93 insertions(+), 96 deletions(-) diffs (truncated from 796 to 300 lines): diff -r ec5346eb7d60 -r e852d1fbf40a TODO --- a/TODO Sat Aug 11 08:03:05 2012 +0300 +++ b/TODO Sat Aug 11 08:10:32 2012 +0300 @@ -1,4 +1,4 @@ - - Unfinished extensions: MOVE, NOTIFY, BINARY + - Unfinished extensions: MOVE, NOTIFY - indexer-worker and maybe others (doveadm?) could support dropping privileges permanently when service_count=1. Note that LMTP can't with multiple RCPT TOs. @@ -11,10 +11,7 @@ - FIFOs maybe should be counted as connections, but unlisten should unlink+reopen it in master? - mailbox list indexes + imaptest test=tests fails - - mailbox_enable() -> mail_user_enable()? - - mailbox_info.name -> vname - change proxy TTL so it stops at 1? - - istream-concat - lmtp client/proxy: Handle multiline replies better - recreate mailbox -> existing sessions log "indexid changed" error - add message/mime limits diff -r ec5346eb7d60 -r e852d1fbf40a src/doveadm/doveadm-mail-altmove.c --- a/src/doveadm/doveadm-mail-altmove.c Sat Aug 11 08:03:05 2012 +0300 +++ b/src/doveadm/doveadm-mail-altmove.c Sat Aug 11 08:10:32 2012 +0300 @@ -32,7 +32,7 @@ while (doveadm_mail_iter_next(iter, &mail)) { if (doveadm_debug) { i_debug("altmove: box=%s uid=%u", - info->name, mail->uid); + info->vname, mail->uid); } mail_update_flags(mail, modify_type, (enum mail_flags)MAIL_INDEX_MAIL_FLAG_BACKEND); diff -r ec5346eb7d60 -r e852d1fbf40a src/doveadm/doveadm-mail-expunge.c --- a/src/doveadm/doveadm-mail-expunge.c Sat Aug 11 08:03:05 2012 +0300 +++ b/src/doveadm/doveadm-mail-expunge.c Sat Aug 11 08:10:32 2012 +0300 @@ -34,7 +34,7 @@ while (doveadm_mail_iter_next(iter, &mail)) { if (doveadm_debug) { i_debug("expunge: box=%s uid=%u", - info->name, mail->uid); + info->vname, mail->uid); } mail_expunge(mail); } diff -r ec5346eb7d60 -r e852d1fbf40a src/doveadm/doveadm-mail-import.c --- a/src/doveadm/doveadm-mail-import.c Sat Aug 11 08:03:05 2012 +0300 +++ b/src/doveadm/doveadm-mail-import.c Sat Aug 11 08:10:32 2012 +0300 @@ -125,7 +125,7 @@ if (doveadm_mail_iter_next(iter, &mail)) { /* at least one mail matches in this mailbox */ - if (dest_mailbox_open_or_create(ctx, dest_user, info->name, + if (dest_mailbox_open_or_create(ctx, dest_user, info->vname, &box) < 0) ret = -1; else { diff -r ec5346eb7d60 -r e852d1fbf40a src/doveadm/doveadm-mail-index.c --- a/src/doveadm/doveadm-mail-index.c Sat Aug 11 08:03:05 2012 +0300 +++ b/src/doveadm/doveadm-mail-index.c Sat Aug 11 08:10:32 2012 +0300 @@ -87,14 +87,14 @@ struct mailbox_status status; int ret = 0; - box = mailbox_alloc(info->ns->list, info->name, + box = mailbox_alloc(info->ns->list, info->vname, MAILBOX_FLAG_IGNORE_ACLS); if (ctx->max_recent_msgs != 0) { /* index only if there aren't too many recent messages. don't bother syncing the mailbox, that alone can take a while with large maildirs. */ if (mailbox_open(box) < 0) { - i_error("Opening mailbox %s failed: %s", info->name, + i_error("Opening mailbox %s failed: %s", info->vname, mail_storage_get_last_error(mailbox_get_storage(box), NULL)); doveadm_mail_failed_mailbox(&ctx->ctx, box); mailbox_free(&box); @@ -109,7 +109,7 @@ } if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) { - i_error("Syncing mailbox %s failed: %s", info->name, + i_error("Syncing mailbox %s failed: %s", info->vname, mail_storage_get_last_error(mailbox_get_storage(box), NULL)); doveadm_mail_failed_mailbox(&ctx->ctx, box); ret = -1; @@ -185,7 +185,7 @@ if ((info->flags & (MAILBOX_NOSELECT | MAILBOX_NONEXISTENT)) == 0) T_BEGIN { if (ctx->queue) - cmd_index_queue(ctx, user, info->name); + cmd_index_queue(ctx, user, info->vname); else { if (cmd_index_box(ctx, info) < 0) ret = -1; diff -r ec5346eb7d60 -r e852d1fbf40a src/doveadm/doveadm-mail-iter.c --- a/src/doveadm/doveadm-mail-iter.c Sat Aug 11 08:03:05 2012 +0300 +++ b/src/doveadm/doveadm-mail-iter.c Sat Aug 11 08:10:32 2012 +0300 @@ -29,12 +29,12 @@ iter = i_new(struct doveadm_mail_iter, 1); iter->ctx = ctx; - iter->box = mailbox_alloc(info->ns->list, info->name, + iter->box = mailbox_alloc(info->ns->list, info->vname, MAILBOX_FLAG_IGNORE_ACLS); iter->search_args = search_args; if (mailbox_sync(iter->box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) { - i_error("Syncing mailbox %s failed: %s", info->name, + i_error("Syncing mailbox %s failed: %s", info->vname, mailbox_get_last_error(iter->box, NULL)); doveadm_mail_failed_mailbox(ctx, iter->box); mailbox_free(&iter->box); diff -r ec5346eb7d60 -r e852d1fbf40a src/doveadm/doveadm-mail-mailbox-status.c --- a/src/doveadm/doveadm-mail-mailbox-status.c Sat Aug 11 08:03:05 2012 +0300 +++ b/src/doveadm/doveadm-mail-mailbox-status.c Sat Aug 11 08:10:32 2012 +0300 @@ -125,7 +125,7 @@ struct mailbox_status status; struct mailbox_metadata metadata; - box = doveadm_mailbox_find(ctx->ctx.cur_mail_user, info->name); + box = doveadm_mailbox_find(ctx->ctx.cur_mail_user, info->vname); if (mailbox_get_status(box, ctx->status_items, &status) < 0 || mailbox_get_metadata(box, ctx->metadata_items, &metadata) < 0) { doveadm_mail_failed_mailbox(&ctx->ctx, box); diff -r ec5346eb7d60 -r e852d1fbf40a src/doveadm/doveadm-mail-mailbox.c --- a/src/doveadm/doveadm-mail-mailbox.c Sat Aug 11 08:03:05 2012 +0300 +++ b/src/doveadm/doveadm-mail-mailbox.c Sat Aug 11 08:10:32 2012 +0300 @@ -121,10 +121,10 @@ iter_flags); while ((info = doveadm_mailbox_list_iter_next(iter)) != NULL) { if (!ctx->mutf7) - doveadm_print(info->name); + doveadm_print(info->vname); else { str_truncate(str, 0); - if (imap_utf8_to_utf7(info->name, str) < 0) + if (imap_utf8_to_utf7(info->vname, str) < 0) i_unreached(); doveadm_print(str_c(str)); } @@ -285,7 +285,7 @@ iter = mailbox_list_iter_init(ns->list, pattern, MAILBOX_LIST_ITER_RETURN_NO_FLAGS); while ((info = mailbox_list_iter_next(iter)) != NULL) { - child_name = t_strdup(info->name); + child_name = t_strdup(info->vname); array_append(mailboxes, &child_name, 1); } return mailbox_list_iter_deinit(&iter); diff -r ec5346eb7d60 -r e852d1fbf40a src/doveadm/doveadm-mail-move.c --- a/src/doveadm/doveadm-mail-move.c Sat Aug 11 08:03:05 2012 +0300 +++ b/src/doveadm/doveadm-mail-move.c Sat Aug 11 08:10:32 2012 +0300 @@ -44,7 +44,7 @@ mail_expunge(mail); else { i_error("Copying message UID %u from '%s' failed: %s", - mail->uid, info->name, + mail->uid, info->vname, mailbox_get_last_error(destbox, NULL)); doveadm_mail_failed_mailbox(&ctx->ctx, destbox); ret = -1; diff -r ec5346eb7d60 -r e852d1fbf40a src/doveadm/doveadm-mail.c --- a/src/doveadm/doveadm-mail.c Sat Aug 11 08:03:05 2012 +0300 +++ b/src/doveadm/doveadm-mail.c Sat Aug 11 08:10:32 2012 +0300 @@ -202,17 +202,17 @@ struct mailbox *box; int ret = 0; - box = mailbox_alloc(info->ns->list, info->name, + box = mailbox_alloc(info->ns->list, info->vname, MAILBOX_FLAG_IGNORE_ACLS); if (mailbox_open(box) < 0) { - i_error("Opening mailbox %s failed: %s", info->name, + i_error("Opening mailbox %s failed: %s", info->vname, mailbox_get_last_error(box, NULL)); doveadm_mail_failed_mailbox(ctx, box); ret = -1; } else if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FORCE_RESYNC | MAILBOX_SYNC_FLAG_FIX_INCONSISTENT) < 0) { i_error("Forcing a resync on mailbox %s failed: %s", - info->name, mailbox_get_last_error(box, NULL)); + info->vname, mailbox_get_last_error(box, NULL)); doveadm_mail_failed_mailbox(ctx, box); ret = -1; } diff -r ec5346eb7d60 -r e852d1fbf40a src/doveadm/doveadm-mailbox-list-iter.c --- a/src/doveadm/doveadm-mailbox-list-iter.c Sat Aug 11 08:03:05 2012 +0300 +++ b/src/doveadm/doveadm-mailbox-list-iter.c Sat Aug 11 08:10:32 2012 +0300 @@ -168,9 +168,9 @@ if (iter->pattern_idx == count) return NULL; - iter->info.name = patterns[iter->pattern_idx++]; + iter->info.vname = patterns[iter->pattern_idx++]; iter->info.ns = mail_namespace_find(iter->user->namespaces, - iter->info.name); + iter->info.vname); if (iter->info.ns != NULL) return &iter->info; /* FIXME: maybe fail?.. or just wait for v2.2 to get rid of @@ -187,7 +187,7 @@ } if (mail_search_args_match_mailbox(iter->search_args, - info->name, sep)) + info->vname, sep)) break; } return info; diff -r ec5346eb7d60 -r e852d1fbf40a src/doveadm/dsync/dsync-mailbox-tree-fill.c --- a/src/doveadm/dsync/dsync-mailbox-tree-fill.c Sat Aug 11 08:03:05 2012 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-tree-fill.c Sat Aug 11 08:10:32 2012 +0300 @@ -18,12 +18,12 @@ { struct dsync_mailbox_node *node; - node = dsync_mailbox_tree_get(tree, info->name); + node = dsync_mailbox_tree_get(tree, info->vname); if (node->ns != info->ns) { i_assert(node->ns != NULL); i_error("Mailbox '%s' exists in two namespaces: '%s' and '%s'", - info->name, node->ns->prefix, info->ns->prefix); + info->vname, node->ns->prefix, info->ns->prefix); return -1; } *node_r = node; @@ -51,7 +51,7 @@ return 0; /* get GUID and UIDVALIDITY for selectable mailbox */ - box = mailbox_alloc(info->ns->list, info->name, 0); + box = mailbox_alloc(info->ns->list, info->vname, 0); if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) < 0 || mailbox_get_status(box, STATUS_UIDVALIDITY, &status) < 0) { errstr = mailbox_get_last_error(box, &error); @@ -64,7 +64,7 @@ break; default: i_error("Failed to access mailbox %s: %s", - info->name, errstr); + info->vname, errstr); mailbox_free(&box); return -1; } diff -r ec5346eb7d60 -r e852d1fbf40a src/imap/cmd-list.c --- a/src/imap/cmd-list.c Sat Aug 11 08:03:05 2012 +0300 +++ b/src/imap/cmd-list.c Sat Aug 11 08:10:32 2012 +0300 @@ -200,7 +200,7 @@ list_iter = mailbox_list_iter_init(ns->list, "INBOX", 0); info = mailbox_list_iter_next(list_iter); if (info != NULL) { - i_assert(strcasecmp(info->name, "INBOX") == 0); + i_assert(strcasecmp(info->vname, "INBOX") == 0); flags = info->flags; } (void)mailbox_list_iter_deinit(&list_iter); @@ -424,7 +424,7 @@ str = t_str_new(256); mutf7_name = t_str_new(128); while ((info = mailbox_list_iter_next(ctx->list_iter)) != NULL) { - name = info->name; + name = info->vname; flags = info->flags; if (strcasecmp(name, "INBOX") == 0) { diff -r ec5346eb7d60 -r e852d1fbf40a src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c --- a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c Sat Aug 11 08:03:05 2012 +0300 +++ b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c Sat Aug 11 08:10:32 2012 +0300 @@ -543,7 +543,7 @@ if ((info->flags & (MAILBOX_NONEXISTENT | MAILBOX_NOSELECT)) == 0) { T_BEGIN { - ret = rebuild_mailbox(ctx, ns, info->name); + ret = rebuild_mailbox(ctx, ns, info->vname); } T_END; if (ret < 0) { ret = -1; diff -r ec5346eb7d60 -r e852d1fbf40a src/lib-storage/index/imapc/imapc-list.c --- a/src/lib-storage/index/imapc/imapc-list.c Sat Aug 11 08:03:05 2012 +0300 +++ b/src/lib-storage/index/imapc/imapc-list.c Sat Aug 11 08:10:32 2012 +0300 @@ -332,9 +332,9 @@ MAILBOX_LIST_ITER_NO_AUTO_BOXES | MAILBOX_LIST_ITER_RETURN_NO_FLAGS); while ((info = mailbox_list_iter_next(iter)) != NULL) { - if (mailbox_tree_lookup(list->mailboxes, info->name) == NULL) { + if (mailbox_tree_lookup(list->mailboxes, info->vname) == NULL) { fs_name = mailbox_list_get_storage_name(fs_list, - info->name); + info->vname); (void)fs_list->v.delete_mailbox(fs_list, fs_name); } } @@ -467,7 +467,7 @@ struct imapc_mailbox_list_iterate_context *ctx = (struct imapc_mailbox_list_iterate_context *)_ctx; struct mailbox_node *node; - const char *name; + const char *vname; From dovecot at dovecot.org Sun Aug 12 01:29:37 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 12 Aug 2012 01:29:37 +0300 Subject: dovecot-2.2: dbox: Crashfixes Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5fc4fab20fd0 changeset: 14866:5fc4fab20fd0 user: Timo Sirainen date: Sun Aug 12 01:29:16 2012 +0300 description: dbox: Crashfixes diffstat: src/lib-storage/index/dbox-common/dbox-file-fix.c | 3 ++- src/lib-storage/index/dbox-common/dbox-save.c | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletions(-) diffs (31 lines): diff -r e852d1fbf40a -r 5fc4fab20fd0 src/lib-storage/index/dbox-common/dbox-file-fix.c --- a/src/lib-storage/index/dbox-common/dbox-file-fix.c Sat Aug 11 08:10:32 2012 +0300 +++ b/src/lib-storage/index/dbox-common/dbox-file-fix.c Sun Aug 12 01:29:16 2012 +0300 @@ -86,9 +86,10 @@ input = i_stream_create_limit(file->input, count); bytes = o_stream_send_istream(output, input); + errno = input->stream_errno; i_stream_unref(&input); - if (input->stream_errno != 0) { + if (errno != 0) { mail_storage_set_critical(&file->storage->storage, "read(%s) failed: %m", file->cur_path); return -1; diff -r e852d1fbf40a -r 5fc4fab20fd0 src/lib-storage/index/dbox-common/dbox-save.c --- a/src/lib-storage/index/dbox-common/dbox-save.c Sat Aug 11 08:10:32 2012 +0300 +++ b/src/lib-storage/index/dbox-common/dbox-save.c Sun Aug 12 01:29:16 2012 +0300 @@ -104,6 +104,12 @@ if (index_attachment_save_finish(&ctx->ctx) < 0) ctx->failed = TRUE; } + if (o_stream_nfinish(ctx->ctx.output) < 0) { + mail_storage_set_critical(ctx->ctx.transaction->box->storage, + "write(%s) failed: %m", + o_stream_get_name(ctx->ctx.output)); + ctx->failed = TRUE; + } if (ctx->ctx.output == dbox_output) return; From dovecot at dovecot.org Sun Aug 12 01:39:01 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 12 Aug 2012 01:39:01 +0300 Subject: dovecot-2.2: imap: (non-UID) MOVE command didn't always send EXP... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a69d858948ca changeset: 14867:a69d858948ca user: Timo Sirainen date: Sun Aug 12 01:38:51 2012 +0300 description: imap: (non-UID) MOVE command didn't always send EXPUNGE for the moved message. diffstat: src/imap/cmd-copy.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (15 lines): diff -r 5fc4fab20fd0 -r a69d858948ca src/imap/cmd-copy.c --- a/src/imap/cmd-copy.c Sun Aug 12 01:29:16 2012 +0300 +++ b/src/imap/cmd-copy.c Sun Aug 12 01:38:51 2012 +0300 @@ -169,7 +169,10 @@ dest_storage = mailbox_get_storage(destbox); if (destbox != client->mailbox) { - sync_flags |= MAILBOX_SYNC_FLAG_FAST; + if (move) + sync_flags |= MAILBOX_SYNC_FLAG_EXPUNGE; + else + sync_flags |= MAILBOX_SYNC_FLAG_FAST; imap_flags |= IMAP_SYNC_FLAG_SAFE; mailbox_free(&destbox); } From dovecot at dovecot.org Sun Aug 12 02:08:36 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 12 Aug 2012 02:08:36 +0300 Subject: dovecot-2.2: imap: Fixed fetching partial ranges from non-BODY[] Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f4de7ed984b3 changeset: 14868:f4de7ed984b3 user: Timo Sirainen date: Sun Aug 12 02:08:30 2012 +0300 description: imap: Fixed fetching partial ranges from non-BODY[] diffstat: src/lib-imap-storage/imap-msgpart.c | 11 ++++++----- 1 files changed, 6 insertions(+), 5 deletions(-) diffs (45 lines): diff -r a69d858948ca -r f4de7ed984b3 src/lib-imap-storage/imap-msgpart.c --- a/src/lib-imap-storage/imap-msgpart.c Sun Aug 12 01:38:51 2012 +0300 +++ b/src/lib-imap-storage/imap-msgpart.c Sun Aug 12 02:08:30 2012 +0300 @@ -362,7 +362,7 @@ static void skip_using_parts(struct mail *mail, struct istream *input, - uoff_t *virtual_skip) + uoff_t physical_start, uoff_t *virtual_skip) { enum mail_lookup_abort old_lookup_abort; struct message_part *parts, *part; @@ -382,14 +382,15 @@ /* skip header */ vpos += part->header_size.virtual_size; *virtual_skip -= part->header_size.virtual_size; - i_stream_seek(input, part->physical_pos + + i_stream_seek(input, physical_start + part->physical_pos + part->header_size.physical_size); if (vpos + part->body_size.virtual_size <= *virtual_skip) { /* skip body */ vpos += part->body_size.virtual_size; *virtual_skip -= part->body_size.virtual_size; - i_stream_seek(input, part->physical_pos + + i_stream_seek(input, physical_start + + part->physical_pos + part->header_size.physical_size + part->body_size.physical_size); part = part->next; @@ -419,12 +420,12 @@ cache->physical_start == physical_start && cache->virtual_pos < virtual_skip) { /* use cache */ - i_stream_seek(input, cache->physical_pos); + i_stream_seek(input, physical_start + cache->physical_pos); virtual_skip -= cache->virtual_pos; } else { /* can't use cache, but maybe we can skip faster using the message parts. */ - skip_using_parts(mail, input, &virtual_skip); + skip_using_parts(mail, input, physical_start, &virtual_skip); } crlf_input = i_stream_create_crlf(input); i_stream_unref(&input); From dovecot at dovecot.org Sun Aug 12 02:26:24 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 12 Aug 2012 02:26:24 +0300 Subject: dovecot-2.2: istream-header-filter: Allow adding more headers at... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f329d7e1dad7 changeset: 14869:f329d7e1dad7 user: Timo Sirainen date: Sun Aug 12 02:24:54 2012 +0300 description: istream-header-filter: Allow adding more headers at the end of headers callback. diffstat: src/lib-mail/istream-header-filter.c | 38 +++++++++++++++++++++++++++-------- 1 files changed, 29 insertions(+), 9 deletions(-) diffs (82 lines): diff -r f4de7ed984b3 -r f329d7e1dad7 src/lib-mail/istream-header-filter.c --- a/src/lib-mail/istream-header-filter.c Sun Aug 12 02:08:30 2012 +0300 +++ b/src/lib-mail/istream-header-filter.c Sun Aug 12 02:24:54 2012 +0300 @@ -133,12 +133,23 @@ buffer_append_c(mstream->hdr_buf, '\n'); } +static ssize_t hdr_stream_update_pos(struct header_filter_istream *mstream) +{ + ssize_t ret; + size_t pos; + + mstream->istream.buffer = buffer_get_data(mstream->hdr_buf, &pos); + ret = (ssize_t)(pos - mstream->istream.pos - mstream->istream.skip); + i_assert(ret >= 0); + mstream->istream.pos = pos; + return ret; +} + static ssize_t read_header(struct header_filter_istream *mstream) { struct message_header_line *hdr; uoff_t highwater_offset; - size_t pos; - ssize_t ret; + ssize_t ret, ret2; bool matched; int hdr_ret; @@ -181,8 +192,10 @@ mstream->context); } - if (!matched) + if (!matched) { + mstream->seen_eoh = FALSE; continue; + } add_eol(mstream); continue; @@ -259,10 +272,7 @@ /* don't copy eof here because we're only returning headers here. the body will be returned in separate read() call. */ - mstream->istream.buffer = buffer_get_data(mstream->hdr_buf, &pos); - ret = (ssize_t)(pos - mstream->istream.pos - mstream->istream.skip); - i_assert(ret >= 0); - mstream->istream.pos = pos; + ret = hdr_stream_update_pos(mstream); if (hdr_ret == 0) { /* need more data to finish parsing headers. we may have some @@ -275,16 +285,26 @@ message_parse_header_deinit(&mstream->hdr_ctx); mstream->hdr_ctx = NULL; - if (!mstream->header_parsed && mstream->callback != NULL) + if (!mstream->header_parsed && mstream->callback != NULL) { mstream->callback(mstream, NULL, &matched, mstream->context); + /* check if the callback added more headers. + this is allowed only of EOH wasn't added yet. */ + ret2 = hdr_stream_update_pos(mstream); + if (!mstream->seen_eoh) + ret += ret2; + else { + i_assert(ret2 == 0); + } + } mstream->header_parsed = TRUE; mstream->header_read = TRUE; mstream->header_size.physical_size = mstream->istream.parent->v_offset; mstream->header_size.virtual_size = - mstream->istream.istream.v_offset + pos; + mstream->istream.istream.v_offset + + mstream->istream.pos; } if (ret == 0) { From dovecot at dovecot.org Sun Aug 12 02:26:24 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 12 Aug 2012 02:26:24 +0300 Subject: dovecot-2.2: lib-storage: mail_get_header_stream() now always re... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2ec8bb1396d1 changeset: 14870:2ec8bb1396d1 user: Timo Sirainen date: Sun Aug 12 02:26:12 2012 +0300 description: lib-storage: mail_get_header_stream() now always returns end-of-headers LF. diffstat: src/lib-storage/index/index-mail-headers.c | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) diffs (32 lines): diff -r f329d7e1dad7 -r 2ec8bb1396d1 src/lib-storage/index/index-mail-headers.c --- a/src/lib-storage/index/index-mail-headers.c Sun Aug 12 02:24:54 2012 +0300 +++ b/src/lib-storage/index/index-mail-headers.c Sun Aug 12 02:26:12 2012 +0300 @@ -782,11 +782,8 @@ static void header_cache_callback(struct header_filter_istream *input ATTR_UNUSED, struct message_header_line *hdr, - bool *matched, struct index_mail *mail) + bool *matched ATTR_UNUSED, struct index_mail *mail) { - if (hdr != NULL && hdr->eoh) - *matched = FALSE; - index_mail_parse_header(NULL, hdr, mail); } @@ -810,6 +807,7 @@ if (mail_cache_lookup_headers(_mail->transaction->cache_view, dest, _mail->seq, headers->idx, headers->count) > 0) { + str_append(dest, "\n"); _mail->transaction->stats.cache_hit_count++; if (mail->data.filter_stream != NULL) i_stream_destroy(&mail->data.filter_stream); @@ -832,6 +830,7 @@ mail->data.filter_stream = i_stream_create_header_filter(mail->data.stream, HEADER_FILTER_INCLUDE | + HEADER_FILTER_ADD_MISSING_EOH | HEADER_FILTER_HIDE_BODY, headers->name, headers->count, header_cache_callback, mail); From dovecot at dovecot.org Sun Aug 12 03:28:36 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 12 Aug 2012 03:28:36 +0300 Subject: dovecot-2.2: lib-storage: Fixed assert-crash on subscribtion cha... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f66e1508dc19 changeset: 14871:f66e1508dc19 user: Timo Sirainen date: Sun Aug 12 03:28:26 2012 +0300 description: lib-storage: Fixed assert-crash on subscribtion change that didn't change anything. diffstat: src/lib-storage/list/subscription-file.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (14 lines): diff -r 2ec8bb1396d1 -r f66e1508dc19 src/lib-storage/list/subscription-file.c --- a/src/lib-storage/list/subscription-file.c Sun Aug 12 02:26:12 2012 +0300 +++ b/src/lib-storage/list/subscription-file.c Sun Aug 12 03:28:26 2012 +0300 @@ -176,8 +176,9 @@ failed = TRUE; } } + } else { + o_stream_ignore_last_errors(output); } - o_stream_destroy(&output); if (failed || !changed) { From dovecot at dovecot.org Sun Aug 12 04:55:00 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 12 Aug 2012 04:55:00 +0300 Subject: dovecot-2.2: imap: More fixes to fetching messages. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9f20f7bd992d changeset: 14872:9f20f7bd992d user: Timo Sirainen date: Sun Aug 12 04:54:54 2012 +0300 description: imap: More fixes to fetching messages. diffstat: src/lib-imap-storage/imap-msgpart.c | 34 ++++++++++++++++++++++------------ 1 files changed, 22 insertions(+), 12 deletions(-) diffs (61 lines): diff -r f66e1508dc19 -r 9f20f7bd992d src/lib-imap-storage/imap-msgpart.c --- a/src/lib-imap-storage/imap-msgpart.c Sun Aug 12 03:28:26 2012 +0300 +++ b/src/lib-imap-storage/imap-msgpart.c Sun Aug 12 04:54:54 2012 +0300 @@ -236,12 +236,13 @@ } if (*section == '\0') { - /* full message/MIME part */ msgpart->wanted_fields |= MAIL_FETCH_STREAM_BODY; if (*msgpart->section_number == '\0') { + /* BODY[] - header+body */ msgpart->fetch_type = FETCH_FULL; msgpart->wanted_fields |= MAIL_FETCH_STREAM_HEADER; } else { + /* BODY[1] - body only */ msgpart->fetch_type = FETCH_MIME_BODY; } return 0; @@ -516,22 +517,31 @@ if (mail_get_parts(mail, &parts) < 0) return -1; part = imap_msgpart_find(parts, msgpart->section_number); - if (part != NULL && (msgpart->fetch_type == FETCH_HEADER || - msgpart->fetch_type == FETCH_BODY)) { - /* fetching message/rfc822 part's header/body */ - if ((part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) == 0) - part = NULL; - else { - i_assert(part->children != NULL && - part->children->next == NULL); - part = part->children; - } - } if (part == NULL) { /* MIME part not found. */ *part_r = NULL; return 0; } + + switch (msgpart->fetch_type) { + case FETCH_FULL: + case FETCH_MIME: + case FETCH_MIME_BODY: + break; + case FETCH_HEADER: + case FETCH_HEADER_FIELDS: + case FETCH_HEADER_FIELDS_NOT: + case FETCH_BODY: + /* fetching message/rfc822 part's header/body */ + if ((part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) == 0) { + *part_r = NULL; + return 0; + } + i_assert(part->children != NULL && + part->children->next == NULL); + part = part->children; + break; + } *part_r = part; return 1; } From dovecot at dovecot.org Sun Aug 12 05:21:49 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 12 Aug 2012 05:21:49 +0300 Subject: dovecot-2.2: FETCH BINARY fix. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/baa8fb155ddc changeset: 14873:baa8fb155ddc user: Timo Sirainen date: Sun Aug 12 05:21:35 2012 +0300 description: FETCH BINARY fix. diffstat: src/lib-storage/index/index-mail-binary.c | 13 +++++++------ 1 files changed, 7 insertions(+), 6 deletions(-) diffs (44 lines): diff -r 9f20f7bd992d -r baa8fb155ddc src/lib-storage/index/index-mail-binary.c --- a/src/lib-storage/index/index-mail-binary.c Sun Aug 12 04:54:54 2012 +0300 +++ b/src/lib-storage/index/index-mail-binary.c Sun Aug 12 05:21:35 2012 +0300 @@ -89,6 +89,7 @@ struct istream *linput; struct binary_block *block; enum message_cte cte; + uoff_t part_end_offset; int ret; /* first parse the header to find c-t-e. */ @@ -146,6 +147,9 @@ } ctx->copy_start_offset = part->physical_pos + part->header_size.physical_size; + part_end_offset = part->physical_pos + + part->header_size.physical_size + + part->body_size.physical_size; if (part->children != NULL) { /* multipart */ @@ -153,9 +157,8 @@ if (add_binary_part(ctx, child, TRUE) < 0) return -1; } - binary_copy_to(ctx, part->physical_pos + - part->header_size.physical_size + - part->body_size.physical_size); + binary_copy_to(ctx, part_end_offset); + ctx->copy_start_offset = part_end_offset; return 0; } @@ -187,9 +190,7 @@ } i_stream_unref(&linput); - ctx->copy_start_offset = part->physical_pos + - part->header_size.physical_size + - part->body_size.physical_size; + ctx->copy_start_offset = part_end_offset; return 0; } From dovecot at dovecot.org Sun Aug 12 05:42:26 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 12 Aug 2012 05:42:26 +0300 Subject: dovecot-2.2: lib-imap: imap_quote() was broken when called with ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/28283c7dc1e9 changeset: 14874:28283c7dc1e9 user: Timo Sirainen date: Sun Aug 12 05:42:14 2012 +0300 description: lib-imap: imap_quote() was broken when called with a datastack pool. diffstat: src/lib-imap/imap-quote.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r baa8fb155ddc -r 28283c7dc1e9 src/lib-imap/imap-quote.c --- a/src/lib-imap/imap-quote.c Sun Aug 12 05:21:35 2012 +0300 +++ b/src/lib-imap/imap-quote.c Sun Aug 12 05:42:14 2012 +0300 @@ -115,7 +115,7 @@ if (value == NULL) return "NIL"; - if (!pool->datastack_pool) + if (pool->datastack_pool) ret = imap_quote_internal(pool, value, value_len, fix_text); else T_BEGIN { ret = imap_quote_internal(pool, value, value_len, fix_text); From dovecot at dovecot.org Sun Aug 12 06:26:47 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 12 Aug 2012 06:26:47 +0300 Subject: dovecot-2.2: Added i_stream_last_line_crlf() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2e88cfd8b595 changeset: 14875:2e88cfd8b595 user: Timo Sirainen date: Sun Aug 12 06:26:35 2012 +0300 description: Added i_stream_last_line_crlf() diffstat: src/lib/istream-private.h | 1 + src/lib/istream.c | 12 ++++++++++-- src/lib/istream.h | 3 +++ 3 files changed, 14 insertions(+), 2 deletions(-) diffs (55 lines): diff -r 28283c7dc1e9 -r 2e88cfd8b595 src/lib/istream-private.h --- a/src/lib/istream-private.h Sun Aug 12 05:42:14 2012 +0300 +++ b/src/lib/istream-private.h Sun Aug 12 06:26:35 2012 +0300 @@ -44,6 +44,7 @@ unsigned int access_counter; string_t *line_str; /* for i_stream_next_line() if w_buffer == NULL */ + unsigned int line_crlf:1; unsigned int return_nolf_line:1; unsigned int stream_size_passthrough:1; /* stream is parent's size */ }; diff -r 28283c7dc1e9 -r 2e88cfd8b595 src/lib/istream.c --- a/src/lib/istream.c Sun Aug 12 05:42:14 2012 +0300 +++ b/src/lib/istream.c Sun Aug 12 06:26:35 2012 +0300 @@ -315,10 +315,13 @@ char *ret; size_t end; - if (i > 0 && stream->buffer[i-1] == '\r') + if (i > 0 && stream->buffer[i-1] == '\r') { end = i - 1; - else + stream->line_crlf = TRUE; + } else { end = i; + stream->line_crlf = FALSE; + } if (stream->w_buffer != NULL) { /* modify the buffer directly */ @@ -386,6 +389,11 @@ return line; } +bool i_stream_last_line_crlf(struct istream *stream) +{ + return stream->real_stream->line_crlf; +} + const unsigned char * i_stream_get_data(const struct istream *stream, size_t *size_r) { diff -r 28283c7dc1e9 -r 2e88cfd8b595 src/lib/istream.h --- a/src/lib/istream.h Sun Aug 12 05:42:14 2012 +0300 +++ b/src/lib/istream.h Sun Aug 12 06:26:35 2012 +0300 @@ -121,6 +121,9 @@ /* Like i_stream_next_line(), but reads for more data if needed. Returns NULL if more data is needed or error occurred. */ char *i_stream_read_next_line(struct istream *stream); +/* Returns TRUE if the last line read with i_stream_next_line() ended with + CRLF (instead of LF). */ +bool i_stream_last_line_crlf(struct istream *stream); /* Returns pointer to beginning of read data, or NULL if there's no data buffered. */ From dovecot at dovecot.org Sun Aug 12 07:21:12 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 12 Aug 2012 07:21:12 +0300 Subject: dovecot-2.2: lib-storage: Update private index before updating s... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ab27926cb173 changeset: 14876:ab27926cb173 user: Timo Sirainen date: Sun Aug 12 07:21:00 2012 +0300 description: lib-storage: Update private index before updating saved search results. diffstat: src/lib-storage/index/index-sync.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) diffs (27 lines): diff -r 2e88cfd8b595 -r ab27926cb173 src/lib-storage/index/index-sync.c --- a/src/lib-storage/index/index-sync.c Sun Aug 12 06:26:35 2012 +0300 +++ b/src/lib-storage/index/index-sync.c Sun Aug 12 07:21:00 2012 +0300 @@ -382,6 +382,12 @@ if (status_r != NULL) status_r->sync_delayed_expunges = delayed_expunges; + /* sync private index if needed. do this after real sync to make sure + that all the new messages are added to the private index, so their + flags can be updated. */ + (void)index_storage_mailbox_sync_pvt(_ctx->box); + + /* update search results after private index is updated */ index_sync_search_results_update(ctx); if (array_is_created(&ctx->flag_updates)) @@ -391,10 +397,6 @@ if (array_is_created(&ctx->all_flag_update_uids)) array_free(&ctx->all_flag_update_uids); - /* sync private index if needed. do this last to make sure that all - the new messages are added to the private index, so their flags can - be updated. */ - (void)index_storage_mailbox_sync_pvt(_ctx->box); i_free(ctx); return ret; } From dovecot at dovecot.org Sun Aug 12 08:34:14 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 12 Aug 2012 08:34:14 +0300 Subject: dovecot-2.2: lib-index: Message flag syncing was broken due to w... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ad22bdfe7bdc changeset: 14877:ad22bdfe7bdc user: Timo Sirainen date: Sun Aug 12 08:05:49 2012 +0300 description: lib-index: Message flag syncing was broken due to wrong struct cast. diffstat: src/lib-index/mail-index-sync.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r ab27926cb173 -r ad22bdfe7bdc src/lib-index/mail-index-sync.c --- a/src/lib-index/mail-index-sync.c Sun Aug 12 07:21:00 2012 +0300 +++ b/src/lib-index/mail-index-sync.c Sun Aug 12 08:05:49 2012 +0300 @@ -626,7 +626,7 @@ static void mail_index_sync_get_update(struct mail_index_sync_rec *rec, - const struct mail_transaction_flag_update *update) + const struct mail_index_flag_update *update) { rec->type = MAIL_INDEX_SYNC_TYPE_FLAGS; rec->uid1 = update->uid1; @@ -705,7 +705,7 @@ (const struct mail_transaction_expunge_guid *)uid_range); } else if (sync_list[i].array == (void *)&sync_trans->updates) { mail_index_sync_get_update(sync_rec, - (const struct mail_transaction_flag_update *)uid_range); + (const struct mail_index_flag_update *)uid_range); } else { mail_index_sync_get_keyword_update(sync_rec, uid_range, &sync_list[i]); From dovecot at dovecot.org Sun Aug 12 08:36:13 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 12 Aug 2012 08:36:13 +0300 Subject: dovecot-2.2: ssl-params socket was missing from login/ directory Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c6fa56ce8860 changeset: 14878:c6fa56ce8860 user: Timo Sirainen date: Sun Aug 12 08:35:29 2012 +0300 description: ssl-params socket was missing from login/ directory diffstat: src/ssl-params/ssl-params-settings.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r ad22bdfe7bdc -r c6fa56ce8860 src/ssl-params/ssl-params-settings.c --- a/src/ssl-params/ssl-params-settings.c Sun Aug 12 08:05:49 2012 +0300 +++ b/src/ssl-params/ssl-params-settings.c Sun Aug 12 08:35:29 2012 +0300 @@ -17,7 +17,8 @@ { "login/ssl-params", 0666, "", "" } }; static struct file_listener_settings *ssl_params_unix_listeners[] = { - &ssl_params_unix_listeners_array[0] + &ssl_params_unix_listeners_array[0], + &ssl_params_unix_listeners_array[1] }; static buffer_t ssl_params_unix_listeners_buf = { ssl_params_unix_listeners, sizeof(ssl_params_unix_listeners), { 0, } From dovecot at dovecot.org Sun Aug 12 08:36:13 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 12 Aug 2012 08:36:13 +0300 Subject: dovecot-2.2: lib-ssl-iostream: Don't crash if protocols setting ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ed07971b21ea changeset: 14879:ed07971b21ea user: Timo Sirainen date: Sun Aug 12 08:36:06 2012 +0300 description: lib-ssl-iostream: Don't crash if protocols setting is NULL. diffstat: src/lib-ssl-iostream/iostream-openssl-context.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (15 lines): diff -r c6fa56ce8860 -r ed07971b21ea src/lib-ssl-iostream/iostream-openssl-context.c --- a/src/lib-ssl-iostream/iostream-openssl-context.c Sun Aug 12 08:35:29 2012 +0300 +++ b/src/lib-ssl-iostream/iostream-openssl-context.c Sun Aug 12 08:36:06 2012 +0300 @@ -352,8 +352,10 @@ ssl_iostream_error()); return -1; } - SSL_CTX_set_options(ctx->ssl_ctx, + if (ctx->set->protocols != NULL) { + SSL_CTX_set_options(ctx->ssl_ctx, openssl_get_protocol_options(ctx->set->protocols)); + } if (set->cert != NULL && ssl_ctx_use_certificate_chain(ctx->ssl_ctx, set->cert) < 0) { From dovecot at dovecot.org Sun Aug 12 09:57:31 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 12 Aug 2012 09:57:31 +0300 Subject: dovecot-2.2: lib-ssl-iostream: Avoid assert-crash when reading a... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d7df4855dc94 changeset: 14880:d7df4855dc94 user: Timo Sirainen date: Sun Aug 12 09:57:20 2012 +0300 description: lib-ssl-iostream: Avoid assert-crash when reading a closed stream. diffstat: src/lib-ssl-iostream/iostream-openssl.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r ed07971b21ea -r d7df4855dc94 src/lib-ssl-iostream/iostream-openssl.c --- a/src/lib-ssl-iostream/iostream-openssl.c Sun Aug 12 08:36:06 2012 +0300 +++ b/src/lib-ssl-iostream/iostream-openssl.c Sun Aug 12 09:57:20 2012 +0300 @@ -312,7 +312,8 @@ fully succeed or completely fail due to some error. */ sent = o_stream_send(ssl_io->plain_output, buffer, bytes); if (sent < 0) { - i_assert(ssl_io->plain_output->stream_errno != 0); + i_assert(ssl_io->plain_output->closed || + ssl_io->plain_output->stream_errno != 0); ssl_io->plain_stream_errno = ssl_io->plain_output->stream_errno; ssl_io->closed = TRUE; From pigeonhole at rename-it.nl Sun Aug 12 16:50:35 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 12 Aug 2012 15:50:35 +0200 Subject: dovecot-2.1-pigeonhole: Removed trailing whitespace everywhere. Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/7e100dcd888a changeset: 1639:7e100dcd888a user: Stephan Bosch date: Sun Aug 12 15:50:27 2012 +0200 description: Removed trailing whitespace everywhere. diffstat: AUTHORS | 4 +- COPYING | 2 +- INSTALL | 138 +- Makefile.am | 4 +- NEWS | 472 +++--- README | 94 +- TODO | 34 +- configure.in | 16 +- doc/devel/DESIGN | 44 +- doc/example-config/conf.d/20-managesieve.conf | 14 +- doc/example-config/conf.d/90-sieve.conf | 24 +- doc/extensions/editheader.txt | 4 +- doc/extensions/include.txt | 4 +- doc/extensions/spamtest-virustest.txt | 40 +- doc/extensions/vacation.txt | 18 +- doc/man/pigeonhole.7.in | 2 +- doc/man/sieve-dump.1.in | 2 +- doc/man/sieve-filter.1.in | 36 +- doc/man/sieve-test.1.in | 8 +- doc/man/sievec.1.in | 2 +- doc/script-location-dict.txt | 4 +- src/lib-managesieve/Makefile.am | 4 +- src/lib-managesieve/managesieve-arg.c | 4 +- src/lib-managesieve/managesieve-arg.h | 8 +- src/lib-managesieve/managesieve-parser.c | 4 +- src/lib-managesieve/managesieve-parser.h | 2 +- src/lib-managesieve/managesieve-quote.c | 10 +- src/lib-sieve-tool/mail-raw.c | 16 +- src/lib-sieve-tool/sieve-tool.c | 58 +- src/lib-sieve-tool/sieve-tool.h | 2 +- src/lib-sieve/Makefile.am | 2 +- src/lib-sieve/cmd-discard.c | 60 +- src/lib-sieve/cmd-if.c | 122 +- src/lib-sieve/cmd-keep.c | 36 +- src/lib-sieve/cmd-redirect.c | 112 +- src/lib-sieve/cmd-require.c | 48 +- src/lib-sieve/cmd-stop.c | 48 +- src/lib-sieve/cmp-i-ascii-casemap.c | 38 +- src/lib-sieve/cmp-i-octet.c | 42 +- src/lib-sieve/edit-mail.c | 70 +- src/lib-sieve/ext-encoded-character.c | 124 +- src/lib-sieve/ext-envelope.c | 164 +- src/lib-sieve/ext-fileinto.c | 84 +- src/lib-sieve/ext-reject.c | 178 +- src/lib-sieve/mcht-contains.c | 18 +- src/lib-sieve/mcht-is.c | 24 +- src/lib-sieve/mcht-matches.c | 170 +- src/lib-sieve/plugins/Makefile.am | 2 +- src/lib-sieve/plugins/body/ext-body-common.c | 72 +- src/lib-sieve/plugins/body/ext-body-common.h | 8 +- src/lib-sieve/plugins/body/ext-body.c | 20 +- src/lib-sieve/plugins/body/tst-body.c | 190 +- src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c | 44 +- src/lib-sieve/plugins/copy/Makefile.am | 2 +- src/lib-sieve/plugins/copy/ext-copy.c | 54 +- src/lib-sieve/plugins/date/ext-date-common.c | 72 +- src/lib-sieve/plugins/date/ext-date-common.h | 8 +- src/lib-sieve/plugins/date/ext-date.c | 16 +- src/lib-sieve/plugins/date/tst-date.c | 132 +- src/lib-sieve/plugins/editheader/cmd-addheader.c | 18 +- src/lib-sieve/plugins/editheader/cmd-deleteheader.c | 146 +- src/lib-sieve/plugins/editheader/ext-editheader-common.c | 26 +- src/lib-sieve/plugins/editheader/ext-editheader-limits.h | 2 +- src/lib-sieve/plugins/editheader/ext-editheader.c | 8 +- src/lib-sieve/plugins/enotify/Makefile.am | 2 +- src/lib-sieve/plugins/enotify/cmd-notify.c | 242 +- src/lib-sieve/plugins/enotify/ext-enotify-common.c | 204 +- src/lib-sieve/plugins/enotify/ext-enotify-common.h | 20 +- src/lib-sieve/plugins/enotify/ext-enotify-limits.h | 2 +- src/lib-sieve/plugins/enotify/ext-enotify.c | 18 +- src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c | 152 +- src/lib-sieve/plugins/enotify/mailto/uri-mailto.c | 190 +- src/lib-sieve/plugins/enotify/mailto/uri-mailto.h | 14 +- src/lib-sieve/plugins/enotify/sieve-ext-enotify.h | 38 +- src/lib-sieve/plugins/enotify/tst-notify-method-capability.c | 98 +- src/lib-sieve/plugins/enotify/tst-valid-notify-method.c | 70 +- src/lib-sieve/plugins/enotify/vmodf-encodeurl.c | 22 +- src/lib-sieve/plugins/environment/ext-environment-common.c | 48 +- src/lib-sieve/plugins/environment/ext-environment-common.h | 6 +- src/lib-sieve/plugins/environment/ext-environment.c | 12 +- src/lib-sieve/plugins/environment/sieve-ext-environment.h | 4 +- src/lib-sieve/plugins/environment/tst-environment.c | 90 +- src/lib-sieve/plugins/ihave/ext-ihave-binary.c | 84 +- src/lib-sieve/plugins/ihave/ext-ihave-binary.h | 4 +- src/lib-sieve/plugins/ihave/ext-ihave-common.c | 4 +- src/lib-sieve/plugins/ihave/ext-ihave.c | 2 +- src/lib-sieve/plugins/ihave/tst-ihave.c | 24 +- src/lib-sieve/plugins/imap4flags/Makefile.am | 2 +- src/lib-sieve/plugins/imap4flags/cmd-flag.c | 104 +- src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c | 228 +- src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h | 20 +- src/lib-sieve/plugins/imap4flags/ext-imap4flags.c | 32 +- src/lib-sieve/plugins/imap4flags/ext-imapflags.c | 36 +- src/lib-sieve/plugins/imap4flags/tag-flags.c | 152 +- src/lib-sieve/plugins/imap4flags/tst-hasflag.c | 84 +- src/lib-sieve/plugins/include/cmd-global.c | 134 +- src/lib-sieve/plugins/include/cmd-include.c | 174 +- src/lib-sieve/plugins/include/cmd-return.c | 32 +- src/lib-sieve/plugins/include/ext-include-binary.c | 166 +- src/lib-sieve/plugins/include/ext-include-binary.h | 8 +- src/lib-sieve/plugins/include/ext-include-common.c | 236 +- src/lib-sieve/plugins/include/ext-include-common.h | 44 +- src/lib-sieve/plugins/include/ext-include-variables.c | 64 +- src/lib-sieve/plugins/include/ext-include-variables.h | 10 +- src/lib-sieve/plugins/include/ext-include.c | 26 +- src/lib-sieve/plugins/mailbox/ext-mailbox.c | 12 +- src/lib-sieve/plugins/mailbox/tag-mailbox-create.c | 50 +- src/lib-sieve/plugins/mailbox/tst-mailboxexists.c | 78 +- src/lib-sieve/plugins/notify/cmd-denotify.c | 78 +- src/lib-sieve/plugins/notify/cmd-notify.c | 176 +- src/lib-sieve/plugins/notify/ext-notify-common.c | 62 +- src/lib-sieve/plugins/notify/ext-notify-common.h | 8 +- src/lib-sieve/plugins/notify/ext-notify-limits.h | 2 +- src/lib-sieve/plugins/notify/ext-notify.c | 14 +- src/lib-sieve/plugins/regex/ext-regex-common.c | 2 +- src/lib-sieve/plugins/regex/ext-regex.c | 10 +- src/lib-sieve/plugins/regex/mcht-regex.c | 62 +- src/lib-sieve/plugins/relational/Makefile.am | 2 +- src/lib-sieve/plugins/relational/ext-relational-common.c | 64 +- src/lib-sieve/plugins/relational/ext-relational-common.h | 22 +- src/lib-sieve/plugins/relational/ext-relational.c | 10 +- src/lib-sieve/plugins/relational/mcht-count.c | 18 +- src/lib-sieve/plugins/relational/mcht-value.c | 18 +- src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c | 104 +- src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.h | 8 +- src/lib-sieve/plugins/spamvirustest/ext-spamvirustest.c | 46 +- src/lib-sieve/plugins/spamvirustest/tst-spamvirustest.c | 124 +- src/lib-sieve/plugins/subaddress/ext-subaddress.c | 36 +- src/lib-sieve/plugins/vacation/cmd-vacation.c | 450 +++--- src/lib-sieve/plugins/vacation/ext-vacation-common.c | 2 +- src/lib-sieve/plugins/vacation/ext-vacation-common.h | 12 +- src/lib-sieve/plugins/vacation/ext-vacation-seconds.c | 8 +- src/lib-sieve/plugins/vacation/ext-vacation.c | 4 +- src/lib-sieve/plugins/variables/Makefile.am | 2 +- src/lib-sieve/plugins/variables/cmd-set.c | 172 +- src/lib-sieve/plugins/variables/ext-variables-arguments.c | 176 +- src/lib-sieve/plugins/variables/ext-variables-arguments.h | 12 +- src/lib-sieve/plugins/variables/ext-variables-common.c | 208 +- src/lib-sieve/plugins/variables/ext-variables-common.h | 26 +- src/lib-sieve/plugins/variables/ext-variables-dump.c | 36 +- src/lib-sieve/plugins/variables/ext-variables-dump.h | 4 +- src/lib-sieve/plugins/variables/ext-variables-limits.h | 2 +- src/lib-sieve/plugins/variables/ext-variables-modifiers.c | 58 +- src/lib-sieve/plugins/variables/ext-variables-modifiers.h | 8 +- src/lib-sieve/plugins/variables/ext-variables-name.h | 16 +- src/lib-sieve/plugins/variables/ext-variables-namespaces.c | 64 +- src/lib-sieve/plugins/variables/ext-variables-namespaces.h | 10 +- src/lib-sieve/plugins/variables/ext-variables-operands.c | 102 +- src/lib-sieve/plugins/variables/ext-variables-operands.h | 20 +- src/lib-sieve/plugins/variables/ext-variables.c | 34 +- src/lib-sieve/plugins/variables/sieve-ext-variables.h | 84 +- src/lib-sieve/plugins/variables/tst-string.c | 102 +- src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate-common.c | 12 +- src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate-common.h | 2 +- src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate.c | 12 +- src/lib-sieve/plugins/vnd.dovecot/duplicate/tst-duplicate.c | 34 +- src/lib-sieve/rfc2822.c | 66 +- src/lib-sieve/rfc2822.h | 6 +- src/lib-sieve/sieve-actions.c | 228 +- src/lib-sieve/sieve-actions.h | 104 +- src/lib-sieve/sieve-address-parts.c | 112 +- src/lib-sieve/sieve-address-parts.h | 26 +- src/lib-sieve/sieve-address.c | 170 +- src/lib-sieve/sieve-address.h | 24 +- src/lib-sieve/sieve-ast.c | 472 +++--- src/lib-sieve/sieve-ast.h | 112 +- src/lib-sieve/sieve-binary-code.c | 114 +- src/lib-sieve/sieve-binary-debug.c | 34 +- src/lib-sieve/sieve-binary-dumper.c | 98 +- src/lib-sieve/sieve-binary-dumper.h | 4 +- src/lib-sieve/sieve-binary-file.c | 316 ++-- src/lib-sieve/sieve-binary-private.h | 78 +- src/lib-sieve/sieve-binary.c | 138 +- src/lib-sieve/sieve-binary.h | 78 +- src/lib-sieve/sieve-code-dumper.c | 92 +- src/lib-sieve/sieve-code-dumper.h | 18 +- src/lib-sieve/sieve-code.c | 456 +++--- src/lib-sieve/sieve-code.h | 88 +- src/lib-sieve/sieve-commands.c | 150 +- src/lib-sieve/sieve-commands.h | 70 +- src/lib-sieve/sieve-common.h | 8 +- src/lib-sieve/sieve-comparators.c | 110 +- src/lib-sieve/sieve-comparators.h | 54 +- src/lib-sieve/sieve-config.h | 2 +- src/lib-sieve/sieve-dump.h | 2 +- src/lib-sieve/sieve-error-private.h | 18 +- src/lib-sieve/sieve-error.c | 324 ++-- src/lib-sieve/sieve-error.h | 28 +- src/lib-sieve/sieve-extensions.c | 124 +- src/lib-sieve/sieve-extensions.h | 42 +- src/lib-sieve/sieve-generator.c | 204 +- src/lib-sieve/sieve-generator.h | 40 +- src/lib-sieve/sieve-interpreter.c | 158 +- src/lib-sieve/sieve-interpreter.h | 38 +- src/lib-sieve/sieve-lexer.c | 330 ++-- src/lib-sieve/sieve-lexer.h | 46 +- src/lib-sieve/sieve-match-types.c | 212 +- src/lib-sieve/sieve-match-types.h | 62 +- src/lib-sieve/sieve-match.c | 38 +- src/lib-sieve/sieve-match.h | 12 +- src/lib-sieve/sieve-message.c | 88 +- src/lib-sieve/sieve-message.h | 8 +- src/lib-sieve/sieve-objects.c | 46 +- src/lib-sieve/sieve-objects.h | 6 +- src/lib-sieve/sieve-parser.c | 328 ++-- src/lib-sieve/sieve-parser.h | 4 +- src/lib-sieve/sieve-plugins.c | 10 +- src/lib-sieve/sieve-plugins.h | 2 +- src/lib-sieve/sieve-result.c | 524 +++--- src/lib-sieve/sieve-result.h | 28 +- src/lib-sieve/sieve-runtime-trace.c | 44 +- src/lib-sieve/sieve-runtime-trace.h | 16 +- src/lib-sieve/sieve-runtime.h | 6 +- src/lib-sieve/sieve-script-dict.c | 14 +- src/lib-sieve/sieve-script-file.c | 42 +- src/lib-sieve/sieve-script-file.h | 2 +- src/lib-sieve/sieve-script-private.h | 2 +- src/lib-sieve/sieve-script.c | 36 +- src/lib-sieve/sieve-script.h | 12 +- src/lib-sieve/sieve-settings.c | 18 +- src/lib-sieve/sieve-stringlist.c | 18 +- src/lib-sieve/sieve-stringlist.h | 4 +- src/lib-sieve/sieve-types.h | 28 +- src/lib-sieve/sieve-validator.c | 684 +++++----- src/lib-sieve/sieve-validator.h | 60 +- src/lib-sieve/sieve.c | 178 +- src/lib-sieve/sieve.h | 42 +- src/lib-sieve/tst-address.c | 124 +- src/lib-sieve/tst-allof.c | 46 +- src/lib-sieve/tst-anyof.c | 48 +- src/lib-sieve/tst-exists.c | 64 +- src/lib-sieve/tst-header.c | 86 +- src/lib-sieve/tst-not.c | 26 +- src/lib-sieve/tst-size.c | 162 +- src/lib-sieve/tst-truefalse.c | 28 +- src/lib-sievestorage/Makefile.am | 2 +- src/lib-sievestorage/sieve-storage-list.c | 16 +- src/lib-sievestorage/sieve-storage-list.h | 4 +- src/lib-sievestorage/sieve-storage-private.h | 2 +- src/lib-sievestorage/sieve-storage-quota.c | 24 +- src/lib-sievestorage/sieve-storage-quota.h | 2 +- src/lib-sievestorage/sieve-storage-save.c | 36 +- src/lib-sievestorage/sieve-storage-script.c | 120 +- src/lib-sievestorage/sieve-storage.c | 70 +- src/lib-sievestorage/sieve-storage.h | 2 +- src/managesieve-login/client-authenticate.c | 12 +- src/managesieve-login/client.c | 40 +- src/managesieve-login/client.h | 2 +- src/managesieve-login/managesieve-login-settings-plugin.c | 12 +- src/managesieve-login/managesieve-login-settings.c | 2 +- src/managesieve-login/managesieve-proxy.c | 58 +- src/managesieve/Makefile.am | 4 +- src/managesieve/cmd-capability.c | 8 +- src/managesieve/cmd-deletescript.c | 2 +- src/managesieve/cmd-getscript.c | 8 +- src/managesieve/cmd-listscripts.c | 12 +- src/managesieve/cmd-putscript.c | 34 +- src/managesieve/cmd-renamescript.c | 2 +- src/managesieve/cmd-setactive.c | 12 +- src/managesieve/managesieve-capabilities.c | 6 +- src/managesieve/managesieve-client.c | 18 +- src/managesieve/managesieve-client.h | 2 +- src/managesieve/managesieve-commands.c | 8 +- src/managesieve/managesieve-quota.c | 16 +- src/managesieve/managesieve-settings.c | 2 +- src/plugins/lda-sieve/Makefile.am | 2 +- src/plugins/lda-sieve/lda-sieve-plugin.c | 50 +- src/sieve-tools/Makefile.am | 10 +- src/sieve-tools/sieve-dump.c | 12 +- src/sieve-tools/sieve-filter.c | 72 +- src/sieve-tools/sieve-test.c | 78 +- src/sieve-tools/sievec.c | 52 +- src/testsuite/cmd-test-binary.c | 84 +- src/testsuite/cmd-test-config.c | 160 +- src/testsuite/cmd-test-fail.c | 66 +- src/testsuite/cmd-test-mailbox.c | 84 +- src/testsuite/cmd-test-message.c | 192 +- src/testsuite/cmd-test-result.c | 52 +- src/testsuite/cmd-test-set.c | 70 +- src/testsuite/cmd-test.c | 82 +- src/testsuite/ext-testsuite.c | 14 +- src/testsuite/testsuite-arguments.c | 80 +- src/testsuite/testsuite-binary.c | 10 +- src/testsuite/testsuite-binary.h | 2 +- src/testsuite/testsuite-common.c | 36 +- src/testsuite/testsuite-common.h | 26 +- src/testsuite/testsuite-log.c | 22 +- src/testsuite/testsuite-mailstore.c | 24 +- src/testsuite/testsuite-mailstore.h | 4 +- src/testsuite/testsuite-message.c | 36 +- src/testsuite/testsuite-objects.c | 166 +- src/testsuite/testsuite-objects.h | 40 +- src/testsuite/testsuite-result.c | 26 +- src/testsuite/testsuite-result.h | 2 +- src/testsuite/testsuite-script.c | 2 +- src/testsuite/testsuite-script.h | 2 +- src/testsuite/testsuite-settings.c | 18 +- src/testsuite/testsuite-smtp.c | 44 +- src/testsuite/testsuite-smtp.h | 6 +- src/testsuite/testsuite-substitutions.c | 114 +- src/testsuite/testsuite-substitutions.h | 4 +- src/testsuite/testsuite-variables.c | 4 +- src/testsuite/testsuite-variables.h | 2 +- src/testsuite/testsuite.c | 10 +- src/testsuite/tst-test-error.c | 70 +- src/testsuite/tst-test-multiscript.c | 50 +- src/testsuite/tst-test-result-action.c | 68 +- src/testsuite/tst-test-result-execute.c | 32 +- src/testsuite/tst-test-script-compile.c | 44 +- src/testsuite/tst-test-script-run.c | 58 +- tests/compile/errors.svtest | 26 +- tests/compile/errors/address.sieve | 6 +- tests/compile/errors/envelope.sieve | 2 +- tests/compile/errors/if.sieve | 4 +- tests/compile/errors/keep.sieve | 2 +- tests/compile/errors/lexer.sieve | 2 +- tests/compile/errors/out-address.sieve | 2 +- tests/compile/errors/parser.sieve | 36 +- tests/compile/errors/require.sieve | 2 +- tests/compile/errors/size.sieve | 2 +- tests/compile/errors/tag.sieve | 2 +- tests/compile/errors/typos.sieve | 10 +- tests/compile/errors/unsupported.sieve | 6 +- tests/compile/recover.svtest | 2 +- tests/control-if.svtest | 40 +- tests/deprecated/notify/basic.svtest | 4 +- tests/deprecated/notify/mailto.svtest | 24 +- tests/execute/actions.svtest | 18 +- tests/execute/actions/redirect.sieve | 2 +- tests/execute/errors.svtest | 4 +- tests/execute/examples.svtest | 2 +- tests/execute/mailstore.svtest | 2 +- tests/extensions/body/basic.svtest | 10 +- tests/extensions/body/content.svtest | 20 +- tests/extensions/body/raw.svtest | 2 +- tests/extensions/date/basic.svtest | 8 +- tests/extensions/date/zones.svtest | 22 +- tests/extensions/editheader/addheader.svtest | 34 +- tests/extensions/editheader/alternating.svtest | 4 +- tests/extensions/editheader/deleteheader.svtest | 10 +- tests/extensions/editheader/errors.svtest | 8 +- tests/extensions/editheader/errors/command-syntax.sieve | 2 +- tests/extensions/editheader/protected.svtest | 12 +- tests/extensions/encoded-character.svtest | 4 +- tests/extensions/enotify/basic.svtest | 6 +- tests/extensions/enotify/errors/uri-mailto.sieve | 2 +- tests/extensions/enotify/mailto.svtest | 18 +- tests/extensions/enotify/valid_notify_method.svtest | 4 +- tests/extensions/envelope.svtest | 6 +- tests/extensions/environment/rfc.svtest | 4 +- tests/extensions/imap4flags/basic.svtest | 16 +- tests/extensions/imap4flags/execute.svtest | 20 +- tests/extensions/imap4flags/execute/flags-side-effect.sieve | 4 +- tests/extensions/imap4flags/hasflag.svtest | 8 +- tests/extensions/imap4flags/multiscript.svtest | 16 +- tests/extensions/include/execute.svtest | 6 +- tests/extensions/regex/basic.svtest | 8 +- tests/extensions/regex/match-values.svtest | 12 +- tests/extensions/relational/basic.svtest | 10 +- tests/extensions/relational/comparators.svtest | 22 +- tests/extensions/relational/errors/validation.sieve | 2 +- tests/extensions/relational/rfc.svtest | 12 +- tests/extensions/spamvirustest/spamtest.svtest | 2 +- tests/extensions/subaddress/basic.svtest | 2 +- tests/extensions/subaddress/rfc.svtest | 4 +- tests/extensions/vacation/execute.svtest | 4 +- tests/extensions/vacation/execute/no-handle.sieve | 6 +- tests/extensions/vacation/message.svtest | 10 +- tests/extensions/vacation/reply.svtest | 2 +- tests/extensions/vacation/utf-8.svtest | 4 +- tests/extensions/variables/basic.svtest | 14 +- tests/extensions/variables/errors/limits.sieve | 2 +- tests/extensions/variables/match.svtest | 34 +- tests/extensions/variables/modifiers.svtest | 12 +- tests/extensions/variables/quoting.svtest | 2 +- tests/extensions/variables/regex.svtest | 6 +- tests/extensions/variables/string.svtest | 2 +- tests/match-types/contains.svtest | 4 +- tests/match-types/is.svtest | 4 +- tests/match-types/matches.svtest | 2 +- tests/multiscript/basic.svtest | 4 +- tests/multiscript/conflicts.svtest | 8 +- tests/test-address.svtest | 28 +- tests/test-allof.svtest | 16 +- tests/test-anyof.svtest | 28 +- tests/test-exists.svtest | 2 +- tests/test-header.svtest | 18 +- tests/testsuite.svtest | 2 +- 388 files changed, 9954 insertions(+), 9954 deletions(-) diffs (truncated from 54658 to 300 lines): diff -r 54a0d0552be7 -r 7e100dcd888a AUTHORS --- a/AUTHORS Thu Aug 09 22:58:53 2012 +0200 +++ b/AUTHORS Sun Aug 12 15:50:27 2012 +0200 @@ -1,8 +1,8 @@ Stephan Bosch -This package is built for and partly based on the Dovecot Secure IMAP server +This package is built for and partly based on the Dovecot Secure IMAP server written by: -Timo Sirainen . +Timo Sirainen . Grepping 'patch by' from ChangeLog shows up more people. diff -r 54a0d0552be7 -r 7e100dcd888a COPYING --- a/COPYING Thu Aug 09 22:58:53 2012 +0200 +++ b/COPYING Sun Aug 12 15:50:27 2012 +0200 @@ -1,4 +1,4 @@ See AUTHORS file for list of copyright holders. -Everything is licenced under LGPLv2.1 (see COPYING.LGPL) unless otherwise +Everything is licenced under LGPLv2.1 (see COPYING.LGPL) unless otherwise mentioned at the beginning of the file. diff -r 54a0d0552be7 -r 7e100dcd888a INSTALL --- a/INSTALL Thu Aug 09 22:58:53 2012 +0200 +++ b/INSTALL Sun Aug 12 15:50:27 2012 +0200 @@ -1,7 +1,7 @@ Compiling ========= -If you downloaded the sources using Mercurial, you will need to execute +If you downloaded the sources using Mercurial, you will need to execute ./autogen.sh first to build the automake structure in your source tree. This process requires autotools and libtool to be installed. @@ -12,7 +12,7 @@ make sudo make install -If your system uses a $prefix different than the default /usr/local, the +If your system uses a $prefix different than the default /usr/local, the configure script can still find the installed dovecot-config automatically when supplied with the proper --prefix argument: @@ -44,7 +44,7 @@ --with-unfinished-features=no Controls whether unfinished features and extensions are built. Enabling this will enable the compilation of code that is considered unfinished and highly - experimental and may therefore introduce bugs and unexpected behavior. + experimental and may therefore introduce bugs and unexpected behavior. In fact, it may not compile at all. Enable this only when you are eager to test some of the new development functionality. @@ -57,12 +57,12 @@ facilitates the actual Sieve filtering upon delivery. - The ManageSieve Service: This implements the ManageSieve protocol through - which users can remotely manage Sieve scripts on the server. + which users can remotely manage Sieve scripts on the server. -The functionality of these items is described in more detail in the README file. +The functionality of these items is described in more detail in the README file. In this file and in this section their configuration is described. Example configuration files are provided in the doc/example-config directory of this -package. +package. Sieve Interpreter - Basic Configuration --------------------------------------- @@ -85,9 +85,9 @@ plugin section of the config file (default values are shown if applicable): sieve = ~/.dovecot.sieve - The location of the user's main active script. - - sieve_default = + The location of the user's main active script. + + sieve_default = The location of the default personal sieve script file, which gets executed ONLY if user's private Sieve script does no exist, e.g. /var/lib/dovecot/default.sieve. This is usually a global script, so be sure @@ -96,20 +96,20 @@ `sieve_global_path', but that name is now deprecated. sieve_global_dir = - Location for :global include scripts for the Sieve include extension. + Location for :global include scripts for the Sieve include extension. sieve_dir = ~/sieve - Location for :personal include scripts for the Sieve include extension. + Location for :personal include scripts for the Sieve include extension. sieve_extensions = - Which Sieve language extensions are available to users. By default, all - supported extensions are available, except for deprecated extensions or those - that are still under development. Some system administrators may want to - disable certain Sieve extensions or enable those that are not available by + Which Sieve language extensions are available to users. By default, all + supported extensions are available, except for deprecated extensions or those + that are still under development. Some system administrators may want to + disable certain Sieve extensions or enable those that are not available by default. This setting can use '+' and '-' to specify differences relative to the default. For example `sieve_extensions = +imapflags' will enable the deprecated imapflags extension in addition to all extensions were already - enabled by default. + enabled by default. sieve_global_extensions = Which Sieve language extensions are ONLY avalable in global scripts. This can @@ -117,7 +117,7 @@ control, for instance when these extensions can cause security concerns. This setting has higher precedence than the `sieve_extensions' setting (above), meaning that the extensions enabled with this setting are never available to - the user's personal script no matter what is specified for the + the user's personal script no matter what is specified for the `sieve_extensions' setting. The syntax of this setting is similar to the `sieve_extensions' setting, with the difference that extensions are enabled or disabled for exclusive use in global scripts. Currently, no @@ -127,16 +127,16 @@ The Pigeonhole Sieve interpreter can have plugins of its own. Using this setting, the used plugins can be specified. Check the Dovecot wiki (wiki2.dovecot.org) or the pigeonhole website (http://pigeonhole.dovecot.org) - for available plugins. + for available plugins. sieve_user_log = The path to the file where the user log file is written. If not configured, a default location is used. If the main user's personal Sieve (as configured with sieve=) is a file, the logfile is set to .log by default. If - it is not a file, the default user log file is ~/.dovecot.sieve.log. + it is not a file, the default user log file is ~/.dovecot.sieve.log. recipient_delimiter = + - The separator that is expected between the :user and :detail address parts + The separator that is expected between the :user and :detail address parts introduced by the subaddress extension. This may also be a sequence of characters (e.g. '--'). The current implementation looks for the separator from the left of the localpart and uses the first one encountered. The :user @@ -150,16 +150,16 @@ # The location of the user's active script: sieve = ~/.dovecot.sieve - # If the user has no personal active script (i.e. if the file + # If the user has no personal active script (i.e. if the file # indicated in sieve= does not exist), use this one: sieve_default = /var/lib/dovecot/sieve/default.sieve - # The include extension fetches the :personal scripts from this - # directory. When ManageSieve is used, this is also where scripts + # The include extension fetches the :personal scripts from this + # directory. When ManageSieve is used, this is also where scripts # are uploaded. sieve_dir = ~/sieve - # The include extension fetches the :global scripts from this + # The include extension fetches the :global scripts from this # directory. sieve_global_dir = /var/lib/dovecot/sieve/global/ } @@ -197,7 +197,7 @@ or a directory containing script files with names structured as `.sieve'. dict - Dovecot dict lookup. The location path is a dict uri. Read - doc/scipt-location-dict.txt for more information and examples. + doc/scipt-location-dict.txt for more information and examples. If the type prefix is omitted, the script location type is 'file'. @@ -219,8 +219,8 @@ directory as where the script file was found if possible. For `dict' type locations, the binary is not stored at all in that case. Don't specify the same directory for different script locations, as this will result in - undefined behavior. - + undefined behavior. + Sieve Interpreter - Per-user Sieve Script Location -------------------------------------------------- @@ -228,14 +228,14 @@ file in the user's home directory (~/.dovecot.sieve). This requires that the home directory is set for the user. -If you want to store the script elsewhere, you can override the default using +If you want to store the script elsewhere, you can override the default using the sieve= setting, which specifies the location of the user's script file. This can be done in two ways: 1. Define the sieve setting in the plugin section of dovecot.conf. - 2. Return sieve extra field from userdb extra fields. + 2. Return sieve extra field from userdb extra fields. -For example, to use a Sieve script file named .sieve in +For example, to use a Sieve script file named .sieve in /var/sieve-scripts, use: plugin { @@ -244,16 +244,16 @@ sieve = /var/sieve-scripts/%u.sieve } -You may use templates like %u, as shown in the example. Refer to +You may use templates like %u, as shown in the example. Refer to http://wiki.dovecot.org/Variables for more information. -A relative path (or just a filename) will be interpreted to point under the +A relative path (or just a filename) will be interpreted to point under the user's home directory. Sieve Interpreter - Executing Multiple Scripts Sequentially ----------------------------------------------------------- -Pigeonhole's Sieve interpreter allows executing multiple Sieve scripts +Pigeonhole's Sieve interpreter allows executing multiple Sieve scripts sequentially. The extra scripts can be executed before and after the user's private script. For example, this allows executing global Sieve policies before the user's script. The following settings in the plugin section of the Dovecot @@ -267,7 +267,7 @@ directory, all the Sieve scripts contained therein (with the proper .sieve extension) are executed. The order of execution within that directory is determined by the file names, using a normal 8bit per-character comparison. - + Multiple script file or directory paths can be specified by appending an increasing number. The Sieve scripts found from these paths are added to the script execution sequence in the specified order. Reading the numbered @@ -278,14 +278,14 @@ sieve_after2 = sieve_after3 = (etc..) Identical to sieve_before, but the specified scripts are executed after the - user's script (only when keep is still in effect, as explained below). + user's script (only when keep is still in effect, as explained below). The script execution ends when the currently executing script in the sequence -does not yield a "keep" result: when the script terminates, the next script is +does not yield a "keep" result: when the script terminates, the next script is only executed if an implicit or explicit "keep" is in effect. Thus, to end all script execution, a script must not execute keep and it must cancel the implicit -keep, e.g. by executing "discard; stop;". This means that the command "keep;" -has different semantics when used in a sequence of scripts. For normal Sieve +keep, e.g. by executing "discard; stop;". This means that the command "keep;" +has different semantics when used in a sequence of scripts. For normal Sieve execution, "keep;" is equivalent to "fileinto "INBOX";", because both cause the message to be stored in INBOX. However, in sequential script execution, it only controls whether the next script is executed. Storing the message into INBOX @@ -304,7 +304,7 @@ Just as for executing a single script the normal way, the Pigeonhole LDA Sieve plugin takes care never to duplicate deliveries, forwards or responses. When -vacation actions are executed multiple times in different scripts, the usual +vacation actions are executed multiple times in different scripts, the usual error is not triggered: the subsequent duplicate vacation actions are simply discarded. @@ -325,7 +325,7 @@ # E.g. user-specific default mail filing rules sieve_after = /var/vmail/%d/%n/sieve-after - # Global scripts executed after the user's personal script + # Global scripts executed after the user's personal script # (if keep is still in effect) # E.g. default mail filing rules. sieve_after2 = /var/lib/dovecot/sieve/after.d/ @@ -385,7 +385,7 @@ Sieve Interpreter - Migration from CMUSieve (Dovecot v1.0/v1.1) --------------------------------------------------------------- -For the most part, migration from CMUSieve to the Pigeonhole LDA Sieve plugin is +For the most part, migration from CMUSieve to the Pigeonhole LDA Sieve plugin is just a matter of changing the used plugin name from 'cmusieve' to 'sieve' in the mail_plugins option in the protocol lda section of the config file (as explained above). However, there are a few important differences: @@ -406,46 +406,46 @@ * The include extension now requires your script file names to end with ".sieve". This means that ` include :personal "myscript"; ' won't work unless - you rename "myscript" to "myscript.sieve" + you rename "myscript" to "myscript.sieve" Sieve Interpreter - Migration from Dovecot Sieve v0.1.x (Dovecot v1.2) ---------------------------------------------------------------------- - * Dovecot v2.0 adds support for LMTP. Much like the Dovecot LDA, it can make - use of the Pigeonhole Sieve plugin. Since the LMTP service has its own - prototocol lmtp section in the config file, you need to add the Sieve plugin + * Dovecot v2.0 adds support for LMTP. Much like the Dovecot LDA, it can make + use of the Pigeonhole Sieve plugin. Since the LMTP service has its own + prototocol lmtp section in the config file, you need to add the Sieve plugin to the mail_plugins setting there too when you decide to use LMTP. - * The 'sieve_subaddress_sep' setting for the Sieve subaddress extension is now + * The 'sieve_subaddress_sep' setting for the Sieve subaddress extension is now known as 'recipient_delimiter'. Although sieve_subaddress_sep is still recognized for backwards compatibility, it is recommended to update the setting to the new name, since the LMTP service also uses the - recipient_delimiter setting. + recipient_delimiter setting. ManageSieve Service - Basic Configuration ----------------------------------------- From pigeonhole at rename-it.nl Sun Aug 12 17:16:30 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 12 Aug 2012 16:16:30 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: Adjusted edit-mail.c to chang... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/c5cebc7dbd6b changeset: 1654:c5cebc7dbd6b user: Stephan Bosch date: Sun Aug 12 16:16:21 2012 +0200 description: lib-sieve: Adjusted edit-mail.c to changes in Dovecot mail storage API. diffstat: src/lib-sieve/edit-mail.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (19 lines): diff -r 69ee3b171848 -r c5cebc7dbd6b src/lib-sieve/edit-mail.c --- a/src/lib-sieve/edit-mail.c Sun Aug 12 16:02:36 2012 +0200 +++ b/src/lib-sieve/edit-mail.c Sun Aug 12 16:16:21 2012 +0200 @@ -14,6 +14,7 @@ #include "message-header-decode.h" #include "mail-user.h" #include "mail-storage-private.h" +#include "index-mail.h" #include "raw-storage.h" #include "rfc2822.h" @@ -1440,6 +1441,7 @@ edit_mail_get_headers, edit_mail_get_header_stream, edit_mail_get_stream, + index_mail_get_binary_stream, edit_mail_get_special, edit_mail_get_real_mail, edit_mail_update_flags, From pigeonhole at rename-it.nl Sun Aug 12 17:16:30 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 12 Aug 2012 16:16:30 +0200 Subject: dovecot-2.2-pigeonhole: Merged changes from Pigeonhole v0.3. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/69ee3b171848 changeset: 1653:69ee3b171848 user: Stephan Bosch date: Sun Aug 12 16:02:36 2012 +0200 description: Merged changes from Pigeonhole v0.3. diffstat: AUTHORS | 4 +- COPYING | 2 +- INSTALL | 138 +- Makefile.am | 4 +- NEWS | 472 +++--- README | 94 +- TODO | 34 +- configure.in | 16 +- doc/devel/DESIGN | 44 +- doc/example-config/conf.d/20-managesieve.conf | 14 +- doc/example-config/conf.d/90-sieve.conf | 24 +- doc/extensions/editheader.txt | 4 +- doc/extensions/include.txt | 4 +- doc/extensions/spamtest-virustest.txt | 40 +- doc/extensions/vacation.txt | 18 +- doc/man/pigeonhole.7.in | 2 +- doc/man/sieve-dump.1.in | 2 +- doc/man/sieve-filter.1.in | 36 +- doc/man/sieve-test.1.in | 8 +- doc/man/sievec.1.in | 2 +- doc/script-location-dict.txt | 4 +- src/lib-managesieve/Makefile.am | 4 +- src/lib-managesieve/managesieve-arg.c | 4 +- src/lib-managesieve/managesieve-arg.h | 8 +- src/lib-managesieve/managesieve-parser.c | 4 +- src/lib-managesieve/managesieve-parser.h | 2 +- src/lib-managesieve/managesieve-quote.c | 10 +- src/lib-sieve-tool/mail-raw.c | 16 +- src/lib-sieve-tool/sieve-tool.c | 58 +- src/lib-sieve-tool/sieve-tool.h | 2 +- src/lib-sieve/Makefile.am | 2 +- src/lib-sieve/cmd-discard.c | 60 +- src/lib-sieve/cmd-if.c | 122 +- src/lib-sieve/cmd-keep.c | 36 +- src/lib-sieve/cmd-redirect.c | 112 +- src/lib-sieve/cmd-require.c | 48 +- src/lib-sieve/cmd-stop.c | 48 +- src/lib-sieve/cmp-i-ascii-casemap.c | 38 +- src/lib-sieve/cmp-i-octet.c | 42 +- src/lib-sieve/edit-mail.c | 70 +- src/lib-sieve/ext-encoded-character.c | 124 +- src/lib-sieve/ext-envelope.c | 164 +- src/lib-sieve/ext-fileinto.c | 84 +- src/lib-sieve/ext-reject.c | 178 +- src/lib-sieve/mcht-contains.c | 18 +- src/lib-sieve/mcht-is.c | 24 +- src/lib-sieve/mcht-matches.c | 170 +- src/lib-sieve/plugins/Makefile.am | 2 +- src/lib-sieve/plugins/body/ext-body-common.c | 76 +- src/lib-sieve/plugins/body/ext-body-common.h | 8 +- src/lib-sieve/plugins/body/ext-body.c | 20 +- src/lib-sieve/plugins/body/tst-body.c | 190 +- src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c | 44 +- src/lib-sieve/plugins/copy/Makefile.am | 2 +- src/lib-sieve/plugins/copy/ext-copy.c | 54 +- src/lib-sieve/plugins/date/ext-date-common.c | 72 +- src/lib-sieve/plugins/date/ext-date-common.h | 8 +- src/lib-sieve/plugins/date/ext-date.c | 16 +- src/lib-sieve/plugins/date/tst-date.c | 132 +- src/lib-sieve/plugins/editheader/cmd-addheader.c | 18 +- src/lib-sieve/plugins/editheader/cmd-deleteheader.c | 146 +- src/lib-sieve/plugins/editheader/ext-editheader-common.c | 26 +- src/lib-sieve/plugins/editheader/ext-editheader-limits.h | 2 +- src/lib-sieve/plugins/editheader/ext-editheader.c | 8 +- src/lib-sieve/plugins/enotify/Makefile.am | 2 +- src/lib-sieve/plugins/enotify/cmd-notify.c | 242 +- src/lib-sieve/plugins/enotify/ext-enotify-common.c | 204 +- src/lib-sieve/plugins/enotify/ext-enotify-common.h | 20 +- src/lib-sieve/plugins/enotify/ext-enotify-limits.h | 2 +- src/lib-sieve/plugins/enotify/ext-enotify.c | 18 +- src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c | 154 +- src/lib-sieve/plugins/enotify/mailto/uri-mailto.c | 190 +- src/lib-sieve/plugins/enotify/mailto/uri-mailto.h | 14 +- src/lib-sieve/plugins/enotify/sieve-ext-enotify.h | 38 +- src/lib-sieve/plugins/enotify/tst-notify-method-capability.c | 98 +- src/lib-sieve/plugins/enotify/tst-valid-notify-method.c | 70 +- src/lib-sieve/plugins/enotify/vmodf-encodeurl.c | 22 +- src/lib-sieve/plugins/environment/ext-environment-common.c | 48 +- src/lib-sieve/plugins/environment/ext-environment-common.h | 6 +- src/lib-sieve/plugins/environment/ext-environment.c | 12 +- src/lib-sieve/plugins/environment/sieve-ext-environment.h | 4 +- src/lib-sieve/plugins/environment/tst-environment.c | 90 +- src/lib-sieve/plugins/ihave/ext-ihave-binary.c | 84 +- src/lib-sieve/plugins/ihave/ext-ihave-binary.h | 4 +- src/lib-sieve/plugins/ihave/ext-ihave-common.c | 4 +- src/lib-sieve/plugins/ihave/ext-ihave.c | 2 +- src/lib-sieve/plugins/ihave/tst-ihave.c | 24 +- src/lib-sieve/plugins/imap4flags/Makefile.am | 2 +- src/lib-sieve/plugins/imap4flags/cmd-flag.c | 104 +- src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c | 228 +- src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h | 20 +- src/lib-sieve/plugins/imap4flags/ext-imap4flags.c | 32 +- src/lib-sieve/plugins/imap4flags/ext-imapflags.c | 36 +- src/lib-sieve/plugins/imap4flags/tag-flags.c | 152 +- src/lib-sieve/plugins/imap4flags/tst-hasflag.c | 84 +- src/lib-sieve/plugins/include/cmd-global.c | 134 +- src/lib-sieve/plugins/include/cmd-include.c | 174 +- src/lib-sieve/plugins/include/cmd-return.c | 32 +- src/lib-sieve/plugins/include/ext-include-binary.c | 166 +- src/lib-sieve/plugins/include/ext-include-binary.h | 8 +- src/lib-sieve/plugins/include/ext-include-common.c | 236 +- src/lib-sieve/plugins/include/ext-include-common.h | 44 +- src/lib-sieve/plugins/include/ext-include-variables.c | 64 +- src/lib-sieve/plugins/include/ext-include-variables.h | 10 +- src/lib-sieve/plugins/include/ext-include.c | 26 +- src/lib-sieve/plugins/mailbox/ext-mailbox.c | 12 +- src/lib-sieve/plugins/mailbox/tag-mailbox-create.c | 50 +- src/lib-sieve/plugins/mailbox/tst-mailboxexists.c | 78 +- src/lib-sieve/plugins/notify/cmd-denotify.c | 78 +- src/lib-sieve/plugins/notify/cmd-notify.c | 172 +- src/lib-sieve/plugins/notify/ext-notify-common.c | 62 +- src/lib-sieve/plugins/notify/ext-notify-common.h | 8 +- src/lib-sieve/plugins/notify/ext-notify-limits.h | 2 +- src/lib-sieve/plugins/notify/ext-notify.c | 14 +- src/lib-sieve/plugins/regex/ext-regex-common.c | 2 +- src/lib-sieve/plugins/regex/ext-regex.c | 10 +- src/lib-sieve/plugins/regex/mcht-regex.c | 62 +- src/lib-sieve/plugins/relational/Makefile.am | 2 +- src/lib-sieve/plugins/relational/ext-relational-common.c | 64 +- src/lib-sieve/plugins/relational/ext-relational-common.h | 22 +- src/lib-sieve/plugins/relational/ext-relational.c | 10 +- src/lib-sieve/plugins/relational/mcht-count.c | 18 +- src/lib-sieve/plugins/relational/mcht-value.c | 18 +- src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c | 104 +- src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.h | 8 +- src/lib-sieve/plugins/spamvirustest/ext-spamvirustest.c | 46 +- src/lib-sieve/plugins/spamvirustest/tst-spamvirustest.c | 124 +- src/lib-sieve/plugins/subaddress/ext-subaddress.c | 36 +- src/lib-sieve/plugins/vacation/cmd-vacation.c | 448 +++--- src/lib-sieve/plugins/vacation/ext-vacation-common.c | 2 +- src/lib-sieve/plugins/vacation/ext-vacation-common.h | 12 +- src/lib-sieve/plugins/vacation/ext-vacation-seconds.c | 8 +- src/lib-sieve/plugins/vacation/ext-vacation.c | 4 +- src/lib-sieve/plugins/variables/Makefile.am | 2 +- src/lib-sieve/plugins/variables/cmd-set.c | 172 +- src/lib-sieve/plugins/variables/ext-variables-arguments.c | 176 +- src/lib-sieve/plugins/variables/ext-variables-arguments.h | 12 +- src/lib-sieve/plugins/variables/ext-variables-common.c | 208 +- src/lib-sieve/plugins/variables/ext-variables-common.h | 26 +- src/lib-sieve/plugins/variables/ext-variables-dump.c | 36 +- src/lib-sieve/plugins/variables/ext-variables-dump.h | 4 +- src/lib-sieve/plugins/variables/ext-variables-limits.h | 2 +- src/lib-sieve/plugins/variables/ext-variables-modifiers.c | 58 +- src/lib-sieve/plugins/variables/ext-variables-modifiers.h | 8 +- src/lib-sieve/plugins/variables/ext-variables-name.h | 16 +- src/lib-sieve/plugins/variables/ext-variables-namespaces.c | 64 +- src/lib-sieve/plugins/variables/ext-variables-namespaces.h | 10 +- src/lib-sieve/plugins/variables/ext-variables-operands.c | 102 +- src/lib-sieve/plugins/variables/ext-variables-operands.h | 20 +- src/lib-sieve/plugins/variables/ext-variables.c | 34 +- src/lib-sieve/plugins/variables/sieve-ext-variables.h | 84 +- src/lib-sieve/plugins/variables/tst-string.c | 102 +- src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate-common.c | 12 +- src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate-common.h | 2 +- src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate.c | 12 +- src/lib-sieve/plugins/vnd.dovecot/duplicate/tst-duplicate.c | 34 +- src/lib-sieve/rfc2822.c | 60 +- src/lib-sieve/rfc2822.h | 6 +- src/lib-sieve/sieve-actions.c | 220 +- src/lib-sieve/sieve-actions.h | 104 +- src/lib-sieve/sieve-address-parts.c | 112 +- src/lib-sieve/sieve-address-parts.h | 26 +- src/lib-sieve/sieve-address.c | 170 +- src/lib-sieve/sieve-address.h | 24 +- src/lib-sieve/sieve-ast.c | 472 +++--- src/lib-sieve/sieve-ast.h | 112 +- src/lib-sieve/sieve-binary-code.c | 114 +- src/lib-sieve/sieve-binary-debug.c | 34 +- src/lib-sieve/sieve-binary-dumper.c | 98 +- src/lib-sieve/sieve-binary-dumper.h | 4 +- src/lib-sieve/sieve-binary-file.c | 316 ++-- src/lib-sieve/sieve-binary-private.h | 78 +- src/lib-sieve/sieve-binary.c | 138 +- src/lib-sieve/sieve-binary.h | 78 +- src/lib-sieve/sieve-code-dumper.c | 92 +- src/lib-sieve/sieve-code-dumper.h | 18 +- src/lib-sieve/sieve-code.c | 456 +++--- src/lib-sieve/sieve-code.h | 88 +- src/lib-sieve/sieve-commands.c | 150 +- src/lib-sieve/sieve-commands.h | 70 +- src/lib-sieve/sieve-common.h | 8 +- src/lib-sieve/sieve-comparators.c | 110 +- src/lib-sieve/sieve-comparators.h | 54 +- src/lib-sieve/sieve-config.h | 2 +- src/lib-sieve/sieve-dump.h | 2 +- src/lib-sieve/sieve-error-private.h | 18 +- src/lib-sieve/sieve-error.c | 324 ++-- src/lib-sieve/sieve-error.h | 28 +- src/lib-sieve/sieve-extensions.c | 124 +- src/lib-sieve/sieve-extensions.h | 42 +- src/lib-sieve/sieve-generator.c | 204 +- src/lib-sieve/sieve-generator.h | 40 +- src/lib-sieve/sieve-interpreter.c | 158 +- src/lib-sieve/sieve-interpreter.h | 38 +- src/lib-sieve/sieve-lexer.c | 330 ++-- src/lib-sieve/sieve-lexer.h | 46 +- src/lib-sieve/sieve-match-types.c | 212 +- src/lib-sieve/sieve-match-types.h | 62 +- src/lib-sieve/sieve-match.c | 38 +- src/lib-sieve/sieve-match.h | 12 +- src/lib-sieve/sieve-message.c | 88 +- src/lib-sieve/sieve-message.h | 8 +- src/lib-sieve/sieve-objects.c | 46 +- src/lib-sieve/sieve-objects.h | 6 +- src/lib-sieve/sieve-parser.c | 328 ++-- src/lib-sieve/sieve-parser.h | 4 +- src/lib-sieve/sieve-plugins.c | 10 +- src/lib-sieve/sieve-plugins.h | 2 +- src/lib-sieve/sieve-result.c | 524 +++--- src/lib-sieve/sieve-result.h | 28 +- src/lib-sieve/sieve-runtime-trace.c | 44 +- src/lib-sieve/sieve-runtime-trace.h | 16 +- src/lib-sieve/sieve-runtime.h | 6 +- src/lib-sieve/sieve-script-dict.c | 14 +- src/lib-sieve/sieve-script-file.c | 42 +- src/lib-sieve/sieve-script-file.h | 2 +- src/lib-sieve/sieve-script-private.h | 2 +- src/lib-sieve/sieve-script.c | 36 +- src/lib-sieve/sieve-script.h | 12 +- src/lib-sieve/sieve-settings.c | 18 +- src/lib-sieve/sieve-stringlist.c | 18 +- src/lib-sieve/sieve-stringlist.h | 4 +- src/lib-sieve/sieve-types.h | 28 +- src/lib-sieve/sieve-validator.c | 684 +++++----- src/lib-sieve/sieve-validator.h | 60 +- src/lib-sieve/sieve.c | 178 +- src/lib-sieve/sieve.h | 42 +- src/lib-sieve/tst-address.c | 124 +- src/lib-sieve/tst-allof.c | 46 +- src/lib-sieve/tst-anyof.c | 48 +- src/lib-sieve/tst-exists.c | 64 +- src/lib-sieve/tst-header.c | 86 +- src/lib-sieve/tst-not.c | 26 +- src/lib-sieve/tst-size.c | 162 +- src/lib-sieve/tst-truefalse.c | 28 +- src/lib-sievestorage/Makefile.am | 2 +- src/lib-sievestorage/sieve-storage-list.c | 16 +- src/lib-sievestorage/sieve-storage-list.h | 4 +- src/lib-sievestorage/sieve-storage-private.h | 2 +- src/lib-sievestorage/sieve-storage-quota.c | 24 +- src/lib-sievestorage/sieve-storage-quota.h | 2 +- src/lib-sievestorage/sieve-storage-save.c | 36 +- src/lib-sievestorage/sieve-storage-script.c | 120 +- src/lib-sievestorage/sieve-storage.c | 70 +- src/lib-sievestorage/sieve-storage.h | 2 +- src/managesieve-login/client-authenticate.c | 8 +- src/managesieve-login/client.c | 38 +- src/managesieve-login/client.h | 2 +- src/managesieve-login/managesieve-login-settings-plugin.c | 12 +- src/managesieve-login/managesieve-login-settings.c | 2 +- src/managesieve-login/managesieve-proxy.c | 58 +- src/managesieve/Makefile.am | 4 +- src/managesieve/cmd-capability.c | 8 +- src/managesieve/cmd-deletescript.c | 2 +- src/managesieve/cmd-getscript.c | 8 +- src/managesieve/cmd-listscripts.c | 12 +- src/managesieve/cmd-putscript.c | 34 +- src/managesieve/cmd-renamescript.c | 2 +- src/managesieve/cmd-setactive.c | 12 +- src/managesieve/managesieve-capabilities.c | 6 +- src/managesieve/managesieve-client.c | 18 +- src/managesieve/managesieve-client.h | 2 +- src/managesieve/managesieve-commands.c | 8 +- src/managesieve/managesieve-quota.c | 16 +- src/managesieve/managesieve-settings.c | 2 +- src/plugins/lda-sieve/Makefile.am | 2 +- src/plugins/lda-sieve/lda-sieve-plugin.c | 50 +- src/sieve-tools/Makefile.am | 10 +- src/sieve-tools/sieve-dump.c | 12 +- src/sieve-tools/sieve-filter.c | 72 +- src/sieve-tools/sieve-test.c | 78 +- src/sieve-tools/sievec.c | 52 +- src/testsuite/cmd-test-binary.c | 84 +- src/testsuite/cmd-test-config.c | 160 +- src/testsuite/cmd-test-fail.c | 66 +- src/testsuite/cmd-test-mailbox.c | 84 +- src/testsuite/cmd-test-message.c | 192 +- src/testsuite/cmd-test-result.c | 52 +- src/testsuite/cmd-test-set.c | 70 +- src/testsuite/cmd-test.c | 82 +- src/testsuite/ext-testsuite.c | 14 +- src/testsuite/testsuite-arguments.c | 80 +- src/testsuite/testsuite-binary.c | 10 +- src/testsuite/testsuite-binary.h | 2 +- src/testsuite/testsuite-common.c | 36 +- src/testsuite/testsuite-common.h | 26 +- src/testsuite/testsuite-log.c | 22 +- src/testsuite/testsuite-mailstore.c | 24 +- src/testsuite/testsuite-mailstore.h | 4 +- src/testsuite/testsuite-message.c | 36 +- src/testsuite/testsuite-objects.c | 166 +- src/testsuite/testsuite-objects.h | 40 +- src/testsuite/testsuite-result.c | 26 +- src/testsuite/testsuite-result.h | 2 +- src/testsuite/testsuite-script.c | 2 +- src/testsuite/testsuite-script.h | 2 +- src/testsuite/testsuite-settings.c | 18 +- src/testsuite/testsuite-smtp.c | 42 +- src/testsuite/testsuite-smtp.h | 6 +- src/testsuite/testsuite-substitutions.c | 114 +- src/testsuite/testsuite-substitutions.h | 4 +- src/testsuite/testsuite-variables.c | 4 +- src/testsuite/testsuite-variables.h | 2 +- src/testsuite/testsuite.c | 10 +- src/testsuite/tst-test-error.c | 70 +- src/testsuite/tst-test-multiscript.c | 50 +- src/testsuite/tst-test-result-action.c | 68 +- src/testsuite/tst-test-result-execute.c | 32 +- src/testsuite/tst-test-script-compile.c | 44 +- src/testsuite/tst-test-script-run.c | 58 +- tests/compile/errors.svtest | 26 +- tests/compile/errors/address.sieve | 6 +- tests/compile/errors/envelope.sieve | 2 +- tests/compile/errors/if.sieve | 4 +- tests/compile/errors/keep.sieve | 2 +- tests/compile/errors/lexer.sieve | 2 +- tests/compile/errors/out-address.sieve | 2 +- tests/compile/errors/parser.sieve | 36 +- tests/compile/errors/require.sieve | 2 +- tests/compile/errors/size.sieve | 2 +- tests/compile/errors/tag.sieve | 2 +- tests/compile/errors/typos.sieve | 10 +- tests/compile/errors/unsupported.sieve | 6 +- tests/compile/recover.svtest | 2 +- tests/control-if.svtest | 40 +- tests/deprecated/notify/basic.svtest | 4 +- tests/deprecated/notify/mailto.svtest | 24 +- tests/execute/actions.svtest | 18 +- tests/execute/actions/redirect.sieve | 2 +- tests/execute/errors.svtest | 4 +- tests/execute/examples.svtest | 2 +- tests/execute/mailstore.svtest | 2 +- tests/extensions/body/basic.svtest | 10 +- tests/extensions/body/content.svtest | 20 +- tests/extensions/body/raw.svtest | 2 +- tests/extensions/date/basic.svtest | 8 +- tests/extensions/date/zones.svtest | 22 +- tests/extensions/editheader/addheader.svtest | 34 +- tests/extensions/editheader/alternating.svtest | 4 +- tests/extensions/editheader/deleteheader.svtest | 10 +- tests/extensions/editheader/errors.svtest | 8 +- tests/extensions/editheader/errors/command-syntax.sieve | 2 +- tests/extensions/editheader/protected.svtest | 12 +- tests/extensions/encoded-character.svtest | 4 +- tests/extensions/enotify/basic.svtest | 6 +- tests/extensions/enotify/errors/uri-mailto.sieve | 2 +- tests/extensions/enotify/mailto.svtest | 18 +- tests/extensions/enotify/valid_notify_method.svtest | 4 +- tests/extensions/envelope.svtest | 6 +- tests/extensions/environment/rfc.svtest | 4 +- tests/extensions/imap4flags/basic.svtest | 16 +- tests/extensions/imap4flags/execute.svtest | 20 +- tests/extensions/imap4flags/execute/flags-side-effect.sieve | 4 +- tests/extensions/imap4flags/hasflag.svtest | 8 +- tests/extensions/imap4flags/multiscript.svtest | 16 +- tests/extensions/include/execute.svtest | 6 +- tests/extensions/regex/basic.svtest | 8 +- tests/extensions/regex/match-values.svtest | 12 +- tests/extensions/relational/basic.svtest | 10 +- tests/extensions/relational/comparators.svtest | 22 +- tests/extensions/relational/errors/validation.sieve | 2 +- tests/extensions/relational/rfc.svtest | 12 +- tests/extensions/spamvirustest/spamtest.svtest | 2 +- tests/extensions/subaddress/basic.svtest | 2 +- tests/extensions/subaddress/rfc.svtest | 4 +- tests/extensions/vacation/execute.svtest | 4 +- tests/extensions/vacation/execute/no-handle.sieve | 6 +- tests/extensions/vacation/message.svtest | 10 +- tests/extensions/vacation/reply.svtest | 2 +- tests/extensions/vacation/utf-8.svtest | 4 +- tests/extensions/variables/basic.svtest | 14 +- tests/extensions/variables/errors/limits.sieve | 2 +- tests/extensions/variables/match.svtest | 34 +- tests/extensions/variables/modifiers.svtest | 12 +- tests/extensions/variables/quoting.svtest | 2 +- tests/extensions/variables/regex.svtest | 6 +- tests/extensions/variables/string.svtest | 2 +- tests/match-types/contains.svtest | 4 +- tests/match-types/is.svtest | 4 +- tests/match-types/matches.svtest | 2 +- tests/multiscript/basic.svtest | 4 +- tests/multiscript/conflicts.svtest | 8 +- tests/test-address.svtest | 28 +- tests/test-allof.svtest | 16 +- tests/test-anyof.svtest | 28 +- tests/test-exists.svtest | 2 +- tests/test-header.svtest | 18 +- tests/testsuite.svtest | 2 +- 388 files changed, 9943 insertions(+), 9943 deletions(-) diffs (truncated from 54597 to 300 lines): diff -r 368c8f1c0511 -r 69ee3b171848 AUTHORS --- a/AUTHORS Thu Aug 09 23:01:43 2012 +0200 +++ b/AUTHORS Sun Aug 12 16:02:36 2012 +0200 @@ -1,8 +1,8 @@ Stephan Bosch -This package is built for and partly based on the Dovecot Secure IMAP server +This package is built for and partly based on the Dovecot Secure IMAP server written by: -Timo Sirainen . +Timo Sirainen . Grepping 'patch by' from ChangeLog shows up more people. diff -r 368c8f1c0511 -r 69ee3b171848 COPYING --- a/COPYING Thu Aug 09 23:01:43 2012 +0200 +++ b/COPYING Sun Aug 12 16:02:36 2012 +0200 @@ -1,4 +1,4 @@ See AUTHORS file for list of copyright holders. -Everything is licenced under LGPLv2.1 (see COPYING.LGPL) unless otherwise +Everything is licenced under LGPLv2.1 (see COPYING.LGPL) unless otherwise mentioned at the beginning of the file. diff -r 368c8f1c0511 -r 69ee3b171848 INSTALL --- a/INSTALL Thu Aug 09 23:01:43 2012 +0200 +++ b/INSTALL Sun Aug 12 16:02:36 2012 +0200 @@ -1,7 +1,7 @@ Compiling ========= -If you downloaded the sources using Mercurial, you will need to execute +If you downloaded the sources using Mercurial, you will need to execute ./autogen.sh first to build the automake structure in your source tree. This process requires autotools and libtool to be installed. @@ -12,7 +12,7 @@ make sudo make install -If your system uses a $prefix different than the default /usr/local, the +If your system uses a $prefix different than the default /usr/local, the configure script can still find the installed dovecot-config automatically when supplied with the proper --prefix argument: @@ -44,7 +44,7 @@ --with-unfinished-features=no Controls whether unfinished features and extensions are built. Enabling this will enable the compilation of code that is considered unfinished and highly - experimental and may therefore introduce bugs and unexpected behavior. + experimental and may therefore introduce bugs and unexpected behavior. In fact, it may not compile at all. Enable this only when you are eager to test some of the new development functionality. @@ -57,12 +57,12 @@ facilitates the actual Sieve filtering upon delivery. - The ManageSieve Service: This implements the ManageSieve protocol through - which users can remotely manage Sieve scripts on the server. + which users can remotely manage Sieve scripts on the server. -The functionality of these items is described in more detail in the README file. +The functionality of these items is described in more detail in the README file. In this file and in this section their configuration is described. Example configuration files are provided in the doc/example-config directory of this -package. +package. Sieve Interpreter - Basic Configuration --------------------------------------- @@ -85,9 +85,9 @@ plugin section of the config file (default values are shown if applicable): sieve = ~/.dovecot.sieve - The location of the user's main active script. - - sieve_default = + The location of the user's main active script. + + sieve_default = The location of the default personal sieve script file, which gets executed ONLY if user's private Sieve script does no exist, e.g. /var/lib/dovecot/default.sieve. This is usually a global script, so be sure @@ -96,20 +96,20 @@ `sieve_global_path', but that name is now deprecated. sieve_global_dir = - Location for :global include scripts for the Sieve include extension. + Location for :global include scripts for the Sieve include extension. sieve_dir = ~/sieve - Location for :personal include scripts for the Sieve include extension. + Location for :personal include scripts for the Sieve include extension. sieve_extensions = - Which Sieve language extensions are available to users. By default, all - supported extensions are available, except for deprecated extensions or those - that are still under development. Some system administrators may want to - disable certain Sieve extensions or enable those that are not available by + Which Sieve language extensions are available to users. By default, all + supported extensions are available, except for deprecated extensions or those + that are still under development. Some system administrators may want to + disable certain Sieve extensions or enable those that are not available by default. This setting can use '+' and '-' to specify differences relative to the default. For example `sieve_extensions = +imapflags' will enable the deprecated imapflags extension in addition to all extensions were already - enabled by default. + enabled by default. sieve_global_extensions = Which Sieve language extensions are ONLY avalable in global scripts. This can @@ -117,7 +117,7 @@ control, for instance when these extensions can cause security concerns. This setting has higher precedence than the `sieve_extensions' setting (above), meaning that the extensions enabled with this setting are never available to - the user's personal script no matter what is specified for the + the user's personal script no matter what is specified for the `sieve_extensions' setting. The syntax of this setting is similar to the `sieve_extensions' setting, with the difference that extensions are enabled or disabled for exclusive use in global scripts. Currently, no @@ -127,16 +127,16 @@ The Pigeonhole Sieve interpreter can have plugins of its own. Using this setting, the used plugins can be specified. Check the Dovecot wiki (wiki2.dovecot.org) or the pigeonhole website (http://pigeonhole.dovecot.org) - for available plugins. + for available plugins. sieve_user_log = The path to the file where the user log file is written. If not configured, a default location is used. If the main user's personal Sieve (as configured with sieve=) is a file, the logfile is set to .log by default. If - it is not a file, the default user log file is ~/.dovecot.sieve.log. + it is not a file, the default user log file is ~/.dovecot.sieve.log. recipient_delimiter = + - The separator that is expected between the :user and :detail address parts + The separator that is expected between the :user and :detail address parts introduced by the subaddress extension. This may also be a sequence of characters (e.g. '--'). The current implementation looks for the separator from the left of the localpart and uses the first one encountered. The :user @@ -150,16 +150,16 @@ # The location of the user's active script: sieve = ~/.dovecot.sieve - # If the user has no personal active script (i.e. if the file + # If the user has no personal active script (i.e. if the file # indicated in sieve= does not exist), use this one: sieve_default = /var/lib/dovecot/sieve/default.sieve - # The include extension fetches the :personal scripts from this - # directory. When ManageSieve is used, this is also where scripts + # The include extension fetches the :personal scripts from this + # directory. When ManageSieve is used, this is also where scripts # are uploaded. sieve_dir = ~/sieve - # The include extension fetches the :global scripts from this + # The include extension fetches the :global scripts from this # directory. sieve_global_dir = /var/lib/dovecot/sieve/global/ } @@ -197,7 +197,7 @@ or a directory containing script files with names structured as `.sieve'. dict - Dovecot dict lookup. The location path is a dict uri. Read - doc/scipt-location-dict.txt for more information and examples. + doc/scipt-location-dict.txt for more information and examples. If the type prefix is omitted, the script location type is 'file'. @@ -219,8 +219,8 @@ directory as where the script file was found if possible. For `dict' type locations, the binary is not stored at all in that case. Don't specify the same directory for different script locations, as this will result in - undefined behavior. - + undefined behavior. + Sieve Interpreter - Per-user Sieve Script Location -------------------------------------------------- @@ -228,14 +228,14 @@ file in the user's home directory (~/.dovecot.sieve). This requires that the home directory is set for the user. -If you want to store the script elsewhere, you can override the default using +If you want to store the script elsewhere, you can override the default using the sieve= setting, which specifies the location of the user's script file. This can be done in two ways: 1. Define the sieve setting in the plugin section of dovecot.conf. - 2. Return sieve extra field from userdb extra fields. + 2. Return sieve extra field from userdb extra fields. -For example, to use a Sieve script file named .sieve in +For example, to use a Sieve script file named .sieve in /var/sieve-scripts, use: plugin { @@ -244,16 +244,16 @@ sieve = /var/sieve-scripts/%u.sieve } -You may use templates like %u, as shown in the example. Refer to +You may use templates like %u, as shown in the example. Refer to http://wiki.dovecot.org/Variables for more information. -A relative path (or just a filename) will be interpreted to point under the +A relative path (or just a filename) will be interpreted to point under the user's home directory. Sieve Interpreter - Executing Multiple Scripts Sequentially ----------------------------------------------------------- -Pigeonhole's Sieve interpreter allows executing multiple Sieve scripts +Pigeonhole's Sieve interpreter allows executing multiple Sieve scripts sequentially. The extra scripts can be executed before and after the user's private script. For example, this allows executing global Sieve policies before the user's script. The following settings in the plugin section of the Dovecot @@ -267,7 +267,7 @@ directory, all the Sieve scripts contained therein (with the proper .sieve extension) are executed. The order of execution within that directory is determined by the file names, using a normal 8bit per-character comparison. - + Multiple script file or directory paths can be specified by appending an increasing number. The Sieve scripts found from these paths are added to the script execution sequence in the specified order. Reading the numbered @@ -278,14 +278,14 @@ sieve_after2 = sieve_after3 = (etc..) Identical to sieve_before, but the specified scripts are executed after the - user's script (only when keep is still in effect, as explained below). + user's script (only when keep is still in effect, as explained below). The script execution ends when the currently executing script in the sequence -does not yield a "keep" result: when the script terminates, the next script is +does not yield a "keep" result: when the script terminates, the next script is only executed if an implicit or explicit "keep" is in effect. Thus, to end all script execution, a script must not execute keep and it must cancel the implicit -keep, e.g. by executing "discard; stop;". This means that the command "keep;" -has different semantics when used in a sequence of scripts. For normal Sieve +keep, e.g. by executing "discard; stop;". This means that the command "keep;" +has different semantics when used in a sequence of scripts. For normal Sieve execution, "keep;" is equivalent to "fileinto "INBOX";", because both cause the message to be stored in INBOX. However, in sequential script execution, it only controls whether the next script is executed. Storing the message into INBOX @@ -304,7 +304,7 @@ Just as for executing a single script the normal way, the Pigeonhole LDA Sieve plugin takes care never to duplicate deliveries, forwards or responses. When -vacation actions are executed multiple times in different scripts, the usual +vacation actions are executed multiple times in different scripts, the usual error is not triggered: the subsequent duplicate vacation actions are simply discarded. @@ -325,7 +325,7 @@ # E.g. user-specific default mail filing rules sieve_after = /var/vmail/%d/%n/sieve-after - # Global scripts executed after the user's personal script + # Global scripts executed after the user's personal script # (if keep is still in effect) # E.g. default mail filing rules. sieve_after2 = /var/lib/dovecot/sieve/after.d/ @@ -385,7 +385,7 @@ Sieve Interpreter - Migration from CMUSieve (Dovecot v1.0/v1.1) --------------------------------------------------------------- -For the most part, migration from CMUSieve to the Pigeonhole LDA Sieve plugin is +For the most part, migration from CMUSieve to the Pigeonhole LDA Sieve plugin is just a matter of changing the used plugin name from 'cmusieve' to 'sieve' in the mail_plugins option in the protocol lda section of the config file (as explained above). However, there are a few important differences: @@ -406,46 +406,46 @@ * The include extension now requires your script file names to end with ".sieve". This means that ` include :personal "myscript"; ' won't work unless - you rename "myscript" to "myscript.sieve" + you rename "myscript" to "myscript.sieve" Sieve Interpreter - Migration from Dovecot Sieve v0.1.x (Dovecot v1.2) ---------------------------------------------------------------------- - * Dovecot v2.0 adds support for LMTP. Much like the Dovecot LDA, it can make - use of the Pigeonhole Sieve plugin. Since the LMTP service has its own - prototocol lmtp section in the config file, you need to add the Sieve plugin + * Dovecot v2.0 adds support for LMTP. Much like the Dovecot LDA, it can make + use of the Pigeonhole Sieve plugin. Since the LMTP service has its own + prototocol lmtp section in the config file, you need to add the Sieve plugin to the mail_plugins setting there too when you decide to use LMTP. - * The 'sieve_subaddress_sep' setting for the Sieve subaddress extension is now + * The 'sieve_subaddress_sep' setting for the Sieve subaddress extension is now known as 'recipient_delimiter'. Although sieve_subaddress_sep is still recognized for backwards compatibility, it is recommended to update the setting to the new name, since the LMTP service also uses the - recipient_delimiter setting. + recipient_delimiter setting. ManageSieve Service - Basic Configuration ----------------------------------------- From pigeonhole at rename-it.nl Sun Aug 12 17:16:29 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 12 Aug 2012 16:16:29 +0200 Subject: dovecot-2.2-pigeonhole: Removed trailing whitespace everywhere. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/7e100dcd888a changeset: 1652:7e100dcd888a user: Stephan Bosch date: Sun Aug 12 15:50:27 2012 +0200 description: Removed trailing whitespace everywhere. diffstat: AUTHORS | 4 +- COPYING | 2 +- INSTALL | 138 +- Makefile.am | 4 +- NEWS | 472 +++--- README | 94 +- TODO | 34 +- configure.in | 16 +- doc/devel/DESIGN | 44 +- doc/example-config/conf.d/20-managesieve.conf | 14 +- doc/example-config/conf.d/90-sieve.conf | 24 +- doc/extensions/editheader.txt | 4 +- doc/extensions/include.txt | 4 +- doc/extensions/spamtest-virustest.txt | 40 +- doc/extensions/vacation.txt | 18 +- doc/man/pigeonhole.7.in | 2 +- doc/man/sieve-dump.1.in | 2 +- doc/man/sieve-filter.1.in | 36 +- doc/man/sieve-test.1.in | 8 +- doc/man/sievec.1.in | 2 +- doc/script-location-dict.txt | 4 +- src/lib-managesieve/Makefile.am | 4 +- src/lib-managesieve/managesieve-arg.c | 4 +- src/lib-managesieve/managesieve-arg.h | 8 +- src/lib-managesieve/managesieve-parser.c | 4 +- src/lib-managesieve/managesieve-parser.h | 2 +- src/lib-managesieve/managesieve-quote.c | 10 +- src/lib-sieve-tool/mail-raw.c | 16 +- src/lib-sieve-tool/sieve-tool.c | 58 +- src/lib-sieve-tool/sieve-tool.h | 2 +- src/lib-sieve/Makefile.am | 2 +- src/lib-sieve/cmd-discard.c | 60 +- src/lib-sieve/cmd-if.c | 122 +- src/lib-sieve/cmd-keep.c | 36 +- src/lib-sieve/cmd-redirect.c | 112 +- src/lib-sieve/cmd-require.c | 48 +- src/lib-sieve/cmd-stop.c | 48 +- src/lib-sieve/cmp-i-ascii-casemap.c | 38 +- src/lib-sieve/cmp-i-octet.c | 42 +- src/lib-sieve/edit-mail.c | 70 +- src/lib-sieve/ext-encoded-character.c | 124 +- src/lib-sieve/ext-envelope.c | 164 +- src/lib-sieve/ext-fileinto.c | 84 +- src/lib-sieve/ext-reject.c | 178 +- src/lib-sieve/mcht-contains.c | 18 +- src/lib-sieve/mcht-is.c | 24 +- src/lib-sieve/mcht-matches.c | 170 +- src/lib-sieve/plugins/Makefile.am | 2 +- src/lib-sieve/plugins/body/ext-body-common.c | 72 +- src/lib-sieve/plugins/body/ext-body-common.h | 8 +- src/lib-sieve/plugins/body/ext-body.c | 20 +- src/lib-sieve/plugins/body/tst-body.c | 190 +- src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c | 44 +- src/lib-sieve/plugins/copy/Makefile.am | 2 +- src/lib-sieve/plugins/copy/ext-copy.c | 54 +- src/lib-sieve/plugins/date/ext-date-common.c | 72 +- src/lib-sieve/plugins/date/ext-date-common.h | 8 +- src/lib-sieve/plugins/date/ext-date.c | 16 +- src/lib-sieve/plugins/date/tst-date.c | 132 +- src/lib-sieve/plugins/editheader/cmd-addheader.c | 18 +- src/lib-sieve/plugins/editheader/cmd-deleteheader.c | 146 +- src/lib-sieve/plugins/editheader/ext-editheader-common.c | 26 +- src/lib-sieve/plugins/editheader/ext-editheader-limits.h | 2 +- src/lib-sieve/plugins/editheader/ext-editheader.c | 8 +- src/lib-sieve/plugins/enotify/Makefile.am | 2 +- src/lib-sieve/plugins/enotify/cmd-notify.c | 242 +- src/lib-sieve/plugins/enotify/ext-enotify-common.c | 204 +- src/lib-sieve/plugins/enotify/ext-enotify-common.h | 20 +- src/lib-sieve/plugins/enotify/ext-enotify-limits.h | 2 +- src/lib-sieve/plugins/enotify/ext-enotify.c | 18 +- src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c | 152 +- src/lib-sieve/plugins/enotify/mailto/uri-mailto.c | 190 +- src/lib-sieve/plugins/enotify/mailto/uri-mailto.h | 14 +- src/lib-sieve/plugins/enotify/sieve-ext-enotify.h | 38 +- src/lib-sieve/plugins/enotify/tst-notify-method-capability.c | 98 +- src/lib-sieve/plugins/enotify/tst-valid-notify-method.c | 70 +- src/lib-sieve/plugins/enotify/vmodf-encodeurl.c | 22 +- src/lib-sieve/plugins/environment/ext-environment-common.c | 48 +- src/lib-sieve/plugins/environment/ext-environment-common.h | 6 +- src/lib-sieve/plugins/environment/ext-environment.c | 12 +- src/lib-sieve/plugins/environment/sieve-ext-environment.h | 4 +- src/lib-sieve/plugins/environment/tst-environment.c | 90 +- src/lib-sieve/plugins/ihave/ext-ihave-binary.c | 84 +- src/lib-sieve/plugins/ihave/ext-ihave-binary.h | 4 +- src/lib-sieve/plugins/ihave/ext-ihave-common.c | 4 +- src/lib-sieve/plugins/ihave/ext-ihave.c | 2 +- src/lib-sieve/plugins/ihave/tst-ihave.c | 24 +- src/lib-sieve/plugins/imap4flags/Makefile.am | 2 +- src/lib-sieve/plugins/imap4flags/cmd-flag.c | 104 +- src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c | 228 +- src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h | 20 +- src/lib-sieve/plugins/imap4flags/ext-imap4flags.c | 32 +- src/lib-sieve/plugins/imap4flags/ext-imapflags.c | 36 +- src/lib-sieve/plugins/imap4flags/tag-flags.c | 152 +- src/lib-sieve/plugins/imap4flags/tst-hasflag.c | 84 +- src/lib-sieve/plugins/include/cmd-global.c | 134 +- src/lib-sieve/plugins/include/cmd-include.c | 174 +- src/lib-sieve/plugins/include/cmd-return.c | 32 +- src/lib-sieve/plugins/include/ext-include-binary.c | 166 +- src/lib-sieve/plugins/include/ext-include-binary.h | 8 +- src/lib-sieve/plugins/include/ext-include-common.c | 236 +- src/lib-sieve/plugins/include/ext-include-common.h | 44 +- src/lib-sieve/plugins/include/ext-include-variables.c | 64 +- src/lib-sieve/plugins/include/ext-include-variables.h | 10 +- src/lib-sieve/plugins/include/ext-include.c | 26 +- src/lib-sieve/plugins/mailbox/ext-mailbox.c | 12 +- src/lib-sieve/plugins/mailbox/tag-mailbox-create.c | 50 +- src/lib-sieve/plugins/mailbox/tst-mailboxexists.c | 78 +- src/lib-sieve/plugins/notify/cmd-denotify.c | 78 +- src/lib-sieve/plugins/notify/cmd-notify.c | 176 +- src/lib-sieve/plugins/notify/ext-notify-common.c | 62 +- src/lib-sieve/plugins/notify/ext-notify-common.h | 8 +- src/lib-sieve/plugins/notify/ext-notify-limits.h | 2 +- src/lib-sieve/plugins/notify/ext-notify.c | 14 +- src/lib-sieve/plugins/regex/ext-regex-common.c | 2 +- src/lib-sieve/plugins/regex/ext-regex.c | 10 +- src/lib-sieve/plugins/regex/mcht-regex.c | 62 +- src/lib-sieve/plugins/relational/Makefile.am | 2 +- src/lib-sieve/plugins/relational/ext-relational-common.c | 64 +- src/lib-sieve/plugins/relational/ext-relational-common.h | 22 +- src/lib-sieve/plugins/relational/ext-relational.c | 10 +- src/lib-sieve/plugins/relational/mcht-count.c | 18 +- src/lib-sieve/plugins/relational/mcht-value.c | 18 +- src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c | 104 +- src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.h | 8 +- src/lib-sieve/plugins/spamvirustest/ext-spamvirustest.c | 46 +- src/lib-sieve/plugins/spamvirustest/tst-spamvirustest.c | 124 +- src/lib-sieve/plugins/subaddress/ext-subaddress.c | 36 +- src/lib-sieve/plugins/vacation/cmd-vacation.c | 450 +++--- src/lib-sieve/plugins/vacation/ext-vacation-common.c | 2 +- src/lib-sieve/plugins/vacation/ext-vacation-common.h | 12 +- src/lib-sieve/plugins/vacation/ext-vacation-seconds.c | 8 +- src/lib-sieve/plugins/vacation/ext-vacation.c | 4 +- src/lib-sieve/plugins/variables/Makefile.am | 2 +- src/lib-sieve/plugins/variables/cmd-set.c | 172 +- src/lib-sieve/plugins/variables/ext-variables-arguments.c | 176 +- src/lib-sieve/plugins/variables/ext-variables-arguments.h | 12 +- src/lib-sieve/plugins/variables/ext-variables-common.c | 208 +- src/lib-sieve/plugins/variables/ext-variables-common.h | 26 +- src/lib-sieve/plugins/variables/ext-variables-dump.c | 36 +- src/lib-sieve/plugins/variables/ext-variables-dump.h | 4 +- src/lib-sieve/plugins/variables/ext-variables-limits.h | 2 +- src/lib-sieve/plugins/variables/ext-variables-modifiers.c | 58 +- src/lib-sieve/plugins/variables/ext-variables-modifiers.h | 8 +- src/lib-sieve/plugins/variables/ext-variables-name.h | 16 +- src/lib-sieve/plugins/variables/ext-variables-namespaces.c | 64 +- src/lib-sieve/plugins/variables/ext-variables-namespaces.h | 10 +- src/lib-sieve/plugins/variables/ext-variables-operands.c | 102 +- src/lib-sieve/plugins/variables/ext-variables-operands.h | 20 +- src/lib-sieve/plugins/variables/ext-variables.c | 34 +- src/lib-sieve/plugins/variables/sieve-ext-variables.h | 84 +- src/lib-sieve/plugins/variables/tst-string.c | 102 +- src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate-common.c | 12 +- src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate-common.h | 2 +- src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate.c | 12 +- src/lib-sieve/plugins/vnd.dovecot/duplicate/tst-duplicate.c | 34 +- src/lib-sieve/rfc2822.c | 66 +- src/lib-sieve/rfc2822.h | 6 +- src/lib-sieve/sieve-actions.c | 228 +- src/lib-sieve/sieve-actions.h | 104 +- src/lib-sieve/sieve-address-parts.c | 112 +- src/lib-sieve/sieve-address-parts.h | 26 +- src/lib-sieve/sieve-address.c | 170 +- src/lib-sieve/sieve-address.h | 24 +- src/lib-sieve/sieve-ast.c | 472 +++--- src/lib-sieve/sieve-ast.h | 112 +- src/lib-sieve/sieve-binary-code.c | 114 +- src/lib-sieve/sieve-binary-debug.c | 34 +- src/lib-sieve/sieve-binary-dumper.c | 98 +- src/lib-sieve/sieve-binary-dumper.h | 4 +- src/lib-sieve/sieve-binary-file.c | 316 ++-- src/lib-sieve/sieve-binary-private.h | 78 +- src/lib-sieve/sieve-binary.c | 138 +- src/lib-sieve/sieve-binary.h | 78 +- src/lib-sieve/sieve-code-dumper.c | 92 +- src/lib-sieve/sieve-code-dumper.h | 18 +- src/lib-sieve/sieve-code.c | 456 +++--- src/lib-sieve/sieve-code.h | 88 +- src/lib-sieve/sieve-commands.c | 150 +- src/lib-sieve/sieve-commands.h | 70 +- src/lib-sieve/sieve-common.h | 8 +- src/lib-sieve/sieve-comparators.c | 110 +- src/lib-sieve/sieve-comparators.h | 54 +- src/lib-sieve/sieve-config.h | 2 +- src/lib-sieve/sieve-dump.h | 2 +- src/lib-sieve/sieve-error-private.h | 18 +- src/lib-sieve/sieve-error.c | 324 ++-- src/lib-sieve/sieve-error.h | 28 +- src/lib-sieve/sieve-extensions.c | 124 +- src/lib-sieve/sieve-extensions.h | 42 +- src/lib-sieve/sieve-generator.c | 204 +- src/lib-sieve/sieve-generator.h | 40 +- src/lib-sieve/sieve-interpreter.c | 158 +- src/lib-sieve/sieve-interpreter.h | 38 +- src/lib-sieve/sieve-lexer.c | 330 ++-- src/lib-sieve/sieve-lexer.h | 46 +- src/lib-sieve/sieve-match-types.c | 212 +- src/lib-sieve/sieve-match-types.h | 62 +- src/lib-sieve/sieve-match.c | 38 +- src/lib-sieve/sieve-match.h | 12 +- src/lib-sieve/sieve-message.c | 88 +- src/lib-sieve/sieve-message.h | 8 +- src/lib-sieve/sieve-objects.c | 46 +- src/lib-sieve/sieve-objects.h | 6 +- src/lib-sieve/sieve-parser.c | 328 ++-- src/lib-sieve/sieve-parser.h | 4 +- src/lib-sieve/sieve-plugins.c | 10 +- src/lib-sieve/sieve-plugins.h | 2 +- src/lib-sieve/sieve-result.c | 524 +++--- src/lib-sieve/sieve-result.h | 28 +- src/lib-sieve/sieve-runtime-trace.c | 44 +- src/lib-sieve/sieve-runtime-trace.h | 16 +- src/lib-sieve/sieve-runtime.h | 6 +- src/lib-sieve/sieve-script-dict.c | 14 +- src/lib-sieve/sieve-script-file.c | 42 +- src/lib-sieve/sieve-script-file.h | 2 +- src/lib-sieve/sieve-script-private.h | 2 +- src/lib-sieve/sieve-script.c | 36 +- src/lib-sieve/sieve-script.h | 12 +- src/lib-sieve/sieve-settings.c | 18 +- src/lib-sieve/sieve-stringlist.c | 18 +- src/lib-sieve/sieve-stringlist.h | 4 +- src/lib-sieve/sieve-types.h | 28 +- src/lib-sieve/sieve-validator.c | 684 +++++----- src/lib-sieve/sieve-validator.h | 60 +- src/lib-sieve/sieve.c | 178 +- src/lib-sieve/sieve.h | 42 +- src/lib-sieve/tst-address.c | 124 +- src/lib-sieve/tst-allof.c | 46 +- src/lib-sieve/tst-anyof.c | 48 +- src/lib-sieve/tst-exists.c | 64 +- src/lib-sieve/tst-header.c | 86 +- src/lib-sieve/tst-not.c | 26 +- src/lib-sieve/tst-size.c | 162 +- src/lib-sieve/tst-truefalse.c | 28 +- src/lib-sievestorage/Makefile.am | 2 +- src/lib-sievestorage/sieve-storage-list.c | 16 +- src/lib-sievestorage/sieve-storage-list.h | 4 +- src/lib-sievestorage/sieve-storage-private.h | 2 +- src/lib-sievestorage/sieve-storage-quota.c | 24 +- src/lib-sievestorage/sieve-storage-quota.h | 2 +- src/lib-sievestorage/sieve-storage-save.c | 36 +- src/lib-sievestorage/sieve-storage-script.c | 120 +- src/lib-sievestorage/sieve-storage.c | 70 +- src/lib-sievestorage/sieve-storage.h | 2 +- src/managesieve-login/client-authenticate.c | 12 +- src/managesieve-login/client.c | 40 +- src/managesieve-login/client.h | 2 +- src/managesieve-login/managesieve-login-settings-plugin.c | 12 +- src/managesieve-login/managesieve-login-settings.c | 2 +- src/managesieve-login/managesieve-proxy.c | 58 +- src/managesieve/Makefile.am | 4 +- src/managesieve/cmd-capability.c | 8 +- src/managesieve/cmd-deletescript.c | 2 +- src/managesieve/cmd-getscript.c | 8 +- src/managesieve/cmd-listscripts.c | 12 +- src/managesieve/cmd-putscript.c | 34 +- src/managesieve/cmd-renamescript.c | 2 +- src/managesieve/cmd-setactive.c | 12 +- src/managesieve/managesieve-capabilities.c | 6 +- src/managesieve/managesieve-client.c | 18 +- src/managesieve/managesieve-client.h | 2 +- src/managesieve/managesieve-commands.c | 8 +- src/managesieve/managesieve-quota.c | 16 +- src/managesieve/managesieve-settings.c | 2 +- src/plugins/lda-sieve/Makefile.am | 2 +- src/plugins/lda-sieve/lda-sieve-plugin.c | 50 +- src/sieve-tools/Makefile.am | 10 +- src/sieve-tools/sieve-dump.c | 12 +- src/sieve-tools/sieve-filter.c | 72 +- src/sieve-tools/sieve-test.c | 78 +- src/sieve-tools/sievec.c | 52 +- src/testsuite/cmd-test-binary.c | 84 +- src/testsuite/cmd-test-config.c | 160 +- src/testsuite/cmd-test-fail.c | 66 +- src/testsuite/cmd-test-mailbox.c | 84 +- src/testsuite/cmd-test-message.c | 192 +- src/testsuite/cmd-test-result.c | 52 +- src/testsuite/cmd-test-set.c | 70 +- src/testsuite/cmd-test.c | 82 +- src/testsuite/ext-testsuite.c | 14 +- src/testsuite/testsuite-arguments.c | 80 +- src/testsuite/testsuite-binary.c | 10 +- src/testsuite/testsuite-binary.h | 2 +- src/testsuite/testsuite-common.c | 36 +- src/testsuite/testsuite-common.h | 26 +- src/testsuite/testsuite-log.c | 22 +- src/testsuite/testsuite-mailstore.c | 24 +- src/testsuite/testsuite-mailstore.h | 4 +- src/testsuite/testsuite-message.c | 36 +- src/testsuite/testsuite-objects.c | 166 +- src/testsuite/testsuite-objects.h | 40 +- src/testsuite/testsuite-result.c | 26 +- src/testsuite/testsuite-result.h | 2 +- src/testsuite/testsuite-script.c | 2 +- src/testsuite/testsuite-script.h | 2 +- src/testsuite/testsuite-settings.c | 18 +- src/testsuite/testsuite-smtp.c | 44 +- src/testsuite/testsuite-smtp.h | 6 +- src/testsuite/testsuite-substitutions.c | 114 +- src/testsuite/testsuite-substitutions.h | 4 +- src/testsuite/testsuite-variables.c | 4 +- src/testsuite/testsuite-variables.h | 2 +- src/testsuite/testsuite.c | 10 +- src/testsuite/tst-test-error.c | 70 +- src/testsuite/tst-test-multiscript.c | 50 +- src/testsuite/tst-test-result-action.c | 68 +- src/testsuite/tst-test-result-execute.c | 32 +- src/testsuite/tst-test-script-compile.c | 44 +- src/testsuite/tst-test-script-run.c | 58 +- tests/compile/errors.svtest | 26 +- tests/compile/errors/address.sieve | 6 +- tests/compile/errors/envelope.sieve | 2 +- tests/compile/errors/if.sieve | 4 +- tests/compile/errors/keep.sieve | 2 +- tests/compile/errors/lexer.sieve | 2 +- tests/compile/errors/out-address.sieve | 2 +- tests/compile/errors/parser.sieve | 36 +- tests/compile/errors/require.sieve | 2 +- tests/compile/errors/size.sieve | 2 +- tests/compile/errors/tag.sieve | 2 +- tests/compile/errors/typos.sieve | 10 +- tests/compile/errors/unsupported.sieve | 6 +- tests/compile/recover.svtest | 2 +- tests/control-if.svtest | 40 +- tests/deprecated/notify/basic.svtest | 4 +- tests/deprecated/notify/mailto.svtest | 24 +- tests/execute/actions.svtest | 18 +- tests/execute/actions/redirect.sieve | 2 +- tests/execute/errors.svtest | 4 +- tests/execute/examples.svtest | 2 +- tests/execute/mailstore.svtest | 2 +- tests/extensions/body/basic.svtest | 10 +- tests/extensions/body/content.svtest | 20 +- tests/extensions/body/raw.svtest | 2 +- tests/extensions/date/basic.svtest | 8 +- tests/extensions/date/zones.svtest | 22 +- tests/extensions/editheader/addheader.svtest | 34 +- tests/extensions/editheader/alternating.svtest | 4 +- tests/extensions/editheader/deleteheader.svtest | 10 +- tests/extensions/editheader/errors.svtest | 8 +- tests/extensions/editheader/errors/command-syntax.sieve | 2 +- tests/extensions/editheader/protected.svtest | 12 +- tests/extensions/encoded-character.svtest | 4 +- tests/extensions/enotify/basic.svtest | 6 +- tests/extensions/enotify/errors/uri-mailto.sieve | 2 +- tests/extensions/enotify/mailto.svtest | 18 +- tests/extensions/enotify/valid_notify_method.svtest | 4 +- tests/extensions/envelope.svtest | 6 +- tests/extensions/environment/rfc.svtest | 4 +- tests/extensions/imap4flags/basic.svtest | 16 +- tests/extensions/imap4flags/execute.svtest | 20 +- tests/extensions/imap4flags/execute/flags-side-effect.sieve | 4 +- tests/extensions/imap4flags/hasflag.svtest | 8 +- tests/extensions/imap4flags/multiscript.svtest | 16 +- tests/extensions/include/execute.svtest | 6 +- tests/extensions/regex/basic.svtest | 8 +- tests/extensions/regex/match-values.svtest | 12 +- tests/extensions/relational/basic.svtest | 10 +- tests/extensions/relational/comparators.svtest | 22 +- tests/extensions/relational/errors/validation.sieve | 2 +- tests/extensions/relational/rfc.svtest | 12 +- tests/extensions/spamvirustest/spamtest.svtest | 2 +- tests/extensions/subaddress/basic.svtest | 2 +- tests/extensions/subaddress/rfc.svtest | 4 +- tests/extensions/vacation/execute.svtest | 4 +- tests/extensions/vacation/execute/no-handle.sieve | 6 +- tests/extensions/vacation/message.svtest | 10 +- tests/extensions/vacation/reply.svtest | 2 +- tests/extensions/vacation/utf-8.svtest | 4 +- tests/extensions/variables/basic.svtest | 14 +- tests/extensions/variables/errors/limits.sieve | 2 +- tests/extensions/variables/match.svtest | 34 +- tests/extensions/variables/modifiers.svtest | 12 +- tests/extensions/variables/quoting.svtest | 2 +- tests/extensions/variables/regex.svtest | 6 +- tests/extensions/variables/string.svtest | 2 +- tests/match-types/contains.svtest | 4 +- tests/match-types/is.svtest | 4 +- tests/match-types/matches.svtest | 2 +- tests/multiscript/basic.svtest | 4 +- tests/multiscript/conflicts.svtest | 8 +- tests/test-address.svtest | 28 +- tests/test-allof.svtest | 16 +- tests/test-anyof.svtest | 28 +- tests/test-exists.svtest | 2 +- tests/test-header.svtest | 18 +- tests/testsuite.svtest | 2 +- 388 files changed, 9954 insertions(+), 9954 deletions(-) diffs (truncated from 54658 to 300 lines): diff -r 54a0d0552be7 -r 7e100dcd888a AUTHORS --- a/AUTHORS Thu Aug 09 22:58:53 2012 +0200 +++ b/AUTHORS Sun Aug 12 15:50:27 2012 +0200 @@ -1,8 +1,8 @@ Stephan Bosch -This package is built for and partly based on the Dovecot Secure IMAP server +This package is built for and partly based on the Dovecot Secure IMAP server written by: -Timo Sirainen . +Timo Sirainen . Grepping 'patch by' from ChangeLog shows up more people. diff -r 54a0d0552be7 -r 7e100dcd888a COPYING --- a/COPYING Thu Aug 09 22:58:53 2012 +0200 +++ b/COPYING Sun Aug 12 15:50:27 2012 +0200 @@ -1,4 +1,4 @@ See AUTHORS file for list of copyright holders. -Everything is licenced under LGPLv2.1 (see COPYING.LGPL) unless otherwise +Everything is licenced under LGPLv2.1 (see COPYING.LGPL) unless otherwise mentioned at the beginning of the file. diff -r 54a0d0552be7 -r 7e100dcd888a INSTALL --- a/INSTALL Thu Aug 09 22:58:53 2012 +0200 +++ b/INSTALL Sun Aug 12 15:50:27 2012 +0200 @@ -1,7 +1,7 @@ Compiling ========= -If you downloaded the sources using Mercurial, you will need to execute +If you downloaded the sources using Mercurial, you will need to execute ./autogen.sh first to build the automake structure in your source tree. This process requires autotools and libtool to be installed. @@ -12,7 +12,7 @@ make sudo make install -If your system uses a $prefix different than the default /usr/local, the +If your system uses a $prefix different than the default /usr/local, the configure script can still find the installed dovecot-config automatically when supplied with the proper --prefix argument: @@ -44,7 +44,7 @@ --with-unfinished-features=no Controls whether unfinished features and extensions are built. Enabling this will enable the compilation of code that is considered unfinished and highly - experimental and may therefore introduce bugs and unexpected behavior. + experimental and may therefore introduce bugs and unexpected behavior. In fact, it may not compile at all. Enable this only when you are eager to test some of the new development functionality. @@ -57,12 +57,12 @@ facilitates the actual Sieve filtering upon delivery. - The ManageSieve Service: This implements the ManageSieve protocol through - which users can remotely manage Sieve scripts on the server. + which users can remotely manage Sieve scripts on the server. -The functionality of these items is described in more detail in the README file. +The functionality of these items is described in more detail in the README file. In this file and in this section their configuration is described. Example configuration files are provided in the doc/example-config directory of this -package. +package. Sieve Interpreter - Basic Configuration --------------------------------------- @@ -85,9 +85,9 @@ plugin section of the config file (default values are shown if applicable): sieve = ~/.dovecot.sieve - The location of the user's main active script. - - sieve_default = + The location of the user's main active script. + + sieve_default = The location of the default personal sieve script file, which gets executed ONLY if user's private Sieve script does no exist, e.g. /var/lib/dovecot/default.sieve. This is usually a global script, so be sure @@ -96,20 +96,20 @@ `sieve_global_path', but that name is now deprecated. sieve_global_dir = - Location for :global include scripts for the Sieve include extension. + Location for :global include scripts for the Sieve include extension. sieve_dir = ~/sieve - Location for :personal include scripts for the Sieve include extension. + Location for :personal include scripts for the Sieve include extension. sieve_extensions = - Which Sieve language extensions are available to users. By default, all - supported extensions are available, except for deprecated extensions or those - that are still under development. Some system administrators may want to - disable certain Sieve extensions or enable those that are not available by + Which Sieve language extensions are available to users. By default, all + supported extensions are available, except for deprecated extensions or those + that are still under development. Some system administrators may want to + disable certain Sieve extensions or enable those that are not available by default. This setting can use '+' and '-' to specify differences relative to the default. For example `sieve_extensions = +imapflags' will enable the deprecated imapflags extension in addition to all extensions were already - enabled by default. + enabled by default. sieve_global_extensions = Which Sieve language extensions are ONLY avalable in global scripts. This can @@ -117,7 +117,7 @@ control, for instance when these extensions can cause security concerns. This setting has higher precedence than the `sieve_extensions' setting (above), meaning that the extensions enabled with this setting are never available to - the user's personal script no matter what is specified for the + the user's personal script no matter what is specified for the `sieve_extensions' setting. The syntax of this setting is similar to the `sieve_extensions' setting, with the difference that extensions are enabled or disabled for exclusive use in global scripts. Currently, no @@ -127,16 +127,16 @@ The Pigeonhole Sieve interpreter can have plugins of its own. Using this setting, the used plugins can be specified. Check the Dovecot wiki (wiki2.dovecot.org) or the pigeonhole website (http://pigeonhole.dovecot.org) - for available plugins. + for available plugins. sieve_user_log = The path to the file where the user log file is written. If not configured, a default location is used. If the main user's personal Sieve (as configured with sieve=) is a file, the logfile is set to .log by default. If - it is not a file, the default user log file is ~/.dovecot.sieve.log. + it is not a file, the default user log file is ~/.dovecot.sieve.log. recipient_delimiter = + - The separator that is expected between the :user and :detail address parts + The separator that is expected between the :user and :detail address parts introduced by the subaddress extension. This may also be a sequence of characters (e.g. '--'). The current implementation looks for the separator from the left of the localpart and uses the first one encountered. The :user @@ -150,16 +150,16 @@ # The location of the user's active script: sieve = ~/.dovecot.sieve - # If the user has no personal active script (i.e. if the file + # If the user has no personal active script (i.e. if the file # indicated in sieve= does not exist), use this one: sieve_default = /var/lib/dovecot/sieve/default.sieve - # The include extension fetches the :personal scripts from this - # directory. When ManageSieve is used, this is also where scripts + # The include extension fetches the :personal scripts from this + # directory. When ManageSieve is used, this is also where scripts # are uploaded. sieve_dir = ~/sieve - # The include extension fetches the :global scripts from this + # The include extension fetches the :global scripts from this # directory. sieve_global_dir = /var/lib/dovecot/sieve/global/ } @@ -197,7 +197,7 @@ or a directory containing script files with names structured as `.sieve'. dict - Dovecot dict lookup. The location path is a dict uri. Read - doc/scipt-location-dict.txt for more information and examples. + doc/scipt-location-dict.txt for more information and examples. If the type prefix is omitted, the script location type is 'file'. @@ -219,8 +219,8 @@ directory as where the script file was found if possible. For `dict' type locations, the binary is not stored at all in that case. Don't specify the same directory for different script locations, as this will result in - undefined behavior. - + undefined behavior. + Sieve Interpreter - Per-user Sieve Script Location -------------------------------------------------- @@ -228,14 +228,14 @@ file in the user's home directory (~/.dovecot.sieve). This requires that the home directory is set for the user. -If you want to store the script elsewhere, you can override the default using +If you want to store the script elsewhere, you can override the default using the sieve= setting, which specifies the location of the user's script file. This can be done in two ways: 1. Define the sieve setting in the plugin section of dovecot.conf. - 2. Return sieve extra field from userdb extra fields. + 2. Return sieve extra field from userdb extra fields. -For example, to use a Sieve script file named .sieve in +For example, to use a Sieve script file named .sieve in /var/sieve-scripts, use: plugin { @@ -244,16 +244,16 @@ sieve = /var/sieve-scripts/%u.sieve } -You may use templates like %u, as shown in the example. Refer to +You may use templates like %u, as shown in the example. Refer to http://wiki.dovecot.org/Variables for more information. -A relative path (or just a filename) will be interpreted to point under the +A relative path (or just a filename) will be interpreted to point under the user's home directory. Sieve Interpreter - Executing Multiple Scripts Sequentially ----------------------------------------------------------- -Pigeonhole's Sieve interpreter allows executing multiple Sieve scripts +Pigeonhole's Sieve interpreter allows executing multiple Sieve scripts sequentially. The extra scripts can be executed before and after the user's private script. For example, this allows executing global Sieve policies before the user's script. The following settings in the plugin section of the Dovecot @@ -267,7 +267,7 @@ directory, all the Sieve scripts contained therein (with the proper .sieve extension) are executed. The order of execution within that directory is determined by the file names, using a normal 8bit per-character comparison. - + Multiple script file or directory paths can be specified by appending an increasing number. The Sieve scripts found from these paths are added to the script execution sequence in the specified order. Reading the numbered @@ -278,14 +278,14 @@ sieve_after2 = sieve_after3 = (etc..) Identical to sieve_before, but the specified scripts are executed after the - user's script (only when keep is still in effect, as explained below). + user's script (only when keep is still in effect, as explained below). The script execution ends when the currently executing script in the sequence -does not yield a "keep" result: when the script terminates, the next script is +does not yield a "keep" result: when the script terminates, the next script is only executed if an implicit or explicit "keep" is in effect. Thus, to end all script execution, a script must not execute keep and it must cancel the implicit -keep, e.g. by executing "discard; stop;". This means that the command "keep;" -has different semantics when used in a sequence of scripts. For normal Sieve +keep, e.g. by executing "discard; stop;". This means that the command "keep;" +has different semantics when used in a sequence of scripts. For normal Sieve execution, "keep;" is equivalent to "fileinto "INBOX";", because both cause the message to be stored in INBOX. However, in sequential script execution, it only controls whether the next script is executed. Storing the message into INBOX @@ -304,7 +304,7 @@ Just as for executing a single script the normal way, the Pigeonhole LDA Sieve plugin takes care never to duplicate deliveries, forwards or responses. When -vacation actions are executed multiple times in different scripts, the usual +vacation actions are executed multiple times in different scripts, the usual error is not triggered: the subsequent duplicate vacation actions are simply discarded. @@ -325,7 +325,7 @@ # E.g. user-specific default mail filing rules sieve_after = /var/vmail/%d/%n/sieve-after - # Global scripts executed after the user's personal script + # Global scripts executed after the user's personal script # (if keep is still in effect) # E.g. default mail filing rules. sieve_after2 = /var/lib/dovecot/sieve/after.d/ @@ -385,7 +385,7 @@ Sieve Interpreter - Migration from CMUSieve (Dovecot v1.0/v1.1) --------------------------------------------------------------- -For the most part, migration from CMUSieve to the Pigeonhole LDA Sieve plugin is +For the most part, migration from CMUSieve to the Pigeonhole LDA Sieve plugin is just a matter of changing the used plugin name from 'cmusieve' to 'sieve' in the mail_plugins option in the protocol lda section of the config file (as explained above). However, there are a few important differences: @@ -406,46 +406,46 @@ * The include extension now requires your script file names to end with ".sieve". This means that ` include :personal "myscript"; ' won't work unless - you rename "myscript" to "myscript.sieve" + you rename "myscript" to "myscript.sieve" Sieve Interpreter - Migration from Dovecot Sieve v0.1.x (Dovecot v1.2) ---------------------------------------------------------------------- - * Dovecot v2.0 adds support for LMTP. Much like the Dovecot LDA, it can make - use of the Pigeonhole Sieve plugin. Since the LMTP service has its own - prototocol lmtp section in the config file, you need to add the Sieve plugin + * Dovecot v2.0 adds support for LMTP. Much like the Dovecot LDA, it can make + use of the Pigeonhole Sieve plugin. Since the LMTP service has its own + prototocol lmtp section in the config file, you need to add the Sieve plugin to the mail_plugins setting there too when you decide to use LMTP. - * The 'sieve_subaddress_sep' setting for the Sieve subaddress extension is now + * The 'sieve_subaddress_sep' setting for the Sieve subaddress extension is now known as 'recipient_delimiter'. Although sieve_subaddress_sep is still recognized for backwards compatibility, it is recommended to update the setting to the new name, since the LMTP service also uses the - recipient_delimiter setting. + recipient_delimiter setting. ManageSieve Service - Basic Configuration ----------------------------------------- From dovecot at dovecot.org Mon Aug 13 00:27:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 00:27:17 +0300 Subject: dovecot-2.2: Verify that mailbox_idle_check_interval setting isn... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/51f9a87170f2 changeset: 14881:51f9a87170f2 user: Timo Sirainen date: Mon Aug 13 00:27:07 2012 +0300 description: Verify that mailbox_idle_check_interval setting isn't 0. diffstat: src/lib-storage/mail-storage-settings.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r d7df4855dc94 -r 51f9a87170f2 src/lib-storage/mail-storage-settings.c --- a/src/lib-storage/mail-storage-settings.c Sun Aug 12 09:57:20 2012 +0300 +++ b/src/lib-storage/mail-storage-settings.c Mon Aug 13 00:27:07 2012 +0300 @@ -352,6 +352,11 @@ bool uidl_format_ok; char c; + if (set->mailbox_idle_check_interval == 0) { + *error_r = "mailbox_idle_check_interval must not be 0"; + return FALSE; + } + if (strcmp(set->mail_fsync, "optimized") == 0) set->parsed_fsync_mode = FSYNC_MODE_OPTIMIZED; else if (strcmp(set->mail_fsync, "never") == 0) From dovecot at dovecot.org Mon Aug 13 00:29:52 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 00:29:52 +0300 Subject: dovecot-2.2: lib-index: Verify validity of ext-intro records in ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ba6b92cf7d49 changeset: 14882:ba6b92cf7d49 user: Timo Sirainen date: Mon Aug 13 00:29:38 2012 +0300 description: lib-index: Verify validity of ext-intro records in transaction log. diffstat: src/lib-index/mail-transaction-log-view.c | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+), 0 deletions(-) diffs (31 lines): diff -r 51f9a87170f2 -r ba6b92cf7d49 src/lib-index/mail-transaction-log-view.c --- a/src/lib-index/mail-transaction-log-view.c Mon Aug 13 00:27:07 2012 +0300 +++ b/src/lib-index/mail-transaction-log-view.c Mon Aug 13 00:29:38 2012 +0300 @@ -586,6 +586,27 @@ array_create_from_buffer(&uids, &uid_buf, sizeof(struct mail_transaction_keyword_reset)); break; + case MAIL_TRANSACTION_EXT_INTRO: { + const struct mail_transaction_ext_intro *rec; + unsigned int i; + + for (i = 0; i < rec_size; ) { + if (i + sizeof(*rec) > rec_size) { + /* should be just extra padding */ + break; + } + + rec = CONST_PTR_OFFSET(data, i); + if (i + sizeof(*rec) + rec->name_size > rec_size) { + mail_transaction_log_file_set_corrupted(file, + "ext intro: name_size too large"); + return FALSE; + } + i += sizeof(*rec) + rec->name_size; + if ((i % 4) != 0) + i += 4 - (i % 4); + } + } default: break; } From dovecot at dovecot.org Mon Aug 13 00:31:46 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 00:31:46 +0300 Subject: dovecot-2.2: lib-index: Removed duplicate ext-intro checking code. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/222c7d752519 changeset: 14883:222c7d752519 user: Timo Sirainen date: Mon Aug 13 00:31:40 2012 +0300 description: lib-index: Removed duplicate ext-intro checking code. diffstat: src/lib-index/mail-index-sync-update.c | 15 +++------------ 1 files changed, 3 insertions(+), 12 deletions(-) diffs (32 lines): diff -r ba6b92cf7d49 -r 222c7d752519 src/lib-index/mail-index-sync-update.c --- a/src/lib-index/mail-index-sync-update.c Mon Aug 13 00:29:38 2012 +0300 +++ b/src/lib-index/mail-index-sync-update.c Mon Aug 13 00:31:40 2012 +0300 @@ -539,12 +539,7 @@ t_array_init(&uids, 64); end = CONST_PTR_OFFSET(data, hdr->size); for (; rec != end; rec++) { - if (rec->uid == 0) { - mail_index_sync_set_corrupted(ctx, - "Expunge-guid for invalid uid=%u", - rec->uid); - break; - } + i_assert(rec->uid != 0); seq_range_array_add(&uids, rec->uid); } @@ -601,12 +596,8 @@ } rec = CONST_PTR_OFFSET(data, i); - if (i + sizeof(*rec) + rec->name_size > hdr->size) { - mail_index_sync_set_corrupted(ctx, - "ext intro: name_size too large"); - ret = -1; - break; - } + /* name_size checked by _log_view_next() */ + i_assert(i + sizeof(*rec) + rec->name_size <= hdr->size); ret = mail_index_sync_ext_intro(ctx, rec); if (ret <= 0) From dovecot at dovecot.org Mon Aug 13 00:33:58 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 00:33:58 +0300 Subject: dovecot-2.2: lib-index: Support clearing the whole log view with... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7aece00b8538 changeset: 14884:7aece00b8538 user: Timo Sirainen date: Mon Aug 13 00:33:47 2012 +0300 description: lib-index: Support clearing the whole log view with mail_transaction_log_view_clear(0) diffstat: src/lib-index/mail-transaction-log-view.c | 3 ++- src/lib-index/mail-transaction-log.h | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diffs (27 lines): diff -r 222c7d752519 -r 7aece00b8538 src/lib-index/mail-transaction-log-view.c --- a/src/lib-index/mail-transaction-log-view.c Mon Aug 13 00:31:40 2012 +0300 +++ b/src/lib-index/mail-transaction-log-view.c Mon Aug 13 00:33:47 2012 +0300 @@ -330,7 +330,8 @@ struct mail_transaction_log_file *file; mail_transaction_log_view_unref_all(view); - if (mail_transaction_log_find_file(view->log, oldest_file_seq, FALSE, + if (oldest_file_seq != 0 && + mail_transaction_log_find_file(view->log, oldest_file_seq, FALSE, &file) > 0) { for (; file != NULL; file = file->next) { array_append(&view->file_refs, &file, 1); diff -r 222c7d752519 -r 7aece00b8538 src/lib-index/mail-transaction-log.h --- a/src/lib-index/mail-transaction-log.h Mon Aug 13 00:31:40 2012 +0300 +++ b/src/lib-index/mail-transaction-log.h Mon Aug 13 00:33:47 2012 +0300 @@ -225,8 +225,8 @@ /* Scan through all of the log files that we can find. Returns -1 if error, 0 if ok. */ int mail_transaction_log_view_set_all(struct mail_transaction_log_view *view); -/* Clear the view. Keep oldest_file_seq and newer log files referenced so we - don't get desynced. */ +/* Clear the view. If oldest_file_seq > 0, keep it and newer log files + referenced so we don't get desynced. */ void mail_transaction_log_view_clear(struct mail_transaction_log_view *view, uint32_t oldest_file_seq); From dovecot at dovecot.org Mon Aug 13 00:36:53 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 00:36:53 +0300 Subject: dovecot-2.2: lib-storage: Mailbox tree API supports now includin... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/acc60089da4f changeset: 14885:acc60089da4f user: Timo Sirainen date: Mon Aug 13 00:36:38 2012 +0300 description: lib-storage: Mailbox tree API supports now including extra data in the nodes. diffstat: src/lib-storage/mailbox-tree.c | 12 +++++++++++- src/lib-storage/mailbox-tree.h | 2 ++ 2 files changed, 13 insertions(+), 1 deletions(-) diffs (53 lines): diff -r 7aece00b8538 -r acc60089da4f src/lib-storage/mailbox-tree.c --- a/src/lib-storage/mailbox-tree.c Mon Aug 13 00:33:47 2012 +0300 +++ b/src/lib-storage/mailbox-tree.c Mon Aug 13 00:36:38 2012 +0300 @@ -9,6 +9,7 @@ pool_t pool; char separator; bool parents_nonexistent; + unsigned int node_size; struct mailbox_node *nodes; }; @@ -28,11 +29,20 @@ struct mailbox_tree_context *mailbox_tree_init(char separator) { + return mailbox_tree_init_size(separator, sizeof(struct mailbox_node)); +} + +struct mailbox_tree_context * +mailbox_tree_init_size(char separator, unsigned int mailbox_node_size) +{ struct mailbox_tree_context *tree; + i_assert(mailbox_node_size >= sizeof(struct mailbox_node)); + tree = i_new(struct mailbox_tree_context, 1); tree->pool = pool_alloconly_create(MEMPOOL_GROWING"mailbox_tree", 10240); tree->separator = separator; + tree->node_size = mailbox_node_size; return tree; } @@ -104,7 +114,7 @@ if (!create) break; - *node = p_new(tree->pool, struct mailbox_node, 1); + *node = p_malloc(tree->pool, tree->node_size); (*node)->parent = parent; (*node)->name = p_strdup(tree->pool, name); if (tree->parents_nonexistent) diff -r 7aece00b8538 -r acc60089da4f src/lib-storage/mailbox-tree.h --- a/src/lib-storage/mailbox-tree.h Mon Aug 13 00:33:47 2012 +0300 +++ b/src/lib-storage/mailbox-tree.h Mon Aug 13 00:36:38 2012 +0300 @@ -13,6 +13,8 @@ }; struct mailbox_tree_context *mailbox_tree_init(char separator); +struct mailbox_tree_context * +mailbox_tree_init_size(char separator, unsigned int mailbox_node_size); void mailbox_tree_deinit(struct mailbox_tree_context **tree); void mailbox_tree_set_separator(struct mailbox_tree_context *tree, From dovecot at dovecot.org Mon Aug 13 02:38:58 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 02:38:58 +0300 Subject: dovecot-2.2: imap: Made STATUS handling API more flexible. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/42cc4c4c4891 changeset: 14886:42cc4c4c4891 user: Timo Sirainen date: Mon Aug 13 01:25:12 2012 +0300 description: imap: Made STATUS handling API more flexible. diffstat: src/imap/cmd-list.c | 5 ++--- src/imap/cmd-status.c | 7 +++---- src/imap/imap-status.c | 21 +++++++++++---------- src/imap/imap-status.h | 15 +++++++++------ 4 files changed, 25 insertions(+), 23 deletions(-) diffs (129 lines): diff -r acc60089da4f -r 42cc4c4c4891 src/imap/cmd-list.c --- a/src/imap/cmd-list.c Mon Aug 13 00:36:38 2012 +0300 +++ b/src/imap/cmd-list.c Mon Aug 13 01:25:12 2012 +0300 @@ -376,7 +376,6 @@ { struct imap_status_result result; struct mail_namespace *ns; - const char *error; if ((flags & (MAILBOX_NONEXISTENT | MAILBOX_NOSELECT)) != 0) { /* doesn't exist, don't even try to get STATUS */ @@ -392,9 +391,9 @@ namespaces, ctx->ns may not point to correct one */ ns = mail_namespace_find(ctx->ns->user->namespaces, name); if (imap_status_get(ctx->cmd, ns, name, - &ctx->status_items, &result, &error) < 0) { + &ctx->status_items, &result) < 0) { client_send_line(ctx->cmd->client, - t_strconcat("* ", error, NULL)); + t_strconcat("* ", result.errstr, NULL)); return; } diff -r acc60089da4f -r 42cc4c4c4891 src/imap/cmd-status.c --- a/src/imap/cmd-status.c Mon Aug 13 00:36:38 2012 +0300 +++ b/src/imap/cmd-status.c Mon Aug 13 01:25:12 2012 +0300 @@ -13,7 +13,7 @@ struct imap_status_items items; struct imap_status_result result; struct mail_namespace *ns; - const char *mailbox, *orig_mailbox, *error; + const char *mailbox, *orig_mailbox; bool selected_mailbox; /* */ @@ -37,9 +37,8 @@ selected_mailbox = client->mailbox != NULL && mailbox_equals(client->mailbox, ns, mailbox); - if (imap_status_get(cmd, ns, mailbox, &items, - &result, &error) < 0) { - client_send_tagline(cmd, error); + if (imap_status_get(cmd, ns, mailbox, &items, &result) < 0) { + client_send_tagline(cmd, result.errstr); return TRUE; } diff -r acc60089da4f -r 42cc4c4c4891 src/imap/imap-status.c --- a/src/imap/imap-status.c Mon Aug 13 00:36:38 2012 +0300 +++ b/src/imap/imap-status.c Mon Aug 13 01:25:12 2012 +0300 @@ -58,13 +58,13 @@ } int imap_status_get(struct client_command_context *cmd, - struct mail_namespace *ns, - const char *mailbox, const struct imap_status_items *items, - struct imap_status_result *result_r, const char **error_r) + struct mail_namespace *ns, const char *mailbox, + const struct imap_status_items *items, + struct imap_status_result *result_r) { struct client *client = cmd->client; struct mailbox *box; - enum mail_error error; + const char *errstr; int ret = 0; if (client->mailbox != NULL && @@ -88,17 +88,18 @@ } if (ret < 0) { - *error_r = mailbox_get_last_error(box, &error); - *error_r = imap_get_error_string(cmd, *error_r, error); + errstr = mailbox_get_last_error(box, &result_r->error); + result_r->errstr = imap_get_error_string(cmd, errstr, + result_r->error); } if (box != client->mailbox) mailbox_free(&box); return ret; } -void imap_status_send(struct client *client, const char *mailbox_mutf7, - const struct imap_status_items *items, - const struct imap_status_result *result) +int imap_status_send(struct client *client, const char *mailbox_mutf7, + const struct imap_status_items *items, + const struct imap_status_result *result) { const struct mailbox_status *status = &result->status; string_t *str; @@ -137,5 +138,5 @@ str_truncate(str, str_len(str)-1); str_append_c(str, ')'); - client_send_line(client, str_c(str)); + return client_send_line_next(client, str_c(str)); } diff -r acc60089da4f -r 42cc4c4c4891 src/imap/imap-status.h --- a/src/imap/imap-status.h Mon Aug 13 00:36:38 2012 +0300 +++ b/src/imap/imap-status.h Mon Aug 13 01:25:12 2012 +0300 @@ -9,17 +9,20 @@ struct imap_status_result { struct mailbox_status status; struct mailbox_metadata metadata; + enum mail_error error; + const char *errstr; }; int imap_status_parse_items(struct client_command_context *cmd, const struct imap_arg *args, struct imap_status_items *items_r); int imap_status_get(struct client_command_context *cmd, - struct mail_namespace *ns, - const char *mailbox, const struct imap_status_items *items, - struct imap_status_result *result_r, const char **error_r); -void imap_status_send(struct client *client, const char *mailbox_mutf7, - const struct imap_status_items *items, - const struct imap_status_result *result); + struct mail_namespace *ns, const char *mailbox, + const struct imap_status_items *items, + struct imap_status_result *result_r); +int imap_status_send(struct client *client, const char *mailbox_mutf7, + const struct imap_status_items *items, + const struct imap_status_result *result) + ATTR_NOWARN_UNUSED_RESULT; #endif From dovecot at dovecot.org Mon Aug 13 02:38:58 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 02:38:58 +0300 Subject: dovecot-2.2: imap: FETCH API cleanup: keep fetch state in a sepa... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0c73a42c194e changeset: 14887:0c73a42c194e user: Timo Sirainen date: Mon Aug 13 01:47:54 2012 +0300 description: imap: FETCH API cleanup: keep fetch state in a separate struct. diffstat: src/imap/cmd-fetch.c | 11 +- src/imap/imap-fetch-body.c | 93 ++++++++++++---------- src/imap/imap-fetch.c | 187 ++++++++++++++++++++++---------------------- src/imap/imap-fetch.h | 45 ++++++---- 4 files changed, 175 insertions(+), 161 deletions(-) diffs (truncated from 767 to 300 lines): diff -r 42cc4c4c4891 -r 0c73a42c194e src/imap/cmd-fetch.c --- a/src/imap/cmd-fetch.c Mon Aug 13 01:25:12 2012 +0300 +++ b/src/imap/cmd-fetch.c Mon Aug 13 01:47:54 2012 +0300 @@ -144,19 +144,20 @@ static const char *ok_message = "OK Fetch completed."; const char *tagged_reply = ok_message; enum mail_error error; + bool seen_flags_changed = ctx->state.seen_flags_changed; - if (ctx->skipped_expunged_msgs) { + if (ctx->state.skipped_expunged_msgs) { tagged_reply = "OK ["IMAP_RESP_CODE_EXPUNGEISSUED"] " "Some messages were already expunged."; } if (imap_fetch_deinit(ctx) < 0) - ctx->failed = TRUE; + ctx->state.failed = TRUE; - if (ctx->failed) { + if (ctx->state.failed) { const char *errstr; - if (ctx->client->output->closed) { + if (cmd->client->output->closed) { client_disconnect(cmd->client, "Disconnected"); return TRUE; } @@ -175,7 +176,7 @@ } return cmd_sync(cmd, - (ctx->seen_flags_changed ? 0 : MAILBOX_SYNC_FLAG_FAST) | + (seen_flags_changed ? 0 : MAILBOX_SYNC_FLAG_FAST) | (cmd->uid ? 0 : MAILBOX_SYNC_FLAG_NO_EXPUNGES), 0, tagged_reply); } diff -r 42cc4c4c4891 -r 0c73a42c194e src/imap/imap-fetch-body.c --- a/src/imap/imap-fetch-body.c Mon Aug 13 01:25:12 2012 +0300 +++ b/src/imap/imap-fetch-body.c Mon Aug 13 01:47:54 2012 +0300 @@ -30,11 +30,13 @@ static void fetch_read_error(struct imap_fetch_context *ctx) { - errno = ctx->cur_input->stream_errno; + struct imap_fetch_state *state = &ctx->state; + + errno = state->cur_input->stream_errno; mail_storage_set_critical(ctx->box->storage, "read(%s) failed: %m (FETCH for mailbox %s UID %u)", - i_stream_get_name(ctx->cur_input), - mailbox_get_vname(ctx->cur_mail->box), ctx->cur_mail->uid); + i_stream_get_name(state->cur_input), + mailbox_get_vname(state->cur_mail->box), state->cur_mail->uid); } static const char *get_body_name(const struct imap_fetch_body_data *body) @@ -63,8 +65,8 @@ string_t *str; str = t_str_new(128); - if (ctx->first) - ctx->first = FALSE; + if (ctx->state.cur_first) + ctx->state.cur_first = FALSE; else str_append_c(str, ' '); @@ -81,31 +83,34 @@ static int fetch_stream_continue(struct imap_fetch_context *ctx) { + struct imap_fetch_state *state = &ctx->state; off_t ret; o_stream_set_max_buffer_size(ctx->client->output, 0); - ret = o_stream_send_istream(ctx->client->output, ctx->cur_input); + ret = o_stream_send_istream(ctx->client->output, state->cur_input); o_stream_set_max_buffer_size(ctx->client->output, (size_t)-1); if (ret > 0) - ctx->cur_offset += ret; + state->cur_offset += ret; - if (ctx->cur_offset != ctx->cur_size) { + if (state->cur_offset != state->cur_size) { /* unfinished */ - if (ctx->cur_input->stream_errno != 0) { + if (state->cur_input->stream_errno != 0) { fetch_read_error(ctx); client_disconnect(ctx->client, "FETCH failed"); return -1; } - if (!i_stream_have_bytes_left(ctx->cur_input)) { + if (!i_stream_have_bytes_left(state->cur_input)) { /* Input stream gave less data than expected */ i_error("FETCH %s for mailbox %s UID %u " "got too little data: " "%"PRIuUOFF_T" vs %"PRIuUOFF_T, - ctx->cur_name, mailbox_get_vname(ctx->cur_mail->box), - ctx->cur_mail->uid, ctx->cur_offset, ctx->cur_size); - mail_set_cache_corrupted(ctx->cur_mail, - ctx->cur_size_field); + state->cur_human_name, + mailbox_get_vname(state->cur_mail->box), + state->cur_mail->uid, + state->cur_offset, state->cur_size); + mail_set_cache_corrupted(state->cur_mail, + state->cur_size_field); client_disconnect(ctx->client, "FETCH failed"); return -1; } @@ -128,17 +133,18 @@ if (imap_msgpart_open(mail, body->msgpart, &result) < 0) return -1; - ctx->cur_input = result.input; - ctx->cur_size = result.size; - ctx->cur_size_field = result.size_field; - ctx->cur_name = p_strconcat(ctx->pool, "[", body->section, "]", NULL); + ctx->state.cur_input = result.input; + ctx->state.cur_size = result.size; + ctx->state.cur_size_field = result.size_field; + ctx->state.cur_human_name = + p_strconcat(ctx->pool, "[", body->section, "]", NULL); - str = get_prefix(ctx, body, ctx->cur_size, + str = get_prefix(ctx, body, ctx->state.cur_size, result.binary_decoded_input_has_nuls); o_stream_nsend(ctx->client->output, str_data(str), str_len(str)); - ctx->cont_handler = fetch_stream_continue; - return ctx->cont_handler(ctx); + ctx->state.cont_handler = fetch_stream_continue; + return ctx->state.cont_handler(ctx); } static int fetch_binary_size(struct imap_fetch_context *ctx, struct mail *mail, @@ -151,8 +157,8 @@ return -1; str = t_str_new(128); - if (ctx->first) - ctx->first = FALSE; + if (ctx->state.cur_first) + ctx->state.cur_first = FALSE; else str_append_c(str, ' '); str_printfa(str, "%s %"PRIuUOFF_T, get_body_name(body), size); @@ -412,7 +418,7 @@ if (mail_get_virtual_size(mail, &size) < 0) return -1; - str_printfa(ctx->cur_str, "RFC822.SIZE %"PRIuUOFF_T" ", size); + str_printfa(ctx->state.cur_str, "RFC822.SIZE %"PRIuUOFF_T" ", size); return 1; } @@ -427,10 +433,10 @@ imap_msgpart_free(_msgpart); if (ret < 0) return -1; - ctx->cur_input = result.input; - ctx->cur_size = result.size; - ctx->cur_size_field = result.size_field; - ctx->cont_handler = fetch_stream_continue; + ctx->state.cur_input = result.input; + ctx->state.cur_size = result.size; + ctx->state.cur_size_field = result.size_field; + ctx->state.cont_handler = fetch_stream_continue; return 0; } @@ -445,14 +451,15 @@ if (fetch_and_free_msgpart(ctx, mail, &msgpart) < 0) return -1; - str = t_strdup_printf(" RFC822 {%"PRIuUOFF_T"}\r\n", ctx->cur_size); - if (ctx->first) { - str++; ctx->first = FALSE; + str = t_strdup_printf(" RFC822 {%"PRIuUOFF_T"}\r\n", + ctx->state.cur_size); + if (ctx->state.cur_first) { + str++; ctx->state.cur_first = FALSE; } o_stream_nsend_str(ctx->client->output, str); - ctx->cur_name = "RFC822"; - return ctx->cont_handler(ctx); + ctx->state.cur_human_name = "RFC822"; + return ctx->state.cont_handler(ctx); } static int ATTR_NULL(3) @@ -467,14 +474,14 @@ return -1; str = t_strdup_printf(" RFC822.HEADER {%"PRIuUOFF_T"}\r\n", - ctx->cur_size); - if (ctx->first) { - str++; ctx->first = FALSE; + ctx->state.cur_size); + if (ctx->state.cur_first) { + str++; ctx->state.cur_first = FALSE; } o_stream_nsend_str(ctx->client->output, str); - ctx->cur_name = "RFC822.HEADER"; - return ctx->cont_handler(ctx); + ctx->state.cur_human_name = "RFC822.HEADER"; + return ctx->state.cont_handler(ctx); } static int ATTR_NULL(3) @@ -489,14 +496,14 @@ return -1; str = t_strdup_printf(" RFC822.TEXT {%"PRIuUOFF_T"}\r\n", - ctx->cur_size); - if (ctx->first) { - str++; ctx->first = FALSE; + ctx->state.cur_size); + if (ctx->state.cur_first) { + str++; ctx->state.cur_first = FALSE; } o_stream_nsend_str(ctx->client->output, str); - ctx->cur_name = "RFC822.TEXT"; - return ctx->cont_handler(ctx); + ctx->state.cur_human_name = "RFC822.TEXT"; + return ctx->state.cont_handler(ctx); } bool imap_fetch_rfc822_init(struct imap_fetch_init_context *ctx) diff -r 42cc4c4c4891 -r 0c73a42c194e src/imap/imap-fetch.c --- a/src/imap/imap-fetch.c Mon Aug 13 01:25:12 2012 +0300 +++ b/src/imap/imap-fetch.c Mon Aug 13 01:47:54 2012 +0300 @@ -105,12 +105,12 @@ ctx->pool = cmd->pool; ctx->box = box; - ctx->cur_str = str_new(default_pool, 8192); + ctx->state.cur_str = str_new(default_pool, 8192); p_array_init(&ctx->all_headers, cmd->pool, 64); p_array_init(&ctx->handlers, cmd->pool, 16); p_array_init(&ctx->tmp_keywords, cmd->pool, client->keywords.announce_count + 8); - ctx->line_finished = TRUE; + ctx->state.line_finished = TRUE; return ctx; } @@ -140,8 +140,8 @@ /* partially because of broken clients, but also partially because it potentially can make client implementations faster, we have a buffered parameter which basically means that the handler promises - to write the output in fetch_ctx->cur_str. The cur_str is then sent - to client before calling any non-buffered handlers. + to write the output in fetch_ctx->state.cur_str. The cur_str is then + sent to client before calling any non-buffered handlers. We try to keep the handler registration order the same as the client requested them. This is especially useful to get UID @@ -327,11 +327,12 @@ int imap_fetch_begin(struct imap_fetch_context *ctx) { + struct mailbox_header_lookup_ctx *wanted_headers = NULL; const void *data; if (ctx->send_vanished) { if (imap_fetch_send_vanished(ctx) < 0) { - ctx->failed = TRUE; + ctx->state.failed = TRUE; return -1; } } @@ -351,24 +352,25 @@ array_append_zero(&ctx->all_headers); data = array_idx(&ctx->all_headers, 0); - ctx->all_headers_ctx = - mailbox_header_lookup_init(ctx->box, data); + wanted_headers = mailbox_header_lookup_init(ctx->box, data); } if ((ctx->fetch_data & (MAIL_FETCH_STREAM_HEADER | MAIL_FETCH_STREAM_BODY)) != 0) ctx->fetch_data |= MAIL_FETCH_NUL_STATE; - ctx->trans = mailbox_transaction_begin(ctx->box, + ctx->state.trans = mailbox_transaction_begin(ctx->box, MAILBOX_TRANSACTION_FLAG_HIDE | MAILBOX_TRANSACTION_FLAG_REFRESH); /* Delayed uidset -> seqset conversion. VANISHED needs the uidset. */ mail_search_args_init(ctx->search_args, ctx->box, TRUE, &ctx->client->search_saved_uidset); - ctx->search_ctx = - mailbox_search_init(ctx->trans, ctx->search_args, NULL, From dovecot at dovecot.org Mon Aug 13 02:41:14 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 02:41:14 +0300 Subject: dovecot-2.2: imap_msgpart_parse() doesn't really need a mailbox ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cf79ab812651 changeset: 14888:cf79ab812651 user: Timo Sirainen date: Mon Aug 13 02:41:08 2012 +0300 description: imap_msgpart_parse() doesn't really need a mailbox parameter. diffstat: src/imap/imap-fetch-body.c | 6 ++---- src/lib-imap-storage/imap-msgpart-url.c | 2 +- src/lib-imap-storage/imap-msgpart.c | 28 +++++++++++++++++----------- src/lib-imap-storage/imap-msgpart.h | 8 ++++++-- 4 files changed, 26 insertions(+), 18 deletions(-) diffs (141 lines): diff -r 0c73a42c194e -r cf79ab812651 src/imap/imap-fetch-body.c --- a/src/imap/imap-fetch-body.c Mon Aug 13 01:47:54 2012 +0300 +++ b/src/imap/imap-fetch-body.c Mon Aug 13 02:41:08 2012 +0300 @@ -312,8 +312,7 @@ body->section, p); p++; } - if (imap_msgpart_parse(ctx->fetch_ctx->box, body->section, - &body->msgpart) < 0) { + if (imap_msgpart_parse(body->section, &body->msgpart) < 0) { ctx->error = "Invalid BODY[..] section"; return -1; } @@ -383,8 +382,7 @@ body->section, p); p++; } - if (imap_msgpart_parse(ctx->fetch_ctx->box, body->section, - &body->msgpart) < 0) { + if (imap_msgpart_parse(body->section, &body->msgpart) < 0) { ctx->error = "Invalid BINARY[..] section"; return -1; } diff -r 0c73a42c194e -r cf79ab812651 src/lib-imap-storage/imap-msgpart-url.c --- a/src/lib-imap-storage/imap-msgpart-url.c Mon Aug 13 01:47:54 2012 +0300 +++ b/src/lib-imap-storage/imap-msgpart-url.c Mon Aug 13 02:41:08 2012 +0300 @@ -174,7 +174,7 @@ if ((ret = imap_msgpart_url_open_mail(mpurl, mail_r, error_r)) <= 0) return ret; - if (imap_msgpart_parse((*mail_r)->box, section, msgpart_r) < 0) { + if (imap_msgpart_parse(section, msgpart_r) < 0) { *error_r = "Invalid section"; return 0; } diff -r 0c73a42c194e -r cf79ab812651 src/lib-imap-storage/imap-msgpart.c --- a/src/lib-imap-storage/imap-msgpart.c Mon Aug 13 01:47:54 2012 +0300 +++ b/src/lib-imap-storage/imap-msgpart.c Mon Aug 13 02:41:08 2012 +0300 @@ -172,8 +172,7 @@ } static int -imap_msgpart_parse_header_fields(struct mailbox *box, - struct imap_msgpart *msgpart, +imap_msgpart_parse_header_fields(struct imap_msgpart *msgpart, const char *header_list) { ARRAY_TYPE(const_string) fields; @@ -185,12 +184,10 @@ array_append_zero(&fields); msgpart->headers = array_idx(&fields, 0); - msgpart->header_ctx = mailbox_header_lookup_init(box, msgpart->headers); return 0; } -int imap_msgpart_parse(struct mailbox *box, const char *section, - struct imap_msgpart **msgpart_r) +int imap_msgpart_parse(const char *section, struct imap_msgpart **msgpart_r) { struct imap_msgpart *msgpart; pool_t pool; @@ -263,11 +260,11 @@ ret = 0; } else if (strncmp(section, "HEADER.FIELDS ", 14) == 0) { msgpart->fetch_type = FETCH_HEADER_FIELDS; - ret = imap_msgpart_parse_header_fields(box, msgpart, + ret = imap_msgpart_parse_header_fields(msgpart, section+14); } else if (strncmp(section, "HEADER.FIELDS.NOT ", 18) == 0) { msgpart->fetch_type = FETCH_HEADER_FIELDS_NOT; - ret = imap_msgpart_parse_header_fields(box, msgpart, + ret = imap_msgpart_parse_header_fields(msgpart, section+18); } else { ret = -1; @@ -295,8 +292,7 @@ *_msgpart = NULL; - if (msgpart->header_ctx != NULL) - mailbox_header_lookup_unref(&msgpart->header_ctx); + imap_msgpart_close_mailbox(msgpart); pool_unref(&msgpart->pool); } @@ -547,7 +543,7 @@ } static int -imap_msgpart_open_normal(struct mail *mail, const struct imap_msgpart *msgpart, +imap_msgpart_open_normal(struct mail *mail, struct imap_msgpart *msgpart, const struct message_part *part, struct message_size *part_size_r, struct imap_msgpart_open_result *result_r) @@ -588,7 +584,11 @@ break; case FETCH_HEADER_FIELDS: /* try to lookup the headers from cache */ - i_assert(msgpart->header_ctx != NULL); + if (msgpart->header_ctx == NULL) { + msgpart->header_ctx = + mailbox_header_lookup_init(mail->box, + msgpart->headers); + } if (mail_get_header_stream(mail, msgpart->header_ctx, &input) < 0) return -1; @@ -720,3 +720,9 @@ include_hdr = msgpart->fetch_type == FETCH_FULL; return mail_get_binary_size(mail, part, include_hdr, size_r); } + +void imap_msgpart_close_mailbox(struct imap_msgpart *msgpart) +{ + if (msgpart->header_ctx != NULL) + mailbox_header_lookup_unref(&msgpart->header_ctx); +} diff -r 0c73a42c194e -r cf79ab812651 src/lib-imap-storage/imap-msgpart.h --- a/src/lib-imap-storage/imap-msgpart.h Mon Aug 13 01:47:54 2012 +0300 +++ b/src/lib-imap-storage/imap-msgpart.h Mon Aug 13 02:41:08 2012 +0300 @@ -21,8 +21,7 @@ /* Parse section into imap_msgpart. Returns 0 and msgpart_r on success, -1 if the section isn't valid. The same imap_msgpart can be used to open multiple messages. */ -int imap_msgpart_parse(struct mailbox *box, const char *section, - struct imap_msgpart **msgpart_r); +int imap_msgpart_parse(const char *section, struct imap_msgpart **msgpart_r); void imap_msgpart_free(struct imap_msgpart **msgpart); /* Decode MIME parts with Content-Transfer-Encoding: base64/quoted-printable @@ -46,4 +45,9 @@ int imap_msgpart_size(struct mail *mail, struct imap_msgpart *msgpart, size_t *size_r); +/* Header context is automatically created by imap_msgpart_open() and destroyed + by imap_msgpart_free(), but if you want to use the same imap_msgpart across + multiple mailboxes, you need to close the part before closing the mailbox. */ +void imap_msgpart_close_mailbox(struct imap_msgpart *msgpart); + #endif From dovecot at dovecot.org Mon Aug 13 02:51:20 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 02:51:20 +0300 Subject: dovecot-2.2: imap: FETCH API updated to allow using the same par... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/00be97a2139a changeset: 14889:00be97a2139a user: Timo Sirainen date: Mon Aug 13 02:51:09 2012 +0300 description: imap: FETCH API updated to allow using the same parsed FETCH in multiple mailboxes. This is in preparation for NOTIFY extension. diffstat: src/imap/cmd-fetch.c | 79 +++++++++++----- src/imap/cmd-select.c | 41 +++++--- src/imap/imap-fetch-body.c | 33 +++--- src/imap/imap-fetch.c | 216 ++++++++++++++++++++++++++------------------ src/imap/imap-fetch.h | 38 +++++-- 5 files changed, 246 insertions(+), 161 deletions(-) diffs (truncated from 858 to 300 lines): diff -r cf79ab812651 -r 00be97a2139a src/imap/cmd-fetch.c --- a/src/imap/cmd-fetch.c Mon Aug 13 02:41:08 2012 +0300 +++ b/src/imap/cmd-fetch.c Mon Aug 13 02:51:09 2012 +0300 @@ -21,6 +21,28 @@ }; static bool +imap_fetch_cmd_init_handler(struct imap_fetch_context *ctx, + struct client_command_context *cmd, + const char *name, const struct imap_arg **args) +{ + struct imap_fetch_init_context init_ctx; + + memset(&init_ctx, 0, sizeof(init_ctx)); + init_ctx.fetch_ctx = ctx; + init_ctx.pool = ctx->ctx_pool; + init_ctx.name = name; + init_ctx.args = *args; + + if (!imap_fetch_init_handler(&init_ctx)) { + i_assert(init_ctx.error != NULL); + client_send_command_error(cmd, init_ctx.error); + return FALSE; + } + *args = init_ctx.args; + return TRUE; +} + +static bool fetch_parse_args(struct imap_fetch_context *ctx, struct client_command_context *cmd, const struct imap_arg *arg, const struct imap_arg **next_arg_r) @@ -81,7 +103,8 @@ static bool fetch_parse_modifier(struct imap_fetch_context *ctx, struct client_command_context *cmd, - const char *name, const struct imap_arg **args) + const char *name, const struct imap_arg **args, + bool *send_vanished) { const char *str; uint64_t modseq; @@ -103,7 +126,7 @@ client_send_command_error(cmd, "QRESYNC not enabled"); return FALSE; } - ctx->send_vanished = TRUE; + *send_vanished = TRUE; return TRUE; } @@ -114,10 +137,12 @@ static bool fetch_parse_modifiers(struct imap_fetch_context *ctx, struct client_command_context *cmd, - const struct imap_arg *args) + const struct imap_arg *args, bool *send_vanished_r) { const char *name; + *send_vanished_r = FALSE; + while (!IMAP_ARG_IS_EOL(args)) { if (!imap_arg_get_atom(args, &name)) { client_send_command_error(cmd, @@ -125,10 +150,11 @@ return FALSE; } args++; - if (!fetch_parse_modifier(ctx, cmd, t_str_ucase(name), &args)) + if (!fetch_parse_modifier(ctx, cmd, t_str_ucase(name), + &args, send_vanished_r)) return FALSE; } - if (ctx->send_vanished && + if (*send_vanished_r && (ctx->search_args->args->next == NULL || ctx->search_args->args->next->type != SEARCH_MODSEQ)) { client_send_command_error(cmd, @@ -144,17 +170,17 @@ static const char *ok_message = "OK Fetch completed."; const char *tagged_reply = ok_message; enum mail_error error; - bool seen_flags_changed = ctx->state.seen_flags_changed; + bool failed, seen_flags_changed = ctx->state.seen_flags_changed; if (ctx->state.skipped_expunged_msgs) { tagged_reply = "OK ["IMAP_RESP_CODE_EXPUNGEISSUED"] " "Some messages were already expunged."; } - if (imap_fetch_deinit(ctx) < 0) - ctx->state.failed = TRUE; + failed = imap_fetch_end(ctx) < 0; + imap_fetch_free(&ctx); - if (ctx->state.failed) { + if (failed) { const char *errstr; if (cmd->client->output->closed) { @@ -198,7 +224,9 @@ struct imap_fetch_context *ctx; const struct imap_arg *args, *next_arg, *list_arg; struct mail_search_args *search_args; + struct imap_fetch_qresync_args qresync_args; const char *messageset; + bool send_vanished = FALSE; int ret; if (!client_read_args(cmd, 0, 0, &args)) @@ -221,29 +249,32 @@ if (ret <= 0) return ret < 0; - ctx = imap_fetch_init(cmd, client->mailbox); - if (ctx == NULL) { - mail_search_args_unref(&search_args); - return TRUE; - } + ctx = imap_fetch_alloc(client, cmd->pool); ctx->search_args = search_args; if (!fetch_parse_args(ctx, cmd, &args[1], &next_arg) || (imap_arg_get_list(next_arg, &list_arg) && - !fetch_parse_modifiers(ctx, cmd, list_arg))) { - (void)imap_fetch_deinit(ctx); + !fetch_parse_modifiers(ctx, cmd, list_arg, &send_vanished))) { + imap_fetch_free(&ctx); return TRUE; } - if (imap_fetch_begin(ctx) == 0) { - if (imap_fetch_more(ctx, cmd) == 0) { - /* unfinished */ - cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT; + if (send_vanished) { + memset(&qresync_args, 0, sizeof(qresync_args)); + if (imap_fetch_send_vanished(client, client->mailbox, + search_args, &qresync_args) < 0) + return cmd_fetch_finish(ctx, cmd); + } - cmd->func = cmd_fetch_continue; - cmd->context = ctx; - return FALSE; - } + imap_fetch_begin_once(ctx, client->mailbox); + + if (imap_fetch_more(ctx, cmd) == 0) { + /* unfinished */ + cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT; + + cmd->func = cmd_fetch_continue; + cmd->context = ctx; + return FALSE; } return cmd_fetch_finish(ctx, cmd); } diff -r cf79ab812651 -r 00be97a2139a src/imap/cmd-select.c --- a/src/imap/cmd-select.c Mon Aug 13 02:41:08 2012 +0300 +++ b/src/imap/cmd-select.c Mon Aug 13 02:51:09 2012 +0300 @@ -219,11 +219,12 @@ return FALSE; } - ret = imap_fetch_deinit(ctx->fetch_ctx); + ret = imap_fetch_end(ctx->fetch_ctx); if (ret < 0) { client_send_storage_error(ctx->cmd, mailbox_get_storage(ctx->box)); } + imap_fetch_free(&ctx->fetch_ctx); cmd_select_finish(ctx, ret); return TRUE; } @@ -232,39 +233,45 @@ { struct imap_fetch_context *fetch_ctx; struct mail_search_args *search_args; + struct imap_fetch_qresync_args qresync_args; search_args = mail_search_build_init(); search_args->args = p_new(search_args->pool, struct mail_search_arg, 1); search_args->args->type = SEARCH_UIDSET; search_args->args->value.seqset = ctx->qresync_known_uids; - fetch_ctx = imap_fetch_init(ctx->cmd, ctx->box); - if (fetch_ctx == NULL) + memset(&qresync_args, 0, sizeof(qresync_args)); + qresync_args.qresync_sample_seqset = &ctx->qresync_sample_seqset; + qresync_args.qresync_sample_uidset = &ctx->qresync_sample_uidset; + + if (imap_fetch_send_vanished(ctx->cmd->client, ctx->box, + search_args, &qresync_args) < 0) { + mail_search_args_unref(&search_args); return -1; + } + fetch_ctx = imap_fetch_alloc(ctx->cmd->client, ctx->cmd->pool); fetch_ctx->search_args = search_args; - fetch_ctx->send_vanished = TRUE; - fetch_ctx->qresync_sample_seqset = &ctx->qresync_sample_seqset; - fetch_ctx->qresync_sample_uidset = &ctx->qresync_sample_uidset; imap_fetch_add_changed_since(fetch_ctx, ctx->qresync_modseq); imap_fetch_init_nofail_handler(fetch_ctx, imap_fetch_uid_init); imap_fetch_init_nofail_handler(fetch_ctx, imap_fetch_flags_init); imap_fetch_init_nofail_handler(fetch_ctx, imap_fetch_modseq_init); - if (imap_fetch_begin(fetch_ctx) == 0) { - if (imap_fetch_more(fetch_ctx, ctx->cmd) == 0) { - /* unfinished */ - ctx->fetch_ctx = fetch_ctx; - ctx->cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT; + imap_fetch_begin_once(fetch_ctx, ctx->box); + if (imap_fetch_more(fetch_ctx, ctx->cmd) == 0) { + /* unfinished */ + ctx->fetch_ctx = fetch_ctx; + ctx->cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT; - ctx->cmd->func = cmd_select_continue; - ctx->cmd->context = ctx; - return 0; - } + ctx->cmd->func = cmd_select_continue; + ctx->cmd->context = ctx; + return 0; } - - return imap_fetch_deinit(fetch_ctx) < 0 ? -1 : 1; + if (imap_fetch_end(fetch_ctx) < 0) + return -1; + imap_fetch_free(&fetch_ctx); + return 1; } static int diff -r cf79ab812651 -r 00be97a2139a src/imap/imap-fetch-body.c --- a/src/imap/imap-fetch-body.c Mon Aug 13 02:41:08 2012 +0300 +++ b/src/imap/imap-fetch-body.c Mon Aug 13 02:51:09 2012 +0300 @@ -33,7 +33,7 @@ struct imap_fetch_state *state = &ctx->state; errno = state->cur_input->stream_errno; - mail_storage_set_critical(ctx->box->storage, + mail_storage_set_critical(state->cur_mail->box->storage, "read(%s) failed: %m (FETCH for mailbox %s UID %u)", i_stream_get_name(state->cur_input), mailbox_get_vname(state->cur_mail->box), state->cur_mail->uid); @@ -58,15 +58,15 @@ return str_c(str); } -static string_t *get_prefix(struct imap_fetch_context *ctx, +static string_t *get_prefix(struct imap_fetch_state *state, const struct imap_fetch_body_data *body, uoff_t size, bool has_nuls) { string_t *str; str = t_str_new(128); - if (ctx->state.cur_first) - ctx->state.cur_first = FALSE; + if (state->cur_first) + state->cur_first = FALSE; else str_append_c(str, ' '); @@ -136,10 +136,9 @@ ctx->state.cur_input = result.input; ctx->state.cur_size = result.size; ctx->state.cur_size_field = result.size_field; - ctx->state.cur_human_name = - p_strconcat(ctx->pool, "[", body->section, "]", NULL); + ctx->state.cur_human_name = body->section; - str = get_prefix(ctx, body, ctx->state.cur_size, + str = get_prefix(&ctx->state, body, ctx->state.cur_size, result.binary_decoded_input_has_nuls); o_stream_nsend(ctx->client->output, str_data(str), str_len(str)); @@ -196,7 +195,7 @@ const char *value; size_t i; - str = str_new(ctx->fetch_ctx->pool, 128); + str = str_new(ctx->pool, 128); str_append(str, prefix); str_append(str, " ("); @@ -277,7 +276,7 @@ i_assert(strncmp(ctx->name, "BODY", 4) == 0); p = ctx->name + 4; - body = p_new(ctx->fetch_ctx->pool, struct imap_fetch_body_data, 1); + body = p_new(ctx->pool, struct imap_fetch_body_data, 1); if (strncmp(p, ".PEEK", 5) == 0) p += 5; From dovecot at dovecot.org Mon Aug 13 02:57:48 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 02:57:48 +0300 Subject: dovecot-2.2: imap: Code cleanup Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cf4f7871cd5d changeset: 14890:cf4f7871cd5d user: Timo Sirainen date: Mon Aug 13 02:57:37 2012 +0300 description: imap: Code cleanup diffstat: src/imap/imap-sync.c | 50 ++++++++++++++++++++++++++++---------------------- 1 files changed, 28 insertions(+), 22 deletions(-) diffs (67 lines): diff -r 00be97a2139a -r cf4f7871cd5d src/imap/imap-sync.c --- a/src/imap/imap-sync.c Mon Aug 13 02:51:09 2012 +0300 +++ b/src/imap/imap-sync.c Mon Aug 13 02:57:37 2012 +0300 @@ -369,6 +369,32 @@ o_stream_nsend(ctx->client->output, str_data(line), str_len(line)); } +static int imap_sync_send_expunges(struct imap_sync_context *ctx, string_t *str) +{ + int ret = 1; + + if (array_is_created(&ctx->expunges)) { + /* Use a single VANISHED line */ + seq_range_array_add_range(&ctx->expunges, + ctx->sync_rec.seq1, + ctx->sync_rec.seq2); + return 1; + } + if (ctx->seq == 0) + ctx->seq = ctx->sync_rec.seq2; + for (; ctx->seq >= ctx->sync_rec.seq1; ctx->seq--) { + if (ret == 0) { + /* buffer full, continue later */ + break; + } + + str_truncate(str, 0); + str_printfa(str, "* %u EXPUNGE", ctx->seq); + ret = client_send_line_next(ctx->client, str_c(str)); + } + return ret; +} + int imap_sync_more(struct imap_sync_context *ctx) { string_t *str; @@ -418,28 +444,8 @@ break; case MAILBOX_SYNC_TYPE_EXPUNGE: ctx->client->sync_seen_expunges = TRUE; - if (array_is_created(&ctx->expunges)) { - /* Use a single VANISHED line */ - seq_range_array_add_range(&ctx->expunges, - ctx->sync_rec.seq1, - ctx->sync_rec.seq2); - ctx->messages_count -= - ctx->sync_rec.seq2 - - ctx->sync_rec.seq1 + 1; - break; - } - if (ctx->seq == 0) - ctx->seq = ctx->sync_rec.seq2; - ret = 1; - for (; ctx->seq >= ctx->sync_rec.seq1; ctx->seq--) { - if (ret == 0) - break; - - str_truncate(str, 0); - str_printfa(str, "* %u EXPUNGE", ctx->seq); - ret = client_send_line_next(ctx->client, str_c(str)); - } - if (ctx->seq < ctx->sync_rec.seq1) { + ret = imap_sync_send_expunges(ctx, str); + if (ret > 0) { /* update only after we're finished, so that the seq2 > messages_count check above doesn't break */ From dovecot at dovecot.org Mon Aug 13 05:45:50 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 05:45:50 +0300 Subject: dovecot-2.2: Compiler warning fixes Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7bda77ccd1fc changeset: 14891:7bda77ccd1fc user: Timo Sirainen date: Mon Aug 13 05:45:35 2012 +0300 description: Compiler warning fixes diffstat: src/config/config-parser.c | 2 ++ src/doveadm/dsync/dsync-brain-mailbox.c | 2 ++ src/master/main.c | 2 ++ 3 files changed, 6 insertions(+), 0 deletions(-) diffs (36 lines): diff -r cf4f7871cd5d -r 7bda77ccd1fc src/config/config-parser.c --- a/src/config/config-parser.c Mon Aug 13 02:57:37 2012 +0300 +++ b/src/config/config-parser.c Mon Aug 13 05:45:35 2012 +0300 @@ -428,6 +428,8 @@ int fd; ssize_t ret; + *error_r = NULL; + fd = open(path, O_RDONLY); if (fd == -1) { *error_r = t_strdup_printf("%s: Can't open file %s: %m", diff -r cf4f7871cd5d -r 7bda77ccd1fc src/doveadm/dsync/dsync-brain-mailbox.c --- a/src/doveadm/dsync/dsync-brain-mailbox.c Mon Aug 13 02:57:37 2012 +0300 +++ b/src/doveadm/dsync/dsync-brain-mailbox.c Mon Aug 13 05:45:35 2012 +0300 @@ -296,6 +296,8 @@ bool synced = FALSE; int ret; + *box_r = NULL; + while (dsync_mailbox_tree_iter_next(brain->local_tree_iter, &vname, &node)) { if (node->existence == DSYNC_MAILBOX_NODE_EXISTS && !guid_128_is_empty(node->mailbox_guid)) diff -r cf4f7871cd5d -r 7bda77ccd1fc src/master/main.c --- a/src/master/main.c Mon Aug 13 02:57:37 2012 +0300 +++ b/src/master/main.c Mon Aug 13 05:45:35 2012 +0300 @@ -222,6 +222,8 @@ ssize_t ret; bool found; + *pid_r = (pid_t)-1; + fd = open(path, O_RDONLY); if (fd == -1) { if (errno == ENOENT) From dovecot at dovecot.org Mon Aug 13 07:26:36 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 07:26:36 +0300 Subject: dovecot-2.1: Memory leak fix Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/963482677c0b changeset: 14663:963482677c0b user: Timo Sirainen date: Mon Aug 13 07:26:25 2012 +0300 description: Memory leak fix diffstat: src/lib/ioloop.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (21 lines): diff -r cc5f888d466a -r 963482677c0b src/lib/ioloop.c --- a/src/lib/ioloop.c Fri Aug 10 07:31:28 2012 +0300 +++ b/src/lib/ioloop.c Mon Aug 13 07:26:25 2012 +0300 @@ -357,7 +357,7 @@ (void *)timeout->callback); } if (ioloop->cur_ctx != NULL) - io_loop_context_activate(ioloop->cur_ctx); + io_loop_context_deactivate(ioloop->cur_ctx); } } @@ -594,6 +594,8 @@ { const struct ioloop_context_callback *cb; + i_assert(ctx->ioloop->cur_ctx == NULL); + ctx->ioloop->cur_ctx = ctx; io_loop_context_ref(ctx); array_foreach(&ctx->callbacks, cb) { From dovecot at dovecot.org Mon Aug 13 07:28:48 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 07:28:48 +0300 Subject: dovecot-2.2: Memory leak fixes Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0e4be366edb4 changeset: 14892:0e4be366edb4 user: Timo Sirainen date: Mon Aug 13 07:28:40 2012 +0300 description: Memory leak fixes diffstat: src/imap/imap-fetch-body.c | 28 +++++++++++++++++++++------- src/imap/imap-fetch.c | 29 ++++++++++++++--------------- 2 files changed, 35 insertions(+), 22 deletions(-) diffs (118 lines): diff -r 7bda77ccd1fc -r 0e4be366edb4 src/imap/imap-fetch-body.c --- a/src/imap/imap-fetch-body.c Mon Aug 13 05:45:35 2012 +0300 +++ b/src/imap/imap-fetch-body.c Mon Aug 13 07:28:40 2012 +0300 @@ -126,11 +126,16 @@ } static int fetch_body_msgpart(struct imap_fetch_context *ctx, struct mail *mail, - const struct imap_fetch_body_data *body) + struct imap_fetch_body_data *body) { struct imap_msgpart_open_result result; string_t *str; + if (mail == NULL) { + imap_msgpart_free(&body->msgpart); + return 1; + } + if (imap_msgpart_open(mail, body->msgpart, &result) < 0) return -1; ctx->state.cur_input = result.input; @@ -147,11 +152,16 @@ } static int fetch_binary_size(struct imap_fetch_context *ctx, struct mail *mail, - const struct imap_fetch_body_data *body) + struct imap_fetch_body_data *body) { string_t *str; size_t size; + if (mail == NULL) { + imap_msgpart_free(&body->msgpart); + return 1; + } + if (imap_msgpart_size(mail, body->msgpart, &size) < 0) return -1; @@ -325,7 +335,8 @@ /* update the section name for the imap_fetch_add_handler() */ ctx->name = p_strdup(ctx->pool, get_body_name(body)); - imap_fetch_add_handler(ctx, 0, "NIL", fetch_body_msgpart, body); + imap_fetch_add_handler(ctx, IMAP_FETCH_HANDLER_FLAG_WANT_DEINIT, + "NIL", fetch_body_msgpart, body); return TRUE; } @@ -397,10 +408,13 @@ /* update the section name for the imap_fetch_add_handler() */ ctx->name = p_strdup(ctx->pool, get_body_name(body)); - if (body->binary_size) - imap_fetch_add_handler(ctx, 0, "NIL", fetch_binary_size, body); - else - imap_fetch_add_handler(ctx, 0, "NIL", fetch_body_msgpart, body); + if (body->binary_size) { + imap_fetch_add_handler(ctx, IMAP_FETCH_HANDLER_FLAG_WANT_DEINIT, + "NIL", fetch_binary_size, body); + } else { + imap_fetch_add_handler(ctx, IMAP_FETCH_HANDLER_FLAG_WANT_DEINIT, + "NIL", fetch_body_msgpart, body); + } return TRUE; } diff -r 7bda77ccd1fc -r 0e4be366edb4 src/imap/imap-fetch.c --- a/src/imap/imap-fetch.c Mon Aug 13 05:45:35 2012 +0300 +++ b/src/imap/imap-fetch.c Mon Aug 13 07:28:40 2012 +0300 @@ -573,22 +573,15 @@ int imap_fetch_end(struct imap_fetch_context *ctx) { struct imap_fetch_state *state = &ctx->state; - const struct imap_fetch_context_handler *handler; - if (!ctx->state.fetching) - return 0; - ctx->state.fetching = FALSE; - - array_foreach(&ctx->handlers, handler) { - if (handler->want_deinit) - handler->handler(ctx, NULL, handler->context); - } - - if (!state->line_finished) { - if (imap_fetch_flush_buffer(ctx) < 0) - state->failed = TRUE; - if (o_stream_send(ctx->client->output, ")\r\n", 3) < 0) - state->failed = TRUE; + if (ctx->state.fetching) { + ctx->state.fetching = FALSE; + if (!state->line_finished) { + if (imap_fetch_flush_buffer(ctx) < 0) + state->failed = TRUE; + if (o_stream_send(ctx->client->output, ")\r\n", 3) < 0) + state->failed = TRUE; + } } if (state->cur_str != NULL) str_free(&state->cur_str); @@ -614,10 +607,16 @@ void imap_fetch_free(struct imap_fetch_context **_ctx) { struct imap_fetch_context *ctx = *_ctx; + const struct imap_fetch_context_handler *handler; *_ctx = NULL; (void)imap_fetch_end(ctx); + + array_foreach(&ctx->handlers, handler) { + if (handler->want_deinit) + handler->handler(ctx, NULL, handler->context); + } if (ctx->search_args != NULL) mail_search_args_unref(&ctx->search_args); pool_unref(&ctx->ctx_pool); From dovecot at dovecot.org Mon Aug 13 14:23:34 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 14:23:34 +0300 Subject: dovecot-2.2: mailbox_list_index=yes: Don't use indexes when iter... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5d058be4aefc changeset: 14893:5d058be4aefc user: Timo Sirainen date: Mon Aug 13 14:23:26 2012 +0300 description: mailbox_list_index=yes: Don't use indexes when iterating with MAILBOX_LIST_ITER_RAW_LIST. diffstat: src/lib-storage/list/mailbox-list-index-iter.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 0e4be366edb4 -r 5d058be4aefc src/lib-storage/list/mailbox-list-index-iter.c --- a/src/lib-storage/list/mailbox-list-index-iter.c Mon Aug 13 07:28:40 2012 +0300 +++ b/src/lib-storage/list/mailbox-list-index-iter.c Mon Aug 13 14:23:26 2012 +0300 @@ -27,7 +27,8 @@ ctx->sep = ns_sep; ctx->info_pool = pool_alloconly_create("mailbox list index iter info", 128); - if (mailbox_list_index_refresh(ctx->ctx.list) < 0) { + if ((flags & MAILBOX_LIST_ITER_RAW_LIST) != 0 || + mailbox_list_index_refresh(ctx->ctx.list) < 0) { /* no indexing */ ctx->backend_ctx = ilist->module_ctx.super. iter_init(list, patterns, flags); From dovecot at dovecot.org Mon Aug 13 15:03:57 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 15:03:57 +0300 Subject: dovecot-2.2: Added MOVE extension to capabilities. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4d6ea3b30235 changeset: 14894:4d6ea3b30235 user: Timo Sirainen date: Mon Aug 13 15:03:46 2012 +0300 description: Added MOVE extension to capabilities. I guess the draft is close enough to being ready now. diffstat: configure.in | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 5d058be4aefc -r 4d6ea3b30235 configure.in --- a/configure.in Mon Aug 13 14:23:26 2012 +0300 +++ b/configure.in Mon Aug 13 15:03:46 2012 +0300 @@ -2718,7 +2718,7 @@ dnl IDLE doesn't really belong to banner. It's there just to make Blackberries dnl happy, because otherwise BIS server disables push email. capability_banner="IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE" -capability="$capability_banner SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE BINARY" +capability="$capability_banner SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE BINARY MOVE" AC_DEFINE_UNQUOTED(CAPABILITY_STRING, "$capability", IMAP capabilities) AC_DEFINE_UNQUOTED(CAPABILITY_BANNER_STRING, "$capability_banner", IMAP capabilities advertised in banner) From dovecot at dovecot.org Mon Aug 13 15:09:41 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 15:09:41 +0300 Subject: dovecot-2.2: imap: If imap_capability setting is set explicitly,... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/722dba791812 changeset: 14895:722dba791812 user: Timo Sirainen date: Mon Aug 13 15:09:30 2012 +0300 description: imap: If imap_capability setting is set explicitly, don't automatically add SEARCH=FUZZY. diffstat: src/imap/imap-client.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (25 lines): diff -r 4d6ea3b30235 -r 722dba791812 src/imap/imap-client.c --- a/src/imap/imap-client.c Mon Aug 13 15:03:46 2012 +0300 +++ b/src/imap/imap-client.c Mon Aug 13 15:09:30 2012 +0300 @@ -42,6 +42,7 @@ struct client *client; const char *ident; pool_t pool; + bool explicit_capability = FALSE; /* always use nonblocking I/O */ net_set_nonblock(fd_in, TRUE); @@ -84,11 +85,12 @@ else if (*set->imap_capability != '+') str_append(client->capability_string, set->imap_capability); else { + explicit_capability = TRUE; str_append(client->capability_string, CAPABILITY_STRING); str_append_c(client->capability_string, ' '); str_append(client->capability_string, set->imap_capability + 1); } - if (user->fuzzy_search) { + if (user->fuzzy_search && !explicit_capability) { /* Enable FUZZY capability only when it actually has a chance of working */ str_append(client->capability_string, " SEARCH=FUZZY"); From dovecot at dovecot.org Mon Aug 13 15:23:46 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 15:23:46 +0300 Subject: dovecot-2.2: lib-index: Added mail_index_view_dup_private() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d76732546de3 changeset: 14896:d76732546de3 user: Timo Sirainen date: Mon Aug 13 15:12:41 2012 +0300 description: lib-index: Added mail_index_view_dup_private() diffstat: src/lib-index/mail-index-view-private.h | 2 ++ src/lib-index/mail-index-view.c | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 0 deletions(-) diffs (37 lines): diff -r 722dba791812 -r d76732546de3 src/lib-index/mail-index-view-private.h --- a/src/lib-index/mail-index-view-private.h Mon Aug 13 15:09:30 2012 +0300 +++ b/src/lib-index/mail-index-view-private.h Mon Aug 13 15:12:41 2012 +0300 @@ -83,6 +83,8 @@ struct mail_index_map *map); void mail_index_view_clone(struct mail_index_view *dest, const struct mail_index_view *src); +struct mail_index_view * +mail_index_view_dup_private(const struct mail_index_view *src); void mail_index_view_ref(struct mail_index_view *view); void mail_index_view_unref_maps(struct mail_index_view *view); void mail_index_view_add_hidden_transaction(struct mail_index_view *view, diff -r 722dba791812 -r d76732546de3 src/lib-index/mail-index-view.c --- a/src/lib-index/mail-index-view.c Mon Aug 13 15:09:30 2012 +0300 +++ b/src/lib-index/mail-index-view.c Mon Aug 13 15:12:41 2012 +0300 @@ -6,6 +6,21 @@ #include "mail-index-view-private.h" #include "mail-transaction-log.h" +struct mail_index_view * +mail_index_view_dup_private(const struct mail_index_view *src) +{ + struct mail_index_view *view; + struct mail_index_map *map; + + view = i_new(struct mail_index_view, 1); + mail_index_view_clone(view, src); + + map = mail_index_map_clone(view->map); + mail_index_unmap(&view->map); + view->map = map; + return view; +} + void mail_index_view_clone(struct mail_index_view *dest, const struct mail_index_view *src) { From dovecot at dovecot.org Mon Aug 13 15:23:46 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 15:23:46 +0300 Subject: dovecot-2.2: mailbox_list_index=yes: Don't log an error when ver... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/026b688b379f changeset: 14897:026b688b379f user: Timo Sirainen date: Mon Aug 13 15:15:07 2012 +0300 description: mailbox_list_index=yes: Don't log an error when verifying existence of already deleted mailbox. diffstat: src/lib-storage/index/index-sync.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r d76732546de3 -r 026b688b379f src/lib-storage/index/index-sync.c --- a/src/lib-storage/index/index-sync.c Mon Aug 13 15:12:41 2012 +0300 +++ b/src/lib-storage/index/index-sync.c Mon Aug 13 15:15:07 2012 +0300 @@ -489,6 +489,8 @@ MAILBOX_LIST_PATH_TYPE_INDEX); path = t_strconcat(dir, "/", box->index_prefix, ".log", NULL); if (stat(path, &st) < 0) { + if (errno == ENOENT) + return 1; mail_storage_set_critical(box->storage, "stat(%s) failed: %m", path); return -1; From dovecot at dovecot.org Mon Aug 13 15:23:46 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 15:23:46 +0300 Subject: dovecot-2.2: lib-storage: Added mailbox-list-notify API for trac... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a16d77a075bb changeset: 14898:a16d77a075bb user: Timo Sirainen date: Mon Aug 13 15:20:33 2012 +0300 description: lib-storage: Added mailbox-list-notify API for tracking changes in all mailboxes. Requires mailbox_list_index=yes to work. diffstat: src/lib-storage/Makefile.am | 2 + src/lib-storage/index/imapc/imapc-list.c | 3 +- src/lib-storage/index/shared/shared-list.c | 3 +- src/lib-storage/list/Makefile.am | 3 + src/lib-storage/list/mailbox-list-fs.c | 3 +- src/lib-storage/list/mailbox-list-index-notify.c | 699 +++++++++++++++++++++++ src/lib-storage/list/mailbox-list-index-status.c | 52 +- src/lib-storage/list/mailbox-list-index-sync.c | 32 + src/lib-storage/list/mailbox-list-index.c | 49 +- src/lib-storage/list/mailbox-list-index.h | 25 +- src/lib-storage/list/mailbox-list-maildir.c | 6 +- src/lib-storage/list/mailbox-list-none.c | 3 +- src/lib-storage/list/mailbox-list-notify-tree.c | 129 ++++ src/lib-storage/list/mailbox-list-notify-tree.h | 27 + src/lib-storage/mailbox-list-notify.c | 35 + src/lib-storage/mailbox-list-notify.h | 58 + src/lib-storage/mailbox-list-private.h | 12 + 17 files changed, 1111 insertions(+), 30 deletions(-) diffs (truncated from 1506 to 300 lines): diff -r 026b688b379f -r a16d77a075bb src/lib-storage/Makefile.am --- a/src/lib-storage/Makefile.am Mon Aug 13 15:15:07 2012 +0300 +++ b/src/lib-storage/Makefile.am Mon Aug 13 15:20:33 2012 +0300 @@ -43,6 +43,7 @@ mailbox-keywords.c \ mailbox-list.c \ mailbox-list-iter.c \ + mailbox-list-notify.c \ mailbox-search-result.c \ mailbox-tree.c \ mailbox-uidvalidity.c @@ -70,6 +71,7 @@ mailbox-guid-cache.h \ mailbox-list.h \ mailbox-list-private.h \ + mailbox-list-notify.h \ mailbox-search-result-private.h \ mailbox-tree.h \ mailbox-uidvalidity.h diff -r 026b688b379f -r a16d77a075bb src/lib-storage/index/imapc/imapc-list.c --- a/src/lib-storage/index/imapc/imapc-list.c Mon Aug 13 15:15:07 2012 +0300 +++ b/src/lib-storage/index/imapc/imapc-list.c Mon Aug 13 15:20:33 2012 +0300 @@ -720,6 +720,7 @@ imapc_list_delete_mailbox, imapc_list_delete_dir, imapc_list_delete_symlink, - imapc_list_rename_mailbox + imapc_list_rename_mailbox, + NULL, NULL, NULL, NULL } }; diff -r 026b688b379f -r a16d77a075bb src/lib-storage/index/shared/shared-list.c --- a/src/lib-storage/index/shared/shared-list.c Mon Aug 13 15:15:07 2012 +0300 +++ b/src/lib-storage/index/shared/shared-list.c Mon Aug 13 15:20:33 2012 +0300 @@ -359,6 +359,7 @@ shared_list_delete_mailbox, shared_list_delete_dir, shared_list_delete_symlink, - shared_list_rename_mailbox + shared_list_rename_mailbox, + NULL, NULL, NULL, NULL } }; diff -r 026b688b379f -r a16d77a075bb src/lib-storage/list/Makefile.am --- a/src/lib-storage/list/Makefile.am Mon Aug 13 15:15:07 2012 +0300 +++ b/src/lib-storage/list/Makefile.am Mon Aug 13 15:20:33 2012 +0300 @@ -15,11 +15,13 @@ mailbox-list-fs-iter.c \ mailbox-list-index.c \ mailbox-list-index-iter.c \ + mailbox-list-index-notify.c \ mailbox-list-index-status.c \ mailbox-list-index-sync.c \ mailbox-list-maildir.c \ mailbox-list-maildir-iter.c \ mailbox-list-none.c \ + mailbox-list-notify-tree.c \ mailbox-list-subscriptions.c \ subscription-file.c @@ -28,6 +30,7 @@ mailbox-list-fs.h \ mailbox-list-index.h \ mailbox-list-maildir.h \ + mailbox-list-notify-tree.h \ mailbox-list-subscriptions.h \ subscription-file.h diff -r 026b688b379f -r a16d77a075bb src/lib-storage/list/mailbox-list-fs.c --- a/src/lib-storage/list/mailbox-list-fs.c Mon Aug 13 15:15:07 2012 +0300 +++ b/src/lib-storage/list/mailbox-list-fs.c Mon Aug 13 15:20:33 2012 +0300 @@ -651,6 +651,7 @@ fs_list_delete_mailbox, fs_list_delete_dir, mailbox_list_delete_symlink_default, - fs_list_rename_mailbox + fs_list_rename_mailbox, + NULL, NULL, NULL, NULL } }; diff -r 026b688b379f -r a16d77a075bb src/lib-storage/list/mailbox-list-index-notify.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-storage/list/mailbox-list-index-notify.c Mon Aug 13 15:20:33 2012 +0300 @@ -0,0 +1,699 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "ioloop.h" +#include "str.h" +#include "mail-index-private.h" +#include "mail-transaction-log-private.h" +#include "mail-storage.h" +#include "mailbox-list-notify.h" +#include "mailbox-list-notify-tree.h" +#include "mailbox-list-index.h" + +#include + +#define NOTIFY_DELAY_MSECS 500 + +enum ilist_ext_type { + ILIST_EXT_NONE, + ILIST_EXT_BASE, + ILIST_EXT_MSGS, + ILIST_EXT_HIGHESTMODSEQ, + ILIST_EXT_UNKNOWN +}; + +struct mailbox_list_notify_rename { + uint32_t old_uid, new_uid; +}; + +struct mailbox_list_inotify_entry { + uint32_t uid; + guid_128_t guid; + bool expunge; +}; + +struct mailbox_list_notify_index { + struct mailbox_list_notify notify; + + struct mailbox_list_notify_tree *tree; + struct mail_index_view *view, *old_view; + struct mail_index_view_sync_ctx *sync_ctx; + enum ilist_ext_type cur_ext; + uint32_t cur_ext_id; + + void (*wait_callback)(void *context); + void *wait_context; + struct io *io_wait; + struct timeout *to_wait, *to_notify; + + ARRAY_TYPE(seq_range) new_uids, expunged_uids, changed_uids; + ARRAY_DEFINE(renames, struct mailbox_list_notify_rename); + struct seq_range_iter new_uids_iter, expunged_uids_iter; + struct seq_range_iter changed_uids_iter; + unsigned int new_uids_n, expunged_uids_n, changed_uids_n; + unsigned int rename_idx; + + struct mailbox_list_notify_rec notify_rec; + string_t *rec_name; + + struct stat last_st; + + unsigned int initialized:1; + unsigned int read_failed:1; +}; + +int mailbox_list_index_notify_init(struct mailbox_list *list, + enum mailbox_list_notify_event mask, + struct mailbox_list_notify **notify_r) +{ + struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list); + struct mailbox_list_notify_index *inotify; + + if (ilist == NULL) { + /* can't do this without mailbox list indexes */ + return -1; + } + + (void)mailbox_list_index_refresh(list); + + inotify = i_new(struct mailbox_list_notify_index, 1); + inotify->notify.list = list; + inotify->notify.mask = mask; + inotify->view = mail_index_view_open(ilist->index); + inotify->old_view = mail_index_view_dup_private(inotify->view); + inotify->tree = mailbox_list_notify_tree_init(list); + i_array_init(&inotify->new_uids, 8); + i_array_init(&inotify->expunged_uids, 8); + i_array_init(&inotify->changed_uids, 16); + i_array_init(&inotify->renames, 16); + inotify->rec_name = str_new(default_pool, 64); + + *notify_r = &inotify->notify; + return 1; +} + +void mailbox_list_index_notify_deinit(struct mailbox_list_notify *notify) +{ + struct mailbox_list_notify_index *inotify = + (struct mailbox_list_notify_index *)notify; + bool b; + + if (inotify->io_wait != NULL) + io_remove(&inotify->io_wait); + if (inotify->to_wait != NULL) + timeout_remove(&inotify->to_wait); + if (inotify->to_notify != NULL) + timeout_remove(&inotify->to_notify); + if (inotify->sync_ctx != NULL) + (void)mail_index_view_sync_commit(&inotify->sync_ctx, &b); + mail_index_view_close(&inotify->view); + mail_index_view_close(&inotify->old_view); + mailbox_list_notify_tree_deinit(&inotify->tree); + array_free(&inotify->new_uids); + array_free(&inotify->expunged_uids); + array_free(&inotify->changed_uids); + array_free(&inotify->renames); + str_free(&inotify->rec_name); + i_free(inotify); +} + +static struct mailbox_list_index_node * +notify_lookup_guid(struct mailbox_list_notify_index *inotify, + struct mail_index_view *view, + uint32_t uid, enum mailbox_status_items items, + struct mailbox_status *status_r, guid_128_t guid_r) +{ + struct mailbox_list_index *ilist = + INDEX_LIST_CONTEXT(inotify->notify.list); + struct mailbox_list_index_node *index_node; + uint32_t seq; + + if (!mail_index_lookup_seq(view, uid, &seq)) + return NULL; + + index_node = mailbox_list_index_lookup_uid(ilist, uid); + if (index_node == NULL) { + /* re-parse the index list using the given view. we could be + jumping here between old and new view. */ + (void)mailbox_list_index_parse(ilist, view, FALSE); + index_node = mailbox_list_index_lookup_uid(ilist, uid); + if (index_node == NULL) + return NULL; + } + + /* get GUID */ + memset(status_r, 0, sizeof(*status_r)); + memset(guid_r, 0, GUID_128_SIZE); + (void)mailbox_list_index_status(inotify->notify.list, view, seq, + items, status_r, guid_r); + return index_node; +} + +static void notify_update_stat(struct mailbox_list_notify_index *inotify) +{ + struct mailbox_list_index *ilist = + INDEX_LIST_CONTEXT(inotify->notify.list); + const char *path = ilist->index->log->filepath; + + if (stat(path, &inotify->last_st) < 0 && errno != ENOENT) { + i_error("stat(%s) failed: %m", path); + mailbox_list_index_notify_wait(&inotify->notify, NULL, NULL); + } +} + +static void +mailbox_list_index_notify_sync_init(struct mailbox_list_notify_index *inotify) +{ + struct mail_index_view_sync_rec sync_rec; + + notify_update_stat(inotify); + (void)mail_index_refresh(inotify->view->index); + + /* sync the view so that map extensions gets updated */ + inotify->sync_ctx = mail_index_view_sync_begin(inotify->view, 0); + mail_transaction_log_view_mark(inotify->view->log_view); + while (mail_index_view_sync_next(inotify->sync_ctx, &sync_rec)) ; + mail_transaction_log_view_rewind(inotify->view->log_view); + + inotify->cur_ext = ILIST_EXT_NONE; + inotify->cur_ext_id = (uint32_t)-1; +} + +static bool notify_ext_rec(struct mailbox_list_notify_index *inotify, + uint32_t uid) +{ + struct mailbox_list_notify *notify = &inotify->notify; + + switch (inotify->cur_ext) { + case ILIST_EXT_NONE: + i_unreached(); + case ILIST_EXT_BASE: + /* UIDVALIDITY changed */ + if ((notify->mask & MAILBOX_LIST_NOTIFY_UIDVALIDITY) == 0) + return FALSE; + break; + case ILIST_EXT_MSGS: + /* APPEND, EXPUNGE, \Seen or \Recent flag change */ + if ((notify->mask & MAILBOX_LIST_NOTIFY_STATUS) == 0) + return FALSE; + break; + case ILIST_EXT_HIGHESTMODSEQ: + /* when this doesn't come with EXT_MSGS update, + it can only be a flag change or an explicit + modseq change */ + if ((notify->mask & MAILBOX_LIST_NOTIFY_MODSEQ_CHANGES) == 0) + return FALSE; + break; + case ILIST_EXT_UNKNOWN: + return FALSE; + } + seq_range_array_add(&inotify->changed_uids, uid); + return TRUE; +} + +static int +mailbox_list_index_notify_read_next(struct mailbox_list_notify_index *inotify) +{ From dovecot at dovecot.org Mon Aug 13 15:23:46 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 13 Aug 2012 15:23:46 +0300 Subject: dovecot-2.2: imap: Implemented NOTIFY extension. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f9d0ea98157f changeset: 14899:f9d0ea98157f user: Timo Sirainen date: Mon Aug 13 15:23:32 2012 +0300 description: imap: Implemented NOTIFY extension. Requires mailbox_list_index=yes to work (and to show up in capabilities). SubscriptionChange event is still unimplemented. diffstat: src/imap/Makefile.am | 5 + src/imap/cmd-cancelupdate.c | 4 +- src/imap/cmd-fetch.c | 23 +- src/imap/cmd-idle.c | 2 +- src/imap/cmd-list.c | 29 +- src/imap/cmd-notify.c | 542 ++++++++++++++++++++++++++++++++++++++++++++ src/imap/cmd-search.c | 5 +- src/imap/cmd-select.c | 9 +- src/imap/cmd-sort.c | 10 +- src/imap/imap-client.c | 105 +++++--- src/imap/imap-client.h | 13 +- src/imap/imap-commands.c | 1 + src/imap/imap-commands.h | 1 + src/imap/imap-fetch.c | 97 +++++-- src/imap/imap-fetch.h | 12 +- src/imap/imap-list.c | 35 ++ src/imap/imap-list.h | 7 + src/imap/imap-notify.c | 518 ++++++++++++++++++++++++++++++++++++++++++ src/imap/imap-notify.h | 71 +++++ src/imap/imap-search.c | 70 +++++- src/imap/imap-search.h | 5 + src/imap/imap-sync.c | 298 +++++++++++++++++------ src/imap/main.c | 2 +- 23 files changed, 1665 insertions(+), 199 deletions(-) diffs (truncated from 2672 to 300 lines): diff -r a16d77a075bb -r f9d0ea98157f src/imap/Makefile.am --- a/src/imap/Makefile.am Mon Aug 13 15:20:33 2012 +0300 +++ b/src/imap/Makefile.am Mon Aug 13 15:23:32 2012 +0300 @@ -43,6 +43,7 @@ cmd-lsub.c \ cmd-namespace.c \ cmd-noop.c \ + cmd-notify.c \ cmd-rename.c \ cmd-search.c \ cmd-select.c \ @@ -64,6 +65,8 @@ imap-expunge.c \ imap-fetch.c \ imap-fetch-body.c \ + imap-list.c \ + imap-notify.c \ imap-search.c \ imap-search-args.c \ imap-settings.c \ @@ -79,6 +82,8 @@ imap-common.h \ imap-expunge.h \ imap-fetch.h \ + imap-list.h \ + imap-notify.h \ imap-search.h \ imap-search-args.h \ imap-settings.h \ diff -r a16d77a075bb -r f9d0ea98157f src/imap/cmd-cancelupdate.c --- a/src/imap/cmd-cancelupdate.c Mon Aug 13 15:20:33 2012 +0300 +++ b/src/imap/cmd-cancelupdate.c Mon Aug 13 15:23:32 2012 +0300 @@ -1,6 +1,7 @@ /* Copyright (c) 2008-2012 Dovecot authors, see the included COPYING file */ #include "imap-common.h" +#include "imap-search.h" #include "imap-commands.h" static bool client_search_update_cancel(struct client *client, const char *tag) @@ -12,8 +13,7 @@ if (update == NULL) return FALSE; - i_free(update->tag); - mailbox_search_result_free(&update->result); + imap_search_update_free(update); array_delete(&client->search_updates, idx, 1); return TRUE; } diff -r a16d77a075bb -r f9d0ea98157f src/imap/cmd-fetch.c --- a/src/imap/cmd-fetch.c Mon Aug 13 15:20:33 2012 +0300 +++ b/src/imap/cmd-fetch.c Mon Aug 13 15:23:32 2012 +0300 @@ -103,6 +103,7 @@ static bool fetch_parse_modifier(struct imap_fetch_context *ctx, struct client_command_context *cmd, + struct mail_search_args *search_args, const char *name, const struct imap_arg **args, bool *send_vanished) { @@ -117,7 +118,7 @@ return FALSE; } *args += 1; - imap_fetch_add_changed_since(ctx, modseq); + imap_fetch_add_changed_since(ctx, search_args, modseq); return TRUE; } if (strcmp(name, "VANISHED") == 0 && cmd->uid) { @@ -137,6 +138,7 @@ static bool fetch_parse_modifiers(struct imap_fetch_context *ctx, struct client_command_context *cmd, + struct mail_search_args *search_args, const struct imap_arg *args, bool *send_vanished_r) { const char *name; @@ -150,13 +152,14 @@ return FALSE; } args++; - if (!fetch_parse_modifier(ctx, cmd, t_str_ucase(name), + if (!fetch_parse_modifier(ctx, cmd, search_args, + t_str_ucase(name), &args, send_vanished_r)) return FALSE; } if (*send_vanished_r && - (ctx->search_args->args->next == NULL || - ctx->search_args->args->next->type != SEARCH_MODSEQ)) { + (search_args->args->next == NULL || + search_args->args->next->type != SEARCH_MODSEQ)) { client_send_command_error(cmd, "VANISHED used without CHANGEDSINCE"); return FALSE; @@ -250,23 +253,27 @@ return ret < 0; ctx = imap_fetch_alloc(client, cmd->pool); - ctx->search_args = search_args; if (!fetch_parse_args(ctx, cmd, &args[1], &next_arg) || (imap_arg_get_list(next_arg, &list_arg) && - !fetch_parse_modifiers(ctx, cmd, list_arg, &send_vanished))) { + !fetch_parse_modifiers(ctx, cmd, search_args, list_arg, + &send_vanished))) { imap_fetch_free(&ctx); + mail_search_args_unref(&search_args); return TRUE; } if (send_vanished) { memset(&qresync_args, 0, sizeof(qresync_args)); if (imap_fetch_send_vanished(client, client->mailbox, - search_args, &qresync_args) < 0) + search_args, &qresync_args) < 0) { + mail_search_args_unref(&search_args); return cmd_fetch_finish(ctx, cmd); + } } - imap_fetch_begin_once(ctx, client->mailbox); + imap_fetch_begin(ctx, client->mailbox, search_args); + mail_search_args_unref(&search_args); if (imap_fetch_more(ctx, cmd) == 0) { /* unfinished */ diff -r a16d77a075bb -r f9d0ea98157f src/imap/cmd-idle.c --- a/src/imap/cmd-idle.c Mon Aug 13 15:20:33 2012 +0300 +++ b/src/imap/cmd-idle.c Mon Aug 13 15:23:32 2012 +0300 @@ -115,7 +115,7 @@ static void keepalive_timeout(struct cmd_idle_context *ctx) { - if (ctx->client->output_lock != NULL) { + if (ctx->client->output_locked) { /* it's busy sending output */ return; } diff -r a16d77a075bb -r f9d0ea98157f src/imap/cmd-list.c --- a/src/imap/cmd-list.c Mon Aug 13 15:20:33 2012 +0300 +++ b/src/imap/cmd-list.c Mon Aug 13 15:23:32 2012 +0300 @@ -9,6 +9,7 @@ #include "imap-match.h" #include "imap-status.h" #include "imap-commands.h" +#include "imap-list.h" #include "mail-namespace.h" struct cmd_list_context { @@ -49,40 +50,22 @@ if ((ctx->list_flags & MAILBOX_LIST_ITER_RETURN_CHILDREN) == 0) flags &= ~(MAILBOX_CHILDREN|MAILBOX_NOCHILDREN); - if ((flags & MAILBOX_SUBSCRIBED) != 0 && - (ctx->list_flags & MAILBOX_LIST_ITER_RETURN_SUBSCRIBED) != 0) - str_append(str, "\\Subscribed "); + if ((ctx->list_flags & MAILBOX_LIST_ITER_RETURN_SUBSCRIBED) == 0) + flags &= ~MAILBOX_SUBSCRIBED; if ((flags & MAILBOX_CHILD_SUBSCRIBED) != 0 && (flags & MAILBOX_SUBSCRIBED) == 0 && !ctx->used_listext) { /* LSUB uses \Noselect for this */ flags |= MAILBOX_NOSELECT; } - - if ((flags & MAILBOX_NOSELECT) != 0) - str_append(str, "\\Noselect "); - if ((flags & MAILBOX_NONEXISTENT) != 0) - str_append(str, "\\NonExistent "); - - if ((flags & MAILBOX_CHILDREN) != 0) - str_append(str, "\\HasChildren "); - else if ((flags & MAILBOX_NOINFERIORS) != 0) - str_append(str, "\\NoInferiors "); - else if ((flags & MAILBOX_NOCHILDREN) != 0) - str_append(str, "\\HasNoChildren "); - - if ((flags & MAILBOX_MARKED) != 0) - str_append(str, "\\Marked "); - if ((flags & MAILBOX_UNMARKED) != 0) - str_append(str, "\\UnMarked "); + imap_mailbox_flags2str(str, flags); if ((ctx->list_flags & MAILBOX_LIST_ITER_RETURN_SPECIALUSE) != 0 && special_use != NULL) { + if (str_len(str) != orig_len) + str_append_c(str, ' '); str_append(str, special_use); - str_append_c(str, ' '); } - if (str_len(str) != orig_len) - str_truncate(str, str_len(str)-1); } static void diff -r a16d77a075bb -r f9d0ea98157f src/imap/cmd-notify.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/imap/cmd-notify.c Mon Aug 13 15:23:32 2012 +0300 @@ -0,0 +1,542 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "imap-common.h" +#include "str.h" +#include "imap-quote.h" +#include "imap-commands.h" +#include "imap-fetch.h" +#include "imap-list.h" +#include "imap-status.h" +#include "imap-notify.h" + +#define IMAP_NOTIFY_MAX_NAMES_PER_NS 100 + +static const char *imap_notify_event_names[] = { + "MessageNew", "MessageExpunge", "FlagChange", "AnnotationChange", + "MailboxName", "SubscriptionChange", "MailboxMetadataChange", + "ServerMetadataChange" +}; + +static int +cmd_notify_parse_event(const struct imap_arg *arg, + enum imap_notify_event *event_r) +{ + const char *str; + unsigned int i; + + if (!imap_arg_get_atom(arg, &str)) + return -1; + + for (i = 0; i < N_ELEMENTS(imap_notify_event_names); i++) { + if (strcasecmp(str, imap_notify_event_names[i]) == 0) { + *event_r = (enum imap_notify_event)(1 << i); + return 0; + } + } + return -1; +} + +static int +cmd_notify_parse_fetch(struct imap_notify_context *ctx, + const struct imap_arg *list) +{ + return imap_fetch_att_list_parse(ctx->client, ctx->pool, list, + &ctx->fetch_ctx, &ctx->error); +} + +static int +cmd_notify_set_selected(struct imap_notify_context *ctx, + const struct imap_arg *events) +{ +#define EV_NEW_OR_EXPUNGE \ + (IMAP_NOTIFY_EVENT_MESSAGE_NEW | IMAP_NOTIFY_EVENT_MESSAGE_EXPUNGE) + const struct imap_arg *list, *fetch_att_list; + const char *str; + enum imap_notify_event event; + + if (imap_arg_get_atom(events, &str) && + strcasecmp(str, "NONE") == 0) { + /* no events for selected mailbox. this is also the default + when NOTIFY command doesn't specify it explicitly */ + return 0; + } + + if (!imap_arg_get_list(events, &list)) + return -1; + + for (; list->type != IMAP_ARG_EOL; list++) { + if (cmd_notify_parse_event(list, &event) < 0) + return -1; + ctx->selected_events |= event; + ctx->global_used_events |= event; + + if (event == IMAP_NOTIFY_EVENT_MESSAGE_NEW && + imap_arg_get_list(&list[1], &fetch_att_list)) { + /* MessageNew: list of fetch-att */ + if (cmd_notify_parse_fetch(ctx, fetch_att_list) < 0) + return -1; + list++; + } + } + + /* if MessageNew or MessageExpunge is specified, both of them must */ + if ((ctx->selected_events & EV_NEW_OR_EXPUNGE) != 0 && + (ctx->selected_events & EV_NEW_OR_EXPUNGE) != EV_NEW_OR_EXPUNGE) { + ctx->error = "MessageNew and MessageExpunge must be together"; + return -1; + } + + /* if FlagChange or AnnotationChange is specified, + MessageNew and MessageExpunge must also be specified */ + if ((ctx->selected_events & + (IMAP_NOTIFY_EVENT_FLAG_CHANGE | + IMAP_NOTIFY_EVENT_ANNOTATION_CHANGE)) != 0 && + (ctx->selected_events & IMAP_NOTIFY_EVENT_MESSAGE_EXPUNGE) == 0) { + ctx->error = "FlagChange requires MessageNew and MessageExpunge"; + return -1; + } + return 0; +} From dovecot at dovecot.org Tue Aug 14 03:03:45 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Aug 2012 03:03:45 +0300 Subject: dovecot-2.1: imap LIST: Don't set \haschildren flag for namespac... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/68a62d79b1b4 changeset: 14664:68a62d79b1b4 user: Timo Sirainen date: Tue Aug 14 01:54:34 2012 +0300 description: imap LIST: Don't set \haschildren flag for namespace prefix if it has list=no diffstat: src/imap/cmd-list.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (18 lines): diff -r 963482677c0b -r 68a62d79b1b4 src/imap/cmd-list.c --- a/src/imap/cmd-list.c Mon Aug 13 07:26:25 2012 +0300 +++ b/src/imap/cmd-list.c Tue Aug 14 01:54:34 2012 +0300 @@ -456,10 +456,12 @@ if (ctx->cur_ns_send_prefix) list_namespace_send_prefix(ctx, TRUE); - /* if there's a namespace with this name, list it as + /* if there's a list=yes namespace with this name, list it as having children */ ns = mail_namespace_find_prefix_nosep(ctx->ns, name); - if (ns != NULL) { + if (ns != NULL && + (ns->flags & (NAMESPACE_FLAG_LIST_PREFIX | + NAMESPACE_FLAG_LIST_CHILDREN)) != 0) { flags |= MAILBOX_CHILDREN; flags &= ~MAILBOX_NOCHILDREN; array_append(&ctx->ns_prefixes_listed, &ns, 1); From dovecot at dovecot.org Tue Aug 14 03:03:45 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Aug 2012 03:03:45 +0300 Subject: dovecot-2.1: lib-storage: If alias_for references inbox=yes name... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/0d3f2902fb68 changeset: 14665:0d3f2902fb68 user: Timo Sirainen date: Tue Aug 14 03:01:07 2012 +0300 description: lib-storage: If alias_for references inbox=yes namespace, copy the inbox=yes to the alias ns. So even though this still doesn't allow giving multiple inbox=yes settings in configuration file, it's now possible for multiple namespaces to have them. They just need to point to the exact same INBOX. diffstat: src/lib-storage/mail-namespace.c | 11 +++++++++-- src/lib-storage/mail-namespace.h | 5 +++-- 2 files changed, 12 insertions(+), 4 deletions(-) diffs (52 lines): diff -r 68a62d79b1b4 -r 0d3f2902fb68 src/lib-storage/mail-namespace.c --- a/src/lib-storage/mail-namespace.c Tue Aug 14 01:54:34 2012 +0300 +++ b/src/lib-storage/mail-namespace.c Tue Aug 14 03:01:07 2012 +0300 @@ -178,6 +178,11 @@ if (!namespace_is_valid_alias_storage(ns, error_r)) return -1; + if ((ns->alias_for->flags & NAMESPACE_FLAG_INBOX_USER) != 0) { + /* copy inbox=yes */ + ns->flags |= NAMESPACE_FLAG_INBOX_USER; + } + ns->alias_chain_next = ns->alias_for->alias_chain_next; ns->alias_for->alias_chain_next = ns; } @@ -200,10 +205,9 @@ ns->prefix); return FALSE; } - if (namespace_set_alias_for(ns, namespaces, error_r) < 0) - return FALSE; if ((ns->flags & NAMESPACE_FLAG_HIDDEN) == 0) visible_namespaces = TRUE; + /* check the inbox=yes status before alias_for changes it */ if ((ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) { if (inbox_ns != NULL) { *error_r = "There can be only one namespace with " @@ -212,6 +216,9 @@ } inbox_ns = ns; } + if (namespace_set_alias_for(ns, namespaces, error_r) < 0) + return FALSE; + if (*ns->prefix != '\0' && (ns->flags & (NAMESPACE_FLAG_LIST_PREFIX | NAMESPACE_FLAG_LIST_CHILDREN)) != 0 && diff -r 68a62d79b1b4 -r 0d3f2902fb68 src/lib-storage/mail-namespace.h --- a/src/lib-storage/mail-namespace.h Tue Aug 14 01:54:34 2012 +0300 +++ b/src/lib-storage/mail-namespace.h Tue Aug 14 03:01:07 2012 +0300 @@ -12,8 +12,9 @@ }; enum namespace_flags { - /* Namespace contains the user's INBOX mailbox (there can be only - one) */ + /* Namespace contains the user's INBOX mailbox. Normally only a single + namespace has this flag set, but when using alias_for for the INBOX + namespace the flag gets copied to the alias namespace as well */ NAMESPACE_FLAG_INBOX_USER = 0x01, /* Namespace contains someone's INBOX. This is set for both user's INBOX namespace and also for any other users' shared namespaces. */ From dovecot at dovecot.org Tue Aug 14 03:03:45 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Aug 2012 03:03:45 +0300 Subject: dovecot-2.1: lib-storage: mailbox_list_get_storage_name() should... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/b0f744014aca changeset: 14666:b0f744014aca user: Timo Sirainen date: Tue Aug 14 03:02:02 2012 +0300 description: lib-storage: mailbox_list_get_storage_name() shouldn't treat INBOX specially in inbox=no namespaces. diffstat: src/lib-storage/mailbox-list.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (20 lines): diff -r 0d3f2902fb68 -r b0f744014aca src/lib-storage/mailbox-list.c --- a/src/lib-storage/mailbox-list.c Tue Aug 14 03:01:07 2012 +0300 +++ b/src/lib-storage/mailbox-list.c Tue Aug 14 03:02:02 2012 +0300 @@ -397,12 +397,14 @@ string_t *str; char list_sep, ns_sep, *ret, *p; - if (strcasecmp(storage_name, "INBOX") == 0) + if (strcasecmp(storage_name, "INBOX") == 0 && + (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) storage_name = "INBOX"; else if (list->set.escape_char != '\0') storage_name = mailbox_list_escape_name(list, vname); - if (prefix_len > 0 && strcmp(storage_name, "INBOX") != 0) { + if (prefix_len > 0 && (strcmp(storage_name, "INBOX") != 0 || + (ns->flags & NAMESPACE_FLAG_INBOX_USER) == 0)) { /* skip namespace prefix, except if this is INBOX */ if (strncmp(ns->prefix, storage_name, prefix_len) == 0) storage_name += prefix_len; From dovecot at dovecot.org Tue Aug 14 03:03:45 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Aug 2012 03:03:45 +0300 Subject: dovecot-2.1: fs layout: Kludge to show INBOX/INBOX mailbox when ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/7a1f49b588a8 changeset: 14667:7a1f49b588a8 user: Timo Sirainen date: Tue Aug 14 03:03:26 2012 +0300 description: fs layout: Kludge to show INBOX/INBOX mailbox when necessary. This happens with one prefix="" namespace and another prefix=INBOX/ namespace when the INBOX mailbox itself has children. diffstat: src/lib-storage/list/mailbox-list-fs-iter.c | 32 ++++++++++++++++++++++++---- 1 files changed, 27 insertions(+), 5 deletions(-) diffs (77 lines): diff -r b0f744014aca -r 7a1f49b588a8 src/lib-storage/list/mailbox-list-fs-iter.c --- a/src/lib-storage/list/mailbox-list-fs-iter.c Tue Aug 14 03:02:02 2012 +0300 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Tue Aug 14 03:03:26 2012 +0300 @@ -49,6 +49,7 @@ struct list_dir_context *dir; unsigned int inbox_found:1; + unsigned int list_inbox_inbox:1; }; static int @@ -526,7 +527,8 @@ return ret; } -static void inbox_flags_set(struct fs_list_iterate_context *ctx) +static void inbox_flags_set(struct fs_list_iterate_context *ctx, + enum imap_match_result child_dir_match) { struct mail_namespace *ns = ctx->ctx.list->ns; @@ -541,8 +543,19 @@ with INBOX = /var/inbox/%u/Maildir, root = ~/Maildir: ~/Maildir/INBOX/foo/ shows up as /INBOX/foo and INBOX can't directly have any children. */ - ctx->info.flags &= ~MAILBOX_CHILDREN; - ctx->info.flags |= MAILBOX_NOINFERIORS; + if (ns->prefix_len == 6 && + strncasecmp(ns->prefix, "INBOX", ns->prefix_len-1) == 0 && + (ctx->info.flags & MAILBOX_CHILDREN) != 0 && + (child_dir_match & IMAP_MATCH_CHILDREN) != 0) { + /* except, INBOX/ prefix is once again a special case. + we're now listing both the namespace prefix and the + INBOX. we're now doing a LIST INBOX/%, so we'll need + to create a fake \NoSelect INBOX/INBOX */ + ctx->list_inbox_inbox = TRUE; + } else { + ctx->info.flags &= ~MAILBOX_CHILDREN; + ctx->info.flags |= MAILBOX_NOINFERIORS; + } } } @@ -570,7 +583,7 @@ (ctx->info.flags & MAILBOX_NONEXISTENT) != 0) return FALSE; - inbox_flags_set(ctx); + inbox_flags_set(ctx, 0); /* we got here because we didn't see INBOX among other mailboxes, which means it has no children. */ ctx->info.flags |= MAILBOX_NOCHILDREN; @@ -645,7 +658,7 @@ } return 0; } - inbox_flags_set(ctx); + inbox_flags_set(ctx, child_dir_match); ctx->inbox_found = TRUE; } else if (strcmp(storage_name, "INBOX") == 0 && (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) { @@ -704,6 +717,15 @@ fs_list_next_root(ctx); } + if (ctx->list_inbox_inbox) { + ctx->info.flags = MAILBOX_CHILDREN | MAILBOX_NOSELECT; + ctx->info.name = + p_strconcat(ctx->info_pool, + ctx->ctx.list->ns->prefix, "INBOX", NULL); + ctx->list_inbox_inbox = FALSE; + if (imap_match(ctx->ctx.glob, ctx->info.name) == IMAP_MATCH_YES) + return 1; + } if (!ctx->inbox_found && ctx->ctx.glob != NULL && (ctx->ctx.list->ns->flags & NAMESPACE_FLAG_INBOX_ANY) != 0 && imap_match(ctx->ctx.glob, From dovecot at dovecot.org Tue Aug 14 06:22:58 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Aug 2012 06:22:58 +0300 Subject: dovecot-2.2: dict: Implemented dict_append() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/87e14707d210 changeset: 14900:87e14707d210 user: Timo Sirainen date: Tue Aug 14 06:22:44 2012 +0300 description: dict: Implemented dict_append() diffstat: src/lib-dict/dict-client.c | 18 ++++++++++++++++++ src/lib-dict/dict-client.h | 1 + src/lib-dict/dict-file.c | 27 +++++++++++++++++++++++++++ src/lib-dict/dict-memcached.c | 1 + src/lib-dict/dict-private.h | 2 ++ src/lib-dict/dict-redis.c | 22 ++++++++++++++++++++++ src/lib-dict/dict-sql.c | 12 ++++++++++++ src/lib-dict/dict.c | 9 +++++++++ src/lib-dict/dict.h | 3 +++ 9 files changed, 95 insertions(+), 0 deletions(-) diffs (227 lines): diff -r f9d0ea98157f -r 87e14707d210 src/lib-dict/dict-client.c --- a/src/lib-dict/dict-client.c Mon Aug 13 15:23:32 2012 +0300 +++ b/src/lib-dict/dict-client.c Tue Aug 14 06:22:44 2012 +0300 @@ -785,6 +785,23 @@ } T_END; } +static void client_dict_append(struct dict_transaction_context *_ctx, + const char *key, const char *value) +{ + struct client_dict_transaction_context *ctx = + (struct client_dict_transaction_context *)_ctx; + + T_BEGIN { + const char *query; + + query = t_strdup_printf("%c%u\t%s\t%s\n", + DICT_PROTOCOL_CMD_APPEND, ctx->id, + dict_client_escape(key), + dict_client_escape(value)); + client_dict_send_transaction_query(ctx, query); + } T_END; +} + static void client_dict_atomic_inc(struct dict_transaction_context *_ctx, const char *key, long long diff) { @@ -816,6 +833,7 @@ client_dict_transaction_rollback, client_dict_set, client_dict_unset, + client_dict_append, client_dict_atomic_inc } }; diff -r f9d0ea98157f -r 87e14707d210 src/lib-dict/dict-client.h --- a/src/lib-dict/dict-client.h Mon Aug 13 15:23:32 2012 +0300 +++ b/src/lib-dict/dict-client.h Tue Aug 14 06:22:44 2012 +0300 @@ -24,6 +24,7 @@ DICT_PROTOCOL_CMD_SET = 'S', /* */ DICT_PROTOCOL_CMD_UNSET = 'U', /* */ + DICT_PROTOCOL_CMD_APPEND = 'P', /* */ DICT_PROTOCOL_CMD_ATOMIC_INC = 'A' /* */ }; diff -r f9d0ea98157f -r 87e14707d210 src/lib-dict/dict-file.c --- a/src/lib-dict/dict-file.c Mon Aug 13 15:23:32 2012 +0300 +++ b/src/lib-dict/dict-file.c Tue Aug 14 06:22:44 2012 +0300 @@ -47,6 +47,7 @@ enum file_dict_change_type { FILE_DICT_CHANGE_TYPE_SET, FILE_DICT_CHANGE_TYPE_UNSET, + FILE_DICT_CHANGE_TYPE_APPEND, FILE_DICT_CHANGE_TYPE_INC }; @@ -347,6 +348,18 @@ } hash_table_update(dict->hash, key, value); break; + case FILE_DICT_CHANGE_TYPE_APPEND: + if (key == NULL) + key = p_strdup(dict->hash_pool, change->key); + if (old_value == NULL) { + value = p_strdup(dict->hash_pool, + change->value.str); + } else { + value = p_strconcat(dict->hash_pool, old_value, + change->value.str, NULL); + } + hash_table_update(dict->hash, key, value); + break; case FILE_DICT_CHANGE_TYPE_UNSET: if (old_value != NULL) hash_table_remove(dict->hash, key); @@ -606,6 +619,19 @@ change->key = p_strdup(ctx->pool, key); } +static void file_dict_append(struct dict_transaction_context *_ctx, + const char *key, const char *value) +{ + struct file_dict_transaction_context *ctx = + (struct file_dict_transaction_context *)_ctx; + struct file_dict_change *change; + + change = array_append_space(&ctx->changes); + change->type = FILE_DICT_CHANGE_TYPE_APPEND; + change->key = p_strdup(ctx->pool, key); + change->value.str = p_strdup(ctx->pool, value); +} + static void file_dict_atomic_inc(struct dict_transaction_context *_ctx, const char *key, long long diff) @@ -635,6 +661,7 @@ file_dict_transaction_rollback, file_dict_set, file_dict_unset, + file_dict_append, file_dict_atomic_inc } }; diff -r f9d0ea98157f -r 87e14707d210 src/lib-dict/dict-memcached.c --- a/src/lib-dict/dict-memcached.c Mon Aug 13 15:23:32 2012 +0300 +++ b/src/lib-dict/dict-memcached.c Tue Aug 14 06:22:44 2012 +0300 @@ -371,6 +371,7 @@ NULL, NULL, NULL, + NULL, NULL } }; diff -r f9d0ea98157f -r 87e14707d210 src/lib-dict/dict-private.h --- a/src/lib-dict/dict-private.h Mon Aug 13 15:23:32 2012 +0300 +++ b/src/lib-dict/dict-private.h Tue Aug 14 06:22:44 2012 +0300 @@ -31,6 +31,8 @@ const char *key, const char *value); void (*unset)(struct dict_transaction_context *ctx, const char *key); + void (*append)(struct dict_transaction_context *ctx, + const char *key, const char *value); void (*atomic_inc)(struct dict_transaction_context *ctx, const char *key, long long diff); }; diff -r f9d0ea98157f -r 87e14707d210 src/lib-dict/dict-redis.c --- a/src/lib-dict/dict-redis.c Mon Aug 13 15:23:32 2012 +0300 +++ b/src/lib-dict/dict-redis.c Tue Aug 14 06:22:44 2012 +0300 @@ -624,6 +624,27 @@ ctx->cmd_count++; } +static void redis_append(struct dict_transaction_context *_ctx, + const char *key, const char *value) +{ + struct redis_dict_transaction_context *ctx = + (struct redis_dict_transaction_context *)_ctx; + struct redis_dict *dict = (struct redis_dict *)_ctx->dict; + const char *cmd; + + if (redis_check_transaction(ctx) < 0) + return; + + key = redis_dict_get_full_key(dict, key); + cmd = t_strdup_printf("*3\r\n$6\r\nAPPEND\r\n$%u\r\n%s\r\n$%u\r\n%s\r\n", + (unsigned int)strlen(key), key, + (unsigned int)strlen(value), value); + if (o_stream_send_str(dict->conn.conn.output, cmd) < 0) + ctx->failed = TRUE; + redis_input_state_add(dict, REDIS_INPUT_STATE_MULTI); + ctx->cmd_count++; +} + static void redis_atomic_inc(struct dict_transaction_context *_ctx, const char *key, long long diff) { @@ -661,6 +682,7 @@ redis_transaction_rollback, redis_set, redis_unset, + redis_append, redis_atomic_inc } }; diff -r f9d0ea98157f -r 87e14707d210 src/lib-dict/dict-sql.c --- a/src/lib-dict/dict-sql.c Mon Aug 13 15:23:32 2012 +0300 +++ b/src/lib-dict/dict-sql.c Tue Aug 14 06:22:44 2012 +0300 @@ -730,6 +730,17 @@ } T_END; } +static void +sql_dict_append(struct dict_transaction_context *_ctx, + const char *key ATTR_UNUSED, const char *value ATTR_UNUSED) +{ + struct sql_dict_transaction_context *ctx = + (struct sql_dict_transaction_context *)_ctx; + + i_error("sql dict: Append command not implemented currently"); + ctx->failed = TRUE; +} + static unsigned int * sql_dict_next_inc_row(struct sql_dict_transaction_context *ctx) { @@ -890,6 +901,7 @@ sql_dict_transaction_rollback, sql_dict_set, sql_dict_unset, + sql_dict_append, sql_dict_atomic_inc } }; diff -r f9d0ea98157f -r 87e14707d210 src/lib-dict/dict.c --- a/src/lib-dict/dict.c Mon Aug 13 15:23:32 2012 +0300 +++ b/src/lib-dict/dict.c Tue Aug 14 06:22:44 2012 +0300 @@ -212,6 +212,15 @@ ctx->changed = TRUE; } +void dict_append(struct dict_transaction_context *ctx, + const char *key, const char *value) +{ + i_assert(dict_key_prefix_is_valid(key)); + + ctx->dict->v.append(ctx, key, value); + ctx->changed = TRUE; +} + void dict_atomic_inc(struct dict_transaction_context *ctx, const char *key, long long diff) { diff -r f9d0ea98157f -r 87e14707d210 src/lib-dict/dict.h --- a/src/lib-dict/dict.h Mon Aug 13 15:23:32 2012 +0300 +++ b/src/lib-dict/dict.h Tue Aug 14 06:22:44 2012 +0300 @@ -77,6 +77,9 @@ /* Unset a record in dictionary, identified by key*/ void dict_unset(struct dict_transaction_context *ctx, const char *key); +/* Append to an existing key in dictionary. Preferably an atomic operation. */ +void dict_append(struct dict_transaction_context *ctx, + const char *key, const char *value); /* Increase/decrease a numeric value in dictionary. Note that the value is changed when transaction is being committed, so you can't know beforehand what the value will become. The value is updated only if it already exists, From dovecot at dovecot.org Tue Aug 14 10:02:20 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Aug 2012 10:02:20 +0300 Subject: dovecot-2.2: connection: connection_disconnect_reason() didn't h... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3d53028cbe9c changeset: 14901:3d53028cbe9c user: Timo Sirainen date: Tue Aug 14 10:02:14 2012 +0300 description: connection: connection_disconnect_reason() didn't handle non-errors correctly. diffstat: src/lib/connection.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 87e14707d210 -r 3d53028cbe9c src/lib/connection.c --- a/src/lib/connection.c Tue Aug 14 06:22:44 2012 +0300 +++ b/src/lib/connection.c Tue Aug 14 10:02:14 2012 +0300 @@ -284,6 +284,8 @@ errno = conn->input->stream_errno; else if (conn->output != NULL && conn->output->stream_errno != 0) errno = conn->output->stream_errno; + else + errno = 0; return errno == 0 || errno == EPIPE ? "Connection closed" : t_strdup_printf("Connection closed: %m"); From dovecot at dovecot.org Tue Aug 14 23:11:04 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 14 Aug 2012 23:11:04 +0300 Subject: dovecot-2.1: imapc: Added imapc_max_idle_time setting to force a... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/f33e3ac28e1d changeset: 14668:f33e3ac28e1d user: Timo Sirainen date: Tue Aug 14 23:09:44 2012 +0300 description: imapc: Added imapc_max_idle_time setting to force activity on connection. Reducing this from the default 29 minutes should help when there's a stateful firewall between imapc and the backend server. diffstat: src/lib-imap-client/imapc-client.h | 1 + src/lib-imap-client/imapc-connection.c | 4 +--- src/lib-storage/index/imapc/imapc-settings.c | 4 ++++ src/lib-storage/index/imapc/imapc-settings.h | 2 ++ src/lib-storage/index/imapc/imapc-storage.c | 1 + 5 files changed, 9 insertions(+), 3 deletions(-) diffs (76 lines): diff -r 7a1f49b588a8 -r f33e3ac28e1d src/lib-imap-client/imapc-client.h --- a/src/lib-imap-client/imapc-client.h Tue Aug 14 03:03:26 2012 +0300 +++ b/src/lib-imap-client/imapc-client.h Tue Aug 14 23:09:44 2012 +0300 @@ -52,6 +52,7 @@ const char *master_user; const char *username; const char *password; + unsigned int max_idle_time; const char *dns_client_socket_path; const char *temp_path_prefix; diff -r 7a1f49b588a8 -r f33e3ac28e1d src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Tue Aug 14 03:03:26 2012 +0300 +++ b/src/lib-imap-client/imapc-connection.c Tue Aug 14 23:09:44 2012 +0300 @@ -24,8 +24,6 @@ #define IMAPC_CONNECT_TIMEOUT_MSECS (1000*30) #define IMAPC_COMMAND_TIMEOUT_MSECS (1000*60*5) #define IMAPC_MAX_INLINE_LITERAL_SIZE (1024*32) -/* IMAP protocol requires activity at least every 30 minutes */ -#define IMAPC_MAX_IDLE_MSECS (1000*60*29) enum imapc_input_state { IMAPC_INPUT_STATE_NONE = 0, @@ -1306,7 +1304,7 @@ conn->parser = imap_parser_create(conn->input, NULL, (size_t)-1); conn->to = timeout_add(IMAPC_CONNECT_TIMEOUT_MSECS, imapc_connection_timeout, conn); - conn->to_output = timeout_add(IMAPC_MAX_IDLE_MSECS, + conn->to_output = timeout_add(conn->client->set.max_idle_time*1000, imapc_connection_reset_idle, conn); if (conn->client->set.debug) { i_debug("imapc(%s): Connecting to %s:%u", conn->name, diff -r 7a1f49b588a8 -r f33e3ac28e1d src/lib-storage/index/imapc/imapc-settings.c --- a/src/lib-storage/index/imapc/imapc-settings.c Tue Aug 14 03:03:26 2012 +0300 +++ b/src/lib-storage/index/imapc/imapc-settings.c Tue Aug 14 23:09:44 2012 +0300 @@ -28,6 +28,8 @@ DEF(SET_STR, imapc_features), DEF(SET_STR, imapc_rawlog_dir), DEF(SET_STR, imapc_list_prefix), + DEF(SET_TIME, imapc_max_idle_time), + DEF(SET_STR, ssl_crypto_device), SETTING_DEFINE_LIST_END @@ -48,6 +50,8 @@ .imapc_features = "", .imapc_rawlog_dir = "", .imapc_list_prefix = "", + .imapc_max_idle_time = 60*29, + .ssl_crypto_device = "" }; diff -r 7a1f49b588a8 -r f33e3ac28e1d src/lib-storage/index/imapc/imapc-settings.h --- a/src/lib-storage/index/imapc/imapc-settings.h Tue Aug 14 03:03:26 2012 +0300 +++ b/src/lib-storage/index/imapc/imapc-settings.h Tue Aug 14 23:09:44 2012 +0300 @@ -23,6 +23,8 @@ const char *imapc_features; const char *imapc_rawlog_dir; const char *imapc_list_prefix; + unsigned int imapc_max_idle_time; + const char *ssl_crypto_device; enum imapc_features parsed_features; diff -r 7a1f49b588a8 -r f33e3ac28e1d src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Tue Aug 14 03:03:26 2012 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.c Tue Aug 14 23:09:44 2012 +0300 @@ -228,6 +228,7 @@ *error_r = "missing imapc_password"; return -1; } + set.max_idle_time = storage->set->imapc_max_idle_time; set.dns_client_socket_path = *_storage->user->set->base_dir == '\0' ? "" : t_strconcat(_storage->user->set->base_dir, "/", From pigeonhole at rename-it.nl Wed Aug 15 01:55:15 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Wed, 15 Aug 2012 00:55:15 +0200 Subject: dovecot-2.1-pigeonhole: sieve-tools: sievec and sieve-dump now i... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/cfe8e9f49dfe changeset: 1640:cfe8e9f49dfe user: Stephan Bosch date: Wed Aug 15 00:55:05 2012 +0200 description: sieve-tools: sievec and sieve-dump now ignore mail_uid and mail_gid settings when run as root. Before, sievec and sieve-dump would switch to mail_uid:mail_gid and then fail to compile/dump a root script. diffstat: src/lib-sieve-tool/sieve-tool.c | 14 ++++++++++---- src/lib-sieve-tool/sieve-tool.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/testsuite.c | 2 +- 7 files changed, 16 insertions(+), 10 deletions(-) diffs (118 lines): diff -r 7e100dcd888a -r cfe8e9f49dfe src/lib-sieve-tool/sieve-tool.c --- a/src/lib-sieve-tool/sieve-tool.c Sun Aug 12 15:50:27 2012 +0200 +++ b/src/lib-sieve-tool/sieve-tool.c Wed Aug 15 00:55:05 2012 +0200 @@ -112,14 +112,14 @@ home == NULL || *home == '\0' ) { if ((pw = getpwuid(process_euid)) != NULL) { - user = pw->pw_name; + user = pw->pw_name; home = pw->pw_dir; } } if ( username_r != NULL ) { if ( user == NULL || *user == '\0' ) { - i_fatal("couldn't lookup our username (uid=%s)", + i_fatal("couldn't lookup our username (uid=%s)", dec2str(process_euid)); } @@ -216,7 +216,7 @@ } struct sieve_instance *sieve_tool_init_finish -(struct sieve_tool *tool, bool init_mailstore) +(struct sieve_tool *tool, bool init_mailstore, bool preserve_root) { enum mail_storage_service_flags storage_service_flags = MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR | @@ -238,9 +238,15 @@ if ( tool->homedir != NULL ) i_free(tool->homedir); tool->homedir = i_strdup(homedir); - } else + + if ( preserve_root ) { + storage_service_flags |= + MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS; + } + } else { storage_service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; + } if ( !init_mailstore ) storage_service_flags |= diff -r 7e100dcd888a -r cfe8e9f49dfe src/lib-sieve-tool/sieve-tool.h --- a/src/lib-sieve-tool/sieve-tool.h Sun Aug 12 15:50:27 2012 +0200 +++ b/src/lib-sieve-tool/sieve-tool.h Wed Aug 15 00:55:05 2012 +0200 @@ -30,7 +30,7 @@ int sieve_tool_getopt(struct sieve_tool *tool); struct sieve_instance *sieve_tool_init_finish - (struct sieve_tool *tool, bool init_mailstore); + (struct sieve_tool *tool, bool init_mailstore, bool preserve_root); void sieve_tool_deinit(struct sieve_tool **_tool); diff -r 7e100dcd888a -r cfe8e9f49dfe src/sieve-tools/sieve-dump.c --- a/src/sieve-tools/sieve-dump.c Sun Aug 12 15:50:27 2012 +0200 +++ b/src/sieve-tools/sieve-dump.c Wed Aug 15 00:55:05 2012 +0200 @@ -75,7 +75,7 @@ } /* Finish tool initialization */ - svinst = sieve_tool_init_finish(sieve_tool, FALSE); + svinst = sieve_tool_init_finish(sieve_tool, FALSE, TRUE); /* Enable debug extension */ sieve_enable_debug_extension(svinst); diff -r 7e100dcd888a -r cfe8e9f49dfe src/sieve-tools/sieve-filter.c --- a/src/sieve-tools/sieve-filter.c Sun Aug 12 15:50:27 2012 +0200 +++ b/src/sieve-tools/sieve-filter.c Wed Aug 15 00:55:05 2012 +0200 @@ -473,7 +473,7 @@ } /* Finish tool initialization */ - svinst = sieve_tool_init_finish(sieve_tool, TRUE); + svinst = sieve_tool_init_finish(sieve_tool, TRUE, FALSE); /* Enable debug extension */ sieve_enable_debug_extension(svinst); diff -r 7e100dcd888a -r cfe8e9f49dfe src/sieve-tools/sieve-test.c --- a/src/sieve-tools/sieve-test.c Sun Aug 12 15:50:27 2012 +0200 +++ b/src/sieve-tools/sieve-test.c Wed Aug 15 00:55:05 2012 +0200 @@ -207,7 +207,7 @@ } /* Finish tool initialization */ - svinst = sieve_tool_init_finish(sieve_tool, execute && mailloc == NULL); + svinst = sieve_tool_init_finish(sieve_tool, execute && mailloc == NULL, FALSE); /* Enable debug extension */ sieve_enable_debug_extension(svinst); diff -r 7e100dcd888a -r cfe8e9f49dfe src/sieve-tools/sievec.c --- a/src/sieve-tools/sievec.c Sun Aug 12 15:50:27 2012 +0200 +++ b/src/sieve-tools/sievec.c Wed Aug 15 00:55:05 2012 +0200 @@ -79,7 +79,7 @@ outfile = "-"; } - svinst = sieve_tool_init_finish(sieve_tool, FALSE); + svinst = sieve_tool_init_finish(sieve_tool, FALSE, TRUE); /* Enable debug extension */ sieve_enable_debug_extension(svinst); diff -r 7e100dcd888a -r cfe8e9f49dfe src/testsuite/testsuite.c --- a/src/testsuite/testsuite.c Sun Aug 12 15:50:27 2012 +0200 +++ b/src/testsuite/testsuite.c Wed Aug 15 00:55:05 2012 +0200 @@ -154,7 +154,7 @@ ("sieve_global_dir", t_strconcat(sieve_dir, "included-global", NULL)); /* Finish testsuite initialization */ - svinst = sieve_tool_init_finish(sieve_tool, FALSE); + svinst = sieve_tool_init_finish(sieve_tool, FALSE, FALSE); testsuite_init(svinst, sieve_dir, log_stdout); printf("Test case: %s:\n\n", scriptfile); From dovecot at dovecot.org Wed Aug 15 09:35:54 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Aug 2012 09:35:54 +0300 Subject: dovecot-2.2: imap: Fixed assert-crash on FETCH error disconnecti... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3ff9acd8080e changeset: 14902:3ff9acd8080e user: Timo Sirainen date: Wed Aug 15 09:35:21 2012 +0300 description: imap: Fixed assert-crash on FETCH error disconnections. diffstat: src/imap/imap-client.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (15 lines): diff -r 3d53028cbe9c -r 3ff9acd8080e src/imap/imap-client.c --- a/src/imap/imap-client.c Tue Aug 14 10:02:14 2012 +0300 +++ b/src/imap/imap-client.c Wed Aug 15 09:35:21 2012 +0300 @@ -574,7 +574,10 @@ *_cmd = NULL; - i_assert(client->output_cmd_lock != cmd); + if (client->output_cmd_lock == cmd) { + i_assert(client->disconnected); + client->output_cmd_lock = NULL; + } /* reset input idle time because command output might have taken a long time and we don't want to disconnect client immediately then */ From dovecot at dovecot.org Wed Aug 15 09:35:54 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Aug 2012 09:35:54 +0300 Subject: dovecot-2.2: dict server: Implemented APPEND command. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/51043aa5fe98 changeset: 14903:51043aa5fe98 user: Timo Sirainen date: Wed Aug 15 09:35:39 2012 +0300 description: dict server: Implemented APPEND command. diffstat: src/dict/dict-commands.c | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+), 0 deletions(-) diffs (37 lines): diff -r 3ff9acd8080e -r 51043aa5fe98 src/dict/dict-commands.c --- a/src/dict/dict-commands.c Wed Aug 15 09:35:21 2012 +0300 +++ b/src/dict/dict-commands.c Wed Aug 15 09:35:39 2012 +0300 @@ -304,6 +304,25 @@ return 0; } +static int cmd_append(struct dict_connection *conn, const char *line) +{ + struct dict_connection_transaction *trans; + const char *const *args; + + /* */ + args = t_strsplit_tab(line); + if (str_array_length(args) != 3) { + i_error("dict client: APPEND: broken input"); + return -1; + } + + if (dict_connection_transaction_lookup_parse(conn, args[0], &trans) < 0) + return -1; + + dict_append(trans->ctx, args[1], args[2]); + return 0; +} + static int cmd_atomic_inc(struct dict_connection *conn, const char *line) { struct dict_connection_transaction *trans; @@ -334,6 +353,7 @@ { DICT_PROTOCOL_CMD_ROLLBACK, cmd_rollback }, { DICT_PROTOCOL_CMD_SET, cmd_set }, { DICT_PROTOCOL_CMD_UNSET, cmd_unset }, + { DICT_PROTOCOL_CMD_APPEND, cmd_append }, { DICT_PROTOCOL_CMD_ATOMIC_INC, cmd_atomic_inc }, { 0, NULL } From dovecot at dovecot.org Wed Aug 15 12:05:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Aug 2012 12:05:39 +0300 Subject: dovecot-2.2: istream-limit: Move parent stream to expected offse... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/aba24a5cc9ff changeset: 14904:aba24a5cc9ff user: Timo Sirainen date: Wed Aug 15 12:05:28 2012 +0300 description: istream-limit: Move parent stream to expected offset also at EOF. diffstat: src/lib/istream-limit.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (22 lines): diff -r 51043aa5fe98 -r aba24a5cc9ff src/lib/istream-limit.c --- a/src/lib/istream-limit.c Wed Aug 15 09:35:39 2012 +0300 +++ b/src/lib/istream-limit.c Wed Aug 15 12:05:28 2012 +0300 @@ -31,15 +31,15 @@ ssize_t ret; size_t pos; + i_stream_seek(stream->parent, lstream->istream.parent_start_offset + + stream->istream.v_offset); + if (stream->istream.v_offset + (stream->pos - stream->skip) >= lstream->v_size) { stream->istream.eof = TRUE; return -1; } - i_stream_seek(stream->parent, lstream->istream.parent_start_offset + - stream->istream.v_offset); - stream->pos -= stream->skip; stream->skip = 0; From dovecot at dovecot.org Wed Aug 15 12:37:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Aug 2012 12:37:39 +0300 Subject: dovecot-2.1: lib-storage: MAX_SORT_PROGRAM_SIZE was too small Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/501f22bf92c3 changeset: 14669:501f22bf92c3 user: Timo Sirainen date: Wed Aug 15 12:37:34 2012 +0300 description: lib-storage: MAX_SORT_PROGRAM_SIZE was too small diffstat: src/lib-storage/mail-storage.h | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diffs (22 lines): diff -r f33e3ac28e1d -r 501f22bf92c3 src/lib-storage/mail-storage.h --- a/src/lib-storage/mail-storage.h Tue Aug 14 23:09:44 2012 +0300 +++ b/src/lib-storage/mail-storage.h Wed Aug 15 12:37:34 2012 +0300 @@ -93,9 +93,6 @@ }; enum mail_sort_type { -/* Maximum size for sort program (each one separately + END) */ -#define MAX_SORT_PROGRAM_SIZE (8 + 1) - MAIL_SORT_ARRIVAL = 0x0001, MAIL_SORT_CC = 0x0002, MAIL_SORT_DATE = 0x0004, @@ -107,6 +104,8 @@ MAIL_SORT_DISPLAYFROM = 0x0100, MAIL_SORT_DISPLAYTO = 0x0200, MAIL_SORT_POP3_ORDER = 0x0400, +/* Maximum size for sort program (each one separately + END) */ +#define MAX_SORT_PROGRAM_SIZE (11 + 1) MAIL_SORT_MASK = 0x0fff, MAIL_SORT_FLAG_REVERSE = 0x1000, /* reverse this mask type */ From dovecot at dovecot.org Wed Aug 15 13:43:22 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Aug 2012 13:43:22 +0300 Subject: dovecot-2.1: imap: Implemented THREAD=ORDEREDSUBJECT extension. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/670f467ff5c5 changeset: 14670:670f467ff5c5 user: Timo Sirainen date: Wed Aug 15 13:43:16 2012 +0300 description: imap: Implemented THREAD=ORDEREDSUBJECT extension. diffstat: configure.in | 2 +- src/imap/cmd-thread.c | 148 +++++++++++++++++++++++++++++++++++++++++- src/lib-storage/mail-thread.c | 2 + 3 files changed, 150 insertions(+), 2 deletions(-) diffs (196 lines): diff -r 501f22bf92c3 -r 670f467ff5c5 configure.in --- a/configure.in Wed Aug 15 12:37:34 2012 +0300 +++ b/configure.in Wed Aug 15 13:43:16 2012 +0300 @@ -2708,7 +2708,7 @@ dnl IDLE doesn't really belong to banner. It's there just to make Blackberries dnl happy, because otherwise BIS server disables push email. capability_banner="IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE" -capability="$capability_banner SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS MULTIAPPEND UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE" +capability="$capability_banner SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE" AC_DEFINE_UNQUOTED(CAPABILITY_STRING, "$capability", IMAP capabilities) AC_DEFINE_UNQUOTED(CAPABILITY_BANNER_STRING, "$capability_banner", IMAP capabilities advertised in banner) diff -r 501f22bf92c3 -r 670f467ff5c5 src/imap/cmd-thread.c --- a/src/imap/cmd-thread.c Wed Aug 15 12:37:34 2012 +0300 +++ b/src/imap/cmd-thread.c Wed Aug 15 13:43:16 2012 +0300 @@ -3,6 +3,7 @@ #include "imap-common.h" #include "str.h" #include "ostream.h" +#include "imap-base-subject.h" #include "imap-commands.h" #include "imap-search-args.h" #include "mail-thread.h" @@ -102,6 +103,148 @@ return ret; } +struct orderedsubject_thread { + time_t timestamp; + ARRAY_TYPE(uint32_t) msgs; +}; + +static int orderedsubject_thread_cmp(const struct orderedsubject_thread *t1, + const struct orderedsubject_thread *t2) +{ + const uint32_t *m1, *m2; + + if (t1->timestamp < t2->timestamp) + return -1; + if (t1->timestamp > t2->timestamp) + return 1; + + m1 = array_idx(&t1->msgs, 0); + m2 = array_idx(&t2->msgs, 0); + if (*m1 < *m2) + return -1; + if (*m1 > *m2) + return 1; + i_unreached(); +} + +static void +imap_orderedsubject_thread_write(struct ostream *output, string_t *reply, + const struct orderedsubject_thread *thread) +{ + const uint32_t *msgs; + unsigned int i, count; + + if (str_len(reply) > 128-10) { + o_stream_send(output, str_data(reply), str_len(reply)); + str_truncate(reply, 0); + } + + msgs = array_get(&thread->msgs, &count); + switch (count) { + case 1: + str_printfa(reply, "(%u)", msgs[0]); + break; + case 2: + str_printfa(reply, "(%u %u)", msgs[0], msgs[1]); + break; + default: + /* (1 (2)(3)) */ + str_printfa(reply, "(%u ", msgs[0]); + for (i = 1; i < count; i++) { + if (str_len(reply) > 128-10) { + o_stream_send(output, str_data(reply), + str_len(reply)); + str_truncate(reply, 0); + } + str_printfa(reply, "(%u)", msgs[i]); + } + str_append_c(reply, ')'); + } +} + +static int imap_thread_orderedsubject(struct client_command_context *cmd, + struct mail_search_args *search_args) +{ + static const enum mail_sort_type sort_program[] = { + MAIL_SORT_SUBJECT, + MAIL_SORT_DATE, + 0 + }; + struct mailbox_transaction_context *trans; + struct mail_search_context *search_ctx; + struct mail *mail; + string_t *prev_subject, *reply; + const char *subject, *base_subject; + pool_t pool; + ARRAY_DEFINE(threads, struct orderedsubject_thread); + const struct orderedsubject_thread *thread; + struct orderedsubject_thread *cur_thread = NULL; + uint32_t num; + int ret; + + prev_subject = str_new(default_pool, 128); + + /* first read all of the threads into memory */ + pool = pool_alloconly_create("orderedsubject thread", 1024); + i_array_init(&threads, 128); + trans = mailbox_transaction_begin(cmd->client->mailbox, 0); + search_ctx = mailbox_search_init(trans, search_args, sort_program, + 0, NULL); + while (mailbox_search_next(search_ctx, &mail)) { + if (mail_get_first_header(mail, "Subject", &subject) <= 0) + subject = ""; + T_BEGIN { + base_subject = imap_get_base_subject_cased( + pool_datastack_create(), subject, NULL); + if (strcmp(str_c(prev_subject), base_subject) != 0) { + /* thread changed */ + cur_thread = NULL; + } + str_truncate(prev_subject, 0); + str_append(prev_subject, base_subject); + } T_END; + + if (cur_thread == NULL) { + /* starting a new thread. get the first message's + date */ + cur_thread = array_append_space(&threads); + if (mail_get_date(mail, &cur_thread->timestamp, NULL) == 0 && + cur_thread->timestamp == 0) { + (void)mail_get_received_date(mail, + &cur_thread->timestamp); + } + p_array_init(&cur_thread->msgs, pool, 4); + } + num = cmd->uid ? mail->uid : mail->seq; + array_append(&cur_thread->msgs, &num, 1); + } + str_free(&prev_subject); + ret = mailbox_search_deinit(&search_ctx); + (void)mailbox_transaction_commit(&trans); + if (ret < 0) { + array_free(&threads); + pool_unref(&pool); + return -1; + } + + /* sort the threads by their first message's timestamp */ + array_sort(&threads, orderedsubject_thread_cmp); + + /* write the threads to client */ + reply = t_str_new(128); + str_append(reply, "* THREAD "); + array_foreach(&threads, thread) { + imap_orderedsubject_thread_write(cmd->client->output, + reply, thread); + } + str_append(reply, "\r\n"); + o_stream_send(cmd->client->output, str_data(reply), str_len(reply)); + + array_free(&threads); + pool_unref(&pool); + return 0; +} + bool cmd_thread(struct client_command_context *cmd) { struct client *client = cmd->client; @@ -133,7 +276,10 @@ if (ret <= 0) return ret < 0; - ret = imap_thread(cmd, sargs, thread_type); + if (thread_type != MAIL_THREAD_ORDEREDSUBJECT) + ret = imap_thread(cmd, sargs, thread_type); + else + ret = imap_thread_orderedsubject(cmd, sargs); mail_search_args_unref(&sargs); if (ret < 0) { client_send_storage_error(cmd, diff -r 501f22bf92c3 -r 670f467ff5c5 src/lib-storage/mail-thread.c --- a/src/lib-storage/mail-thread.c Wed Aug 15 12:37:34 2012 +0300 +++ b/src/lib-storage/mail-thread.c Wed Aug 15 13:43:16 2012 +0300 @@ -9,6 +9,8 @@ *type_r = MAIL_THREAD_REFERENCES; else if (strcasecmp(str, "REFS") == 0) *type_r = MAIL_THREAD_REFS; + else if (strcasecmp(str, "ORDEREDSUBJECT") == 0) + *type_r = MAIL_THREAD_ORDEREDSUBJECT; else return FALSE; return TRUE; From dovecot at dovecot.org Wed Aug 15 16:56:29 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Aug 2012 16:56:29 +0300 Subject: dovecot-2.2: lib-dict: Moved "in-memory transaction" code from d... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e266c31ebd02 changeset: 14905:e266c31ebd02 user: Timo Sirainen date: Wed Aug 15 16:55:44 2012 +0300 description: lib-dict: Moved "in-memory transaction" code from dict-file to more generic API. diffstat: src/lib-dict/Makefile.am | 6 +- src/lib-dict/dict-file.c | 135 ++++++-------------------------- src/lib-dict/dict-transaction-memory.c | 72 +++++++++++++++++ src/lib-dict/dict-transaction-memory.h | 41 ++++++++++ 4 files changed, 144 insertions(+), 110 deletions(-) diffs (truncated from 387 to 300 lines): diff -r aba24a5cc9ff -r e266c31ebd02 src/lib-dict/Makefile.am --- a/src/lib-dict/Makefile.am Wed Aug 15 12:05:28 2012 +0300 +++ b/src/lib-dict/Makefile.am Wed Aug 15 16:55:44 2012 +0300 @@ -15,7 +15,8 @@ dict-client.c \ dict-file.c \ dict-memcached.c \ - dict-redis.c + dict-redis.c \ + dict-transaction-memory.c libdict_la_SOURCES = \ $(base_sources) @@ -33,7 +34,8 @@ dict-client.h \ dict-private.h \ dict-sql.h \ - dict-sql-settings.h + dict-sql-settings.h \ + dict-transaction-memory.h pkginc_libdir=$(pkgincludedir) pkginc_lib_HEADERS = $(headers) diff -r aba24a5cc9ff -r e266c31ebd02 src/lib-dict/dict-file.c --- a/src/lib-dict/dict-file.c Wed Aug 15 12:05:28 2012 +0300 +++ b/src/lib-dict/dict-file.c Wed Aug 15 16:55:44 2012 +0300 @@ -8,6 +8,7 @@ #include "nfs-workarounds.h" #include "istream.h" #include "ostream.h" +#include "dict-transaction-memory.h" #include "dict-private.h" #include @@ -44,31 +45,6 @@ unsigned int failed:1; }; -enum file_dict_change_type { - FILE_DICT_CHANGE_TYPE_SET, - FILE_DICT_CHANGE_TYPE_UNSET, - FILE_DICT_CHANGE_TYPE_APPEND, - FILE_DICT_CHANGE_TYPE_INC -}; - -struct file_dict_change { - enum file_dict_change_type type; - const char *key; - union { - const char *str; - long long diff; - } value; -}; - -struct file_dict_transaction_context { - struct dict_transaction_context ctx; - - pool_t pool; - ARRAY_DEFINE(changes, struct file_dict_change); - - unsigned int atomic_inc_not_found:1; -}; - static struct dotlock_settings file_dict_dotlock_settings = { .timeout = 60*2, .stale_timeout = 60, @@ -290,24 +266,23 @@ static struct dict_transaction_context * file_dict_transaction_init(struct dict *_dict) { - struct file_dict_transaction_context *ctx; + struct dict_transaction_memory_context *ctx; pool_t pool; pool = pool_alloconly_create("file dict transaction", 2048); - ctx = p_new(pool, struct file_dict_transaction_context, 1); - ctx->ctx.dict = _dict; - ctx->pool = pool; - p_array_init(&ctx->changes, pool, 32); + ctx = p_new(pool, struct dict_transaction_memory_context, 1); + dict_transaction_memory_init(ctx, _dict, pool); return &ctx->ctx; } -static void file_dict_apply_changes(struct file_dict_transaction_context *ctx) +static void file_dict_apply_changes(struct dict_transaction_memory_context *ctx, + bool *atomic_inc_not_found_r) { struct file_dict *dict = (struct file_dict *)ctx->ctx.dict; const char *tmp; char *key, *value, *old_value; void *orig_key, *orig_value; - const struct file_dict_change *change; + const struct dict_transaction_memory_change *change; unsigned int new_len; long long diff; @@ -323,9 +298,9 @@ value = NULL; switch (change->type) { - case FILE_DICT_CHANGE_TYPE_INC: + case DICT_CHANGE_TYPE_INC: if (old_value == NULL) { - ctx->atomic_inc_not_found = TRUE; + *atomic_inc_not_found_r = TRUE; break; } diff = strtoll(old_value, NULL, 10) + @@ -339,7 +314,7 @@ value = old_value; } /* fall through */ - case FILE_DICT_CHANGE_TYPE_SET: + case DICT_CHANGE_TYPE_SET: if (key == NULL) key = p_strdup(dict->hash_pool, change->key); if (value == NULL) { @@ -348,7 +323,7 @@ } hash_table_update(dict->hash, key, value); break; - case FILE_DICT_CHANGE_TYPE_APPEND: + case DICT_CHANGE_TYPE_APPEND: if (key == NULL) key = p_strdup(dict->hash_pool, change->key); if (old_value == NULL) { @@ -360,7 +335,7 @@ } hash_table_update(dict->hash, key, value); break; - case FILE_DICT_CHANGE_TYPE_UNSET: + case DICT_CHANGE_TYPE_UNSET: if (old_value != NULL) hash_table_remove(dict->hash, key); break; @@ -466,7 +441,8 @@ return ret < 0 ? -1 : 0; } -static int file_dict_write_changes(struct file_dict_transaction_context *ctx) +static int file_dict_write_changes(struct dict_transaction_memory_context *ctx, + bool *atomic_inc_not_found_r) { struct file_dict *dict = (struct file_dict *)ctx->ctx.dict; struct dotlock *dotlock = NULL; @@ -477,6 +453,8 @@ void *key, *value; int fd = -1; + *atomic_inc_not_found_r = FALSE; + switch (dict->lock_method) { case FILE_LOCK_METHOD_FCNTL: case FILE_LOCK_METHOD_FLOCK: @@ -519,7 +497,7 @@ /* get initial permissions from parent directory */ (void)fd_copy_parent_dir_permissions(dict->path, fd, temp_path); } - file_dict_apply_changes(ctx); + file_dict_apply_changes(ctx, atomic_inc_not_found_r); output = o_stream_create_fd(fd, 0, FALSE); o_stream_cork(output); @@ -569,13 +547,14 @@ dict_transaction_commit_callback_t *callback, void *context) { - struct file_dict_transaction_context *ctx = - (struct file_dict_transaction_context *)_ctx; + struct dict_transaction_memory_context *ctx = + (struct dict_transaction_memory_context *)_ctx; + bool atomic_inc_not_found; int ret; - if (file_dict_write_changes(ctx) < 0) + if (file_dict_write_changes(ctx, &atomic_inc_not_found) < 0) ret = -1; - else if (ctx->atomic_inc_not_found) + else if (atomic_inc_not_found) ret = 0; else ret = 1; @@ -586,66 +565,6 @@ return ret; } -static void file_dict_transaction_rollback(struct dict_transaction_context *_ctx) -{ - struct file_dict_transaction_context *ctx = - (struct file_dict_transaction_context *)_ctx; - - pool_unref(&ctx->pool); -} - -static void file_dict_set(struct dict_transaction_context *_ctx, - const char *key, const char *value) -{ - struct file_dict_transaction_context *ctx = - (struct file_dict_transaction_context *)_ctx; - struct file_dict_change *change; - - change = array_append_space(&ctx->changes); - change->type = FILE_DICT_CHANGE_TYPE_SET; - change->key = p_strdup(ctx->pool, key); - change->value.str = p_strdup(ctx->pool, value); -} - -static void file_dict_unset(struct dict_transaction_context *_ctx, - const char *key) -{ - struct file_dict_transaction_context *ctx = - (struct file_dict_transaction_context *)_ctx; - struct file_dict_change *change; - - change = array_append_space(&ctx->changes); - change->type = FILE_DICT_CHANGE_TYPE_UNSET; - change->key = p_strdup(ctx->pool, key); -} - -static void file_dict_append(struct dict_transaction_context *_ctx, - const char *key, const char *value) -{ - struct file_dict_transaction_context *ctx = - (struct file_dict_transaction_context *)_ctx; - struct file_dict_change *change; - - change = array_append_space(&ctx->changes); - change->type = FILE_DICT_CHANGE_TYPE_APPEND; - change->key = p_strdup(ctx->pool, key); - change->value.str = p_strdup(ctx->pool, value); -} - -static void -file_dict_atomic_inc(struct dict_transaction_context *_ctx, - const char *key, long long diff) -{ - struct file_dict_transaction_context *ctx = - (struct file_dict_transaction_context *)_ctx; - struct file_dict_change *change; - - change = array_append_space(&ctx->changes); - change->type = FILE_DICT_CHANGE_TYPE_INC; - change->key = p_strdup(ctx->pool, key); - change->value.diff = diff; -} - struct dict dict_driver_file = { .name = "file", { @@ -658,10 +577,10 @@ file_dict_iterate_deinit, file_dict_transaction_init, file_dict_transaction_commit, - file_dict_transaction_rollback, - file_dict_set, - file_dict_unset, - file_dict_append, - file_dict_atomic_inc + dict_transaction_memory_rollback, + dict_transaction_memory_set, + dict_transaction_memory_unset, + dict_transaction_memory_append, + dict_transaction_memory_atomic_inc } }; diff -r aba24a5cc9ff -r e266c31ebd02 src/lib-dict/dict-transaction-memory.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-dict/dict-transaction-memory.c Wed Aug 15 16:55:44 2012 +0300 @@ -0,0 +1,72 @@ +/* Copyright (c) 2005-2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "array.h" +#include "dict-transaction-memory.h" + +void dict_transaction_memory_init(struct dict_transaction_memory_context *ctx, + struct dict *dict, pool_t pool) +{ + ctx->ctx.dict = dict; + ctx->pool = pool; + p_array_init(&ctx->changes, pool, 32); +} + +void dict_transaction_memory_rollback(struct dict_transaction_context *_ctx) +{ + struct dict_transaction_memory_context *ctx = + (struct dict_transaction_memory_context *)_ctx; + + pool_unref(&ctx->pool); +} + +void dict_transaction_memory_set(struct dict_transaction_context *_ctx, + const char *key, const char *value) +{ + struct dict_transaction_memory_context *ctx = + (struct dict_transaction_memory_context *)_ctx; + struct dict_transaction_memory_change *change; + + change = array_append_space(&ctx->changes); From dovecot at dovecot.org Wed Aug 15 16:56:30 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 15 Aug 2012 16:56:30 +0300 Subject: dovecot-2.2: lib-dict: Added memcached_ascii backend. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/96a9a086c052 changeset: 14906:96a9a086c052 user: Timo Sirainen date: Wed Aug 15 16:56:17 2012 +0300 description: lib-dict: Added memcached_ascii backend. diffstat: src/lib-dict/Makefile.am | 1 + src/lib-dict/dict-memcached-ascii.c | 636 ++++++++++++++++++++++++++++++++++++ src/lib-dict/dict-private.h | 1 + src/lib-dict/dict.c | 2 + src/lib-dict/test-dict.c | 1 + 5 files changed, 641 insertions(+), 0 deletions(-) diffs (truncated from 692 to 300 lines): diff -r e266c31ebd02 -r 96a9a086c052 src/lib-dict/Makefile.am --- a/src/lib-dict/Makefile.am Wed Aug 15 16:55:44 2012 +0300 +++ b/src/lib-dict/Makefile.am Wed Aug 15 16:56:17 2012 +0300 @@ -15,6 +15,7 @@ dict-client.c \ dict-file.c \ dict-memcached.c \ + dict-memcached-ascii.c \ dict-redis.c \ dict-transaction-memory.c diff -r e266c31ebd02 -r 96a9a086c052 src/lib-dict/dict-memcached-ascii.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-dict/dict-memcached-ascii.c Wed Aug 15 16:56:17 2012 +0300 @@ -0,0 +1,636 @@ +/* Copyright (c) 2008-2012 Dovecot authors, see the included COPYING memcached_ascii */ + +#include "lib.h" +#include "array.h" +#include "str.h" +#include "istream.h" +#include "ostream.h" +#include "connection.h" +#include "dict-transaction-memory.h" +#include "dict-private.h" + +#define MEMCACHED_DEFAULT_PORT 11211 +#define MEMCACHED_DEFAULT_LOOKUP_TIMEOUT_MSECS (1000*30) +#define DICT_USERNAME_SEPARATOR '/' + +enum memcached_ascii_input_state { + /* GET: expecting VALUE or END */ + MEMCACHED_INPUT_STATE_GET, + /* SET/(APPEND+ADD): expecting STORED / NOT_STORED */ + MEMCACHED_INPUT_STATE_STORED, + /* DELETE: expecting DELETED */ + MEMCACHED_INPUT_STATE_DELETED, + /* (INCR+ADD)/DECR: expecting number / NOT_FOUND / STORED / NOT_STORED */ + MEMCACHED_INPUT_STATE_INCRDECR +}; + +struct memcached_ascii_connection { + struct connection conn; + struct memcached_ascii_dict *dict; + + string_t *reply_str; + unsigned int reply_bytes_left; + bool value_received; + bool value_waiting_end; +}; + +struct memcached_ascii_dict_reply { + unsigned int reply_count; + dict_transaction_commit_callback_t *callback; + void *context; +}; + +struct dict_memcached_ascii_commit_ctx { + struct memcached_ascii_dict *dict; + struct dict_transaction_memory_context *memctx; + string_t *str; + + dict_transaction_commit_callback_t *callback; + void *context; +}; + +struct memcached_ascii_dict { + struct dict dict; + struct ip_addr ip; + char *username, *key_prefix; + unsigned int port; + unsigned int timeout_msecs; + + struct ioloop *ioloop; + struct timeout *to; + struct memcached_ascii_connection conn; + + ARRAY_DEFINE(input_states, enum memcached_ascii_input_state); + ARRAY_DEFINE(replies, struct memcached_ascii_dict_reply); +}; + +static struct connection_list *memcached_ascii_connections; + +static void memcached_ascii_conn_destroy(struct connection *_conn) +{ + struct memcached_ascii_connection *conn = + (struct memcached_ascii_connection *)_conn; + const struct memcached_ascii_dict_reply *reply; + + connection_disconnect(_conn); + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); + + array_foreach(&conn->dict->replies, reply) { + if (reply->callback != NULL) + reply->callback(-1, reply->context); + } + array_clear(&conn->dict->replies); + array_clear(&conn->dict->input_states); + conn->reply_bytes_left = 0; +} + +static bool memcached_ascii_input_value(struct memcached_ascii_connection *conn) +{ + const unsigned char *data; + size_t size; + + data = i_stream_get_data(conn->conn.input, &size); + if (size > conn->reply_bytes_left) + size = conn->reply_bytes_left; + conn->reply_bytes_left -= size; + + str_append_n(conn->reply_str, data, size); + i_stream_skip(conn->conn.input, size); + if (conn->reply_bytes_left > 0) + return FALSE; + + /* finished. drop the trailing CRLF */ + str_truncate(conn->reply_str, str_len(conn->reply_str)-2); + conn->value_received = TRUE; + return TRUE; +} + +static int memcached_ascii_input_reply_read(struct memcached_ascii_dict *dict) +{ + struct memcached_ascii_connection *conn = &dict->conn; + const enum memcached_ascii_input_state *states; + const char *line, *p; + unsigned int count; + long long num; + + if (conn->reply_bytes_left > 0) { + /* continue reading bulk reply */ + if (!memcached_ascii_input_value(conn)) + return 0; + conn->value_waiting_end = TRUE; + } else if (conn->value_waiting_end) { + conn->value_waiting_end = FALSE; + } else { + str_truncate(conn->reply_str, 0); + conn->value_received = FALSE; + } + + line = i_stream_next_line(conn->conn.input); + if (line == NULL) + return 0; + + states = array_get(&dict->input_states, &count); + if (count == 0) { + i_error("memcached_ascii: Unexpected input (expected nothing): %s", + line); + return -1; + } + switch (states[0]) { + case MEMCACHED_INPUT_STATE_GET: + /* VALUE + END */ + if (strncmp(line, "VALUE ", 6) == 0) { + p = strrchr(line, ' '); + if (str_to_uint(p+1, &conn->reply_bytes_left) < 0) + break; + conn->reply_bytes_left += 2; /* CRLF */ + return memcached_ascii_input_reply_read(dict); + } else if (strcmp(line, "END") == 0) + return 1; + break; + case MEMCACHED_INPUT_STATE_STORED: + if (strcmp(line, "STORED") != 0 && + strcmp(line, "NOT_STORED") != 0) + break; + return 1; + case MEMCACHED_INPUT_STATE_DELETED: + if (strcmp(line, "DELETED") != 0) + break; + return 1; + case MEMCACHED_INPUT_STATE_INCRDECR: + if (strcmp(line, "NOT_FOUND") != 0 && + strcmp(line, "STORED") != 0 && + strcmp(line, "NOT_STORED") != 0 && + str_to_llong(line, &num) < 0) + break; + return 1; + } + i_error("memcached_ascii: Unexpected input (state=%d): %s", + states[0], line); + return -1; +} + +static int memcached_ascii_input_reply(struct memcached_ascii_dict *dict) +{ + struct memcached_ascii_dict_reply *replies; + unsigned int count; + int ret; + + if ((ret = memcached_ascii_input_reply_read(dict)) <= 0) + return ret; + /* finished a reply */ + array_delete(&dict->input_states, 0, 1); + + replies = array_get_modifiable(&dict->replies, &count); + i_assert(count > 0); + i_assert(replies[0].reply_count > 0); + if (--replies[0].reply_count == 0) { + if (replies[0].callback != NULL) + replies[0].callback(1, replies[0].context); + array_delete(&dict->replies, 0, 1); + } + return 1; +} + +static void memcached_ascii_conn_input(struct connection *_conn) +{ + struct memcached_ascii_connection *conn = + (struct memcached_ascii_connection *)_conn; + + switch (i_stream_read(_conn->input)) { + case 0: + return; + case -1: + memcached_ascii_conn_destroy(_conn); + return; + default: + break; + } + + while (array_count(&conn->dict->input_states) > 0) { + if (memcached_ascii_input_reply(conn->dict) < 0) { + memcached_ascii_conn_destroy(_conn); + break; + } + } + io_loop_stop(conn->dict->ioloop); +} + +static int memcached_ascii_input_wait(struct memcached_ascii_dict *dict) +{ + struct ioloop *old_ioloop = current_ioloop; + + current_ioloop = dict->ioloop; + if (dict->to != NULL) + dict->to = io_loop_move_timeout(&dict->to); + connection_switch_ioloop(&dict->conn.conn); + io_loop_run(dict->ioloop); + + current_ioloop = old_ioloop; + if (dict->to != NULL) + dict->to = io_loop_move_timeout(&dict->to); + connection_switch_ioloop(&dict->conn.conn); + + return dict->conn.conn.fd_in == -1 ? -1 : 0; +} + +static void memcached_ascii_input_timeout(struct memcached_ascii_dict *dict) +{ + i_error("memcached_ascii: Request timed out in %u.%03u secs", + dict->timeout_msecs/1000, dict->timeout_msecs%1000); + memcached_ascii_conn_destroy(&dict->conn.conn); +} + +static int memcached_ascii_wait_replies(struct memcached_ascii_dict *dict) +{ + int ret; + + dict->to = timeout_add(dict->timeout_msecs, + memcached_ascii_input_timeout, dict); + while (array_count(&dict->input_states) > 0) { + i_assert(array_count(&dict->replies) > 0); + + if ((ret = memcached_ascii_input_reply(dict)) != 0) { + if (ret < 0) + memcached_ascii_conn_destroy(&dict->conn.conn); + break; + } + ret = memcached_ascii_input_wait(dict); + if (ret != 0) + break; + } + + timeout_remove(&dict->to); + return ret < 0 ? -1 : 0; +} + +static int memcached_ascii_wait(struct memcached_ascii_dict *dict) +{ + int ret; + + i_assert(dict->conn.conn.fd_in != -1); + + if (dict->conn.conn.input == NULL) { + /* waiting for connection to finish */ + dict->to = timeout_add(dict->timeout_msecs, + memcached_ascii_input_timeout, dict); + ret = memcached_ascii_input_wait(dict); + timeout_remove(&dict->to); + if (ret < 0) + return -1; + } + if (memcached_ascii_wait_replies(dict) < 0) + return -1; + i_assert(array_count(&dict->input_states) == 0); From dovecot at dovecot.org Thu Aug 16 05:42:10 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 16 Aug 2012 05:42:10 +0300 Subject: dovecot-2.2: dict memcached-ascii bugfixes Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f5dc8abad16b changeset: 14907:f5dc8abad16b user: Timo Sirainen date: Thu Aug 16 05:41:57 2012 +0300 description: dict memcached-ascii bugfixes diffstat: src/lib-dict/dict-memcached-ascii.c | 12 +++++------- 1 files changed, 5 insertions(+), 7 deletions(-) diffs (36 lines): diff -r 96a9a086c052 -r f5dc8abad16b src/lib-dict/dict-memcached-ascii.c --- a/src/lib-dict/dict-memcached-ascii.c Wed Aug 15 16:56:17 2012 +0300 +++ b/src/lib-dict/dict-memcached-ascii.c Thu Aug 16 05:41:57 2012 +0300 @@ -197,6 +197,7 @@ { struct memcached_ascii_connection *conn = (struct memcached_ascii_connection *)_conn; + int ret; switch (i_stream_read(_conn->input)) { case 0: @@ -208,12 +209,9 @@ break; } - while (array_count(&conn->dict->input_states) > 0) { - if (memcached_ascii_input_reply(conn->dict) < 0) { - memcached_ascii_conn_destroy(_conn); - break; - } - } + while ((ret = memcached_ascii_input_reply(conn->dict)) > 0) ; + if (ret < 0) + memcached_ascii_conn_destroy(_conn); io_loop_stop(conn->dict->ioloop); } @@ -244,7 +242,7 @@ static int memcached_ascii_wait_replies(struct memcached_ascii_dict *dict) { - int ret; + int ret = 0; dict->to = timeout_add(dict->timeout_msecs, memcached_ascii_input_timeout, dict); From dovecot at dovecot.org Thu Aug 16 06:09:35 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 16 Aug 2012 06:09:35 +0300 Subject: dovecot-2.2: connection API: Fixed connected() callback to actua... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/deb47efdc006 changeset: 14908:deb47efdc006 user: Timo Sirainen date: Thu Aug 16 06:09:22 2012 +0300 description: connection API: Fixed connected() callback to actually allow detecting failed connects. diffstat: src/lib-dict/dict-memcached-ascii.c | 7 ++++--- src/lib-dict/dict-memcached.c | 9 +++++---- src/lib-dict/dict-redis.c | 6 +++--- src/lib/connection.c | 26 ++++++++++++++++++++------ src/lib/connection.h | 8 +++++++- 5 files changed, 39 insertions(+), 17 deletions(-) diffs (159 lines): diff -r f5dc8abad16b -r deb47efdc006 src/lib-dict/dict-memcached-ascii.c --- a/src/lib-dict/dict-memcached-ascii.c Thu Aug 16 05:41:57 2012 +0300 +++ b/src/lib-dict/dict-memcached-ascii.c Thu Aug 16 06:09:22 2012 +0300 @@ -285,11 +285,12 @@ return 0; } -static void memcached_ascii_conn_connected(struct connection *_conn) +static void +memcached_ascii_conn_connected(struct connection *_conn, bool success) { struct memcached_ascii_connection *conn = (struct memcached_ascii_connection *)_conn; - if ((errno = net_geterror(_conn->fd_in)) != 0) { + if (!success) { i_error("memcached_ascii: connect(%s, %u) failed: %m", net_ip2addr(&conn->dict->ip), conn->dict->port); } @@ -306,7 +307,7 @@ static const struct connection_vfuncs memcached_ascii_conn_vfuncs = { .destroy = memcached_ascii_conn_destroy, .input = memcached_ascii_conn_input, - .connected = memcached_ascii_conn_connected + .client_connected = memcached_ascii_conn_connected }; static const char *memcached_ascii_escape_username(const char *username) diff -r f5dc8abad16b -r deb47efdc006 src/lib-dict/dict-memcached.c --- a/src/lib-dict/dict-memcached.c Thu Aug 16 05:41:57 2012 +0300 +++ b/src/lib-dict/dict-memcached.c Thu Aug 16 06:09:22 2012 +0300 @@ -140,11 +140,12 @@ memcached_conn_destroy(_conn); } -static void memcached_conn_connected(struct connection *_conn) +static void memcached_conn_connected(struct connection *_conn, bool success) { - struct memcached_connection *conn = (struct memcached_connection *)_conn; + struct memcached_connection *conn = + (struct memcached_connection *)_conn; - if ((errno = net_geterror(_conn->fd_in)) != 0) { + if (!success) { i_error("memcached: connect(%s, %u) failed: %m", net_ip2addr(&conn->dict->ip), conn->dict->port); } else { @@ -163,7 +164,7 @@ static const struct connection_vfuncs memcached_conn_vfuncs = { .destroy = memcached_conn_destroy, .input = memcached_conn_input, - .connected = memcached_conn_connected + .client_connected = memcached_conn_connected }; static struct dict * diff -r f5dc8abad16b -r deb47efdc006 src/lib-dict/dict-redis.c --- a/src/lib-dict/dict-redis.c Thu Aug 16 05:41:57 2012 +0300 +++ b/src/lib-dict/dict-redis.c Thu Aug 16 06:09:22 2012 +0300 @@ -255,11 +255,11 @@ redis_conn_destroy(_conn); } -static void redis_conn_connected(struct connection *_conn) +static void redis_conn_connected(struct connection *_conn, bool success) { struct redis_connection *conn = (struct redis_connection *)_conn; - if ((errno = net_geterror(_conn->fd_in)) != 0) { + if (!success) { i_error("redis: connect(%s, %u) failed: %m", net_ip2addr(&conn->dict->ip), conn->dict->port); } else { @@ -278,7 +278,7 @@ static const struct connection_vfuncs redis_conn_vfuncs = { .destroy = redis_conn_destroy, .input = redis_conn_input, - .connected = redis_conn_connected + .client_connected = redis_conn_connected }; static const char *redis_escape_username(const char *username) diff -r f5dc8abad16b -r deb47efdc006 src/lib/connection.c --- a/src/lib/connection.c Thu Aug 16 05:41:57 2012 +0300 +++ b/src/lib/connection.c Thu Aug 16 06:09:22 2012 +0300 @@ -132,8 +132,21 @@ "VERSION\t%s\t%u\t%u\n", set->service_name_out, set->major_version, set->minor_version)); } - if (conn->list->v.connected != NULL) - conn->list->v.connected(conn); +} + +static void connection_client_connected(struct connection *conn, bool success) +{ + i_assert(conn->list->set.client); + + if (success) + connection_init_streams(conn); + if (conn->list->v.client_connected != NULL) + conn->list->v.client_connected(conn, success); + if (!success) { + conn->disconnect_reason = + CONNECTION_DISCONNECT_CONN_CLOSED; + conn->list->v.destroy(conn); + } } void connection_init_server(struct connection_list *list, @@ -180,13 +193,14 @@ DLLIST_PREPEND(&list->connections, conn); } -static void connection_connected(struct connection *conn) +static void connection_ip_connected(struct connection *conn) { io_remove(&conn->io); if (conn->to != NULL) timeout_remove(&conn->to); - connection_init_streams(conn); + errno = net_geterror(conn->fd_in); + connection_client_connected(conn, errno == 0); } int connection_client_connect(struct connection *conn) @@ -207,13 +221,13 @@ if (conn->port != 0) { conn->io = io_add(conn->fd_out, IO_WRITE, - connection_connected, conn); + connection_ip_connected, conn); if (set->client_connect_timeout_msecs != 0) { conn->to = timeout_add(set->client_connect_timeout_msecs, connection_connect_timeout, conn); } } else { - connection_init_streams(conn); + connection_client_connected(conn, TRUE); } return 0; } diff -r f5dc8abad16b -r deb47efdc006 src/lib/connection.h --- a/src/lib/connection.h Thu Aug 16 05:41:57 2012 +0300 +++ b/src/lib/connection.h Thu Aug 16 06:09:22 2012 +0300 @@ -27,7 +27,13 @@ struct connection_vfuncs { void (*destroy)(struct connection *conn); - void (*connected)(struct connection *conn); + /* For UNIX socket clients this gets called immediately with + success=TRUE, for IP connections it gets called later: + + If connect() fails, sets success=FALSE and errno. Streams aren't + initialized in that situation either. destroy() is called after + the callback. */ + void (*client_connected)(struct connection *conn, bool success); /* implement one of the input*() methods. They return 0 = ok, -1 = error, disconnect the client */ From dovecot at dovecot.org Thu Aug 16 14:25:28 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 16 Aug 2012 14:25:28 +0300 Subject: dovecot-2.2: Makefile: iostream-*ssl.h wasn't being installed. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7436df9a9922 changeset: 14909:7436df9a9922 user: Timo Sirainen date: Thu Aug 16 14:25:21 2012 +0300 description: Makefile: iostream-*ssl.h wasn't being installed. diffstat: src/lib-ssl-iostream/Makefile.am | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (14 lines): diff -r deb47efdc006 -r 7436df9a9922 src/lib-ssl-iostream/Makefile.am --- a/src/lib-ssl-iostream/Makefile.am Thu Aug 16 06:09:22 2012 +0300 +++ b/src/lib-ssl-iostream/Makefile.am Thu Aug 16 14:25:21 2012 +0300 @@ -21,6 +21,9 @@ libssl_iostream_la_LIBADD = \ $(SSL_LIBS) -noinst_HEADERS = \ +headers = \ iostream-openssl.h \ iostream-ssl.h + +pkginc_libdir=$(pkgincludedir) +pkginc_lib_HEADERS = $(headers) From dovecot at dovecot.org Thu Aug 16 14:58:08 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 16 Aug 2012 14:58:08 +0300 Subject: dovecot-2.2: dovecot-config: Added LIBDOVECOT_DOVEADM_INCLUDE Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/85b22a4af8d4 changeset: 14910:85b22a4af8d4 user: Timo Sirainen date: Thu Aug 16 14:57:55 2012 +0300 description: dovecot-config: Added LIBDOVECOT_DOVEADM_INCLUDE diffstat: dovecot-config.in.in | 1 + dovecot.m4 | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diffs (32 lines): diff -r 7436df9a9922 -r 85b22a4af8d4 dovecot-config.in.in --- a/dovecot-config.in.in Thu Aug 16 14:25:21 2012 +0300 +++ b/dovecot-config.in.in Thu Aug 16 14:57:55 2012 +0300 @@ -22,6 +22,7 @@ LIBDOVECOT_INCLUDE="-I$(incdir) -I$(incdir)/src/lib -I$(incdir)/src/lib-dict -I$(incdir)/src/lib-dns -I$(incdir)/src/lib-mail -I$(incdir)/src/lib-imap -I$(incdir)/src/lib-fs -I$(incdir)/src/lib-charset -I$(incdir)/src/lib-auth -I$(incdir)/src/lib-master -I$(incdir)/src/lib-ssl-iostream -I$(incdir)/src/lib-compression -I$(incdir)/src/lib-settings -I$(incdir)/src/lib-test" LIBDOVECOT_LDA_INCLUDE="-I$(incdir)/src/lib-lda -I$(incdir)/src/lda" +LIBDOVECOT_DOVEADM_INCLUDE="-I$(incdir)/src/doveadm" LIBDOVECOT_STORAGE_INCLUDE="-I$(incdir)/src/lib-index -I$(incdir)/src/lib-storage -I$(incdir)/src/lib-storage/index -I$(incdir)/src/lib-storage/index/raw" LIBDOVECOT_LOGIN_INCLUDE="-I$(incdir)/src/login-common" LIBDOVECOT_IMAP_INCLUDE="-I$(incdir)/src/imap" diff -r 7436df9a9922 -r 85b22a4af8d4 dovecot.m4 --- a/dovecot.m4 Thu Aug 16 14:25:21 2012 +0300 +++ b/dovecot.m4 Thu Aug 16 14:57:55 2012 +0300 @@ -6,7 +6,7 @@ # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. -# serial 8 +# serial 9 AC_DEFUN([DC_DOVECOT_MODULEDIR],[ AC_ARG_WITH(moduledir, @@ -87,7 +87,7 @@ AX_SUBST_L([DOVECOT_CFLAGS], [DOVECOT_LIBS], [DOVECOT_SSL_LIBS], [DOVECOT_SQL_LIBS], [DOVECOT_COMPRESS_LIBS]) AX_SUBST_L([LIBDOVECOT], [LIBDOVECOT_LOGIN], [LIBDOVECOT_SQL], [LIBDOVECOT_SSL], [LIBDOVECOT_COMPRESS], [LIBDOVECOT_LDA], [LIBDOVECOT_STORAGE]) AX_SUBST_L([LIBDOVECOT_DEPS], [LIBDOVECOT_LOGIN_DEPS], [LIBDOVECOT_SQL_DEPS], [LIBDOVECOT_SSL_DEPS], [LIBDOVECOT_COMPRESS_DEPS], [LIBDOVECOT_LDA_DEPS], [LIBDOVECOT_STORAGE_DEPS]) - AX_SUBST_L([LIBDOVECOT_INCLUDE], [LIBDOVECOT_LDA_INCLUDE], [LIBDOVECOT_SERVICE_INCLUDE], [LIBDOVECOT_STORAGE_INCLUDE], [LIBDOVECOT_LOGIN_INCLUDE], [LIBDOVECOT_CONFIG_INCLUDE], [LIBDOVECOT_IMAP_INCLUDE]) + AX_SUBST_L([LIBDOVECOT_INCLUDE], [LIBDOVECOT_LDA_INCLUDE], [LIBDOVECOT_DOVEADM_INCLUDE], [LIBDOVECOT_SERVICE_INCLUDE], [LIBDOVECOT_STORAGE_INCLUDE], [LIBDOVECOT_LOGIN_INCLUDE], [LIBDOVECOT_CONFIG_INCLUDE], [LIBDOVECOT_IMAP_INCLUDE]) DC_PLUGIN_DEPS ]) From pigeonhole at rename-it.nl Thu Aug 16 23:28:11 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 16 Aug 2012 22:28:11 +0200 Subject: dovecot-2.1-pigeonhole: lib-sieve: spamvirustest: improved trace... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/ff55c9946366 changeset: 1641:ff55c9946366 user: Stephan Bosch date: Thu Aug 16 22:28:06 2012 +0200 description: lib-sieve: spamvirustest: improved trace debugging of score calculation. diffstat: src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c | 47 +++++---- src/lib-sieve/plugins/spamvirustest/tst-spamvirustest.c | 2 + 2 files changed, 27 insertions(+), 22 deletions(-) diffs (159 lines): diff -r cfe8e9f49dfe -r ff55c9946366 src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c --- a/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c Wed Aug 15 00:55:05 2012 +0200 +++ b/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c Thu Aug 16 22:28:06 2012 +0200 @@ -457,7 +457,6 @@ const struct sieve_message_data *msgdata = renv->msgdata; struct sieve_message_context *msgctx = renv->msgctx; struct ext_spamvirustest_message_context *mctx; - const char *ext_name = sieve_extension_name(ext); regmatch_t match_values[2]; const char *header_value, *error; const char *status = NULL, *max = NULL; @@ -470,7 +469,7 @@ */ if ( ext_data == NULL ) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, - "%s: extension not configured", ext_name); + "error: extension not configured"); return "0"; } @@ -504,8 +503,8 @@ (msgdata->mail, max_header->header_name, &header_value) < 0 || header_value == NULL ) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, - "%s: header '%s' not found in message", - ext_name, max_header->header_name); + "header '%s' not found in message", + max_header->header_name); goto failed; } @@ -514,16 +513,16 @@ if ( regexec(&max_header->regexp, header_value, 2, match_values, 0) != 0 ) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, - "%s: regexp for header '%s' did not match " - "on value '%s'", ext_name, max_header->header_name, header_value); + "regexp for header '%s' did not match " + "on value '%s'", max_header->header_name, header_value); goto failed; } max = _regexp_match_get_value(header_value, 1, match_values, 2); if ( max == NULL ) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, - "%s: regexp did not return match value " - "for string '%s'", ext_name, header_value); + "regexp did not return match value " + "for string '%s'", header_value); goto failed; } } else { @@ -532,7 +531,7 @@ if ( !ext_spamvirustest_parse_decimal_value(max, &max_value, &error) ) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, - "%s: failed to parse maximum value: %s", ext_name, error); + "failed to parse maximum value: %s", error); goto failed; } } else { @@ -541,7 +540,7 @@ if ( max_value == 0 ) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, - "%s: max value is 0", ext_name); + "error: max value is 0"); goto failed; } } else { @@ -557,8 +556,8 @@ (msgdata->mail, status_header->header_name, &header_value) < 0 || header_value == NULL ) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, - "%s: header '%s' not found in message", - ext_name, status_header->header_name); + "header '%s' not found in message", + status_header->header_name); goto failed; } @@ -567,16 +566,16 @@ if ( regexec(&status_header->regexp, header_value, 2, match_values, 0) != 0 ) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, - "%s: regexp for header '%s' did not match on value '%s'", - ext_name, status_header->header_name, header_value); + "regexp for header '%s' did not match on value '%s'", + status_header->header_name, header_value); goto failed; } status = _regexp_match_get_value(header_value, 1, match_values, 2); if ( status == NULL ) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, - "%s: regexp did not return match value for string '%s'", - ext_name, header_value); + "regexp did not return match value for string '%s'", + header_value); goto failed; } } else { @@ -588,8 +587,8 @@ if ( !ext_spamvirustest_parse_decimal_value (status, &status_value, &error) ) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, - "%s: failed to parse status value '%s': %s", - ext_name, status, error); + "failed to parse status value '%s': %s", + status, error); goto failed; } break; @@ -597,8 +596,8 @@ if ( !ext_spamvirustest_parse_strlen_value (status, &status_value, &error) ) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, - "%s: failed to parse status value '%s': %s", - ext_name, status, error); + "failed to parse status value '%s': %s", + status, error); goto failed; } break; @@ -618,8 +617,8 @@ if ( i > max_text ) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, - "%s: failed to match textstatus value '%s'", - ext_name, status); + "failed to match textstatus value '%s'", + status); goto failed; } break; @@ -636,6 +635,10 @@ else mctx->score_ratio = (status_value / max_value); + sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, + "extracted score=%.3f, max=%.3f, ratio=%.0f %%", + status_value, max_value, mctx->score_ratio * 100); + return ext_spamvirustest_get_score(ext, mctx->score_ratio, percent); failed: diff -r cfe8e9f49dfe -r ff55c9946366 src/lib-sieve/plugins/spamvirustest/tst-spamvirustest.c --- a/src/lib-sieve/plugins/spamvirustest/tst-spamvirustest.c Wed Aug 15 00:55:05 2012 +0200 +++ b/src/lib-sieve/plugins/spamvirustest/tst-spamvirustest.c Thu Aug 16 22:28:06 2012 +0200 @@ -290,7 +290,9 @@ } /* Get score value */ + sieve_runtime_trace_descend(renv); score_value = ext_spamvirustest_get_value(renv, this_ext, percent); + sieve_runtime_trace_ascend(renv); /* Construct value list */ value_list = sieve_single_stringlist_create_cstr(renv, score_value, TRUE); From dovecot at dovecot.org Fri Aug 17 07:47:27 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 17 Aug 2012 07:47:27 +0300 Subject: dovecot-2.2: imap: Added more tests to return empty data when FE... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2535dbe7c503 changeset: 14911:2535dbe7c503 user: Timo Sirainen date: Fri Aug 17 07:47:16 2012 +0300 description: imap: Added more tests to return empty data when FETCHing invalid MIME parts. diffstat: src/lib-imap-storage/imap-msgpart.c | 15 +++++++++++++-- 1 files changed, 13 insertions(+), 2 deletions(-) diffs (35 lines): diff -r 85b22a4af8d4 -r 2535dbe7c503 src/lib-imap-storage/imap-msgpart.c --- a/src/lib-imap-storage/imap-msgpart.c Thu Aug 16 14:57:55 2012 +0300 +++ b/src/lib-imap-storage/imap-msgpart.c Fri Aug 17 07:47:16 2012 +0300 @@ -112,9 +112,14 @@ for (; num > 1 && part != NULL; num--) part = part->next; } else { - /* only 1 allowed with non-multipart messages */ + /* only 1 allowed with non-multipart messages. + if the child isn't message/rfc822, the path must be + finished after this. */ if (num != 1) part = NULL; + else if (*path != '\0' && + (part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) == 0) + part = NULL; } if (part != NULL && @@ -520,8 +525,14 @@ } switch (msgpart->fetch_type) { + case FETCH_MIME: + if (part->parent == NULL) { + /* root message has no MIME headers */ + *part_r = NULL; + return 0; + } + break; case FETCH_FULL: - case FETCH_MIME: case FETCH_MIME_BODY: break; case FETCH_HEADER: From dovecot at dovecot.org Fri Aug 17 08:46:27 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 17 Aug 2012 08:46:27 +0300 Subject: dovecot-2.2: imap: FETCH[x.MIME] for message/rfc822 should produ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0c25f3ce29ef changeset: 14912:0c25f3ce29ef user: Timo Sirainen date: Fri Aug 17 08:46:22 2012 +0300 description: imap: FETCH[x.MIME] for message/rfc822 should produce empty result diffstat: src/lib-imap-storage/imap-msgpart.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (15 lines): diff -r 2535dbe7c503 -r 0c25f3ce29ef src/lib-imap-storage/imap-msgpart.c --- a/src/lib-imap-storage/imap-msgpart.c Fri Aug 17 07:47:16 2012 +0300 +++ b/src/lib-imap-storage/imap-msgpart.c Fri Aug 17 08:46:22 2012 +0300 @@ -526,8 +526,9 @@ switch (msgpart->fetch_type) { case FETCH_MIME: - if (part->parent == NULL) { - /* root message has no MIME headers */ + if (part->parent == NULL || + (part->parent->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) != 0) { + /* message/rfc822 itself has no MIME headers */ *part_r = NULL; return 0; } From dovecot at dovecot.org Fri Aug 17 09:17:58 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 17 Aug 2012 09:17:58 +0300 Subject: dovecot-2.1: doveadm backup: Fixed "is source empty" check. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/5f280c1ec9fd changeset: 14671:5f280c1ec9fd user: Timo Sirainen date: Fri Aug 17 09:17:48 2012 +0300 description: doveadm backup: Fixed "is source empty" check. In POP3 boxes there is only INBOX, and it's possible that source becomes empty while backup has mails. The check is now "has source always been empty?" diffstat: src/doveadm/dsync/dsync-brain.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 670f467ff5c5 -r 5f280c1ec9fd src/doveadm/dsync/dsync-brain.c --- a/src/doveadm/dsync/dsync-brain.c Wed Aug 15 13:43:16 2012 +0300 +++ b/src/doveadm/dsync/dsync-brain.c Fri Aug 17 09:17:48 2012 +0300 @@ -313,7 +313,7 @@ if (count == 0) return TRUE; if (count == 1 && strcasecmp(boxes[0]->name, "INBOX") == 0 && - boxes[0]->message_count == 0) + boxes[0]->message_count == 0 && boxes[0]->uid_next == 1) return TRUE; return FALSE; } From dovecot at dovecot.org Fri Aug 17 11:15:34 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 17 Aug 2012 11:15:34 +0300 Subject: dovecot-2.2: Makefile: Install the useful doveadm*.h headers. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f3dbc8bd625b changeset: 14913:f3dbc8bd625b user: Timo Sirainen date: Fri Aug 17 11:15:21 2012 +0300 description: Makefile: Install the useful doveadm*.h headers. diffstat: src/doveadm/Makefile.am | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-) diffs (30 lines): diff -r 0c25f3ce29ef -r f3dbc8bd625b src/doveadm/Makefile.am --- a/src/doveadm/Makefile.am Fri Aug 17 08:46:22 2012 +0300 +++ b/src/doveadm/Makefile.am Fri Aug 17 11:15:21 2012 +0300 @@ -116,9 +116,8 @@ doveadm-print-server.c \ main.c -noinst_HEADERS = \ - client-connection.h \ - server-connection.h \ +pkginc_libdir = $(pkgincludedir) +pkginc_lib_HEADERS = \ doveadm.h \ doveadm-dump.h \ doveadm-mail.h \ @@ -126,9 +125,13 @@ doveadm-mailbox-list-iter.h \ doveadm-print.h \ doveadm-print-private.h \ + doveadm-util.h + +noinst_HEADERS = \ + client-connection.h \ + server-connection.h \ doveadm-server.h \ doveadm-settings.h \ - doveadm-util.h \ doveadm-who.h install-exec-local: From dovecot at dovecot.org Fri Aug 17 19:01:23 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 17 Aug 2012 19:01:23 +0300 Subject: dovecot-2.1: doveadm: Improved "passdb lookup failed" error mess... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/fe492bba225a changeset: 14672:fe492bba225a user: Timo Sirainen date: Fri Aug 17 19:01:03 2012 +0300 description: doveadm: Improved "passdb lookup failed" error message. diffstat: src/doveadm/doveadm-mail-server.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r 5f280c1ec9fd -r fe492bba225a src/doveadm/doveadm-mail-server.c --- a/src/doveadm/doveadm-mail-server.c Fri Aug 17 09:17:48 2012 +0300 +++ b/src/doveadm/doveadm-mail-server.c Fri Aug 17 19:01:03 2012 +0300 @@ -183,6 +183,9 @@ if (ret < 0) { *error_r = fields[0] != NULL ? t_strdup(fields[0]) : "passdb lookup failed"; + *error_r = t_strdup_printf("%s (to see if user is proxied, " + "because doveadm_proxy_port is set)", + *error_r); } else if (ret == 0) { /* user not found from passdb. it could be in userdb though, so just continue with the default host */ From dovecot at dovecot.org Sat Aug 18 10:31:29 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 18 Aug 2012 10:31:29 +0300 Subject: dovecot-2.2: connection API: Allow calling connection_input_defa... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/373879abd7f4 changeset: 14914:373879abd7f4 user: Timo Sirainen date: Sat Aug 18 10:31:19 2012 +0300 description: connection API: Allow calling connection_input_default() for buffered input. diffstat: src/lib/connection.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (13 lines): diff -r f3dbc8bd625b -r 373879abd7f4 src/lib/connection.c --- a/src/lib/connection.c Fri Aug 17 11:15:21 2012 +0300 +++ b/src/lib/connection.c Sat Aug 18 10:31:19 2012 +0300 @@ -31,8 +31,8 @@ switch (connection_input_read(conn)) { case -1: - case 0: return; + case 0: /* allow calling this function for buffered input */ case 1: break; default: From dovecot at dovecot.org Sat Aug 18 15:56:38 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 18 Aug 2012 15:56:38 +0300 Subject: dovecot-2.2: ostream-file: Fixed writing with zero buffer size. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/23e9660f0473 changeset: 14915:23e9660f0473 user: Timo Sirainen date: Sat Aug 18 15:56:30 2012 +0300 description: ostream-file: Fixed writing with zero buffer size. diffstat: src/lib/ostream-file.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (22 lines): diff -r 373879abd7f4 -r 23e9660f0473 src/lib/ostream-file.c --- a/src/lib/ostream-file.c Sat Aug 18 10:31:19 2012 +0300 +++ b/src/lib/ostream-file.c Sat Aug 18 15:56:30 2012 +0300 @@ -174,6 +174,8 @@ o_stream_socket_cork(fstream); if (iov_size == 1) { + i_assert(iov->iov_len > 0); + if (!fstream->file || fstream->real_offset == fstream->buffer_offset) { ret = write(fstream->fd, iov->iov_base, iov->iov_len); @@ -505,7 +507,8 @@ if (fstream->tail == fstream->buffer_size) fstream->tail = 0; - if (fstream->head == fstream->tail) + if (fstream->head == fstream->tail && + fstream->buffer_size > 0) fstream->full = TRUE; } From dovecot at dovecot.org Sat Aug 18 17:06:10 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 18 Aug 2012 17:06:10 +0300 Subject: dovecot-2.2: Added i_stream_create_seekable_path() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ecb92e343152 changeset: 14916:ecb92e343152 user: Timo Sirainen date: Sat Aug 18 17:05:59 2012 +0300 description: Added i_stream_create_seekable_path() diffstat: src/lib/istream-seekable.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ src/lib/istream-seekable.h | 5 ++++ 2 files changed, 52 insertions(+), 0 deletions(-) diffs (90 lines): diff -r 23e9660f0473 -r ecb92e343152 src/lib/istream-seekable.c --- a/src/lib/istream-seekable.c Sat Aug 18 15:56:30 2012 +0300 +++ b/src/lib/istream-seekable.c Sat Aug 18 17:05:59 2012 +0300 @@ -2,8 +2,10 @@ #include "lib.h" #include "buffer.h" +#include "str.h" #include "read-full.h" #include "write-full.h" +#include "safe-mkstemp.h" #include "istream-private.h" #include "istream-concat.h" #include "istream-seekable.h" @@ -27,6 +29,7 @@ struct istream *fd_input; unsigned int cur_idx; int fd; + bool free_context; }; static void i_stream_seekable_close(struct iostream_private *stream) @@ -59,6 +62,8 @@ i_stream_unref(&sstream->fd_input); unref_streams(sstream); + if (sstream->free_context) + i_free(sstream->context); i_free(sstream->temp_path); i_free(sstream->input); } @@ -405,3 +410,45 @@ return i_streams_merge(input, max_buffer_size, fd_callback, context); } + +static int seekable_fd_callback(const char **path_r, void *context) +{ + char *temp_path_prefix = context; + string_t *path; + int fd; + + path = t_str_new(128); + str_append(path, temp_path_prefix); + fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1); + if (fd == -1) { + i_error("safe_mkstemp(%s) failed: %m", str_c(path)); + return -1; + } + + /* we just want the fd, unlink it */ + if (unlink(str_c(path)) < 0) { + /* shouldn't happen.. */ + i_error("unlink(%s) failed: %m", str_c(path)); + i_close_fd(&fd); + return -1; + } + + *path_r = str_c(path); + return fd; +} + +struct istream * +i_stream_create_seekable_path(struct istream *input[], + size_t max_buffer_size, + const char *temp_path_prefix) +{ + struct seekable_istream *sstream; + struct istream *stream; + + stream = i_stream_create_seekable(input, max_buffer_size, + seekable_fd_callback, + i_strdup(temp_path_prefix)); + sstream = (struct seekable_istream *)stream; + sstream->free_context = TRUE; + return stream; +} diff -r 23e9660f0473 -r ecb92e343152 src/lib/istream-seekable.h --- a/src/lib/istream-seekable.h Sat Aug 18 15:56:30 2012 +0300 +++ b/src/lib/istream-seekable.h Sat Aug 18 17:05:59 2012 +0300 @@ -20,4 +20,9 @@ int (*fd_callback)(const char **path_r, void *context), void *context) ATTR_NULL(4); +struct istream * +i_stream_create_seekable_path(struct istream *input[], + size_t max_buffer_size, + const char *temp_path_prefix); + #endif From dovecot at dovecot.org Sun Aug 19 07:20:24 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 19 Aug 2012 07:20:24 +0300 Subject: dovecot-2.2: hash_table_create(): Removed table_pool parameter. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1ce71b5bc94a changeset: 14917:1ce71b5bc94a user: Timo Sirainen date: Sun Aug 19 07:20:13 2012 +0300 description: hash_table_create(): Removed table_pool parameter. Every single caller was using default_pool there, so there's no point in having it. diffstat: src/anvil/connect-limit.c | 4 +- src/anvil/penalty.c | 2 +- src/auth/auth-cache.c | 2 +- src/auth/auth-request-handler.c | 2 +- src/auth/db-checkpassword.c | 2 +- src/auth/db-ldap.c | 2 +- src/auth/db-passwd-file.c | 5 +-- src/auth/mech-otp-skey-common.c | 3 +- src/config/config-request.c | 4 +- src/director/director-test.c | 6 ++-- src/director/user-directory.c | 3 +- src/doveadm/doveadm-director.c | 2 +- src/doveadm/doveadm-kick.c | 2 +- src/doveadm/doveadm-log.c | 2 +- src/doveadm/doveadm-mail-server.c | 3 +- src/doveadm/doveadm-stats.c | 2 +- src/doveadm/doveadm-who.c | 2 +- src/doveadm/dsync/dsync-brain.c | 3 +- src/doveadm/dsync/dsync-mailbox-export.c | 4 +- src/doveadm/dsync/dsync-mailbox-import.c | 4 +- src/doveadm/dsync/dsync-mailbox-tree.c | 6 ++-- src/doveadm/dsync/dsync-transaction-log-scan.c | 3 +- src/indexer/indexer-queue.c | 2 +- src/lib-auth/auth-server-connection.c | 2 +- src/lib-dict/dict-file.c | 2 +- src/lib-index/mail-cache.c | 2 +- src/lib-index/mail-index.c | 2 +- src/lib-lda/duplicate.c | 2 +- src/lib-master/master-auth.c | 3 +- src/lib-master/master-login-auth.c | 2 +- src/lib-master/master-service-settings-cache.c | 4 +- src/lib-settings/settings-parser.c | 7 ++--- src/lib-sql/sql-db-cache.c | 2 +- src/lib-storage/index/dbox-multi/mdbox-purge.c | 2 +- src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c | 2 +- src/lib-storage/index/index-thread-finish.c | 2 +- src/lib-storage/index/maildir/maildir-keywords.c | 4 +- src/lib-storage/index/maildir/maildir-uidlist.c | 4 +- src/lib-storage/list/mailbox-list-index.c | 6 +--- src/lib-storage/mailbox-guid-cache.c | 3 +- src/lib/child-wait.c | 3 +- src/lib/hash.c | 17 +++++++-------- src/lib/hash.h | 2 +- src/log/log-connection.c | 3 +- src/login-common/login-proxy-state.c | 2 +- src/login-common/ssl-proxy-gnutls.c | 3 +- src/login-common/ssl-proxy-openssl.c | 2 +- src/master/service.c | 2 +- src/plugins/acl/acl-cache.c | 4 +- src/plugins/expire/doveadm-expire.c | 5 +-- src/plugins/fts-lucene/fts-backend-lucene.c | 3 +- src/plugins/fts-lucene/lucene-wrapper.cc | 3 +- src/plugins/fts-solr/fts-backend-solr-old.c | 2 +- src/plugins/fts-solr/fts-backend-solr.c | 2 +- src/plugins/fts-solr/solr-connection.c | 2 +- src/plugins/fts/fts-expunge-log.c | 4 +-- src/pop3/pop3-commands.c | 4 +- src/replication/aggregator/replicator-connection.c | 3 +- src/replication/replicator/replicator-queue.c | 5 +-- src/stats/mail-domain.c | 2 +- src/stats/mail-ip.c | 2 +- src/stats/mail-session.c | 2 +- src/stats/mail-user.c | 2 +- 63 files changed, 89 insertions(+), 111 deletions(-) diffs (truncated from 932 to 300 lines): diff -r ecb92e343152 -r 1ce71b5bc94a src/anvil/connect-limit.c --- a/src/anvil/connect-limit.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/anvil/connect-limit.c Sun Aug 19 07:20:13 2012 +0300 @@ -46,10 +46,10 @@ limit = i_new(struct connect_limit, 1); limit->ident_hash = - hash_table_create(default_pool, default_pool, 0, + hash_table_create(default_pool, 0, str_hash, (hash_cmp_callback_t *)strcmp); limit->ident_pid_hash = - hash_table_create(default_pool, default_pool, 0, + hash_table_create(default_pool, 0, ident_pid_hash, ident_pid_cmp); return limit; } diff -r ecb92e343152 -r 1ce71b5bc94a src/anvil/penalty.c --- a/src/anvil/penalty.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/anvil/penalty.c Sun Aug 19 07:20:13 2012 +0300 @@ -51,7 +51,7 @@ penalty = i_new(struct penalty, 1); penalty->hash = - hash_table_create(default_pool, default_pool, 0, + hash_table_create(default_pool, 0, str_hash, (hash_cmp_callback_t *)strcmp); penalty->expire_secs = PENALTY_DEFAULT_EXPIRE_SECS; return penalty; diff -r ecb92e343152 -r 1ce71b5bc94a src/auth/auth-cache.c --- a/src/auth/auth-cache.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/auth/auth-cache.c Sun Aug 19 07:20:13 2012 +0300 @@ -221,7 +221,7 @@ struct auth_cache *cache; cache = i_new(struct auth_cache, 1); - cache->hash = hash_table_create(default_pool, default_pool, 0, str_hash, + cache->hash = hash_table_create(default_pool, 0, str_hash, (hash_cmp_callback_t *)strcmp); cache->size_left = max_size; cache->ttl_secs = ttl_secs; diff -r ecb92e343152 -r 1ce71b5bc94a src/auth/auth-request-handler.c --- a/src/auth/auth-request-handler.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/auth/auth-request-handler.c Sun Aug 19 07:20:13 2012 +0300 @@ -52,7 +52,7 @@ handler = p_new(pool, struct auth_request_handler, 1); handler->refcount = 1; handler->pool = pool; - handler->requests = hash_table_create(default_pool, pool, 0, NULL, NULL); + handler->requests = hash_table_create(pool, 0, NULL, NULL); handler->callback = callback; handler->context = context; handler->master_callback = master_callback; diff -r ecb92e343152 -r 1ce71b5bc94a src/auth/db-checkpassword.c --- a/src/auth/db-checkpassword.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/auth/db-checkpassword.c Sun Aug 19 07:20:13 2012 +0300 @@ -545,7 +545,7 @@ db = i_new(struct db_checkpassword, 1); db->checkpassword_path = i_strdup(checkpassword_path); db->checkpassword_reply_path = i_strdup(checkpassword_reply_path); - db->clients = hash_table_create(default_pool, default_pool, 0, + db->clients = hash_table_create(default_pool, 0, NULL, NULL); db->child_wait = child_wait_new_with_pid((pid_t)-1, sigchld_handler, db); diff -r ecb92e343152 -r 1ce71b5bc94a src/auth/db-ldap.c --- a/src/auth/db-ldap.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/auth/db-ldap.c Sun Aug 19 07:20:13 2012 +0300 @@ -1196,7 +1196,7 @@ ctx->auth_request = auth_request; ctx->attr_map = attr_map; ctx->ldap_attrs = - hash_table_create(default_pool, pool, 0, strcase_hash, + hash_table_create(pool, 0, strcase_hash, (hash_cmp_callback_t *)strcasecmp); if (auth_request->set->debug) ctx->debug = t_str_new(256); diff -r ecb92e343152 -r 1ce71b5bc94a src/auth/db-passwd-file.c --- a/src/auth/db-passwd-file.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/auth/db-passwd-file.c Sun Aug 19 07:20:13 2012 +0300 @@ -194,7 +194,7 @@ pw->size = st.st_size; pw->pool = pool_alloconly_create(MEMPOOL_GROWING"passwd_file", 10240); - pw->users = hash_table_create(default_pool, pw->pool, 100, + pw->users = hash_table_create(pw->pool, 100, str_hash, (hash_cmp_callback_t *)strcmp); start_time = time(NULL); @@ -344,8 +344,7 @@ db->path = i_strdup(path); if (db->vars) { - db->files = hash_table_create(default_pool, default_pool, 100, - str_hash, + db->files = hash_table_create(default_pool, 100, str_hash, (hash_cmp_callback_t *)strcmp); } else { db->default_file = passwd_file_new(db, path); diff -r ecb92e343152 -r 1ce71b5bc94a src/auth/mech-otp-skey-common.c --- a/src/auth/mech-otp-skey-common.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/auth/mech-otp-skey-common.c Sun Aug 19 07:20:13 2012 +0300 @@ -20,8 +20,7 @@ if (otp_lock_table != NULL) return; - otp_lock_table = hash_table_create(system_pool, system_pool, - 128, strcase_hash, + otp_lock_table = hash_table_create(default_pool, 128, strcase_hash, (hash_cmp_callback_t *)strcasecmp); } diff -r ecb92e343152 -r 1ce71b5bc94a src/config/config-request.c --- a/src/config/config-request.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/config/config-request.c Sun Aug 19 07:20:13 2012 +0300 @@ -361,8 +361,8 @@ ctx->scope = scope; ctx->value = t_str_new(256); ctx->prefix = t_str_new(64); - ctx->keys = hash_table_create(default_pool, ctx->pool, 0, - str_hash, (hash_cmp_callback_t *)strcmp); + ctx->keys = hash_table_create(ctx->pool, 0, str_hash, + (hash_cmp_callback_t *)strcmp); return ctx; } diff -r ecb92e343152 -r 1ce71b5bc94a src/director/director-test.c --- a/src/director/director-test.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/director/director-test.c Sun Aug 19 07:20:13 2012 +0300 @@ -532,9 +532,9 @@ static void main_init(const char *admin_path) { - users = hash_table_create(default_pool, default_pool, 0, - str_hash, (hash_cmp_callback_t *)strcmp); - hosts = hash_table_create(default_pool, default_pool, 0, + users = hash_table_create(default_pool, 0, str_hash, + (hash_cmp_callback_t *)strcmp); + hosts = hash_table_create(default_pool, 0, (hash_callback_t *)net_ip_hash, (hash_cmp_callback_t *)net_ip_cmp); i_array_init(&hosts_array, 256); diff -r ecb92e343152 -r 1ce71b5bc94a src/director/user-directory.c --- a/src/director/user-directory.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/director/user-directory.c Sun Aug 19 07:20:13 2012 +0300 @@ -225,8 +225,7 @@ I_MAX(dir->user_near_expiring_secs, 1); dir->username_hash_fmt = i_strdup(username_hash_fmt); - dir->hash = hash_table_create(default_pool, default_pool, - 0, NULL, NULL); + dir->hash = hash_table_create(default_pool, 0, NULL, NULL); i_array_init(&dir->iters, 8); return dir; } diff -r ecb92e343152 -r 1ce71b5bc94a src/doveadm/doveadm-director.c --- a/src/doveadm/doveadm-director.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/doveadm/doveadm-director.c Sun Aug 19 07:20:13 2012 +0300 @@ -295,7 +295,7 @@ director_get_host(argv[optind], &ips, &ips_count); pool = pool_alloconly_create("director map users", 1024*128); - users = hash_table_create(default_pool, pool, 0, NULL, NULL); + users = hash_table_create(pool, 0, NULL, NULL); if (ctx->users_path == NULL) userdb_get_user_list(NULL, pool, users); else diff -r ecb92e343152 -r 1ce71b5bc94a src/doveadm/doveadm-kick.c --- a/src/doveadm/doveadm-kick.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/doveadm/doveadm-kick.c Sun Aug 19 07:20:13 2012 +0300 @@ -179,7 +179,7 @@ ctx.who.anvil_path = t_strconcat(doveadm_settings->base_dir, "/anvil", NULL); ctx.force_kick = FALSE; ctx.who.pool = pool_alloconly_create("kick pids", 10240); - ctx.pids = hash_table_create(default_pool, ctx.who.pool, 0, NULL, NULL); + ctx.pids = hash_table_create(ctx.who.pool, 0, NULL, NULL); while ((c = getopt(argc, argv, "a:f")) > 0) { switch (c) { diff -r ecb92e343152 -r 1ce71b5bc94a src/doveadm/doveadm-log.c --- a/src/doveadm/doveadm-log.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/doveadm/doveadm-log.c Sun Aug 19 07:20:13 2012 +0300 @@ -222,7 +222,7 @@ memset(&ctx, 0, sizeof(ctx)); ctx.pool = pool_alloconly_create("log file", 1024*32); - ctx.files = hash_table_create(default_pool, ctx.pool, 0, + ctx.files = hash_table_create(ctx.pool, 0, str_hash, (hash_cmp_callback_t *)strcmp); /* first get the paths that we know are used */ diff -r ecb92e343152 -r 1ce71b5bc94a src/doveadm/doveadm-mail-server.c --- a/src/doveadm/doveadm-mail-server.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/doveadm/doveadm-mail-server.c Sun Aug 19 07:20:13 2012 +0300 @@ -38,8 +38,7 @@ if (servers == NULL) { server_pool = pool_alloconly_create("doveadm servers", 1024*16); - servers = hash_table_create(default_pool, server_pool, 0, - str_hash, + servers = hash_table_create(server_pool, 0, str_hash, (hash_cmp_callback_t *)strcmp); } server = hash_table_lookup(servers, name); diff -r ecb92e343152 -r 1ce71b5bc94a src/doveadm/doveadm-stats.c --- a/src/doveadm/doveadm-stats.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/doveadm/doveadm-stats.c Sun Aug 19 07:20:13 2012 +0300 @@ -478,7 +478,7 @@ ctx.cur_pool = pool_alloconly_create("stats top", 1024*16); i_array_init(&ctx.lines, 128); ctx.sessions = - hash_table_create(default_pool, default_pool, 0, + hash_table_create(default_pool, 0, str_hash, (hash_cmp_callback_t *)strcmp); net_set_nonblock(ctx.fd, FALSE); diff -r ecb92e343152 -r 1ce71b5bc94a src/doveadm/doveadm-who.c --- a/src/doveadm/doveadm-who.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/doveadm/doveadm-who.c Sun Aug 19 07:20:13 2012 +0300 @@ -274,7 +274,7 @@ memset(&ctx, 0, sizeof(ctx)); ctx.anvil_path = t_strconcat(doveadm_settings->base_dir, "/anvil", NULL); ctx.pool = pool_alloconly_create("who users", 10240); - ctx.users = hash_table_create(default_pool, ctx.pool, 0, + ctx.users = hash_table_create(ctx.pool, 0, who_user_hash, who_user_cmp); while ((c = getopt(argc, argv, "1a:")) > 0) { diff -r ecb92e343152 -r 1ce71b5bc94a src/doveadm/dsync/dsync-brain.c --- a/src/doveadm/dsync/dsync-brain.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/doveadm/dsync/dsync-brain.c Sun Aug 19 07:20:13 2012 +0300 @@ -48,8 +48,7 @@ brain->slave = slave; brain->sync_type = DSYNC_BRAIN_SYNC_TYPE_UNKNOWN; brain->remote_mailbox_states = - hash_table_create(default_pool, brain->pool, 0, - guid_128_hash, guid_128_cmp); + hash_table_create(brain->pool, 0, guid_128_hash, guid_128_cmp); p_array_init(&brain->mailbox_states, pool, 64); return brain; } diff -r ecb92e343152 -r 1ce71b5bc94a src/doveadm/dsync/dsync-mailbox-export.c --- a/src/doveadm/dsync/dsync-mailbox-export.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-export.c Sun Aug 19 07:20:13 2012 +0300 @@ -392,7 +392,7 @@ /* clone the hash table, since we're changing it. */ exporter->changes = - hash_table_create(default_pool, exporter->pool, + hash_table_create(exporter->pool, hash_table_count(log_changes), NULL, NULL); iter = hash_table_iterate_init(log_changes); while (hash_table_iterate(iter, &key, &value)) { @@ -431,7 +431,7 @@ (flags & DSYNC_MAILBOX_EXPORTER_FLAG_MAILS_HAVE_GUIDS) != 0; p_array_init(&exporter->requested_uids, pool, 16); exporter->export_guids = - hash_table_create(default_pool, pool, 0, + hash_table_create(pool, 0, str_hash, (hash_cmp_callback_t *)strcmp); p_array_init(&exporter->expunged_seqs, pool, 16); p_array_init(&exporter->expunged_guids, pool, 16); diff -r ecb92e343152 -r 1ce71b5bc94a src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Sun Aug 19 07:20:13 2012 +0300 @@ -135,10 +135,10 @@ importer->remote_highest_modseq = remote_highest_modseq; importer->import_guids = - hash_table_create(default_pool, pool, 0, + hash_table_create(pool, 0, str_hash, (hash_cmp_callback_t *)strcmp); importer->import_uids = - hash_table_create(default_pool, pool, 0, NULL, NULL); + hash_table_create(pool, 0, NULL, NULL); i_array_init(&importer->maybe_expunge_uids, 16); i_array_init(&importer->maybe_saves, 128); i_array_init(&importer->newmails, 128); diff -r ecb92e343152 -r 1ce71b5bc94a src/doveadm/dsync/dsync-mailbox-tree.c --- a/src/doveadm/dsync/dsync-mailbox-tree.c Sat Aug 18 17:05:59 2012 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-tree.c Sun Aug 19 07:20:13 2012 +0300 @@ -211,7 +211,7 @@ i_assert(tree->name128_hash == NULL); - tree->name128_hash = hash_table_create(default_pool, tree->pool, 0, + tree->name128_hash = hash_table_create(tree->pool, 0, guid_128_hash, guid_128_cmp); iter = dsync_mailbox_tree_iter_init(tree); while (dsync_mailbox_tree_iter_next(iter, &name, &node)) { @@ -251,7 +251,7 @@ i_assert(tree->name128_remotesep_hash == NULL); tree->name128_remotesep_hash = - hash_table_create(default_pool, tree->pool, 0, + hash_table_create(tree->pool, 0, guid_128_hash, guid_128_cmp); iter = dsync_mailbox_tree_iter_init(tree); while (dsync_mailbox_tree_iter_next(iter, &name, &node)) { @@ -296,7 +296,7 @@ From dovecot at dovecot.org Sun Aug 19 12:53:15 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 19 Aug 2012 12:53:15 +0300 Subject: dovecot-2.1: replicator: Crashfix Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/f68f5aca440e changeset: 14673:f68f5aca440e user: Timo Sirainen date: Sun Aug 19 12:53:06 2012 +0300 description: replicator: Crashfix diffstat: src/replication/aggregator/replicator-connection.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r fe492bba225a -r f68f5aca440e src/replication/aggregator/replicator-connection.c --- a/src/replication/aggregator/replicator-connection.c Fri Aug 17 19:01:03 2012 +0300 +++ b/src/replication/aggregator/replicator-connection.c Sun Aug 19 12:53:06 2012 +0300 @@ -54,7 +54,7 @@ i_error("Replicator sent invalid ID: %u", id); return -1; } - hash_table_remove(conn->requests, context); + hash_table_remove(conn->requests, POINTER_CAST(id)); conn->callback(line[0] == '+', context); return 0; } From dovecot at dovecot.org Sun Aug 19 13:55:45 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 19 Aug 2012 13:55:45 +0300 Subject: dovecot-2.2: Hash table API is now (mostly) type safe. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8eae4e205c82 changeset: 14918:8eae4e205c82 user: Timo Sirainen date: Sun Aug 19 13:55:34 2012 +0300 description: Hash table API is now (mostly) type safe. diffstat: src/anvil/connect-limit.c | 66 +++---- src/anvil/penalty.c | 6 +- src/auth/auth-cache.c | 14 +- src/auth/auth-request-handler.c | 19 +- src/auth/db-checkpassword.c | 14 +- src/auth/db-ldap.c | 18 +- src/auth/db-passwd-file.c | 21 +- src/auth/db-passwd-file.h | 6 +- src/auth/mech-otp-skey-common.c | 9 +- src/config/config-request.c | 5 +- src/director/director-test.c | 11 +- src/director/user-directory.c | 12 +- src/doveadm/doveadm-director.c | 21 +- src/doveadm/doveadm-kick.c | 17 +- src/doveadm/doveadm-log.c | 5 +- src/doveadm/doveadm-mail-server.c | 16 +- src/doveadm/doveadm-stats.c | 15 +- src/doveadm/doveadm-who.c | 12 +- src/doveadm/doveadm-who.h | 2 +- src/doveadm/dsync/dsync-brain-mailbox.c | 5 +- src/doveadm/dsync/dsync-brain-private.h | 3 +- src/doveadm/dsync/dsync-brain.c | 4 +- src/doveadm/dsync/dsync-mailbox-export.c | 26 +- src/doveadm/dsync/dsync-mailbox-import.c | 63 +++++-- src/doveadm/dsync/dsync-mailbox-tree-fill.c | 7 +- src/doveadm/dsync/dsync-mailbox-tree-private.h | 6 +- src/doveadm/dsync/dsync-mailbox-tree-sync.c | 22 +- src/doveadm/dsync/dsync-mailbox-tree.c | 51 +++--- src/doveadm/dsync/dsync-transaction-log-scan.c | 13 +- src/doveadm/dsync/dsync-transaction-log-scan.h | 5 +- src/indexer/indexer-queue.c | 17 +- src/lib-auth/auth-server-connection.c | 8 +- src/lib-auth/auth-server-connection.h | 2 +- src/lib-dict/dict-file.c | 22 +- src/lib-index/mail-cache-fields.c | 5 +- src/lib-index/mail-cache-private.h | 2 +- src/lib-index/mail-cache.c | 5 +- src/lib-index/mail-index-private.h | 2 +- src/lib-index/mail-index.c | 10 +- src/lib-lda/duplicate.c | 18 +- src/lib-master/master-auth.c | 14 +- src/lib-master/master-login-auth.c | 12 +- src/lib-master/master-service-settings-cache.c | 28 +-- src/lib-settings/settings-parser.c | 25 +- src/lib-sql/sql-db-cache.c | 5 +- src/lib-storage/index/dbox-multi/mdbox-purge.c | 23 +- src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c | 18 +- src/lib-storage/index/index-thread-finish.c | 15 +- src/lib-storage/index/maildir/maildir-filename.c | 7 +- src/lib-storage/index/maildir/maildir-filename.h | 4 +- src/lib-storage/index/maildir/maildir-keywords.c | 21 +- src/lib-storage/index/maildir/maildir-uidlist.c | 23 +- src/lib-storage/list/mailbox-list-index-sync.c | 9 +- src/lib-storage/list/mailbox-list-index.c | 15 +- src/lib-storage/list/mailbox-list-index.h | 8 +- src/lib-storage/mailbox-guid-cache.c | 20 +- src/lib-storage/mailbox-list-private.h | 2 +- src/lib-storage/mailbox-list.c | 2 +- src/lib/child-wait.c | 15 +- src/lib/guid.c | 10 +- src/lib/guid.h | 4 +- src/lib/hash.c | 74 ++++++--- src/lib/hash.h | 118 +++++++++++++- src/lib/lib.h | 1 + src/lib/macros.h | 7 +- src/log/log-connection.c | 18 +- src/login-common/login-proxy-state.c | 18 +- src/login-common/ssl-proxy-openssl.c | 23 +- src/master/service-monitor.c | 4 +- src/master/service-process.c | 4 +- src/master/service.c | 20 +-- src/master/service.h | 3 +- src/plugins/acl/acl-cache.c | 33 +-- src/plugins/expire/doveadm-expire.c | 23 +- src/plugins/fts-lucene/fts-backend-lucene.c | 11 +- src/plugins/fts-lucene/lucene-wrapper.cc | 36 ++-- src/plugins/fts-lucene/lucene-wrapper.h | 5 +- src/plugins/fts-solr/fts-backend-solr-old.c | 5 +- src/plugins/fts-solr/fts-backend-solr.c | 5 +- src/plugins/fts-solr/solr-connection.c | 7 +- src/plugins/fts/fts-expunge-log.c | 19 +- src/pop3/pop3-commands.c | 23 +- src/replication/aggregator/replicator-connection.c | 10 +- src/replication/replicator/replicator-queue.c | 6 +- src/stats/mail-domain.c | 6 +- src/stats/mail-ip.c | 8 +- src/stats/mail-session.c | 26 ++- src/stats/mail-user.c | 6 +- 88 files changed, 729 insertions(+), 655 deletions(-) diffs (truncated from 4261 to 300 lines): diff -r 1ce71b5bc94a -r 8eae4e205c82 src/anvil/connect-limit.c --- a/src/anvil/connect-limit.c Sun Aug 19 07:20:13 2012 +0300 +++ b/src/anvil/connect-limit.c Sun Aug 19 13:55:34 2012 +0300 @@ -16,22 +16,18 @@ struct connect_limit { /* ident => refcount */ - struct hash_table *ident_hash; + HASH_TABLE(char *, unsigned int) ident_hash; /* struct ident_pid => struct ident_pid */ - struct hash_table *ident_pid_hash; + HASH_TABLE(struct ident_pid *, struct ident_pid *) ident_pid_hash; }; -static unsigned int ident_pid_hash(const void *p) +static unsigned int ident_pid_hash(const struct ident_pid *i) { - const struct ident_pid *i = p; - return str_hash(i->ident) ^ i->pid; } -static int ident_pid_cmp(const void *p1, const void *p2) +static int ident_pid_cmp(const struct ident_pid *i1, const struct ident_pid *i2) { - const struct ident_pid *i1 = p1, *i2 = p2; - if (i1->pid < i2->pid) return -1; else if (i1->pid > i2->pid) @@ -45,12 +41,9 @@ struct connect_limit *limit; limit = i_new(struct connect_limit, 1); - limit->ident_hash = - hash_table_create(default_pool, 0, - str_hash, (hash_cmp_callback_t *)strcmp); - limit->ident_pid_hash = - hash_table_create(default_pool, 0, - ident_pid_hash, ident_pid_cmp); + hash_table_create(&limit->ident_hash, default_pool, 0, str_hash, strcmp); + hash_table_create(&limit->ident_pid_hash, default_pool, 0, + ident_pid_hash, ident_pid_cmp); return limit; } @@ -67,27 +60,24 @@ unsigned int connect_limit_lookup(struct connect_limit *limit, const char *ident) { - void *value; - - value = hash_table_lookup(limit->ident_hash, ident); - if (value == NULL) - return 0; - - return POINTER_CAST_TO(value, unsigned int); + return hash_table_lookup(limit->ident_hash, ident); } void connect_limit_connect(struct connect_limit *limit, pid_t pid, const char *ident) { struct ident_pid *i, lookup_i; - void *key, *value; + void *orig_key, *orig_value; + char *key; + unsigned int value; - if (!hash_table_lookup_full(limit->ident_hash, ident, &key, &value)) { + if (!hash_table_lookup_full(limit->ident_hash, ident, + &orig_key, &orig_value)) { key = i_strdup(ident); - value = POINTER_CAST(1); - hash_table_insert(limit->ident_hash, key, value); + hash_table_insert(limit->ident_hash, key, 1U); } else { - value = POINTER_CAST(POINTER_CAST_TO(value, unsigned int) + 1); + key = orig_key; + value = POINTER_CAST_TO(orig_value, unsigned int) + 1; hash_table_update(limit->ident_hash, key, value); } @@ -108,16 +98,18 @@ static void connect_limit_ident_hash_unref(struct connect_limit *limit, const char *ident) { - void *key, *value; + void *orig_key, *orig_value; + char *key; unsigned int new_refcount; - if (!hash_table_lookup_full(limit->ident_hash, ident, &key, &value)) + if (!hash_table_lookup_full(limit->ident_hash, ident, + &orig_key, &orig_value)) i_panic("connect limit hash tables are inconsistent"); - new_refcount = POINTER_CAST_TO(value, unsigned int) - 1; + key = orig_key; + new_refcount = POINTER_CAST_TO(orig_value, unsigned int) - 1; if (new_refcount > 0) { - value = POINTER_CAST(new_refcount); - hash_table_update(limit->ident_hash, key, value); + hash_table_update(limit->ident_hash, key, new_refcount); } else { hash_table_remove(limit->ident_hash, key); i_free(key); @@ -150,14 +142,12 @@ void connect_limit_disconnect_pid(struct connect_limit *limit, pid_t pid) { struct hash_iterate_context *iter; - struct ident_pid *i; - void *key, *value; + struct ident_pid *i, *value; /* this should happen rarely (or never), so this slow implementation should be fine. */ iter = hash_table_iterate_init(limit->ident_pid_hash); - while (hash_table_iterate(iter, &key, &value)) { - i = key; + while (hash_table_iterate_t(iter, limit->ident_pid_hash, &i, &value)) { if (i->pid == pid) { hash_table_remove(limit->ident_pid_hash, i); for (; i->refcount > 0; i->refcount--) @@ -171,13 +161,11 @@ void connect_limit_dump(struct connect_limit *limit, struct ostream *output) { struct hash_iterate_context *iter; - void *key, *value; + struct ident_pid *i, *value; string_t *str = t_str_new(256); iter = hash_table_iterate_init(limit->ident_pid_hash); - while (hash_table_iterate(iter, &key, &value)) { - struct ident_pid *i = key; - + while (hash_table_iterate_t(iter, limit->ident_pid_hash, &i, &value)) { str_truncate(str, 0); str_tabescape_write(str, i->ident); str_printfa(str, "\t%ld\t%u\n", (long)i->pid, i->refcount); diff -r 1ce71b5bc94a -r 8eae4e205c82 src/anvil/penalty.c --- a/src/anvil/penalty.c Sun Aug 19 07:20:13 2012 +0300 +++ b/src/anvil/penalty.c Sun Aug 19 13:55:34 2012 +0300 @@ -38,7 +38,7 @@ struct penalty { /* ident => penalty_rec */ - struct hash_table *hash; + HASH_TABLE(char *, struct penalty_rec *) hash; struct penalty_rec *oldest, *newest; unsigned int expire_secs; @@ -50,9 +50,7 @@ struct penalty *penalty; penalty = i_new(struct penalty, 1); - penalty->hash = - hash_table_create(default_pool, 0, - str_hash, (hash_cmp_callback_t *)strcmp); + hash_table_create(&penalty->hash, default_pool, 0, str_hash, strcmp); penalty->expire_secs = PENALTY_DEFAULT_EXPIRE_SECS; return penalty; } diff -r 1ce71b5bc94a -r 8eae4e205c82 src/auth/auth-cache.c --- a/src/auth/auth-cache.c Sun Aug 19 07:20:13 2012 +0300 +++ b/src/auth/auth-cache.c Sun Aug 19 13:55:34 2012 +0300 @@ -12,7 +12,7 @@ #include struct auth_cache { - struct hash_table *hash; + HASH_TABLE(char *, struct auth_cache_node *) hash; struct auth_cache_node *head, *tail; size_t size_left; @@ -178,10 +178,12 @@ static void auth_cache_node_destroy(struct auth_cache *cache, struct auth_cache_node *node) { + char *key = node->data; + auth_cache_node_unlink(cache, node); cache->size_left += node->alloc_size; - hash_table_remove(cache->hash, node->data); + hash_table_remove(cache->hash, key); i_free(node); } @@ -221,8 +223,7 @@ struct auth_cache *cache; cache = i_new(struct auth_cache, 1); - cache->hash = hash_table_create(default_pool, 0, str_hash, - (hash_cmp_callback_t *)strcmp); + hash_table_create(&cache->hash, default_pool, 0, str_hash, strcmp); cache->size_left = max_size; cache->ttl_secs = ttl_secs; cache->neg_ttl_secs = neg_ttl_secs; @@ -386,7 +387,7 @@ { struct auth_cache_node *node; size_t data_size, alloc_size, key_len, value_len = strlen(value); - char *current_username; + char *hash_key, *current_username; if (*value == '\0' && cache->neg_ttl_secs == 0) { /* we're not caching negative entries */ @@ -430,7 +431,8 @@ auth_cache_node_link_head(cache, node); cache->size_left -= alloc_size; - hash_table_insert(cache->hash, node->data, node); + hash_key = node->data; + hash_table_insert(cache->hash, hash_key, node); if (*value != '\0') { cache->pos_entries++; diff -r 1ce71b5bc94a -r 8eae4e205c82 src/auth/auth-request-handler.c --- a/src/auth/auth-request-handler.c Sun Aug 19 07:20:13 2012 +0300 +++ b/src/auth/auth-request-handler.c Sun Aug 19 13:55:34 2012 +0300 @@ -21,7 +21,7 @@ struct auth_request_handler { int refcount; pool_t pool; - struct hash_table *requests; + HASH_TABLE(unsigned int, struct auth_request *) requests; unsigned int connect_uid, client_pid; @@ -52,7 +52,7 @@ handler = p_new(pool, struct auth_request_handler, 1); handler->refcount = 1; handler->pool = pool; - handler->requests = hash_table_create(pool, 0, NULL, NULL); + hash_table_create_direct(&handler->requests, pool, 0); handler->callback = callback; handler->context = context; handler->master_callback = master_callback; @@ -72,6 +72,7 @@ iter = hash_table_iterate_init(handler->requests); while (hash_table_iterate(iter, &key, &value)) { + unsigned int id = POINTER_CAST_TO(key, unsigned int); struct auth_request *auth_request = value; switch (auth_request->state) { @@ -79,7 +80,7 @@ case AUTH_REQUEST_STATE_MECH_CONTINUE: case AUTH_REQUEST_STATE_FINISHED: auth_request_unref(&auth_request); - hash_table_remove(handler->requests, key); + hash_table_remove(handler->requests, id); break; case AUTH_REQUEST_STATE_PASSDB: case AUTH_REQUEST_STATE_USERDB: @@ -146,7 +147,7 @@ request, so make sure we don't get back here. */ timeout_remove(&request->to_abort); - hash_table_remove(handler->requests, POINTER_CAST(request->id)); + hash_table_remove(handler->requests, request->id); auth_request_unref(&request); } @@ -513,7 +514,7 @@ auth_request_unref(&request); return FALSE; } - if (hash_table_lookup(handler->requests, POINTER_CAST(id)) != NULL) { + if (hash_table_lookup(handler->requests, id) != NULL) { i_error("BUG: Authentication client %u " "sent a duplicate ID %u", handler->client_pid, id); auth_request_unref(&request); @@ -523,7 +524,7 @@ request->to_abort = timeout_add(MASTER_AUTH_SERVER_TIMEOUT_SECS * 1000, auth_request_timeout, request); - hash_table_insert(handler->requests, POINTER_CAST(id), request); + hash_table_insert(handler->requests, id, request); if (request->set->ssl_require_client_cert && !request->valid_client_cert) { @@ -578,7 +579,7 @@ } data++; - request = hash_table_lookup(handler->requests, POINTER_CAST(id)); + request = hash_table_lookup(handler->requests, id); if (request == NULL) { struct auth_stream_reply *reply; @@ -685,7 +686,7 @@ reply = auth_stream_reply_init(pool_datastack_create()); - request = hash_table_lookup(handler->requests, POINTER_CAST(client_id)); + request = hash_table_lookup(handler->requests, client_id); if (request == NULL) { i_error("Master request %u.%u not found", From dovecot at dovecot.org Sun Aug 19 14:01:27 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 19 Aug 2012 14:01:27 +0300 Subject: dovecot-2.2: Added missing hash-decl.h Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ed0fd7c1e8ff changeset: 14919:ed0fd7c1e8ff user: Timo Sirainen date: Sun Aug 19 14:01:15 2012 +0300 description: Added missing hash-decl.h diffstat: src/lib/Makefile.am | 1 + src/lib/hash-decl.h | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 0 deletions(-) diffs (35 lines): diff -r 8eae4e205c82 -r ed0fd7c1e8ff src/lib/Makefile.am --- a/src/lib/Makefile.am Sun Aug 19 13:55:34 2012 +0300 +++ b/src/lib/Makefile.am Sun Aug 19 14:01:15 2012 +0300 @@ -164,6 +164,7 @@ fsync-mode.h \ guid.h \ hash.h \ + hash-decl.h \ hash-format.h \ hash-method.h \ hash2.h \ diff -r 8eae4e205c82 -r ed0fd7c1e8ff src/lib/hash-decl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/hash-decl.h Sun Aug 19 14:01:15 2012 +0300 @@ -0,0 +1,20 @@ +#ifndef HASH_DECL_H +#define HASH_DECL_H + +#define HASH_TABLE_UNION(key_type, value_type) { \ + struct hash_table *_table; \ + key_type _key; \ + key_type *_keyp; \ + const key_type _const_key; \ + value_type _value; \ + value_type *_valuep; \ + } + +#define HASH_TABLE_DEFINE_TYPE(name, key_type, value_type) \ + union hash ## __ ## name HASH_TABLE_UNION(key_type, value_type) +#define HASH_TABLE(key_type, value_type) \ + union HASH_TABLE_UNION(key_type, value_type) +#define HASH_TABLE_TYPE(name) \ + union hash ## __ ## name + +#endif From dovecot at dovecot.org Sun Aug 19 14:21:52 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 19 Aug 2012 14:21:52 +0300 Subject: dovecot-2.2: Array API changed: ARRAY_DEFINE(name, type) -> ARRA... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a097ef0a9d6d changeset: 14920:a097ef0a9d6d user: Timo Sirainen date: Sun Aug 19 14:21:37 2012 +0300 description: Array API changed: ARRAY_DEFINE(name, type) -> ARRAY(type) name Easy way to update your existing code: perl -i -pe 's:ARRAY_DEFINE\(([^,]+), *([^)]+)\);:ARRAY($2) $1;:' **/*.[ch] diffstat: src/auth/auth-request-handler.c | 2 +- src/auth/auth-settings.c | 2 +- src/auth/auth-settings.h | 4 +- src/auth/auth-worker-server.c | 4 +- src/auth/auth.c | 2 +- src/auth/db-ldap.h | 2 +- src/auth/main.c | 2 +- src/auth/passdb-template.c | 2 +- src/auth/passdb.c | 4 +- src/auth/userdb-template.c | 2 +- src/auth/userdb.c | 4 +- src/config/config-parser-private.h | 2 +- src/config/config-parser.c | 2 +- src/dict/dict-connection.h | 2 +- src/dict/dict-settings.h | 2 +- src/director/director-test.c | 2 +- src/director/director.h | 6 +- src/director/mail-host.c | 2 +- src/director/main.c | 2 +- src/director/user-directory.c | 2 +- src/doveadm/doveadm-dump.c | 2 +- src/doveadm/doveadm-kick.c | 4 +- src/doveadm/doveadm-mail-altmove.c | 2 +- src/doveadm/doveadm-mail-fetch.c | 2 +- src/doveadm/doveadm-mail.h | 2 +- src/doveadm/doveadm-print-flow.c | 2 +- src/doveadm/doveadm-print-pager.c | 2 +- src/doveadm/doveadm-print-table.c | 2 +- src/doveadm/doveadm-print.c | 2 +- src/doveadm/doveadm-server.h | 2 +- src/doveadm/doveadm-settings.h | 2 +- src/doveadm/doveadm-stats.c | 2 +- src/doveadm/doveadm-who.c | 4 +- src/doveadm/doveadm.c | 2 +- src/doveadm/dsync/dsync-mailbox-export.c | 2 +- src/doveadm/dsync/dsync-mailbox-import.c | 6 +- src/doveadm/dsync/dsync-mailbox-tree-private.h | 2 +- src/doveadm/dsync/dsync-mailbox-tree-sync.c | 4 +- src/doveadm/dsync/dsync-slave-pipe.c | 4 +- src/imap/cmd-list.c | 6 +- src/imap/imap-client.h | 6 +- src/imap/imap-commands-util.c | 2 +- src/imap/imap-commands.c | 2 +- src/imap/imap-fetch.c | 2 +- src/imap/imap-fetch.h | 2 +- src/imap/imap-notify.h | 4 +- src/imap/imap-search.h | 2 +- src/indexer/worker-connection.c | 2 +- src/ipc/ipc-connection.h | 2 +- src/ipc/ipc-group.c | 2 +- src/lib-auth/auth-server-connection.h | 2 +- src/lib-dict/dict-memcached-ascii.c | 4 +- src/lib-dict/dict-redis.c | 4 +- src/lib-dict/dict-sql-settings.c | 2 +- src/lib-dict/dict-sql-settings.h | 2 +- src/lib-dict/dict-sql.c | 2 +- src/lib-dict/dict-transaction-memory.h | 2 +- src/lib-dict/dict.c | 2 +- src/lib-imap-client/imapc-client-private.h | 2 +- src/lib-imap-client/imapc-connection.c | 4 +- src/lib-index/mail-cache-compress.c | 2 +- src/lib-index/mail-cache-lookup.c | 2 +- src/lib-index/mail-cache-transaction.c | 4 +- src/lib-index/mail-index-modseq.c | 2 +- src/lib-index/mail-index-private.h | 14 ++++---- src/lib-index/mail-index-strmap.c | 2 +- src/lib-index/mail-index-sync-private.h | 4 +- src/lib-index/mail-index-sync.c | 2 +- src/lib-index/mail-index-transaction-export.c | 2 +- src/lib-index/mail-index-transaction-private.h | 25 +++++++-------- src/lib-index/mail-index-transaction-view.c | 2 +- src/lib-index/mail-index-view-private.h | 4 +- src/lib-index/mail-transaction-log-view-private.h | 2 +- src/lib-lda/lmtp-client.c | 2 +- src/lib-lda/mail-deliver.h | 2 +- src/lib-mail/istream-attachment-connector.c | 2 +- src/lib-mail/istream-header-filter.c | 2 +- src/lib-mail/rfc2231-parser.c | 2 +- src/lib-mail/test-istream-attachment.c | 2 +- src/lib-master/anvil-client.c | 2 +- src/lib-master/ipc-client.c | 2 +- src/lib-master/master-instance.c | 2 +- src/lib-master/master-service-settings.c | 2 +- src/lib-master/mountpoint-list.c | 2 +- src/lib-settings/settings-parser.c | 2 +- src/lib-sql/driver-pgsql.c | 2 +- src/lib-sql/driver-sqlpool.c | 4 +- src/lib-sql/sql-api-private.h | 2 +- src/lib-storage/index/dbox-common/dbox-file.h | 2 +- src/lib-storage/index/dbox-multi/mdbox-map-private.h | 6 +- src/lib-storage/index/dbox-multi/mdbox-save.c | 2 +- src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c | 2 +- src/lib-storage/index/dbox-multi/mdbox-storage.h | 2 +- src/lib-storage/index/dbox-single/sdbox-save.c | 2 +- src/lib-storage/index/imapc/imapc-storage.h | 8 ++-- src/lib-storage/index/index-mail-binary.c | 2 +- src/lib-storage/index/index-mail-headers.c | 4 +- src/lib-storage/index/index-mail.h | 6 +- src/lib-storage/index/index-search-private.h | 2 +- src/lib-storage/index/index-storage.c | 2 +- src/lib-storage/index/index-sync-changes.c | 2 +- src/lib-storage/index/index-thread-finish.c | 4 +- src/lib-storage/index/maildir/maildir-keywords.c | 2 +- src/lib-storage/index/maildir/maildir-save.c | 2 +- src/lib-storage/index/mbox/mbox-sync-private.h | 2 +- src/lib-storage/list/mailbox-list-fs-iter.c | 6 +- src/lib-storage/list/mailbox-list-index-notify.c | 4 +- src/lib-storage/list/mailbox-list-maildir.c | 2 +- src/lib-storage/mail-search-register-human.c | 2 +- src/lib-storage/mail-search-register.c | 2 +- src/lib-storage/mail-storage-hooks.c | 8 +--- src/lib-storage/mail-storage-private.h | 15 ++++----- src/lib-storage/mail-storage-settings.h | 6 +- src/lib-storage/mail-user.h | 4 +- src/lib-storage/mailbox-keywords.c | 2 +- src/lib-storage/mailbox-list-iter.c | 2 +- src/lib-storage/mailbox-list-private.h | 5 +- src/lib-storage/mailbox-list.c | 2 +- src/lib-storage/mailbox-tree.c | 2 +- src/lib/array-decl.h | 2 +- src/lib/array.h | 2 +- src/lib/ioloop-epoll.c | 4 +- src/lib/ioloop-kqueue.c | 2 +- src/lib/ioloop-private.h | 2 +- src/lib/lib.h | 2 +- src/lib/module-context.h | 2 +- src/lib/priorityq.c | 2 +- src/lib/test-aqueue.c | 2 +- src/lib/test-array.c | 4 +- src/lib/var-expand.c | 2 +- src/lmtp/client.h | 2 +- src/lmtp/lmtp-proxy.c | 4 +- src/log/log-connection.c | 2 +- src/master/service-listen.c | 4 +- src/master/service-process-notify.c | 2 +- src/master/service.h | 4 +- src/plugins/acl/acl-backend-vfile.h | 4 +- src/plugins/acl/acl-cache.c | 2 +- src/plugins/expire/doveadm-expire.c | 2 +- src/plugins/expire/expire-set.c | 2 +- src/plugins/fts-lucene/fts-backend-lucene.c | 2 +- src/plugins/fts-lucene/lucene-wrapper.cc | 2 +- src/plugins/fts-solr/fts-backend-solr-old.c | 2 +- src/plugins/fts-solr/fts-backend-solr.c | 4 +- src/plugins/fts-solr/solr-connection.c | 2 +- src/plugins/fts-squat/squat-trie.c | 2 +- src/plugins/fts-squat/squat-uidlist.c | 2 +- src/plugins/fts/fts-api.c | 2 +- src/plugins/fts/fts-parser-script.c | 2 +- src/plugins/fts/fts-storage.h | 2 +- src/plugins/pop3-migration/pop3-migration-plugin.c | 4 +- src/plugins/quota/quota-private.h | 12 +++--- src/plugins/quota/quota-storage.c | 4 +- src/plugins/quota/quota.c | 2 +- src/plugins/trash/trash-plugin.c | 2 +- src/plugins/virtual/virtual-mail.c | 2 +- src/plugins/virtual/virtual-search.c | 2 +- src/plugins/virtual/virtual-storage.h | 2 +- src/plugins/virtual/virtual-sync.c | 2 +- src/plugins/virtual/virtual-transaction.h | 3 +- src/pop3/pop3-client.c | 2 +- src/pop3/pop3-client.h | 2 +- src/replication/replicator/replicator-brain.c | 2 +- src/replication/replicator/replicator-queue.c | 4 +- src/ssl-params/main.c | 2 +- 165 files changed, 244 insertions(+), 252 deletions(-) diffs (truncated from 2442 to 300 lines): diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/auth/auth-request-handler.c --- a/src/auth/auth-request-handler.c Sun Aug 19 14:01:15 2012 +0300 +++ b/src/auth/auth-request-handler.c Sun Aug 19 14:21:37 2012 +0300 @@ -33,7 +33,7 @@ unsigned int destroyed:1; }; -static ARRAY_DEFINE(auth_failures_arr, struct auth_request *); +static ARRAY(struct auth_request *) auth_failures_arr; static struct aqueue *auth_failures; static struct timeout *to_auth_failures; diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/auth/auth-settings.c --- a/src/auth/auth-settings.c Sun Aug 19 14:01:15 2012 +0300 +++ b/src/auth/auth-settings.c Sun Aug 19 14:21:37 2012 +0300 @@ -278,7 +278,7 @@ const char **error_r) { const char *const *tmp; - ARRAY_DEFINE(ips_array, struct ip_addr); + ARRAY(struct ip_addr) ips_array; struct ip_addr *ips; unsigned int ips_count; int ret; diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/auth/auth-settings.h --- a/src/auth/auth-settings.h Sun Aug 19 14:01:15 2012 +0300 +++ b/src/auth/auth-settings.h Sun Aug 19 14:21:37 2012 +0300 @@ -49,8 +49,8 @@ unsigned int worker_max_count; - ARRAY_DEFINE(passdbs, struct auth_passdb_settings *); - ARRAY_DEFINE(userdbs, struct auth_userdb_settings *); + ARRAY(struct auth_passdb_settings *) passdbs; + ARRAY(struct auth_userdb_settings *) userdbs; const char *base_dir; bool verbose_proctitle; diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/auth/auth-worker-server.c --- a/src/auth/auth-worker-server.c Sun Aug 19 14:01:15 2012 +0300 +++ b/src/auth/auth-worker-server.c Sun Aug 19 14:21:37 2012 +0300 @@ -46,9 +46,9 @@ unsigned int shutdown:1; }; -static ARRAY_DEFINE(connections, struct auth_worker_connection *) = ARRAY_INIT; +static ARRAY(struct auth_worker_connection *) connections = ARRAY_INIT; static unsigned int idle_count = 0, auth_workers_with_errors = 0; -static ARRAY_DEFINE(worker_request_array, struct auth_worker_request *); +static ARRAY(struct auth_worker_request *) worker_request_array; static struct aqueue *worker_request_queue; static time_t auth_worker_last_warn; static unsigned int auth_workers_throttle_count; diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/auth/auth.c --- a/src/auth/auth.c Sun Aug 19 14:01:15 2012 +0300 +++ b/src/auth/auth.c Sun Aug 19 14:21:37 2012 +0300 @@ -16,7 +16,7 @@ .override_fields = "" }; -static ARRAY_DEFINE(auths, struct auth *); +static ARRAY(struct auth *) auths; static void auth_passdb_preinit(struct auth *auth, const struct auth_passdb_settings *set, diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/auth/db-ldap.h --- a/src/auth/db-ldap.h Sun Aug 19 14:01:15 2012 +0300 +++ b/src/auth/db-ldap.h Sun Aug 19 14:21:37 2012 +0300 @@ -149,7 +149,7 @@ /* Request queue contains sent requests at tail (msgid != -1) and queued requests at head (msgid == -1). */ struct aqueue *request_queue; - ARRAY_DEFINE(request_array, struct ldap_request *); + ARRAY(struct ldap_request *) request_array; /* Number of messages in queue with msgid != -1 */ unsigned int pending_count; diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/auth/main.c --- a/src/auth/main.c Sun Aug 19 14:01:15 2012 +0300 +++ b/src/auth/main.c Sun Aug 19 14:21:37 2012 +0300 @@ -56,7 +56,7 @@ static pool_t auth_set_pool; static struct module *modules = NULL; static struct mechanisms_register *mech_reg; -static ARRAY_DEFINE(listeners, struct auth_socket_listener); +static ARRAY(struct auth_socket_listener) listeners; void auth_refresh_proctitle(void) { diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/auth/passdb-template.c --- a/src/auth/passdb-template.c Sun Aug 19 14:01:15 2012 +0300 +++ b/src/auth/passdb-template.c Sun Aug 19 14:21:37 2012 +0300 @@ -8,7 +8,7 @@ #include "passdb-template.h" struct passdb_template { - ARRAY_DEFINE(args, const char *); + ARRAY(const char *) args; }; struct passdb_template *passdb_template_build(pool_t pool, const char *args) diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/auth/passdb.c --- a/src/auth/passdb.c Sun Aug 19 14:01:15 2012 +0300 +++ b/src/auth/passdb.c Sun Aug 19 14:21:37 2012 +0300 @@ -9,8 +9,8 @@ #include -static ARRAY_DEFINE(passdb_interfaces, struct passdb_module_interface *); -static ARRAY_DEFINE(passdb_modules, struct passdb_module *); +static ARRAY(struct passdb_module_interface *) passdb_interfaces; +static ARRAY(struct passdb_module *) passdb_modules; static const struct passdb_module_interface passdb_iface_deinit = { .name = "deinit" diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/auth/userdb-template.c --- a/src/auth/userdb-template.c Sun Aug 19 14:01:15 2012 +0300 +++ b/src/auth/userdb-template.c Sun Aug 19 14:21:37 2012 +0300 @@ -8,7 +8,7 @@ #include "userdb-template.h" struct userdb_template { - ARRAY_DEFINE(args, const char *); + ARRAY(const char *) args; }; struct userdb_template * diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/auth/userdb.c --- a/src/auth/userdb.c Sun Aug 19 14:01:15 2012 +0300 +++ b/src/auth/userdb.c Sun Aug 19 14:21:37 2012 +0300 @@ -9,8 +9,8 @@ #include -static ARRAY_DEFINE(userdb_interfaces, struct userdb_module_interface *); -static ARRAY_DEFINE(userdb_modules, struct userdb_module *); +static ARRAY(struct userdb_module_interface *) userdb_interfaces; +static ARRAY(struct userdb_module *) userdb_modules; static const struct userdb_module_interface userdb_iface_deinit = { .name = "deinit" diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/config/config-parser-private.h --- a/src/config/config-parser-private.h Sun Aug 19 14:01:15 2012 +0300 +++ b/src/config/config-parser-private.h Sun Aug 19 14:21:37 2012 +0300 @@ -41,7 +41,7 @@ const char *path; const char *module; - ARRAY_DEFINE(all_parsers, struct config_filter_parser *); + ARRAY(struct config_filter_parser *) all_parsers; struct config_module_parser *root_parsers; struct config_section_stack *cur_section; struct input_stack *cur_input; diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/config/config-parser.c --- a/src/config/config-parser.c Sun Aug 19 14:01:15 2012 +0300 +++ b/src/config/config-parser.c Sun Aug 19 14:21:37 2012 +0300 @@ -980,7 +980,7 @@ struct module_dir_load_settings mod_set; struct module *m; const struct setting_parser_info **roots; - ARRAY_DEFINE(new_roots, const struct setting_parser_info *); + ARRAY(const struct setting_parser_info *) new_roots; ARRAY_TYPE(service_settings) new_services; struct service_settings *const *services, *service_set; unsigned int i, count; diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/dict/dict-connection.h --- a/src/dict/dict-connection.h Sun Aug 19 14:01:15 2012 +0300 +++ b/src/dict/dict-connection.h Sun Aug 19 14:21:37 2012 +0300 @@ -27,7 +27,7 @@ /* There are only a few transactions per client, so keeping them in array is fast enough */ - ARRAY_DEFINE(transactions, struct dict_connection_transaction); + ARRAY(struct dict_connection_transaction) transactions; }; struct dict_connection *dict_connection_create(int fd); diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/dict/dict-settings.h --- a/src/dict/dict-settings.h Sun Aug 19 14:01:15 2012 +0300 +++ b/src/dict/dict-settings.h Sun Aug 19 14:21:37 2012 +0300 @@ -4,7 +4,7 @@ struct dict_settings { const char *base_dir; const char *dict_db_config; - ARRAY_DEFINE(dicts, const char *); + ARRAY(const char *) dicts; }; extern const struct setting_parser_info dict_setting_parser_info; diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/director/director-test.c --- a/src/director/director-test.c Sun Aug 19 14:01:15 2012 +0300 +++ b/src/director/director-test.c Sun Aug 19 14:21:37 2012 +0300 @@ -91,7 +91,7 @@ static struct director_connection *director_connections; static HASH_TABLE(char *, struct user *) users; static HASH_TABLE(struct ip_addr *, struct host *) hosts; -static ARRAY_DEFINE(hosts_array, struct host *); +static ARRAY(struct host *) hosts_array; static struct admin_connection *admin; static struct timeout *to_disconnect; diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/director/director.h --- a/src/director/director.h Sun Aug 19 14:01:15 2012 +0300 +++ b/src/director/director.h Sun Aug 19 14:21:37 2012 +0300 @@ -39,7 +39,7 @@ is long. */ struct director_connection *left, *right; /* all director connections */ - ARRAY_DEFINE(connections, struct director_connection *); + ARRAY(struct director_connection *) connections; struct timeout *to_reconnect; struct timeout *to_sync; @@ -52,14 +52,14 @@ struct user_directory *users; /* these requests are waiting for directors to be in synced */ - ARRAY_DEFINE(pending_requests, struct director_request *); + ARRAY(struct director_request *) pending_requests; struct timeout *to_request; struct timeout *to_handshake_warning; director_state_change_callback_t *state_change_callback; /* director hosts are sorted by IP (and port) */ - ARRAY_DEFINE(dir_hosts, struct director_host *); + ARRAY(struct director_host *) dir_hosts; struct timeout *to_remove_dirs; struct ipc_client *ipc_proxy; diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/director/mail-host.c --- a/src/director/mail-host.c Sun Aug 19 14:01:15 2012 +0300 +++ b/src/director/mail-host.c Sun Aug 19 14:21:37 2012 +0300 @@ -8,7 +8,7 @@ struct mail_host_list { ARRAY_TYPE(mail_host) hosts; - ARRAY_DEFINE(vhosts, struct mail_host *); + ARRAY(struct mail_host *) vhosts; bool hosts_unsorted; }; diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/director/main.c --- a/src/director/main.c Sun Aug 19 14:01:15 2012 +0300 +++ b/src/director/main.c Sun Aug 19 14:21:37 2012 +0300 @@ -116,7 +116,7 @@ static void director_state_changed(struct director *dir) { struct director_request *const *requestp; - ARRAY_DEFINE(new_requests, struct director_request *); + ARRAY(struct director_request *) new_requests; bool ret; if (!dir->ring_synced || diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/director/user-directory.c --- a/src/director/user-directory.c Sun Aug 19 14:01:15 2012 +0300 +++ b/src/director/user-directory.c Sun Aug 19 14:21:37 2012 +0300 @@ -26,7 +26,7 @@ struct user *head, *tail; struct user *prev_insert_pos; - ARRAY_DEFINE(iters, struct user_directory_iter *); + ARRAY(struct user_directory_iter *) iters; char *username_hash_fmt; unsigned int timeout_secs; diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/doveadm/doveadm-dump.c --- a/src/doveadm/doveadm-dump.c Sun Aug 19 14:01:15 2012 +0300 +++ b/src/doveadm/doveadm-dump.c Sun Aug 19 14:21:37 2012 +0300 @@ -8,7 +8,7 @@ #include #include -static ARRAY_DEFINE(dumps, const struct doveadm_cmd_dump *); +static ARRAY(const struct doveadm_cmd_dump *) dumps; void doveadm_dump_register(const struct doveadm_cmd_dump *dump) { diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/doveadm/doveadm-kick.c --- a/src/doveadm/doveadm-kick.c Sun Aug 19 14:01:15 2012 +0300 +++ b/src/doveadm/doveadm-kick.c Sun Aug 19 14:21:37 2012 +0300 @@ -21,7 +21,7 @@ struct kick_pid { pid_t pid; - ARRAY_DEFINE(users, struct kick_user); + ARRAY(struct kick_user) users; bool kick; }; @@ -29,7 +29,7 @@ struct who_context who; HASH_TABLE(pid_t, struct kick_pid *) pids; bool force_kick; - ARRAY_DEFINE(kicked_users, const char *); + ARRAY(const char *) kicked_users; }; static void diff -r ed0fd7c1e8ff -r a097ef0a9d6d src/doveadm/doveadm-mail-altmove.c From dovecot at dovecot.org Sun Aug 19 16:17:47 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 19 Aug 2012 16:17:47 +0300 Subject: dovecot-2.2: Removed CONTEXT_TYPE_SAFETY macro and reimplemented... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d3db2ba15d00 changeset: 14921:d3db2ba15d00 user: Timo Sirainen date: Sun Aug 19 16:17:32 2012 +0300 description: Removed CONTEXT_TYPE_SAFETY macro and reimplemented its functionality better. gcc/clang now gives a compiler error in many places if callback isn't exactly what was expected. It's also now much easier to add more of these checks. diffstat: src/anvil/anvil-connection.c | 5 +- src/auth/auth-request-handler.h | 16 +++----- src/auth/db-dict.c | 3 +- src/auth/db-ldap.c | 3 +- src/auth/db-sql.c | 3 +- src/config/config-connection.c | 3 +- src/doveadm/doveadm-mail-mailbox.c | 4 +- src/doveadm/doveadm-stats.c | 2 +- src/doveadm/doveadm.c | 6 +- src/imap/imap-fetch.h | 15 ++----- src/indexer/indexer-client.c | 3 +- src/lib-dns/dns-lookup.c | 4 +- src/lib-dns/dns-lookup.h | 11 +++-- src/lib-imap-storage/imap-msgpart.c | 6 ++- src/lib-index/mail-index-util.c | 16 ++----- src/lib-lda/mail-send.c | 5 +- src/lib-mail/istream-header-filter.c | 8 ++-- src/lib-mail/istream-header-filter.h | 19 +++------ src/lib-mail/message-header-parser.h | 15 ++----- src/lib-mail/message-parser.h | 30 +++++---------- src/lib-mail/test-istream-header-filter.c | 8 ++- src/lib-master/master-service.c | 4 +- src/lib-settings/settings.c | 7 +-- src/lib-settings/settings.h | 30 ++++++++------- src/lib-sql/sql-api.h | 27 ++++--------- src/lib-storage/index/dbox-multi/mdbox-purge.c | 5 +- src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c | 14 +++---- src/lib-storage/index/imapc/imapc-mail-fetch.c | 2 +- src/lib-storage/index/index-mail-binary.c | 2 +- src/lib-storage/index/index-mail.c | 2 +- src/lib-storage/index/index-search.c | 7 +-- src/lib-storage/index/index-sort-string.c | 5 +- src/lib-storage/index/index-thread.c | 6 +-- src/lib-storage/index/maildir/maildir-mail.c | 3 +- src/lib-storage/index/maildir/maildir-storage.h | 15 ++----- src/lib-storage/index/maildir/maildir-sync-index.c | 4 +- src/lib-storage/index/mbox/mbox-mail.c | 2 +- src/lib-storage/index/pop3c/pop3c-sync.c | 4 +- src/lib-storage/mail-search.h | 13 ++---- src/lib-storage/mail-storage.h | 14 ++----- src/lib-storage/mailbox-header.c | 2 +- src/lib/array.h | 27 ++++---------- src/lib/bsearch-insert-pos.c | 1 + src/lib/bsearch-insert-pos.h | 22 +++++----- src/lib/child-wait.h | 14 ++---- src/lib/connection.c | 2 +- src/lib/ioloop.h | 30 ++++++++-------- src/lib/istream.h | 5 +- src/lib/macros.h | 17 ++------ src/lib/module-dir.c | 2 +- src/lib/ostream.h | 5 +- src/lib/strfuncs.c | 18 ++------- src/lib/strfuncs.h | 20 ++++++++-- src/lib/test-bsearch-insert-pos.c | 4 +- src/plugins/acl/acl-backend.c | 8 ++-- src/plugins/fts-squat/squat-uidlist.c | 6 +-- src/plugins/pop3-migration/pop3-migration-plugin.c | 2 +- 57 files changed, 218 insertions(+), 318 deletions(-) diffs (truncated from 1272 to 300 lines): diff -r a097ef0a9d6d -r d3db2ba15d00 src/anvil/anvil-connection.c --- a/src/anvil/anvil-connection.c Sun Aug 19 14:21:37 2012 +0300 +++ b/src/anvil/anvil-connection.c Sun Aug 19 16:17:32 2012 +0300 @@ -129,9 +129,8 @@ return 0; } -static void anvil_connection_input(void *context) +static void anvil_connection_input(struct anvil_connection *conn) { - struct anvil_connection *conn = context; const char *line, *const *args, *error; switch (i_stream_read(conn->input)) { @@ -153,7 +152,7 @@ if (anvil_restarted && (conn->master || conn->fifo)) { /* old pending data. ignore input until we get the handshake. */ - anvil_connection_input(context); + anvil_connection_input(conn); return; } i_error("Anvil client not compatible with this server " diff -r a097ef0a9d6d -r d3db2ba15d00 src/auth/auth-request-handler.h --- a/src/auth/auth-request-handler.h Sun Aug 19 14:21:37 2012 +0300 +++ b/src/auth/auth-request-handler.h Sun Aug 19 16:17:32 2012 +0300 @@ -17,18 +17,14 @@ struct auth_request_handler * auth_request_handler_create(auth_request_callback_t *callback, void *context, auth_request_callback_t *master_callback); -#ifdef CONTEXT_TYPE_SAFETY -# define auth_request_handler_create(callback, context, master_callback)\ - ({(void)(1 ? 0 : callback((struct auth_stream_reply *)NULL, context)); \ +#define auth_request_handler_create(callback, context, master_callback)\ auth_request_handler_create( \ - (auth_request_callback_t *)callback, context, \ - master_callback); }) -#else -# define auth_request_handler_create(callback, context, master_callback)\ - auth_request_handler_create( \ - (auth_request_callback_t *)callback, context, \ + (auth_request_callback_t *)callback, \ + (void *)((char*)context + \ + CALLBACK_TYPECHECK(callback, void (*)( \ + struct auth_stream_reply *, typeof(context)))), \ master_callback) -#endif + void auth_request_handler_destroy(struct auth_request_handler **handler); void auth_request_handler_unref(struct auth_request_handler **handler); void auth_request_handler_abort_requests(struct auth_request_handler *handler); diff -r a097ef0a9d6d -r d3db2ba15d00 src/auth/db-dict.c --- a/src/auth/db-dict.c Sun Aug 19 14:21:37 2012 +0300 +++ b/src/auth/db-dict.c Sun Aug 19 16:17:32 2012 +0300 @@ -81,8 +81,7 @@ conn->config_path = p_strdup(pool, config_path); conn->set = default_dict_settings; - if (!settings_read(config_path, NULL, parse_setting, - null_settings_section_callback, conn)) + if (!settings_read_nosection(config_path, parse_setting, conn)) exit(FATAL_DEFAULT); if (conn->set.uri == NULL) diff -r a097ef0a9d6d -r d3db2ba15d00 src/auth/db-ldap.c --- a/src/auth/db-ldap.c Sun Aug 19 14:21:37 2012 +0300 +++ b/src/auth/db-ldap.c Sun Aug 19 16:17:32 2012 +0300 @@ -1402,8 +1402,7 @@ conn->fd = -1; conn->config_path = p_strdup(pool, config_path); conn->set = default_ldap_settings; - if (!settings_read(config_path, NULL, parse_setting, - null_settings_section_callback, conn)) + if (!settings_read_nosection(config_path, parse_setting, conn)) exit(FATAL_DEFAULT); if (conn->set.base == NULL) diff -r a097ef0a9d6d -r d3db2ba15d00 src/auth/db-sql.c --- a/src/auth/db-sql.c Sun Aug 19 14:21:37 2012 +0300 +++ b/src/auth/db-sql.c Sun Aug 19 16:17:32 2012 +0300 @@ -86,8 +86,7 @@ conn->config_path = p_strdup(pool, config_path); conn->set = default_sql_settings; - if (!settings_read(config_path, NULL, parse_setting, - null_settings_section_callback, conn)) + if (!settings_read_nosection(config_path, parse_setting, conn)) exit(FATAL_DEFAULT); if (conn->set.password_query == default_sql_settings.password_query) diff -r a097ef0a9d6d -r d3db2ba15d00 src/config/config-connection.c --- a/src/config/config-connection.c Sun Aug 19 14:21:37 2012 +0300 +++ b/src/config/config-connection.c Sun Aug 19 16:17:32 2012 +0300 @@ -140,9 +140,8 @@ return 0; } -static void config_connection_input(void *context) +static void config_connection_input(struct config_connection *conn) { - struct config_connection *conn = context; const char *const *args, *line; switch (i_stream_read(conn->input)) { diff -r a097ef0a9d6d -r d3db2ba15d00 src/doveadm/doveadm-mail-mailbox.c --- a/src/doveadm/doveadm-mail-mailbox.c Sun Aug 19 14:21:37 2012 +0300 +++ b/src/doveadm/doveadm-mail-mailbox.c Sun Aug 19 16:17:32 2012 +0300 @@ -261,10 +261,8 @@ return &ctx->ctx.ctx; } -static int i_strcmp_reverse_p(const void *p1, const void *p2) +static int i_strcmp_reverse_p(const char *const *s1, const char *const *s2) { - const char *const *s1 = p1, *const *s2 = p2; - return -strcmp(*s1, *s2); } diff -r a097ef0a9d6d -r d3db2ba15d00 src/doveadm/doveadm-stats.c --- a/src/doveadm/doveadm-stats.c Sun Aug 19 14:21:37 2012 +0300 +++ b/src/doveadm/doveadm-stats.c Sun Aug 19 16:17:32 2012 +0300 @@ -372,7 +372,7 @@ stats_drop_stale(ctx); sort_ctx = ctx; - array_sort(&ctx->lines, ctx->lines_sort); + array_sort(&ctx->lines, *ctx->lines_sort); sort_ctx = NULL; return TRUE; } diff -r a097ef0a9d6d -r d3db2ba15d00 src/doveadm/doveadm.c --- a/src/doveadm/doveadm.c Sun Aug 19 14:21:37 2012 +0300 +++ b/src/doveadm/doveadm.c Sun Aug 19 16:17:32 2012 +0300 @@ -55,15 +55,15 @@ doveadm_usage_compress_lines(FILE *out, const char *str, const char *prefix) { const char *cmd, *args, *p, *short_name, *prev_name = ""; - char **lines; + const char **lines; unsigned int i, count, prefix_len = strlen(prefix); /* split lines */ - lines = p_strsplit(pool_datastack_create(), str, "\n"); + lines = (void *)p_strsplit(pool_datastack_create(), str, "\n"); for (count = 0; lines[count] != NULL; count++) ; /* sort lines */ - qsort(lines, count, sizeof(*lines), i_strcmp_p); + i_qsort(lines, count, sizeof(*lines), i_strcmp_p); /* print lines, compress subcommands into a single line */ for (i = 0; i < count; i++) { diff -r a097ef0a9d6d -r d3db2ba15d00 src/imap/imap-fetch.h --- a/src/imap/imap-fetch.h Sun Aug 19 14:21:37 2012 +0300 +++ b/src/imap/imap-fetch.h Sun Aug 19 16:17:32 2012 +0300 @@ -97,17 +97,12 @@ const char *nil_reply, imap_fetch_handler_t *handler, void *context) ATTR_NULL(3, 5); -#ifdef CONTEXT_TYPE_SAFETY -# define imap_fetch_add_handler(ctx, flags, nil_reply, handler, context) \ - ({(void)(1 ? 0 : handler((struct imap_fetch_context *)NULL, \ - (struct mail *)NULL, context)); \ - imap_fetch_add_handler(ctx, flags, nil_reply, \ - (imap_fetch_handler_t *)handler, context); }) -#else -# define imap_fetch_add_handler(ctx, flags, nil_reply, handler, context) \ - imap_fetch_add_handler(ctx, flags, nil_reply, \ +#define imap_fetch_add_handler(ctx, flags, nil_reply, handler, context) \ + imap_fetch_add_handler(ctx, flags, nil_reply + \ + CALLBACK_TYPECHECK(handler, int (*)( \ + struct imap_fetch_context *, struct mail *, \ + typeof(context))), \ (imap_fetch_handler_t *)handler, context) -#endif int imap_fetch_att_list_parse(struct client *client, pool_t pool, const struct imap_arg *list, diff -r a097ef0a9d6d -r d3db2ba15d00 src/indexer/indexer-client.c --- a/src/indexer/indexer-client.c Sun Aug 19 14:21:37 2012 +0300 +++ b/src/indexer/indexer-client.c Sun Aug 19 16:17:32 2012 +0300 @@ -147,9 +147,8 @@ } } -static void indexer_client_input(void *context) +static void indexer_client_input(struct indexer_client *client) { - struct indexer_client *client = context; const char *line, *const *args, *error; switch (i_stream_read(client->input)) { diff -r a097ef0a9d6d -r d3db2ba15d00 src/lib-dns/dns-lookup.c --- a/src/lib-dns/dns-lookup.c Sun Aug 19 14:21:37 2012 +0300 +++ b/src/lib-dns/dns-lookup.c Sun Aug 19 16:17:32 2012 +0300 @@ -121,8 +121,8 @@ #undef dns_lookup int dns_lookup(const char *host, const struct dns_lookup_settings *set, - struct dns_lookup **lookup_r, - dns_lookup_callback_t *callback, void *context) + dns_lookup_callback_t *callback, void *context, + struct dns_lookup **lookup_r) { struct dns_lookup *lookup; struct dns_lookup_result result; diff -r a097ef0a9d6d -r d3db2ba15d00 src/lib-dns/dns-lookup.h --- a/src/lib-dns/dns-lookup.h Sun Aug 19 14:21:37 2012 +0300 +++ b/src/lib-dns/dns-lookup.h Sun Aug 19 16:17:32 2012 +0300 @@ -29,12 +29,13 @@ When failing with -1, the callback is called before returning from the function. */ int dns_lookup(const char *host, const struct dns_lookup_settings *set, - struct dns_lookup **lookup_r, - dns_lookup_callback_t *callback, void *context) ATTR_NULL(5); + dns_lookup_callback_t *callback, void *context, + struct dns_lookup **lookup_r) ATTR_NULL(4); #define dns_lookup(host, set, callback, context, lookup_r) \ - CONTEXT_CALLBACK2(dns_lookup, dns_lookup_callback_t, \ - callback, const struct dns_lookup_result *, \ - context, host, set, lookup_r) + dns_lookup(host + \ + CALLBACK_TYPECHECK(callback, void (*)( \ + const struct dns_lookup_result *, typeof(context))), \ + set, (dns_lookup_callback_t *)callback, context, lookup_r) /* Abort the DNS lookup without calling the callback. */ void dns_lookup_abort(struct dns_lookup **lookup); diff -r a097ef0a9d6d -r d3db2ba15d00 src/lib-imap-storage/imap-msgpart.c --- a/src/lib-imap-storage/imap-msgpart.c Sun Aug 19 14:21:37 2012 +0300 +++ b/src/lib-imap-storage/imap-msgpart.c Sun Aug 19 16:17:32 2012 +0300 @@ -339,14 +339,16 @@ HEADER_FILTER_INCLUDE | HEADER_FILTER_HIDE_BODY, hdr_fields, hdr_count, - null_header_filter_callback, NULL); + *null_header_filter_callback, + (void *)NULL); } else { i_assert(msgpart->fetch_type == FETCH_HEADER_FIELDS_NOT); input = i_stream_create_header_filter(mail_input, HEADER_FILTER_EXCLUDE | HEADER_FILTER_HIDE_BODY, hdr_fields, hdr_count, - null_header_filter_callback, NULL); + *null_header_filter_callback, + (void *)NULL); } if (message_get_header_size(input, hdr_size_r, &has_nuls) < 0) { diff -r a097ef0a9d6d -r d3db2ba15d00 src/lib-index/mail-index-util.c --- a/src/lib-index/mail-index-util.c Sun Aug 19 14:21:37 2012 +0300 +++ b/src/lib-index/mail-index-util.c Sun Aug 19 16:17:32 2012 +0300 @@ -103,23 +103,17 @@ return 0; } -static int mail_index_seq_record_cmp(const void *key, const void *data) +static int mail_index_seq_record_cmp(const uint32_t *key_seq, + const uint32_t *data_seq) { - const uint32_t *seq_p = key; - const uint32_t *data_seq = data; - - return *seq_p - *data_seq; + return *key_seq - *data_seq; } bool mail_index_seq_array_lookup(const ARRAY_TYPE(seq_array) *array, uint32_t seq, unsigned int *idx_r) { - const void *base; - unsigned int count; - - base = array_get(array, &count); - return bsearch_insert_pos(&seq, base, count, array->arr.element_size, - mail_index_seq_record_cmp, idx_r); + return array_bsearch_insert_pos(array, &seq, + mail_index_seq_record_cmp, idx_r); } bool mail_index_seq_array_add(ARRAY_TYPE(seq_array) *array, uint32_t seq, diff -r a097ef0a9d6d -r d3db2ba15d00 src/lib-lda/mail-send.c --- a/src/lib-lda/mail-send.c Sun Aug 19 14:21:37 2012 +0300 +++ b/src/lib-lda/mail-send.c Sun Aug 19 16:17:32 2012 +0300 @@ -169,7 +169,7 @@ HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR | HEADER_FILTER_HIDE_BODY, exclude_headers, N_ELEMENTS(exclude_headers), - null_header_filter_callback, NULL); + *null_header_filter_callback, (void *)NULL); ret = o_stream_send_istream(output, input); i_stream_unref(&input); @@ -207,7 +207,8 @@ input = i_stream_create_header_filter(input, HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR, hide_headers, N_ELEMENTS(hide_headers), - null_header_filter_callback, NULL); From dovecot at dovecot.org Mon Aug 20 08:31:14 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 08:31:14 +0300 Subject: dovecot-2.2: Compiler error fix due to hash table changes. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/edb1d5babfcd changeset: 14922:edb1d5babfcd user: Timo Sirainen date: Mon Aug 20 08:31:00 2012 +0300 description: Compiler error fix due to hash table changes. diffstat: src/doveadm/dsync/dsync-mailbox-export.c | 2 +- src/doveadm/dsync/dsync-mailbox-import.c | 2 +- src/doveadm/dsync/dsync-transaction-log-scan.c | 6 +++--- src/doveadm/dsync/dsync-transaction-log-scan.h | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diffs (55 lines): diff -r d3db2ba15d00 -r edb1d5babfcd src/doveadm/dsync/dsync-mailbox-export.c --- a/src/doveadm/dsync/dsync-mailbox-export.c Sun Aug 19 16:17:32 2012 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-export.c Mon Aug 20 08:31:00 2012 +0300 @@ -385,7 +385,7 @@ void *key, *value; struct dsync_mail_change *dup_change; - log_changes = dsync_transaction_log_scan_get_hash(log_scan); + dsync_transaction_log_scan_get_hash(log_scan, &log_changes); if (dsync_transaction_log_scan_has_all_changes(log_scan)) exporter->return_all_mails = TRUE; diff -r d3db2ba15d00 -r edb1d5babfcd src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Sun Aug 19 16:17:32 2012 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Mon Aug 20 08:31:00 2012 +0300 @@ -166,7 +166,7 @@ importer->local_initial_highestmodseq = status.highest_modseq; dsync_mailbox_import_search_init(importer); - importer->local_changes = dsync_transaction_log_scan_get_hash(log_scan); + dsync_transaction_log_scan_get_hash(log_scan, &importer->local_changes); return importer; } diff -r d3db2ba15d00 -r edb1d5babfcd src/doveadm/dsync/dsync-transaction-log-scan.c --- a/src/doveadm/dsync/dsync-transaction-log-scan.c Sun Aug 19 16:17:32 2012 +0300 +++ b/src/doveadm/dsync/dsync-transaction-log-scan.c Mon Aug 20 08:31:00 2012 +0300 @@ -406,10 +406,10 @@ return 0; } -HASH_TABLE_TYPE(dsync_uid_mail_change) -dsync_transaction_log_scan_get_hash(struct dsync_transaction_log_scan *scan) +void dsync_transaction_log_scan_get_hash(struct dsync_transaction_log_scan *scan, + HASH_TABLE_TYPE(dsync_uid_mail_change) *hash_r) { - return scan->changes; + hash_r->_table = scan->changes._table; } bool diff -r d3db2ba15d00 -r edb1d5babfcd src/doveadm/dsync/dsync-transaction-log-scan.h --- a/src/doveadm/dsync/dsync-transaction-log-scan.h Sun Aug 19 16:17:32 2012 +0300 +++ b/src/doveadm/dsync/dsync-transaction-log-scan.h Mon Aug 20 08:31:00 2012 +0300 @@ -11,8 +11,8 @@ uint32_t highest_wanted_uid, uint64_t modseq, struct dsync_transaction_log_scan **scan_r); -HASH_TABLE_TYPE(dsync_uid_mail_change) -dsync_transaction_log_scan_get_hash(struct dsync_transaction_log_scan *scan); +void dsync_transaction_log_scan_get_hash(struct dsync_transaction_log_scan *scan, + HASH_TABLE_TYPE(dsync_uid_mail_change) *hash_r); /* Returns TRUE if the entire transaction log was scanned */ bool dsync_transaction_log_scan_has_all_changes(struct dsync_transaction_log_scan *scan); /* If the given UID has been expunged after the initial log scan, create/update From dovecot at dovecot.org Mon Aug 20 09:47:47 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 09:47:47 +0300 Subject: dovecot-2.2: Reverted "support for non-pointers" part of the has... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/96fd2c3bf932 changeset: 14923:96fd2c3bf932 user: Timo Sirainen date: Mon Aug 20 09:47:28 2012 +0300 description: Reverted "support for non-pointers" part of the hash table API changes. Originally I wrote it using clang, which didn't give as many warnings as gcc did. I guess this way is safer anyway.. diffstat: src/anvil/connect-limit.c | 35 +++++++------ src/auth/auth-request-handler.c | 24 ++++----- src/auth/db-checkpassword.c | 18 +++--- src/auth/db-ldap.c | 2 +- src/auth/db-passwd-file.c | 2 +- src/director/director-test.c | 13 ++-- src/director/user-directory.c | 10 +- src/doveadm/doveadm-director.c | 9 +- src/doveadm/doveadm-kick.c | 17 ++--- src/doveadm/doveadm-log.c | 14 ++--- src/doveadm/doveadm-mail-server.c | 9 +- src/doveadm/doveadm-stats.c | 2 +- src/doveadm/doveadm-who.c | 6 +- src/doveadm/dsync/dsync-mailbox-export.c | 56 ++++++++++----------- src/doveadm/dsync/dsync-mailbox-import.c | 29 ++++++----- src/doveadm/dsync/dsync-transaction-log-scan.c | 7 +- src/doveadm/dsync/dsync-transaction-log-scan.h | 2 +- src/imap/imap-client.c | 2 +- src/lib-auth/auth-server-connection.c | 13 ++-- src/lib-auth/auth-server-connection.h | 3 +- src/lib-dict/dict-file.c | 8 +- src/lib-index/mail-cache-fields.c | 22 ++++---- src/lib-index/mail-cache-private.h | 2 +- src/lib-index/mail-index-private.h | 2 +- src/lib-index/mail-index.c | 6 +- src/lib-lda/duplicate.c | 2 +- src/lib-master/master-auth.c | 16 +++--- src/lib-master/master-login-auth.c | 10 +- src/lib-settings/settings-parser.c | 7 +- src/lib-storage/index/dbox-multi/mdbox-purge.c | 15 +++- src/lib-storage/index/index-thread-finish.c | 4 +- src/lib-storage/index/maildir/maildir-keywords.c | 18 +++--- src/lib-storage/list/mailbox-list-index-sync.c | 9 ++- src/lib-storage/list/mailbox-list-index.c | 9 +- src/lib-storage/list/mailbox-list-index.h | 8 +- src/lib/child-wait.c | 24 +++++---- src/lib/hash.c | 6 +- src/lib/hash.h | 26 +++------ src/log/log-connection.c | 20 ++++--- src/login-common/ssl-proxy-openssl.c | 2 +- src/master/service-monitor.c | 4 +- src/master/service-process.c | 4 +- src/master/service.c | 7 +- src/master/service.h | 2 +- src/plugins/acl/acl-cache.c | 14 +++-- src/plugins/expire/doveadm-expire.c | 14 +++-- src/plugins/fts-lucene/lucene-wrapper.cc | 2 +- src/plugins/fts/fts-expunge-log.c | 2 +- src/pop3/pop3-commands.c | 14 ++--- src/replication/aggregator/replicator-connection.c | 10 +- 50 files changed, 282 insertions(+), 280 deletions(-) diffs (truncated from 1920 to 300 lines): diff -r edb1d5babfcd -r 96fd2c3bf932 src/anvil/connect-limit.c --- a/src/anvil/connect-limit.c Mon Aug 20 08:31:00 2012 +0300 +++ b/src/anvil/connect-limit.c Mon Aug 20 09:47:28 2012 +0300 @@ -15,8 +15,8 @@ }; struct connect_limit { - /* ident => refcount */ - HASH_TABLE(char *, unsigned int) ident_hash; + /* ident => unsigned int refcount */ + HASH_TABLE(char *, void *) ident_hash; /* struct ident_pid => struct ident_pid */ HASH_TABLE(struct ident_pid *, struct ident_pid *) ident_pid_hash; }; @@ -60,24 +60,26 @@ unsigned int connect_limit_lookup(struct connect_limit *limit, const char *ident) { - return hash_table_lookup(limit->ident_hash, ident); + void *value; + + value = hash_table_lookup(limit->ident_hash, ident); + return POINTER_CAST_TO(value, unsigned int); } void connect_limit_connect(struct connect_limit *limit, pid_t pid, const char *ident) { struct ident_pid *i, lookup_i; - void *orig_key, *orig_value; char *key; - unsigned int value; + void *value; if (!hash_table_lookup_full(limit->ident_hash, ident, - &orig_key, &orig_value)) { + &key, &value)) { key = i_strdup(ident); - hash_table_insert(limit->ident_hash, key, 1U); + value = POINTER_CAST(1); + hash_table_insert(limit->ident_hash, key, value); } else { - key = orig_key; - value = POINTER_CAST_TO(orig_value, unsigned int) + 1; + value = POINTER_CAST(POINTER_CAST_TO(value, unsigned int) + 1); hash_table_update(limit->ident_hash, key, value); } @@ -98,18 +100,17 @@ static void connect_limit_ident_hash_unref(struct connect_limit *limit, const char *ident) { - void *orig_key, *orig_value; char *key; + void *value; unsigned int new_refcount; - if (!hash_table_lookup_full(limit->ident_hash, ident, - &orig_key, &orig_value)) + if (!hash_table_lookup_full(limit->ident_hash, ident, &key, &value)) i_panic("connect limit hash tables are inconsistent"); - key = orig_key; - new_refcount = POINTER_CAST_TO(orig_value, unsigned int) - 1; + new_refcount = POINTER_CAST_TO(value, unsigned int) - 1; if (new_refcount > 0) { - hash_table_update(limit->ident_hash, key, new_refcount); + value = POINTER_CAST(new_refcount); + hash_table_update(limit->ident_hash, key, value); } else { hash_table_remove(limit->ident_hash, key); i_free(key); @@ -147,7 +148,7 @@ /* this should happen rarely (or never), so this slow implementation should be fine. */ iter = hash_table_iterate_init(limit->ident_pid_hash); - while (hash_table_iterate_t(iter, limit->ident_pid_hash, &i, &value)) { + while (hash_table_iterate(iter, limit->ident_pid_hash, &i, &value)) { if (i->pid == pid) { hash_table_remove(limit->ident_pid_hash, i); for (; i->refcount > 0; i->refcount--) @@ -165,7 +166,7 @@ string_t *str = t_str_new(256); iter = hash_table_iterate_init(limit->ident_pid_hash); - while (hash_table_iterate_t(iter, limit->ident_pid_hash, &i, &value)) { + while (hash_table_iterate(iter, limit->ident_pid_hash, &i, &value)) { str_truncate(str, 0); str_tabescape_write(str, i->ident); str_printfa(str, "\t%ld\t%u\n", (long)i->pid, i->refcount); diff -r edb1d5babfcd -r 96fd2c3bf932 src/auth/auth-request-handler.c --- a/src/auth/auth-request-handler.c Mon Aug 20 08:31:00 2012 +0300 +++ b/src/auth/auth-request-handler.c Mon Aug 20 09:47:28 2012 +0300 @@ -21,7 +21,7 @@ struct auth_request_handler { int refcount; pool_t pool; - HASH_TABLE(unsigned int, struct auth_request *) requests; + HASH_TABLE(void *, struct auth_request *) requests; unsigned int connect_uid, client_pid; @@ -68,19 +68,17 @@ void auth_request_handler_abort_requests(struct auth_request_handler *handler) { struct hash_iterate_context *iter; - void *key, *value; + void *key; + struct auth_request *auth_request; iter = hash_table_iterate_init(handler->requests); - while (hash_table_iterate(iter, &key, &value)) { - unsigned int id = POINTER_CAST_TO(key, unsigned int); - struct auth_request *auth_request = value; - + while (hash_table_iterate(iter, handler->requests, &key, &auth_request)) { switch (auth_request->state) { case AUTH_REQUEST_STATE_NEW: case AUTH_REQUEST_STATE_MECH_CONTINUE: case AUTH_REQUEST_STATE_FINISHED: auth_request_unref(&auth_request); - hash_table_remove(handler->requests, id); + hash_table_remove(handler->requests, key); break; case AUTH_REQUEST_STATE_PASSDB: case AUTH_REQUEST_STATE_USERDB: @@ -147,7 +145,7 @@ request, so make sure we don't get back here. */ timeout_remove(&request->to_abort); - hash_table_remove(handler->requests, request->id); + hash_table_remove(handler->requests, POINTER_CAST(request->id)); auth_request_unref(&request); } @@ -514,7 +512,7 @@ auth_request_unref(&request); return FALSE; } - if (hash_table_lookup(handler->requests, id) != NULL) { + if (hash_table_lookup(handler->requests, POINTER_CAST(id)) != NULL) { i_error("BUG: Authentication client %u " "sent a duplicate ID %u", handler->client_pid, id); auth_request_unref(&request); @@ -524,7 +522,7 @@ request->to_abort = timeout_add(MASTER_AUTH_SERVER_TIMEOUT_SECS * 1000, auth_request_timeout, request); - hash_table_insert(handler->requests, id, request); + hash_table_insert(handler->requests, POINTER_CAST(id), request); if (request->set->ssl_require_client_cert && !request->valid_client_cert) { @@ -579,7 +577,7 @@ } data++; - request = hash_table_lookup(handler->requests, id); + request = hash_table_lookup(handler->requests, POINTER_CAST(id)); if (request == NULL) { struct auth_stream_reply *reply; @@ -686,7 +684,7 @@ reply = auth_stream_reply_init(pool_datastack_create()); - request = hash_table_lookup(handler->requests, client_id); + request = hash_table_lookup(handler->requests, POINTER_CAST(client_id)); if (request == NULL) { i_error("Master request %u.%u not found", handler->client_pid, client_id); @@ -731,7 +729,7 @@ { struct auth_request *request; - request = hash_table_lookup(handler->requests, client_id); + request = hash_table_lookup(handler->requests, POINTER_CAST(client_id)); if (request != NULL) auth_request_handler_remove(handler, request); } diff -r edb1d5babfcd -r 96fd2c3bf932 src/auth/db-checkpassword.c --- a/src/auth/db-checkpassword.c Mon Aug 20 08:31:00 2012 +0300 +++ b/src/auth/db-checkpassword.c Mon Aug 20 09:47:28 2012 +0300 @@ -45,7 +45,7 @@ struct db_checkpassword { char *checkpassword_path, *checkpassword_reply_path; - HASH_TABLE(pid_t, struct chkpw_auth_request *) clients; + HASH_TABLE(void *, struct chkpw_auth_request *) clients; struct child_wait *child_wait; }; @@ -89,7 +89,8 @@ *_request = NULL; if (!request->exited) { - hash_table_remove(request->db->clients, request->pid); + hash_table_remove(request->db->clients, + POINTER_CAST(request->pid)); child_wait_remove_pid(request->db->child_wait, request->pid); } checkpassword_request_close(request); @@ -415,11 +416,11 @@ struct db_checkpassword *db) { struct chkpw_auth_request *request = - hash_table_lookup(db->clients, status->pid); + hash_table_lookup(db->clients, POINTER_CAST(status->pid)); i_assert(request != NULL); - hash_table_remove(db->clients, status->pid); + hash_table_remove(db->clients, POINTER_CAST(status->pid)); request->exited = TRUE; if (WIFSIGNALED(status->status)) { @@ -531,7 +532,7 @@ io_add(fd_out[1], IO_WRITE, checkpassword_child_output, chkpw_auth_request); - hash_table_insert(db->clients, pid, chkpw_auth_request); + hash_table_insert(db->clients, POINTER_CAST(pid), chkpw_auth_request); child_wait_add_pid(db->child_wait, pid); } @@ -554,15 +555,14 @@ { struct db_checkpassword *db = *_db; struct hash_iterate_context *iter; - void *key, *value; + void *key; + struct chkpw_auth_request *request; *_db = NULL; iter = hash_table_iterate_init(db->clients); - while (hash_table_iterate(iter, &key, &value)) { - struct chkpw_auth_request *request = value; + while (hash_table_iterate(iter, db->clients, &key, &request)) checkpassword_internal_failure(&request); - } hash_table_iterate_deinit(&iter); child_wait_free(&db->child_wait); diff -r edb1d5babfcd -r 96fd2c3bf932 src/auth/db-ldap.c --- a/src/auth/db-ldap.c Mon Aug 20 08:31:00 2012 +0300 +++ b/src/auth/db-ldap.c Mon Aug 20 09:47:28 2012 +0300 @@ -1324,7 +1324,7 @@ str_append(ctx->debug, "; "); iter = hash_table_iterate_init(ctx->ldap_attrs); - while (hash_table_iterate_t(iter, ctx->ldap_attrs, &name, &value)) { + while (hash_table_iterate(iter, ctx->ldap_attrs, &name, &value)) { if (!value->used) { str_printfa(ctx->debug, "%s,", name); unused_count++; diff -r edb1d5babfcd -r 96fd2c3bf932 src/auth/db-passwd-file.c --- a/src/auth/db-passwd-file.c Mon Aug 20 08:31:00 2012 +0300 +++ b/src/auth/db-passwd-file.c Mon Aug 20 09:47:28 2012 +0300 @@ -386,7 +386,7 @@ passwd_file_free(db->default_file); else { iter = hash_table_iterate_init(db->files); - while (hash_table_iterate_t(iter, db->files, &path, &file)) + while (hash_table_iterate(iter, db->files, &path, &file)) passwd_file_free(file); hash_table_iterate_deinit(&iter); hash_table_destroy(&db->files); diff -r edb1d5babfcd -r 96fd2c3bf932 src/director/director-test.c --- a/src/director/director-test.c Mon Aug 20 08:31:00 2012 +0300 +++ b/src/director/director-test.c Mon Aug 20 09:47:28 2012 +0300 @@ -548,7 +548,10 @@ static void main_deinit(void) { struct hash_iterate_context *iter; - void *key, *value; + char *username; + struct ip_addr *ip; + struct user *user; + struct host *host; while (imap_clients != NULL) { struct imap_client *client = imap_clients; @@ -562,18 +565,14 @@ } iter = hash_table_iterate_init(users); - while (hash_table_iterate(iter, &key, &value)) { - struct user *user = value; + while (hash_table_iterate(iter, users, &username, &user)) user_free(user); - } hash_table_iterate_deinit(&iter); hash_table_destroy(&users); iter = hash_table_iterate_init(hosts); - while (hash_table_iterate(iter, &key, &value)) { - struct host *host = value; + while (hash_table_iterate(iter, hosts, &ip, &host)) host_unref(&host); From dovecot at dovecot.org Mon Aug 20 10:01:14 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 10:01:14 +0300 Subject: dovecot-2.2: imap: Allow fetching [x.MIME] for message/rfc822 ag... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6c55e57c98a1 changeset: 14924:6c55e57c98a1 user: Timo Sirainen date: Mon Aug 20 10:01:03 2012 +0300 description: imap: Allow fetching [x.MIME] for message/rfc822 again. It's not clear which is the correct behavior. diffstat: src/lib-imap-storage/imap-msgpart.c | 13 ++++++------- 1 files changed, 6 insertions(+), 7 deletions(-) diffs (23 lines): diff -r 96fd2c3bf932 -r 6c55e57c98a1 src/lib-imap-storage/imap-msgpart.c --- a/src/lib-imap-storage/imap-msgpart.c Mon Aug 20 09:47:28 2012 +0300 +++ b/src/lib-imap-storage/imap-msgpart.c Mon Aug 20 10:01:03 2012 +0300 @@ -528,13 +528,12 @@ switch (msgpart->fetch_type) { case FETCH_MIME: - if (part->parent == NULL || - (part->parent->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) != 0) { - /* message/rfc822 itself has no MIME headers */ - *part_r = NULL; - return 0; - } - break; + /* What to do if this is a message/rfc822? Does it have + MIME headers or not? Possibilities are: a) no, return + empty string (UW-IMAP does this), b) return the same as + HEADER. Dovecot has done b) for a long time and it's not + very clear which one is correct, so we'll just continue + with b) */ case FETCH_FULL: case FETCH_MIME_BODY: break; From pigeonhole at rename-it.nl Mon Aug 20 10:13:47 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Mon, 20 Aug 2012 09:13:47 +0200 Subject: dovecot-2.2-pigeonhole: Adjusted to some more changes in Dovecot... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/6ccbfb64bea5 changeset: 1656:6ccbfb64bea5 user: Stephan Bosch date: Mon Aug 20 09:13:32 2012 +0200 description: Adjusted to some more changes in Dovecot API. diffstat: src/lib-sieve/plugins/include/ext-include-binary.c | 4 ++-- src/lib-sieve/plugins/variables/ext-variables-common.c | 2 +- src/lib-sieve/sieve-extensions.c | 2 +- src/testsuite/testsuite-settings.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diffs (57 lines): diff -r 02f24456eabf -r 6ccbfb64bea5 src/lib-sieve/plugins/include/ext-include-binary.c --- a/src/lib-sieve/plugins/include/ext-include-binary.c Mon Aug 20 08:43:55 2012 +0200 +++ b/src/lib-sieve/plugins/include/ext-include-binary.c Mon Aug 20 09:13:32 2012 +0200 @@ -363,7 +363,7 @@ /* Release references to all included script objects */ hctx = hash_table_iterate_init(binctx->included_scripts); - while ( hash_table_iterate_t(hctx, binctx->included_scripts, &script, &incscript) ) + while ( hash_table_iterate(hctx, binctx->included_scripts, &script, &incscript) ) sieve_script_unref(&incscript->script); hash_table_iterate_deinit(&hctx); @@ -391,7 +391,7 @@ return FALSE; hctx = hash_table_iterate_init(binctx->included_scripts); - while ( hash_table_iterate_t(hctx, binctx->included_scripts, &script, &incscript) ) { + while ( hash_table_iterate(hctx, binctx->included_scripts, &script, &incscript) ) { unsigned int block_id = sieve_binary_block_get_id(incscript->block); sieve_binary_dump_sectionf(denv, "Included %s script '%s' (block: %d)", diff -r 02f24456eabf -r 6ccbfb64bea5 src/lib-sieve/plugins/variables/ext-variables-common.c --- a/src/lib-sieve/plugins/variables/ext-variables-common.c Mon Aug 20 08:43:55 2012 +0200 +++ b/src/lib-sieve/plugins/variables/ext-variables-common.c Mon Aug 20 09:13:32 2012 +0200 @@ -186,7 +186,7 @@ { const char *key; - return hash_table_iterate_t + return hash_table_iterate (iter->hctx, iter->scope->variables, &key, var_r); } diff -r 02f24456eabf -r 6ccbfb64bea5 src/lib-sieve/sieve-extensions.c --- a/src/lib-sieve/sieve-extensions.c Mon Aug 20 08:43:55 2012 +0200 +++ b/src/lib-sieve/sieve-extensions.c Mon Aug 20 09:13:32 2012 +0200 @@ -753,7 +753,7 @@ struct sieve_capability_registration *reg; hictx = hash_table_iterate_init(ext_reg->capabilities_index); - while ( hash_table_iterate_t(hictx, ext_reg->capabilities_index, &name, ®) ) { + while ( hash_table_iterate(hictx, ext_reg->capabilities_index, &name, ®) ) { if ( reg->ext == ext ) hash_table_remove(ext_reg->capabilities_index, name); } diff -r 02f24456eabf -r 6ccbfb64bea5 src/testsuite/testsuite-settings.c --- a/src/testsuite/testsuite-settings.c Mon Aug 20 08:43:55 2012 +0200 +++ b/src/testsuite/testsuite-settings.c Mon Aug 20 09:13:32 2012 +0200 @@ -35,7 +35,7 @@ const char *key; struct testsuite_setting *setting; - while ( hash_table_iterate_t(itx, settings, &key, &setting) ) { + while ( hash_table_iterate(itx, settings, &key, &setting) ) { i_free(setting->identifier); i_free(setting->value); i_free(setting); From pigeonhole at rename-it.nl Mon Aug 20 10:13:47 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Mon, 20 Aug 2012 09:13:47 +0200 Subject: dovecot-2.2-pigeonhole: Adjusted to changes in Dovecot API regar... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/02f24456eabf changeset: 1655:02f24456eabf user: Stephan Bosch date: Mon Aug 20 08:43:55 2012 +0200 description: Adjusted to changes in Dovecot API regarding arrays and hash tables. Also contains a few other small fixes by Timo. diffstat: src/lib-sieve/cmd-redirect.c | 2 +- src/lib-sieve/edit-mail.c | 2 +- src/lib-sieve/ext-envelope.c | 10 +- src/lib-sieve/plugins/body/ext-body-common.c | 6 +- src/lib-sieve/plugins/editheader/ext-editheader-common.c | 2 +- src/lib-sieve/plugins/enotify/ext-enotify-common.h | 2 +- src/lib-sieve/plugins/environment/ext-environment-common.c | 13 +- src/lib-sieve/plugins/ihave/ext-ihave-binary.c | 2 +- src/lib-sieve/plugins/ihave/ext-ihave-common.h | 2 +- src/lib-sieve/plugins/ihave/tst-ihave.c | 2 +- src/lib-sieve/plugins/imap4flags/tag-flags.c | 2 +- src/lib-sieve/plugins/include/ext-include-binary.c | 34 +++----- src/lib-sieve/plugins/include/ext-include-common.c | 2 +- src/lib-sieve/plugins/include/ext-include-common.h | 2 +- src/lib-sieve/plugins/regex/mcht-regex.c | 2 +- src/lib-sieve/plugins/vacation/cmd-vacation.c | 2 +- src/lib-sieve/plugins/variables/cmd-set.c | 2 +- src/lib-sieve/plugins/variables/ext-variables-common.c | 29 +++---- src/lib-sieve/plugins/variables/ext-variables-dump.c | 2 +- src/lib-sieve/sieve-actions.c | 2 +- src/lib-sieve/sieve-ast.c | 4 +- src/lib-sieve/sieve-binary-private.h | 8 +- src/lib-sieve/sieve-code-dumper.c | 2 +- src/lib-sieve/sieve-error.c | 2 +- src/lib-sieve/sieve-extensions.c | 51 ++++++------- 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-match-types.c | 2 +- src/lib-sieve/sieve-message.c | 4 +- src/lib-sieve/sieve-result.c | 34 +++----- src/lib-sieve/sieve-stringlist.c | 2 +- src/lib-sieve/sieve-validator.c | 21 ++--- src/managesieve/cmd-putscript.c | 3 +- src/managesieve/managesieve-capabilities.c | 2 +- src/managesieve/managesieve-commands.c | 2 +- src/testsuite/testsuite-log.c | 6 +- src/testsuite/testsuite-settings.c | 21 ++--- src/testsuite/testsuite-smtp.c | 2 +- 39 files changed, 131 insertions(+), 163 deletions(-) diffs (truncated from 1084 to 300 lines): diff -r c5cebc7dbd6b -r 02f24456eabf src/lib-sieve/cmd-redirect.c --- a/src/lib-sieve/cmd-redirect.c Sun Aug 12 16:16:21 2012 +0200 +++ b/src/lib-sieve/cmd-redirect.c Mon Aug 20 08:43:55 2012 +0200 @@ -338,7 +338,7 @@ /* Remove unwanted headers */ input = i_stream_create_header_filter (input, HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR, hide_headers, - N_ELEMENTS(hide_headers), null_header_filter_callback, NULL); + N_ELEMENTS(hide_headers), *null_header_filter_callback, (void *)NULL); T_BEGIN { string_t *hdr = t_str_new(256); diff -r c5cebc7dbd6b -r 02f24456eabf src/lib-sieve/edit-mail.c --- a/src/lib-sieve/edit-mail.c Sun Aug 12 16:16:21 2012 +0200 +++ b/src/lib-sieve/edit-mail.c Mon Aug 20 08:43:55 2012 +0200 @@ -1224,7 +1224,7 @@ struct _header_index *header_idx; struct _header_field_index *field_idx; const char *const *headers; - ARRAY_DEFINE(header_values, const char *); + ARRAY(const char *) header_values; if ( !edmail->modified || edmail->headers_head == NULL ) { /* Unmodified */ diff -r c5cebc7dbd6b -r 02f24456eabf src/lib-sieve/ext-envelope.c --- a/src/lib-sieve/ext-envelope.c Sun Aug 12 16:16:21 2012 +0200 +++ b/src/lib-sieve/ext-envelope.c Mon Aug 20 08:43:55 2012 +0200 @@ -183,7 +183,7 @@ static const struct sieve_address *const *_from_part_get_addresses (const struct sieve_runtime_env *renv) { - ARRAY_DEFINE(envelope_values, const struct sieve_address *); + ARRAY(const struct sieve_address *) envelope_values; const struct sieve_address *address = sieve_message_get_sender_address(renv->msgctx); @@ -202,7 +202,7 @@ static const char *const *_from_part_get_values (const struct sieve_runtime_env *renv) { - ARRAY_DEFINE(envelope_values, const char *); + ARRAY(const char *) envelope_values; t_array_init(&envelope_values, 2); @@ -218,7 +218,7 @@ static const struct sieve_address *const *_to_part_get_addresses (const struct sieve_runtime_env *renv) { - ARRAY_DEFINE(envelope_values, const struct sieve_address *); + ARRAY(const struct sieve_address *) envelope_values; const struct sieve_address *address = sieve_message_get_orig_recipient_address(renv->msgctx); @@ -237,7 +237,7 @@ static const char *const *_to_part_get_values (const struct sieve_runtime_env *renv) { - ARRAY_DEFINE(envelope_values, const char *); + ARRAY(const char *) envelope_values; t_array_init(&envelope_values, 2); @@ -253,7 +253,7 @@ static const char *const *_auth_part_get_values (const struct sieve_runtime_env *renv) { - ARRAY_DEFINE(envelope_values, const char *); + ARRAY(const char *) envelope_values; t_array_init(&envelope_values, 2); diff -r c5cebc7dbd6b -r 02f24456eabf src/lib-sieve/plugins/body/ext-body-common.c --- a/src/lib-sieve/plugins/body/ext-body-common.c Sun Aug 12 16:16:21 2012 +0200 +++ b/src/lib-sieve/plugins/body/ext-body-common.c Mon Aug 20 08:43:55 2012 +0200 @@ -43,8 +43,8 @@ struct ext_body_message_context { pool_t pool; - ARRAY_DEFINE(cached_body_parts, struct ext_body_part_cached); - ARRAY_DEFINE(return_body_parts, struct ext_body_part); + ARRAY(struct ext_body_part_cached) cached_body_parts; + ARRAY(struct ext_body_part) return_body_parts; buffer_t *tmp_buffer; buffer_t *raw_body; }; @@ -220,7 +220,7 @@ struct message_decoder_context *decoder; struct message_block block, decoded; struct message_part *parts, *prev_part = NULL; - ARRAY_DEFINE(part_index, struct message_part *); + ARRAY(struct message_part *) part_index; struct istream *input; unsigned int idx = 0; bool save_body = FALSE, want_multipart, have_all; diff -r c5cebc7dbd6b -r 02f24456eabf src/lib-sieve/plugins/editheader/ext-editheader-common.c --- a/src/lib-sieve/plugins/editheader/ext-editheader-common.c Sun Aug 12 16:16:21 2012 +0200 +++ b/src/lib-sieve/plugins/editheader/ext-editheader-common.c Mon Aug 20 08:43:55 2012 +0200 @@ -29,7 +29,7 @@ struct ext_editheader_config { pool_t pool; - ARRAY_DEFINE(headers, struct ext_editheader_header); + ARRAY(struct ext_editheader_header) headers; size_t max_header_size; }; diff -r c5cebc7dbd6b -r 02f24456eabf src/lib-sieve/plugins/enotify/ext-enotify-common.h --- a/src/lib-sieve/plugins/enotify/ext-enotify-common.h Sun Aug 12 16:16:21 2012 +0200 +++ b/src/lib-sieve/plugins/enotify/ext-enotify-common.h Mon Aug 20 08:43:55 2012 +0200 @@ -22,7 +22,7 @@ struct ext_enotify_context { const struct sieve_extension *var_ext; - ARRAY_DEFINE(notify_methods, struct sieve_enotify_method); + ARRAY(struct sieve_enotify_method) notify_methods; }; diff -r c5cebc7dbd6b -r 02f24456eabf src/lib-sieve/plugins/environment/ext-environment-common.c --- a/src/lib-sieve/plugins/environment/ext-environment-common.c Sun Aug 12 16:16:21 2012 +0200 +++ b/src/lib-sieve/plugins/environment/ext-environment-common.c Mon Aug 20 08:43:55 2012 +0200 @@ -10,7 +10,8 @@ #include "ext-environment-common.h" struct ext_environment_context { - struct hash_table *environment_items; + HASH_TABLE(const char *, + const struct sieve_environment_item *) environment_items; }; /* @@ -36,8 +37,7 @@ (struct ext_environment_context *ectx, const struct sieve_environment_item *item) { - hash_table_insert - (ectx->environment_items, (void *) item->name, (void *) item); + hash_table_insert(ectx->environment_items, item->name, item); } void sieve_ext_environment_item_register @@ -61,8 +61,8 @@ unsigned int i; - ectx->environment_items = hash_table_create - (default_pool, default_pool, 0, str_hash, (hash_cmp_callback_t *)strcmp); + hash_table_create + (&ectx->environment_items, default_pool, 0, str_hash, strcmp); for ( i = 0; i < core_env_items_count; i++ ) { ext_environment_item_register(ectx, core_env_items[i]); @@ -94,8 +94,7 @@ struct ext_environment_context *ectx = (struct ext_environment_context *) ext->context; const struct sieve_environment_item *item = - (const struct sieve_environment_item *) - hash_table_lookup(ectx->environment_items, name); + hash_table_lookup(ectx->environment_items, name); if ( item == NULL ) return NULL; diff -r c5cebc7dbd6b -r 02f24456eabf src/lib-sieve/plugins/ihave/ext-ihave-binary.c --- a/src/lib-sieve/plugins/ihave/ext-ihave-binary.c Sun Aug 12 16:16:21 2012 +0200 +++ b/src/lib-sieve/plugins/ihave/ext-ihave-binary.c Mon Aug 20 08:43:55 2012 +0200 @@ -48,7 +48,7 @@ struct sieve_binary *binary; struct sieve_binary_block *block; - ARRAY_DEFINE(missing_extensions, const char *); + ARRAY(const char *) missing_extensions; }; static struct ext_ihave_binary_context *ext_ihave_binary_create_context diff -r c5cebc7dbd6b -r 02f24456eabf src/lib-sieve/plugins/ihave/ext-ihave-common.h --- a/src/lib-sieve/plugins/ihave/ext-ihave-common.h Sun Aug 12 16:16:21 2012 +0200 +++ b/src/lib-sieve/plugins/ihave/ext-ihave-common.h Mon Aug 20 08:43:55 2012 +0200 @@ -35,7 +35,7 @@ */ struct ext_ihave_ast_context { - ARRAY_DEFINE(missing_extensions, const char *); + ARRAY(const char *) missing_extensions; }; struct ext_ihave_ast_context *ext_ihave_get_ast_context diff -r c5cebc7dbd6b -r 02f24456eabf src/lib-sieve/plugins/ihave/tst-ihave.c --- a/src/lib-sieve/plugins/ihave/tst-ihave.c Sun Aug 12 16:16:21 2012 +0200 +++ b/src/lib-sieve/plugins/ihave/tst-ihave.c Mon Aug 20 08:43:55 2012 +0200 @@ -51,7 +51,7 @@ struct sieve_ast_argument *stritem; enum sieve_compile_flags cpflags = sieve_validator_compile_flags(valdtr); bool no_global = ( (cpflags & SIEVE_COMPILE_FLAG_NOGLOBAL) != 0 ); - ARRAY_DEFINE(capabilities, struct _capability); + ARRAY(struct _capability) capabilities; struct _capability capability; const struct _capability *caps; unsigned int i, count; diff -r c5cebc7dbd6b -r 02f24456eabf src/lib-sieve/plugins/imap4flags/tag-flags.c --- a/src/lib-sieve/plugins/imap4flags/tag-flags.c Sun Aug 12 16:16:21 2012 +0200 +++ b/src/lib-sieve/plugins/imap4flags/tag-flags.c Mon Aug 20 08:43:55 2012 +0200 @@ -187,7 +187,7 @@ /* Context data */ struct seff_flags_context { - ARRAY_DEFINE(keywords, const char *); + ARRAY(const char *) keywords; enum mail_flags flags; }; diff -r c5cebc7dbd6b -r 02f24456eabf src/lib-sieve/plugins/include/ext-include-binary.c --- a/src/lib-sieve/plugins/include/ext-include-binary.c Sun Aug 12 16:16:21 2012 +0200 +++ b/src/lib-sieve/plugins/include/ext-include-binary.c Mon Aug 20 08:43:55 2012 +0200 @@ -53,8 +53,9 @@ struct sieve_binary *binary; struct sieve_binary_block *dependency_block; - struct hash_table *included_scripts; - ARRAY_DEFINE(include_index, struct ext_include_script_info *); + HASH_TABLE(struct sieve_script *, + struct ext_include_script_info *) included_scripts; + ARRAY(struct ext_include_script_info *) include_index; struct sieve_variable_scope_binary *global_vars; @@ -70,9 +71,8 @@ p_new(pool, struct ext_include_binary_context, 1); ctx->binary = sbin; - ctx->included_scripts = hash_table_create(default_pool, pool, 0, - (hash_callback_t *) sieve_script_hash, - (hash_cmp_callback_t *) sieve_script_cmp); + hash_table_create(&ctx->included_scripts, pool, 0, + sieve_script_hash, sieve_script_cmp); p_array_init(&ctx->include_index, pool, 128); sieve_binary_extension_set(sbin, this_ext, &include_binary_ext, ctx); @@ -137,8 +137,7 @@ /* Unreferenced on binary_free */ sieve_script_ref(script); - hash_table_insert - (binctx->included_scripts, (void *) script, (void *) incscript); + hash_table_insert(binctx->included_scripts, script, incscript); array_append(&binctx->include_index, &incscript, 1); return incscript; @@ -148,7 +147,7 @@ (struct ext_include_binary_context *binctx, struct sieve_script *script, const struct ext_include_script_info **script_info_r) { - struct ext_include_script_info *incscript = (struct ext_include_script_info *) + struct ext_include_script_info *incscript = hash_table_lookup(binctx->included_scripts, script); if ( incscript == NULL ) @@ -175,8 +174,7 @@ const struct ext_include_script_info *ext_include_binary_script_get (struct ext_include_binary_context *binctx, struct sieve_script *script) { - return (struct ext_include_script_info *) - hash_table_lookup(binctx->included_scripts, script); + return hash_table_lookup(binctx->included_scripts, script); } unsigned int ext_include_binary_script_get_count @@ -360,16 +358,13 @@ struct ext_include_binary_context *binctx = (struct ext_include_binary_context *) context; struct hash_iterate_context *hctx; - void *key, *value; + struct sieve_script *script; + struct ext_include_script_info *incscript; /* Release references to all included script objects */ hctx = hash_table_iterate_init(binctx->included_scripts); - while ( hash_table_iterate(hctx, &key, &value) ) { - struct ext_include_script_info *incscript = - (struct ext_include_script_info *) value; - + while ( hash_table_iterate_t(hctx, binctx->included_scripts, &script, &incscript) ) sieve_script_unref(&incscript->script); - } hash_table_iterate_deinit(&hctx); hash_table_destroy(&binctx->included_scripts); @@ -389,15 +384,14 @@ struct ext_include_binary_context *binctx = ext_include_binary_get_context(ext, sbin); struct hash_iterate_context *hctx; - void *key, *value; + struct sieve_script *script; + struct ext_include_script_info *incscript; if ( !ext_include_variables_dump(denv, binctx->global_vars) ) return FALSE; hctx = hash_table_iterate_init(binctx->included_scripts); - while ( hash_table_iterate(hctx, &key, &value) ) { From dovecot at dovecot.org Mon Aug 20 10:20:05 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 10:20:05 +0300 Subject: dovecot-2.2: Fixed some aliasing warnings with hash table API. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/44013be2e3d8 changeset: 14925:44013be2e3d8 user: Timo Sirainen date: Mon Aug 20 10:19:57 2012 +0300 description: Fixed some aliasing warnings with hash table API. diffstat: src/lib/hash.h | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diffs (32 lines): diff -r 6c55e57c98a1 -r 44013be2e3d8 src/lib/hash.h --- a/src/lib/hash.h Mon Aug 20 10:01:03 2012 +0300 +++ b/src/lib/hash.h Mon Aug 20 10:19:57 2012 +0300 @@ -85,10 +85,10 @@ #define hash_table_lookup_full(table, lookup_key, orig_key_r, value_r) \ hash_table_lookup_full((table)._table, \ (void *)((const char *)(lookup_key) + COMPILE_ERROR_IF_TYPES2_NOT_COMPATIBLE((table)._const_key, (table)._key, lookup_key)), \ - (void **)(orig_key_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._keyp, orig_key_r) + \ - COMPILE_ERROR_IF_TRUE(sizeof(*orig_key_r) != sizeof(void *)), \ - (void **)(value_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._valuep, value_r) + \ - COMPILE_ERROR_IF_TRUE(sizeof(*value_r) != sizeof(void *))) + (void **)(void *)((orig_key_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._keyp, orig_key_r) + \ + COMPILE_ERROR_IF_TRUE(sizeof(*orig_key_r) != sizeof(void *))), \ + (void **)(void *)((value_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._valuep, value_r) + \ + COMPILE_ERROR_IF_TRUE(sizeof(*value_r) != sizeof(void *)))) /* Insert/update node in hash table. The difference is that hash_table_insert() replaces the key in table to given one, while hash_table_update() doesnt. */ @@ -121,10 +121,10 @@ void **key_r, void **value_r); #define hash_table_iterate(ctx, table, key_r, value_r) \ hash_table_iterate(ctx, \ - (void **)(key_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._keyp, key_r) + \ + (void **)(void *)((key_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._keyp, key_r) + \ COMPILE_ERROR_IF_TRUE(sizeof(*key_r) != sizeof(void *)) + \ - COMPILE_ERROR_IF_TRUE(sizeof(*value_r) != sizeof(void *)), \ - (void **)(value_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._valuep, value_r)) + COMPILE_ERROR_IF_TRUE(sizeof(*value_r) != sizeof(void *))), \ + (void **)(void *)((value_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._valuep, value_r))) void hash_table_iterate_deinit(struct hash_iterate_context **ctx); /* Hash table isn't resized, and removed nodes aren't removed from From dovecot at dovecot.org Mon Aug 20 10:54:20 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 10:54:20 +0300 Subject: dovecot-2.2: Simplified hash table union now that it again works... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9c69df65af7b changeset: 14926:9c69df65af7b user: Timo Sirainen date: Mon Aug 20 10:54:04 2012 +0300 description: Simplified hash table union now that it again works only with pointers. diffstat: TODO | 15 +++++++++++---- src/doveadm/dsync/dsync-mailbox-export.c | 2 +- src/doveadm/dsync/dsync-mailbox-import.c | 2 +- src/doveadm/dsync/dsync-transaction-log-scan.c | 6 +++--- src/doveadm/dsync/dsync-transaction-log-scan.h | 4 ++-- src/lib/hash-decl.h | 3 --- src/lib/hash.h | 19 ++++++++++--------- 7 files changed, 28 insertions(+), 23 deletions(-) diffs (164 lines): diff -r 44013be2e3d8 -r 9c69df65af7b TODO --- a/TODO Mon Aug 20 10:19:57 2012 +0300 +++ b/TODO Mon Aug 20 10:54:04 2012 +0300 @@ -1,4 +1,13 @@ - - Unfinished extensions: MOVE, NOTIFY + - crashes: rm -rf ~/abox;printf "1 select inbox\n2 fetch 1 body[]\n"|./imap -o plugin/archive_customer_id=1 + - connection api: connected(conn, bool success) + errno + - mailbox list indexes + imaptest test=tests fails + - NOTIFY: implement SubscriptionChange + - libssl-iostream read all of file input stream, no buffer limits in ssl + - finish dsync rewrite + - catenate: {1234} and {1234+} error handling is wrong for both + + - doveadm: if running via doveadm-server and it fails, say something about + error being in the log - indexer-worker and maybe others (doveadm?) could support dropping privileges permanently when service_count=1. Note that LMTP can't with multiple RCPT TOs. @@ -6,12 +15,10 @@ - if indexpvt is enabled, mailbox_list_indexes should go there? at least private flags are otherwise problematic.. possibly only for shared/public mailboxes?.. - - catenate: {1234} and {1234+} error handling is wrong for both - index_mail_parse_headers() etc. message_parsers don't check for stream errors - FIFOs maybe should be counted as connections, but unlisten should unlink+reopen it in master? - - mailbox list indexes + imaptest test=tests fails - - change proxy TTL so it stops at 1? + - change proxy TTL so it stops at 1? (instead of 0) - lmtp client/proxy: Handle multiline replies better - recreate mailbox -> existing sessions log "indexid changed" error - add message/mime limits diff -r 44013be2e3d8 -r 9c69df65af7b src/doveadm/dsync/dsync-mailbox-export.c --- a/src/doveadm/dsync/dsync-mailbox-export.c Mon Aug 20 10:19:57 2012 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-export.c Mon Aug 20 10:54:04 2012 +0300 @@ -382,7 +382,7 @@ void *key; struct dsync_mail_change *change, *dup_change; - dsync_transaction_log_scan_get_hash(log_scan, &log_changes); + log_changes = dsync_transaction_log_scan_get_hash(log_scan); if (dsync_transaction_log_scan_has_all_changes(log_scan)) exporter->return_all_mails = TRUE; diff -r 44013be2e3d8 -r 9c69df65af7b src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Mon Aug 20 10:19:57 2012 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Mon Aug 20 10:54:04 2012 +0300 @@ -166,7 +166,7 @@ importer->local_initial_highestmodseq = status.highest_modseq; dsync_mailbox_import_search_init(importer); - dsync_transaction_log_scan_get_hash(log_scan, &importer->local_changes); + importer->local_changes = dsync_transaction_log_scan_get_hash(log_scan); return importer; } diff -r 44013be2e3d8 -r 9c69df65af7b src/doveadm/dsync/dsync-transaction-log-scan.c --- a/src/doveadm/dsync/dsync-transaction-log-scan.c Mon Aug 20 10:19:57 2012 +0300 +++ b/src/doveadm/dsync/dsync-transaction-log-scan.c Mon Aug 20 10:54:04 2012 +0300 @@ -406,10 +406,10 @@ return 0; } -void dsync_transaction_log_scan_get_hash(struct dsync_transaction_log_scan *scan, - HASH_TABLE_TYPE(dsync_uid_mail_change) *hash_r) +HASH_TABLE_TYPE(dsync_uid_mail_change) +dsync_transaction_log_scan_get_hash(struct dsync_transaction_log_scan *scan) { - hash_r->_table = scan->changes._table; + return scan->changes; } bool diff -r 44013be2e3d8 -r 9c69df65af7b src/doveadm/dsync/dsync-transaction-log-scan.h --- a/src/doveadm/dsync/dsync-transaction-log-scan.h Mon Aug 20 10:19:57 2012 +0300 +++ b/src/doveadm/dsync/dsync-transaction-log-scan.h Mon Aug 20 10:54:04 2012 +0300 @@ -11,8 +11,8 @@ uint32_t highest_wanted_uid, uint64_t modseq, struct dsync_transaction_log_scan **scan_r); -void dsync_transaction_log_scan_get_hash(struct dsync_transaction_log_scan *scan, - HASH_TABLE_TYPE(dsync_uid_mail_change) *hash_r); +HASH_TABLE_TYPE(dsync_uid_mail_change) +dsync_transaction_log_scan_get_hash(struct dsync_transaction_log_scan *scan); /* Returns TRUE if the entire transaction log was scanned */ bool dsync_transaction_log_scan_has_all_changes(struct dsync_transaction_log_scan *scan); /* If the given UID has been expunged after the initial log scan, create/update diff -r 44013be2e3d8 -r 9c69df65af7b src/lib/hash-decl.h --- a/src/lib/hash-decl.h Mon Aug 20 10:19:57 2012 +0300 +++ b/src/lib/hash-decl.h Mon Aug 20 10:54:04 2012 +0300 @@ -4,10 +4,7 @@ #define HASH_TABLE_UNION(key_type, value_type) { \ struct hash_table *_table; \ key_type _key; \ - key_type *_keyp; \ - const key_type _const_key; \ value_type _value; \ - value_type *_valuep; \ } #define HASH_TABLE_DEFINE_TYPE(name, key_type, value_type) \ diff -r 44013be2e3d8 -r 9c69df65af7b src/lib/hash.h --- a/src/lib/hash.h Mon Aug 20 10:19:57 2012 +0300 +++ b/src/lib/hash.h Mon Aug 20 10:54:04 2012 +0300 @@ -31,12 +31,13 @@ !__builtin_types_compatible_p(typeof(&key_cmp_cb), \ int (*)(typeof((*table)._key), typeof((*table)._key))) && \ !__builtin_types_compatible_p(typeof(&key_cmp_cb), \ - int (*)(typeof((*table)._const_key), typeof((*table)._const_key)))); \ + int (*)(typeof(const typeof(*(*table)._key) *), \ + typeof(const typeof(*(*table)._key) *)))); \ (void)COMPILE_ERROR_IF_TRUE( \ !__builtin_types_compatible_p(typeof(&hash_cb), \ unsigned int (*)(typeof((*table)._key))) && \ !__builtin_types_compatible_p(typeof(&hash_cb), \ - unsigned int (*)(typeof((*table)._const_key)))); \ + unsigned int (*)(typeof(const typeof(*(*table)._key) *)))); \ hash_table_create(&(*table)._table, pool, size, \ (hash_callback_t *)hash_cb, \ (hash_cmp_callback_t *)key_cmp_cb);}) @@ -77,17 +78,17 @@ void *hash_table_lookup(const struct hash_table *table, const void *key) ATTR_PURE; #define hash_table_lookup(table, key) \ HASH_VALUE_CAST(table)hash_table_lookup((table)._table, \ - (const void *)((const char *)(key) + COMPILE_ERROR_IF_TYPES2_NOT_COMPATIBLE((table)._key, (table)._const_key, key))) + (const void *)((const char *)(key) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE(*(table)._key, *key))) bool hash_table_lookup_full(const struct hash_table *table, const void *lookup_key, void **orig_key_r, void **value_r); #define hash_table_lookup_full(table, lookup_key, orig_key_r, value_r) \ hash_table_lookup_full((table)._table, \ - (void *)((const char *)(lookup_key) + COMPILE_ERROR_IF_TYPES2_NOT_COMPATIBLE((table)._const_key, (table)._key, lookup_key)), \ - (void **)(void *)((orig_key_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._keyp, orig_key_r) + \ + (void *)((const char *)(lookup_key) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE(*(table)._key, *lookup_key)), \ + (void **)(void *)((orig_key_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._key, *orig_key_r) + \ COMPILE_ERROR_IF_TRUE(sizeof(*orig_key_r) != sizeof(void *))), \ - (void **)(void *)((value_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._valuep, value_r) + \ + (void **)(void *)((value_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._value, *value_r) + \ COMPILE_ERROR_IF_TRUE(sizeof(*value_r) != sizeof(void *)))) /* Insert/update node in hash table. The difference is that hash_table_insert() @@ -106,7 +107,7 @@ void hash_table_remove(struct hash_table *table, const void *key); #define hash_table_remove(table, key) \ hash_table_remove((table)._table, \ - (const void *)((const char *)(key) + COMPILE_ERROR_IF_TYPES2_NOT_COMPATIBLE((table)._const_key, (table)._key, key))) + (const void *)((const char *)(key) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE(*(table)._key, *key))) unsigned int hash_table_count(const struct hash_table *table) ATTR_PURE; #define hash_table_count(table) \ hash_table_count((table)._table) @@ -121,10 +122,10 @@ void **key_r, void **value_r); #define hash_table_iterate(ctx, table, key_r, value_r) \ hash_table_iterate(ctx, \ - (void **)(void *)((key_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._keyp, key_r) + \ + (void **)(void *)((key_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._key, *key_r) + \ COMPILE_ERROR_IF_TRUE(sizeof(*key_r) != sizeof(void *)) + \ COMPILE_ERROR_IF_TRUE(sizeof(*value_r) != sizeof(void *))), \ - (void **)(void *)((value_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._valuep, value_r))) + (void **)(void *)((value_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._value, *value_r))) void hash_table_iterate_deinit(struct hash_iterate_context **ctx); /* Hash table isn't resized, and removed nodes aren't removed from From dovecot at dovecot.org Mon Aug 20 11:09:52 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 11:09:52 +0300 Subject: dovecot-2.2: quoted-printable decode didn't ignore whitespace at... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cc5f888d466a changeset: 14927:cc5f888d466a user: Timo Sirainen date: Fri Aug 10 07:31:28 2012 +0300 description: quoted-printable decode didn't ignore whitespace at the end of soft line break. diffstat: src/lib-mail/quoted-printable.c | 42 +++++++++++++++++++++++------------ src/lib-mail/test-quoted-printable.c | 6 ++-- 2 files changed, 30 insertions(+), 18 deletions(-) diffs (85 lines): diff -r 9d0873cefa08 -r cc5f888d466a src/lib-mail/quoted-printable.c --- a/src/lib-mail/quoted-printable.c Fri Aug 10 02:34:34 2012 +0300 +++ b/src/lib-mail/quoted-printable.c Fri Aug 10 07:31:28 2012 +0300 @@ -8,11 +8,31 @@ #define QP_IS_TRAILING_SPACE(c) \ ((c) == ' ' || (c) == '\t') +static int +qp_is_end_of_line(const unsigned char *src, size_t *src_pos, size_t size) +{ + size_t i = *src_pos; + + i_assert(src[i] == '='); + for (i++; i < size; i++) { + if (QP_IS_TRAILING_SPACE(src[i]) || src[i] == '\r') + continue; + + if (src[i] != '\n') + return 0; + + *src_pos = i; + return 1; + } + return -1; +} + void quoted_printable_decode(const unsigned char *src, size_t src_size, size_t *src_pos_r, buffer_t *dest) { char hexbuf[3]; size_t src_pos, pos, next; + int ret; hexbuf[2] = '\0'; @@ -38,26 +58,18 @@ buffer_append(dest, src + next, src_pos - next); next = src_pos; - if (src_pos+1 >= src_size) - break; - - if (src[src_pos+1] == '\n') { - /* =\n -> skip both */ - src_pos++; - next += 2; + if ((ret = qp_is_end_of_line(src, &src_pos, src_size)) > 0) { + /* =[whitespace][\r]\n */ + next = src_pos+1; continue; } - + if (ret < 0) { + /* unknown yet if this is end of line */ + break; + } if (src_pos+2 >= src_size) break; - if (src[src_pos+1] == '\r' && src[src_pos+2] == '\n') { - /* =\r\n -> skip both */ - src_pos += 2; - next += 3; - continue; - } - /* = */ hexbuf[0] = src[src_pos+1]; hexbuf[1] = src[src_pos+2]; diff -r 9d0873cefa08 -r cc5f888d466a src/lib-mail/test-quoted-printable.c --- a/src/lib-mail/test-quoted-printable.c Fri Aug 10 02:34:34 2012 +0300 +++ b/src/lib-mail/test-quoted-printable.c Fri Aug 10 07:31:28 2012 +0300 @@ -16,9 +16,9 @@ { static struct test_quoted_printable_decode_data data[] = { { "foo \r\nbar=", "foo\r\nbar", 1 }, - { "foo =\nbar", "foo bar", 0 }, - { "foo =\n=01", "foo \001", 0 }, - { "foo =\r\nbar", "foo bar", 0 }, + { "foo\t=\nbar", "foo\tbar", 0 }, + { "foo = \n=01", "foo \001", 0 }, + { "foo =\t\r\nbar", "foo bar", 0 }, { "foo =\r\n=01", "foo \001", 0 }, { "foo \nbar=", "foo\r\nbar", 1 }, { "=0A=0D ", "\n\r", 2 }, From dovecot at dovecot.org Mon Aug 20 11:09:52 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 11:09:52 +0300 Subject: dovecot-2.2: Memory leak fix Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/963482677c0b changeset: 14928:963482677c0b user: Timo Sirainen date: Mon Aug 13 07:26:25 2012 +0300 description: Memory leak fix diffstat: src/lib/ioloop.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (21 lines): diff -r cc5f888d466a -r 963482677c0b src/lib/ioloop.c --- a/src/lib/ioloop.c Fri Aug 10 07:31:28 2012 +0300 +++ b/src/lib/ioloop.c Mon Aug 13 07:26:25 2012 +0300 @@ -357,7 +357,7 @@ (void *)timeout->callback); } if (ioloop->cur_ctx != NULL) - io_loop_context_activate(ioloop->cur_ctx); + io_loop_context_deactivate(ioloop->cur_ctx); } } @@ -594,6 +594,8 @@ { const struct ioloop_context_callback *cb; + i_assert(ctx->ioloop->cur_ctx == NULL); + ctx->ioloop->cur_ctx = ctx; io_loop_context_ref(ctx); array_foreach(&ctx->callbacks, cb) { From dovecot at dovecot.org Mon Aug 20 11:09:52 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 11:09:52 +0300 Subject: dovecot-2.2: lib-storage: If alias_for references inbox=yes name... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0d3f2902fb68 changeset: 14930:0d3f2902fb68 user: Timo Sirainen date: Tue Aug 14 03:01:07 2012 +0300 description: lib-storage: If alias_for references inbox=yes namespace, copy the inbox=yes to the alias ns. So even though this still doesn't allow giving multiple inbox=yes settings in configuration file, it's now possible for multiple namespaces to have them. They just need to point to the exact same INBOX. diffstat: src/lib-storage/mail-namespace.c | 11 +++++++++-- src/lib-storage/mail-namespace.h | 5 +++-- 2 files changed, 12 insertions(+), 4 deletions(-) diffs (52 lines): diff -r 68a62d79b1b4 -r 0d3f2902fb68 src/lib-storage/mail-namespace.c --- a/src/lib-storage/mail-namespace.c Tue Aug 14 01:54:34 2012 +0300 +++ b/src/lib-storage/mail-namespace.c Tue Aug 14 03:01:07 2012 +0300 @@ -178,6 +178,11 @@ if (!namespace_is_valid_alias_storage(ns, error_r)) return -1; + if ((ns->alias_for->flags & NAMESPACE_FLAG_INBOX_USER) != 0) { + /* copy inbox=yes */ + ns->flags |= NAMESPACE_FLAG_INBOX_USER; + } + ns->alias_chain_next = ns->alias_for->alias_chain_next; ns->alias_for->alias_chain_next = ns; } @@ -200,10 +205,9 @@ ns->prefix); return FALSE; } - if (namespace_set_alias_for(ns, namespaces, error_r) < 0) - return FALSE; if ((ns->flags & NAMESPACE_FLAG_HIDDEN) == 0) visible_namespaces = TRUE; + /* check the inbox=yes status before alias_for changes it */ if ((ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) { if (inbox_ns != NULL) { *error_r = "There can be only one namespace with " @@ -212,6 +216,9 @@ } inbox_ns = ns; } + if (namespace_set_alias_for(ns, namespaces, error_r) < 0) + return FALSE; + if (*ns->prefix != '\0' && (ns->flags & (NAMESPACE_FLAG_LIST_PREFIX | NAMESPACE_FLAG_LIST_CHILDREN)) != 0 && diff -r 68a62d79b1b4 -r 0d3f2902fb68 src/lib-storage/mail-namespace.h --- a/src/lib-storage/mail-namespace.h Tue Aug 14 01:54:34 2012 +0300 +++ b/src/lib-storage/mail-namespace.h Tue Aug 14 03:01:07 2012 +0300 @@ -12,8 +12,9 @@ }; enum namespace_flags { - /* Namespace contains the user's INBOX mailbox (there can be only - one) */ + /* Namespace contains the user's INBOX mailbox. Normally only a single + namespace has this flag set, but when using alias_for for the INBOX + namespace the flag gets copied to the alias namespace as well */ NAMESPACE_FLAG_INBOX_USER = 0x01, /* Namespace contains someone's INBOX. This is set for both user's INBOX namespace and also for any other users' shared namespaces. */ From dovecot at dovecot.org Mon Aug 20 11:09:52 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 11:09:52 +0300 Subject: dovecot-2.2: imap LIST: Don't set \haschildren flag for namespac... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/68a62d79b1b4 changeset: 14929:68a62d79b1b4 user: Timo Sirainen date: Tue Aug 14 01:54:34 2012 +0300 description: imap LIST: Don't set \haschildren flag for namespace prefix if it has list=no diffstat: src/imap/cmd-list.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (18 lines): diff -r 963482677c0b -r 68a62d79b1b4 src/imap/cmd-list.c --- a/src/imap/cmd-list.c Mon Aug 13 07:26:25 2012 +0300 +++ b/src/imap/cmd-list.c Tue Aug 14 01:54:34 2012 +0300 @@ -456,10 +456,12 @@ if (ctx->cur_ns_send_prefix) list_namespace_send_prefix(ctx, TRUE); - /* if there's a namespace with this name, list it as + /* if there's a list=yes namespace with this name, list it as having children */ ns = mail_namespace_find_prefix_nosep(ctx->ns, name); - if (ns != NULL) { + if (ns != NULL && + (ns->flags & (NAMESPACE_FLAG_LIST_PREFIX | + NAMESPACE_FLAG_LIST_CHILDREN)) != 0) { flags |= MAILBOX_CHILDREN; flags &= ~MAILBOX_NOCHILDREN; array_append(&ctx->ns_prefixes_listed, &ns, 1); From dovecot at dovecot.org Mon Aug 20 11:09:52 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 11:09:52 +0300 Subject: dovecot-2.2: fs layout: Kludge to show INBOX/INBOX mailbox when ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7a1f49b588a8 changeset: 14932:7a1f49b588a8 user: Timo Sirainen date: Tue Aug 14 03:03:26 2012 +0300 description: fs layout: Kludge to show INBOX/INBOX mailbox when necessary. This happens with one prefix="" namespace and another prefix=INBOX/ namespace when the INBOX mailbox itself has children. diffstat: src/lib-storage/list/mailbox-list-fs-iter.c | 32 ++++++++++++++++++++++++---- 1 files changed, 27 insertions(+), 5 deletions(-) diffs (77 lines): diff -r b0f744014aca -r 7a1f49b588a8 src/lib-storage/list/mailbox-list-fs-iter.c --- a/src/lib-storage/list/mailbox-list-fs-iter.c Tue Aug 14 03:02:02 2012 +0300 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Tue Aug 14 03:03:26 2012 +0300 @@ -49,6 +49,7 @@ struct list_dir_context *dir; unsigned int inbox_found:1; + unsigned int list_inbox_inbox:1; }; static int @@ -526,7 +527,8 @@ return ret; } -static void inbox_flags_set(struct fs_list_iterate_context *ctx) +static void inbox_flags_set(struct fs_list_iterate_context *ctx, + enum imap_match_result child_dir_match) { struct mail_namespace *ns = ctx->ctx.list->ns; @@ -541,8 +543,19 @@ with INBOX = /var/inbox/%u/Maildir, root = ~/Maildir: ~/Maildir/INBOX/foo/ shows up as /INBOX/foo and INBOX can't directly have any children. */ - ctx->info.flags &= ~MAILBOX_CHILDREN; - ctx->info.flags |= MAILBOX_NOINFERIORS; + if (ns->prefix_len == 6 && + strncasecmp(ns->prefix, "INBOX", ns->prefix_len-1) == 0 && + (ctx->info.flags & MAILBOX_CHILDREN) != 0 && + (child_dir_match & IMAP_MATCH_CHILDREN) != 0) { + /* except, INBOX/ prefix is once again a special case. + we're now listing both the namespace prefix and the + INBOX. we're now doing a LIST INBOX/%, so we'll need + to create a fake \NoSelect INBOX/INBOX */ + ctx->list_inbox_inbox = TRUE; + } else { + ctx->info.flags &= ~MAILBOX_CHILDREN; + ctx->info.flags |= MAILBOX_NOINFERIORS; + } } } @@ -570,7 +583,7 @@ (ctx->info.flags & MAILBOX_NONEXISTENT) != 0) return FALSE; - inbox_flags_set(ctx); + inbox_flags_set(ctx, 0); /* we got here because we didn't see INBOX among other mailboxes, which means it has no children. */ ctx->info.flags |= MAILBOX_NOCHILDREN; @@ -645,7 +658,7 @@ } return 0; } - inbox_flags_set(ctx); + inbox_flags_set(ctx, child_dir_match); ctx->inbox_found = TRUE; } else if (strcmp(storage_name, "INBOX") == 0 && (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) { @@ -704,6 +717,15 @@ fs_list_next_root(ctx); } + if (ctx->list_inbox_inbox) { + ctx->info.flags = MAILBOX_CHILDREN | MAILBOX_NOSELECT; + ctx->info.name = + p_strconcat(ctx->info_pool, + ctx->ctx.list->ns->prefix, "INBOX", NULL); + ctx->list_inbox_inbox = FALSE; + if (imap_match(ctx->ctx.glob, ctx->info.name) == IMAP_MATCH_YES) + return 1; + } if (!ctx->inbox_found && ctx->ctx.glob != NULL && (ctx->ctx.list->ns->flags & NAMESPACE_FLAG_INBOX_ANY) != 0 && imap_match(ctx->ctx.glob, From dovecot at dovecot.org Mon Aug 20 11:09:52 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 11:09:52 +0300 Subject: dovecot-2.2: lib-storage: mailbox_list_get_storage_name() should... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b0f744014aca changeset: 14931:b0f744014aca user: Timo Sirainen date: Tue Aug 14 03:02:02 2012 +0300 description: lib-storage: mailbox_list_get_storage_name() shouldn't treat INBOX specially in inbox=no namespaces. diffstat: src/lib-storage/mailbox-list.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (20 lines): diff -r 0d3f2902fb68 -r b0f744014aca src/lib-storage/mailbox-list.c --- a/src/lib-storage/mailbox-list.c Tue Aug 14 03:01:07 2012 +0300 +++ b/src/lib-storage/mailbox-list.c Tue Aug 14 03:02:02 2012 +0300 @@ -397,12 +397,14 @@ string_t *str; char list_sep, ns_sep, *ret, *p; - if (strcasecmp(storage_name, "INBOX") == 0) + if (strcasecmp(storage_name, "INBOX") == 0 && + (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) storage_name = "INBOX"; else if (list->set.escape_char != '\0') storage_name = mailbox_list_escape_name(list, vname); - if (prefix_len > 0 && strcmp(storage_name, "INBOX") != 0) { + if (prefix_len > 0 && (strcmp(storage_name, "INBOX") != 0 || + (ns->flags & NAMESPACE_FLAG_INBOX_USER) == 0)) { /* skip namespace prefix, except if this is INBOX */ if (strncmp(ns->prefix, storage_name, prefix_len) == 0) storage_name += prefix_len; From dovecot at dovecot.org Mon Aug 20 11:09:52 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 11:09:52 +0300 Subject: dovecot-2.2: imapc: Added imapc_max_idle_time setting to force a... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f33e3ac28e1d changeset: 14933:f33e3ac28e1d user: Timo Sirainen date: Tue Aug 14 23:09:44 2012 +0300 description: imapc: Added imapc_max_idle_time setting to force activity on connection. Reducing this from the default 29 minutes should help when there's a stateful firewall between imapc and the backend server. diffstat: src/lib-imap-client/imapc-client.h | 1 + src/lib-imap-client/imapc-connection.c | 4 +--- src/lib-storage/index/imapc/imapc-settings.c | 4 ++++ src/lib-storage/index/imapc/imapc-settings.h | 2 ++ src/lib-storage/index/imapc/imapc-storage.c | 1 + 5 files changed, 9 insertions(+), 3 deletions(-) diffs (76 lines): diff -r 7a1f49b588a8 -r f33e3ac28e1d src/lib-imap-client/imapc-client.h --- a/src/lib-imap-client/imapc-client.h Tue Aug 14 03:03:26 2012 +0300 +++ b/src/lib-imap-client/imapc-client.h Tue Aug 14 23:09:44 2012 +0300 @@ -52,6 +52,7 @@ const char *master_user; const char *username; const char *password; + unsigned int max_idle_time; const char *dns_client_socket_path; const char *temp_path_prefix; diff -r 7a1f49b588a8 -r f33e3ac28e1d src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Tue Aug 14 03:03:26 2012 +0300 +++ b/src/lib-imap-client/imapc-connection.c Tue Aug 14 23:09:44 2012 +0300 @@ -24,8 +24,6 @@ #define IMAPC_CONNECT_TIMEOUT_MSECS (1000*30) #define IMAPC_COMMAND_TIMEOUT_MSECS (1000*60*5) #define IMAPC_MAX_INLINE_LITERAL_SIZE (1024*32) -/* IMAP protocol requires activity at least every 30 minutes */ -#define IMAPC_MAX_IDLE_MSECS (1000*60*29) enum imapc_input_state { IMAPC_INPUT_STATE_NONE = 0, @@ -1306,7 +1304,7 @@ conn->parser = imap_parser_create(conn->input, NULL, (size_t)-1); conn->to = timeout_add(IMAPC_CONNECT_TIMEOUT_MSECS, imapc_connection_timeout, conn); - conn->to_output = timeout_add(IMAPC_MAX_IDLE_MSECS, + conn->to_output = timeout_add(conn->client->set.max_idle_time*1000, imapc_connection_reset_idle, conn); if (conn->client->set.debug) { i_debug("imapc(%s): Connecting to %s:%u", conn->name, diff -r 7a1f49b588a8 -r f33e3ac28e1d src/lib-storage/index/imapc/imapc-settings.c --- a/src/lib-storage/index/imapc/imapc-settings.c Tue Aug 14 03:03:26 2012 +0300 +++ b/src/lib-storage/index/imapc/imapc-settings.c Tue Aug 14 23:09:44 2012 +0300 @@ -28,6 +28,8 @@ DEF(SET_STR, imapc_features), DEF(SET_STR, imapc_rawlog_dir), DEF(SET_STR, imapc_list_prefix), + DEF(SET_TIME, imapc_max_idle_time), + DEF(SET_STR, ssl_crypto_device), SETTING_DEFINE_LIST_END @@ -48,6 +50,8 @@ .imapc_features = "", .imapc_rawlog_dir = "", .imapc_list_prefix = "", + .imapc_max_idle_time = 60*29, + .ssl_crypto_device = "" }; diff -r 7a1f49b588a8 -r f33e3ac28e1d src/lib-storage/index/imapc/imapc-settings.h --- a/src/lib-storage/index/imapc/imapc-settings.h Tue Aug 14 03:03:26 2012 +0300 +++ b/src/lib-storage/index/imapc/imapc-settings.h Tue Aug 14 23:09:44 2012 +0300 @@ -23,6 +23,8 @@ const char *imapc_features; const char *imapc_rawlog_dir; const char *imapc_list_prefix; + unsigned int imapc_max_idle_time; + const char *ssl_crypto_device; enum imapc_features parsed_features; diff -r 7a1f49b588a8 -r f33e3ac28e1d src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Tue Aug 14 03:03:26 2012 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.c Tue Aug 14 23:09:44 2012 +0300 @@ -228,6 +228,7 @@ *error_r = "missing imapc_password"; return -1; } + set.max_idle_time = storage->set->imapc_max_idle_time; set.dns_client_socket_path = *_storage->user->set->base_dir == '\0' ? "" : t_strconcat(_storage->user->set->base_dir, "/", From dovecot at dovecot.org Mon Aug 20 11:09:52 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 11:09:52 +0300 Subject: dovecot-2.2: imap: Implemented THREAD=ORDEREDSUBJECT extension. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/670f467ff5c5 changeset: 14935:670f467ff5c5 user: Timo Sirainen date: Wed Aug 15 13:43:16 2012 +0300 description: imap: Implemented THREAD=ORDEREDSUBJECT extension. diffstat: configure.in | 2 +- src/imap/cmd-thread.c | 148 +++++++++++++++++++++++++++++++++++++++++- src/lib-storage/mail-thread.c | 2 + 3 files changed, 150 insertions(+), 2 deletions(-) diffs (196 lines): diff -r 501f22bf92c3 -r 670f467ff5c5 configure.in --- a/configure.in Wed Aug 15 12:37:34 2012 +0300 +++ b/configure.in Wed Aug 15 13:43:16 2012 +0300 @@ -2708,7 +2708,7 @@ dnl IDLE doesn't really belong to banner. It's there just to make Blackberries dnl happy, because otherwise BIS server disables push email. capability_banner="IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE" -capability="$capability_banner SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS MULTIAPPEND UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE" +capability="$capability_banner SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE" AC_DEFINE_UNQUOTED(CAPABILITY_STRING, "$capability", IMAP capabilities) AC_DEFINE_UNQUOTED(CAPABILITY_BANNER_STRING, "$capability_banner", IMAP capabilities advertised in banner) diff -r 501f22bf92c3 -r 670f467ff5c5 src/imap/cmd-thread.c --- a/src/imap/cmd-thread.c Wed Aug 15 12:37:34 2012 +0300 +++ b/src/imap/cmd-thread.c Wed Aug 15 13:43:16 2012 +0300 @@ -3,6 +3,7 @@ #include "imap-common.h" #include "str.h" #include "ostream.h" +#include "imap-base-subject.h" #include "imap-commands.h" #include "imap-search-args.h" #include "mail-thread.h" @@ -102,6 +103,148 @@ return ret; } +struct orderedsubject_thread { + time_t timestamp; + ARRAY_TYPE(uint32_t) msgs; +}; + +static int orderedsubject_thread_cmp(const struct orderedsubject_thread *t1, + const struct orderedsubject_thread *t2) +{ + const uint32_t *m1, *m2; + + if (t1->timestamp < t2->timestamp) + return -1; + if (t1->timestamp > t2->timestamp) + return 1; + + m1 = array_idx(&t1->msgs, 0); + m2 = array_idx(&t2->msgs, 0); + if (*m1 < *m2) + return -1; + if (*m1 > *m2) + return 1; + i_unreached(); +} + +static void +imap_orderedsubject_thread_write(struct ostream *output, string_t *reply, + const struct orderedsubject_thread *thread) +{ + const uint32_t *msgs; + unsigned int i, count; + + if (str_len(reply) > 128-10) { + o_stream_send(output, str_data(reply), str_len(reply)); + str_truncate(reply, 0); + } + + msgs = array_get(&thread->msgs, &count); + switch (count) { + case 1: + str_printfa(reply, "(%u)", msgs[0]); + break; + case 2: + str_printfa(reply, "(%u %u)", msgs[0], msgs[1]); + break; + default: + /* (1 (2)(3)) */ + str_printfa(reply, "(%u ", msgs[0]); + for (i = 1; i < count; i++) { + if (str_len(reply) > 128-10) { + o_stream_send(output, str_data(reply), + str_len(reply)); + str_truncate(reply, 0); + } + str_printfa(reply, "(%u)", msgs[i]); + } + str_append_c(reply, ')'); + } +} + +static int imap_thread_orderedsubject(struct client_command_context *cmd, + struct mail_search_args *search_args) +{ + static const enum mail_sort_type sort_program[] = { + MAIL_SORT_SUBJECT, + MAIL_SORT_DATE, + 0 + }; + struct mailbox_transaction_context *trans; + struct mail_search_context *search_ctx; + struct mail *mail; + string_t *prev_subject, *reply; + const char *subject, *base_subject; + pool_t pool; + ARRAY_DEFINE(threads, struct orderedsubject_thread); + const struct orderedsubject_thread *thread; + struct orderedsubject_thread *cur_thread = NULL; + uint32_t num; + int ret; + + prev_subject = str_new(default_pool, 128); + + /* first read all of the threads into memory */ + pool = pool_alloconly_create("orderedsubject thread", 1024); + i_array_init(&threads, 128); + trans = mailbox_transaction_begin(cmd->client->mailbox, 0); + search_ctx = mailbox_search_init(trans, search_args, sort_program, + 0, NULL); + while (mailbox_search_next(search_ctx, &mail)) { + if (mail_get_first_header(mail, "Subject", &subject) <= 0) + subject = ""; + T_BEGIN { + base_subject = imap_get_base_subject_cased( + pool_datastack_create(), subject, NULL); + if (strcmp(str_c(prev_subject), base_subject) != 0) { + /* thread changed */ + cur_thread = NULL; + } + str_truncate(prev_subject, 0); + str_append(prev_subject, base_subject); + } T_END; + + if (cur_thread == NULL) { + /* starting a new thread. get the first message's + date */ + cur_thread = array_append_space(&threads); + if (mail_get_date(mail, &cur_thread->timestamp, NULL) == 0 && + cur_thread->timestamp == 0) { + (void)mail_get_received_date(mail, + &cur_thread->timestamp); + } + p_array_init(&cur_thread->msgs, pool, 4); + } + num = cmd->uid ? mail->uid : mail->seq; + array_append(&cur_thread->msgs, &num, 1); + } + str_free(&prev_subject); + ret = mailbox_search_deinit(&search_ctx); + (void)mailbox_transaction_commit(&trans); + if (ret < 0) { + array_free(&threads); + pool_unref(&pool); + return -1; + } + + /* sort the threads by their first message's timestamp */ + array_sort(&threads, orderedsubject_thread_cmp); + + /* write the threads to client */ + reply = t_str_new(128); + str_append(reply, "* THREAD "); + array_foreach(&threads, thread) { + imap_orderedsubject_thread_write(cmd->client->output, + reply, thread); + } + str_append(reply, "\r\n"); + o_stream_send(cmd->client->output, str_data(reply), str_len(reply)); + + array_free(&threads); + pool_unref(&pool); + return 0; +} + bool cmd_thread(struct client_command_context *cmd) { struct client *client = cmd->client; @@ -133,7 +276,10 @@ if (ret <= 0) return ret < 0; - ret = imap_thread(cmd, sargs, thread_type); + if (thread_type != MAIL_THREAD_ORDEREDSUBJECT) + ret = imap_thread(cmd, sargs, thread_type); + else + ret = imap_thread_orderedsubject(cmd, sargs); mail_search_args_unref(&sargs); if (ret < 0) { client_send_storage_error(cmd, diff -r 501f22bf92c3 -r 670f467ff5c5 src/lib-storage/mail-thread.c --- a/src/lib-storage/mail-thread.c Wed Aug 15 12:37:34 2012 +0300 +++ b/src/lib-storage/mail-thread.c Wed Aug 15 13:43:16 2012 +0300 @@ -9,6 +9,8 @@ *type_r = MAIL_THREAD_REFERENCES; else if (strcasecmp(str, "REFS") == 0) *type_r = MAIL_THREAD_REFS; + else if (strcasecmp(str, "ORDEREDSUBJECT") == 0) + *type_r = MAIL_THREAD_ORDEREDSUBJECT; else return FALSE; return TRUE; From dovecot at dovecot.org Mon Aug 20 11:09:52 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 11:09:52 +0300 Subject: dovecot-2.2: doveadm backup: Fixed "is source empty" check. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5f280c1ec9fd changeset: 14936:5f280c1ec9fd user: Timo Sirainen date: Fri Aug 17 09:17:48 2012 +0300 description: doveadm backup: Fixed "is source empty" check. In POP3 boxes there is only INBOX, and it's possible that source becomes empty while backup has mails. The check is now "has source always been empty?" diffstat: src/doveadm/dsync/dsync-brain.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 670f467ff5c5 -r 5f280c1ec9fd src/doveadm/dsync/dsync-brain.c --- a/src/doveadm/dsync/dsync-brain.c Wed Aug 15 13:43:16 2012 +0300 +++ b/src/doveadm/dsync/dsync-brain.c Fri Aug 17 09:17:48 2012 +0300 @@ -313,7 +313,7 @@ if (count == 0) return TRUE; if (count == 1 && strcasecmp(boxes[0]->name, "INBOX") == 0 && - boxes[0]->message_count == 0) + boxes[0]->message_count == 0 && boxes[0]->uid_next == 1) return TRUE; return FALSE; } From dovecot at dovecot.org Mon Aug 20 11:09:52 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 11:09:52 +0300 Subject: dovecot-2.2: doveadm: Improved "passdb lookup failed" error mess... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fe492bba225a changeset: 14937:fe492bba225a user: Timo Sirainen date: Fri Aug 17 19:01:03 2012 +0300 description: doveadm: Improved "passdb lookup failed" error message. diffstat: src/doveadm/doveadm-mail-server.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r 5f280c1ec9fd -r fe492bba225a src/doveadm/doveadm-mail-server.c --- a/src/doveadm/doveadm-mail-server.c Fri Aug 17 09:17:48 2012 +0300 +++ b/src/doveadm/doveadm-mail-server.c Fri Aug 17 19:01:03 2012 +0300 @@ -183,6 +183,9 @@ if (ret < 0) { *error_r = fields[0] != NULL ? t_strdup(fields[0]) : "passdb lookup failed"; + *error_r = t_strdup_printf("%s (to see if user is proxied, " + "because doveadm_proxy_port is set)", + *error_r); } else if (ret == 0) { /* user not found from passdb. it could be in userdb though, so just continue with the default host */ From dovecot at dovecot.org Mon Aug 20 11:09:52 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 11:09:52 +0300 Subject: dovecot-2.2: lib-storage: MAX_SORT_PROGRAM_SIZE was too small Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/501f22bf92c3 changeset: 14934:501f22bf92c3 user: Timo Sirainen date: Wed Aug 15 12:37:34 2012 +0300 description: lib-storage: MAX_SORT_PROGRAM_SIZE was too small diffstat: src/lib-storage/mail-storage.h | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diffs (22 lines): diff -r f33e3ac28e1d -r 501f22bf92c3 src/lib-storage/mail-storage.h --- a/src/lib-storage/mail-storage.h Tue Aug 14 23:09:44 2012 +0300 +++ b/src/lib-storage/mail-storage.h Wed Aug 15 12:37:34 2012 +0300 @@ -93,9 +93,6 @@ }; enum mail_sort_type { -/* Maximum size for sort program (each one separately + END) */ -#define MAX_SORT_PROGRAM_SIZE (8 + 1) - MAIL_SORT_ARRIVAL = 0x0001, MAIL_SORT_CC = 0x0002, MAIL_SORT_DATE = 0x0004, @@ -107,6 +104,8 @@ MAIL_SORT_DISPLAYFROM = 0x0100, MAIL_SORT_DISPLAYTO = 0x0200, MAIL_SORT_POP3_ORDER = 0x0400, +/* Maximum size for sort program (each one separately + END) */ +#define MAX_SORT_PROGRAM_SIZE (11 + 1) MAIL_SORT_MASK = 0x0fff, MAIL_SORT_FLAG_REVERSE = 0x1000, /* reverse this mask type */ From dovecot at dovecot.org Mon Aug 20 11:09:52 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 11:09:52 +0300 Subject: dovecot-2.2: replicator: Crashfix Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f68f5aca440e changeset: 14938:f68f5aca440e user: Timo Sirainen date: Sun Aug 19 12:53:06 2012 +0300 description: replicator: Crashfix diffstat: src/replication/aggregator/replicator-connection.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r fe492bba225a -r f68f5aca440e src/replication/aggregator/replicator-connection.c --- a/src/replication/aggregator/replicator-connection.c Fri Aug 17 19:01:03 2012 +0300 +++ b/src/replication/aggregator/replicator-connection.c Sun Aug 19 12:53:06 2012 +0300 @@ -54,7 +54,7 @@ i_error("Replicator sent invalid ID: %u", id); return -1; } - hash_table_remove(conn->requests, context); + hash_table_remove(conn->requests, POINTER_CAST(id)); conn->callback(line[0] == '+', context); return 0; } From dovecot at dovecot.org Mon Aug 20 11:09:53 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 11:09:53 +0300 Subject: dovecot-2.2: Merged changes from v2.1 tree. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2fc74b72817b changeset: 14939:2fc74b72817b user: Timo Sirainen date: Mon Aug 20 11:09:42 2012 +0300 description: Merged changes from v2.1 tree. diffstat: configure.in | 2 +- src/doveadm/doveadm-mail-server.c | 3 + src/imap/cmd-list.c | 6 +- src/imap/cmd-thread.c | 148 ++++++++++++++++++++++++++- src/lib-imap-client/imapc-client.h | 1 + src/lib-imap-client/imapc-connection.c | 4 +- src/lib-storage/index/imapc/imapc-settings.c | 4 + src/lib-storage/index/imapc/imapc-settings.h | 2 + src/lib-storage/index/imapc/imapc-storage.c | 1 + src/lib-storage/list/mailbox-list-fs-iter.c | 32 ++++- src/lib-storage/mail-namespace.c | 11 +- src/lib-storage/mail-namespace.h | 5 +- src/lib-storage/mail-storage.h | 5 +- src/lib-storage/mail-thread.c | 2 + src/lib-storage/mailbox-list.c | 6 +- src/lib/ioloop.c | 4 +- 16 files changed, 214 insertions(+), 22 deletions(-) diffs (truncated from 495 to 300 lines): diff -r 9c69df65af7b -r 2fc74b72817b configure.in --- a/configure.in Mon Aug 20 10:54:04 2012 +0300 +++ b/configure.in Mon Aug 20 11:09:42 2012 +0300 @@ -2718,7 +2718,7 @@ dnl IDLE doesn't really belong to banner. It's there just to make Blackberries dnl happy, because otherwise BIS server disables push email. capability_banner="IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE" -capability="$capability_banner SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE BINARY MOVE" +capability="$capability_banner SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE BINARY MOVE" AC_DEFINE_UNQUOTED(CAPABILITY_STRING, "$capability", IMAP capabilities) AC_DEFINE_UNQUOTED(CAPABILITY_BANNER_STRING, "$capability_banner", IMAP capabilities advertised in banner) diff -r 9c69df65af7b -r 2fc74b72817b src/doveadm/doveadm-mail-server.c --- a/src/doveadm/doveadm-mail-server.c Mon Aug 20 10:54:04 2012 +0300 +++ b/src/doveadm/doveadm-mail-server.c Mon Aug 20 11:09:42 2012 +0300 @@ -181,6 +181,9 @@ if (ret < 0) { *error_r = fields[0] != NULL ? t_strdup(fields[0]) : "passdb lookup failed"; + *error_r = t_strdup_printf("%s (to see if user is proxied, " + "because doveadm_proxy_port is set)", + *error_r); } else if (ret == 0) { /* user not found from passdb. it could be in userdb though, so just continue with the default host */ diff -r 9c69df65af7b -r 2fc74b72817b src/imap/cmd-list.c --- a/src/imap/cmd-list.c Mon Aug 20 10:54:04 2012 +0300 +++ b/src/imap/cmd-list.c Mon Aug 20 11:09:42 2012 +0300 @@ -438,10 +438,12 @@ if (ctx->cur_ns_send_prefix) list_namespace_send_prefix(ctx, TRUE); - /* if there's a namespace with this name, list it as + /* if there's a list=yes namespace with this name, list it as having children */ ns = mail_namespace_find_prefix_nosep(ctx->ns, name); - if (ns != NULL) { + if (ns != NULL && + (ns->flags & (NAMESPACE_FLAG_LIST_PREFIX | + NAMESPACE_FLAG_LIST_CHILDREN)) != 0) { flags |= MAILBOX_CHILDREN; flags &= ~MAILBOX_NOCHILDREN; array_append(&ctx->ns_prefixes_listed, &ns, 1); diff -r 9c69df65af7b -r 2fc74b72817b src/imap/cmd-thread.c --- a/src/imap/cmd-thread.c Mon Aug 20 10:54:04 2012 +0300 +++ b/src/imap/cmd-thread.c Mon Aug 20 11:09:42 2012 +0300 @@ -3,6 +3,7 @@ #include "imap-common.h" #include "str.h" #include "ostream.h" +#include "imap-base-subject.h" #include "imap-commands.h" #include "imap-search-args.h" #include "mail-thread.h" @@ -100,6 +101,148 @@ return ret; } +struct orderedsubject_thread { + time_t timestamp; + ARRAY_TYPE(uint32_t) msgs; +}; + +static int orderedsubject_thread_cmp(const struct orderedsubject_thread *t1, + const struct orderedsubject_thread *t2) +{ + const uint32_t *m1, *m2; + + if (t1->timestamp < t2->timestamp) + return -1; + if (t1->timestamp > t2->timestamp) + return 1; + + m1 = array_idx(&t1->msgs, 0); + m2 = array_idx(&t2->msgs, 0); + if (*m1 < *m2) + return -1; + if (*m1 > *m2) + return 1; + i_unreached(); +} + +static void +imap_orderedsubject_thread_write(struct ostream *output, string_t *reply, + const struct orderedsubject_thread *thread) +{ + const uint32_t *msgs; + unsigned int i, count; + + if (str_len(reply) > 128-10) { + o_stream_send(output, str_data(reply), str_len(reply)); + str_truncate(reply, 0); + } + + msgs = array_get(&thread->msgs, &count); + switch (count) { + case 1: + str_printfa(reply, "(%u)", msgs[0]); + break; + case 2: + str_printfa(reply, "(%u %u)", msgs[0], msgs[1]); + break; + default: + /* (1 (2)(3)) */ + str_printfa(reply, "(%u ", msgs[0]); + for (i = 1; i < count; i++) { + if (str_len(reply) > 128-10) { + o_stream_send(output, str_data(reply), + str_len(reply)); + str_truncate(reply, 0); + } + str_printfa(reply, "(%u)", msgs[i]); + } + str_append_c(reply, ')'); + } +} + +static int imap_thread_orderedsubject(struct client_command_context *cmd, + struct mail_search_args *search_args) +{ + static const enum mail_sort_type sort_program[] = { + MAIL_SORT_SUBJECT, + MAIL_SORT_DATE, + 0 + }; + struct mailbox_transaction_context *trans; + struct mail_search_context *search_ctx; + struct mail *mail; + string_t *prev_subject, *reply; + const char *subject, *base_subject; + pool_t pool; + ARRAY(struct orderedsubject_thread) threads; + const struct orderedsubject_thread *thread; + struct orderedsubject_thread *cur_thread = NULL; + uint32_t num; + int ret; + + prev_subject = str_new(default_pool, 128); + + /* first read all of the threads into memory */ + pool = pool_alloconly_create("orderedsubject thread", 1024); + i_array_init(&threads, 128); + trans = mailbox_transaction_begin(cmd->client->mailbox, 0); + search_ctx = mailbox_search_init(trans, search_args, sort_program, + 0, NULL); + while (mailbox_search_next(search_ctx, &mail)) { + if (mail_get_first_header(mail, "Subject", &subject) <= 0) + subject = ""; + T_BEGIN { + base_subject = imap_get_base_subject_cased( + pool_datastack_create(), subject, NULL); + if (strcmp(str_c(prev_subject), base_subject) != 0) { + /* thread changed */ + cur_thread = NULL; + } + str_truncate(prev_subject, 0); + str_append(prev_subject, base_subject); + } T_END; + + if (cur_thread == NULL) { + /* starting a new thread. get the first message's + date */ + cur_thread = array_append_space(&threads); + if (mail_get_date(mail, &cur_thread->timestamp, NULL) == 0 && + cur_thread->timestamp == 0) { + (void)mail_get_received_date(mail, + &cur_thread->timestamp); + } + p_array_init(&cur_thread->msgs, pool, 4); + } + num = cmd->uid ? mail->uid : mail->seq; + array_append(&cur_thread->msgs, &num, 1); + } + str_free(&prev_subject); + ret = mailbox_search_deinit(&search_ctx); + (void)mailbox_transaction_commit(&trans); + if (ret < 0) { + array_free(&threads); + pool_unref(&pool); + return -1; + } + + /* sort the threads by their first message's timestamp */ + array_sort(&threads, orderedsubject_thread_cmp); + + /* write the threads to client */ + reply = t_str_new(128); + str_append(reply, "* THREAD "); + array_foreach(&threads, thread) { + imap_orderedsubject_thread_write(cmd->client->output, + reply, thread); + } + str_append(reply, "\r\n"); + o_stream_send(cmd->client->output, str_data(reply), str_len(reply)); + + array_free(&threads); + pool_unref(&pool); + return 0; +} + bool cmd_thread(struct client_command_context *cmd) { struct client *client = cmd->client; @@ -131,7 +274,10 @@ if (ret <= 0) return ret < 0; - ret = imap_thread(cmd, sargs, thread_type); + if (thread_type != MAIL_THREAD_ORDEREDSUBJECT) + ret = imap_thread(cmd, sargs, thread_type); + else + ret = imap_thread_orderedsubject(cmd, sargs); mail_search_args_unref(&sargs); if (ret < 0) { client_send_storage_error(cmd, diff -r 9c69df65af7b -r 2fc74b72817b src/lib-imap-client/imapc-client.h --- a/src/lib-imap-client/imapc-client.h Mon Aug 20 10:54:04 2012 +0300 +++ b/src/lib-imap-client/imapc-client.h Mon Aug 20 11:09:42 2012 +0300 @@ -52,6 +52,7 @@ const char *master_user; const char *username; const char *password; + unsigned int max_idle_time; const char *dns_client_socket_path; const char *temp_path_prefix; diff -r 9c69df65af7b -r 2fc74b72817b src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Mon Aug 20 10:54:04 2012 +0300 +++ b/src/lib-imap-client/imapc-connection.c Mon Aug 20 11:09:42 2012 +0300 @@ -24,8 +24,6 @@ #define IMAPC_CONNECT_TIMEOUT_MSECS (1000*30) #define IMAPC_COMMAND_TIMEOUT_MSECS (1000*60*5) #define IMAPC_MAX_INLINE_LITERAL_SIZE (1024*32) -/* IMAP protocol requires activity at least every 30 minutes */ -#define IMAPC_MAX_IDLE_MSECS (1000*60*29) enum imapc_input_state { IMAPC_INPUT_STATE_NONE = 0, @@ -1310,7 +1308,7 @@ conn->parser = imap_parser_create(conn->input, NULL, (size_t)-1); conn->to = timeout_add(IMAPC_CONNECT_TIMEOUT_MSECS, imapc_connection_timeout, conn); - conn->to_output = timeout_add(IMAPC_MAX_IDLE_MSECS, + conn->to_output = timeout_add(conn->client->set.max_idle_time*1000, imapc_connection_reset_idle, conn); if (conn->client->set.debug) { i_debug("imapc(%s): Connecting to %s:%u", conn->name, diff -r 9c69df65af7b -r 2fc74b72817b src/lib-storage/index/imapc/imapc-settings.c --- a/src/lib-storage/index/imapc/imapc-settings.c Mon Aug 20 10:54:04 2012 +0300 +++ b/src/lib-storage/index/imapc/imapc-settings.c Mon Aug 20 11:09:42 2012 +0300 @@ -28,6 +28,8 @@ DEF(SET_STR, imapc_features), DEF(SET_STR, imapc_rawlog_dir), DEF(SET_STR, imapc_list_prefix), + DEF(SET_TIME, imapc_max_idle_time), + DEF(SET_STR, ssl_crypto_device), SETTING_DEFINE_LIST_END @@ -48,6 +50,8 @@ .imapc_features = "", .imapc_rawlog_dir = "", .imapc_list_prefix = "", + .imapc_max_idle_time = 60*29, + .ssl_crypto_device = "" }; diff -r 9c69df65af7b -r 2fc74b72817b src/lib-storage/index/imapc/imapc-settings.h --- a/src/lib-storage/index/imapc/imapc-settings.h Mon Aug 20 10:54:04 2012 +0300 +++ b/src/lib-storage/index/imapc/imapc-settings.h Mon Aug 20 11:09:42 2012 +0300 @@ -23,6 +23,8 @@ const char *imapc_features; const char *imapc_rawlog_dir; const char *imapc_list_prefix; + unsigned int imapc_max_idle_time; + const char *ssl_crypto_device; enum imapc_features parsed_features; diff -r 9c69df65af7b -r 2fc74b72817b src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Mon Aug 20 10:54:04 2012 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.c Mon Aug 20 11:09:42 2012 +0300 @@ -228,6 +228,7 @@ *error_r = "missing imapc_password"; return -1; } + set.max_idle_time = storage->set->imapc_max_idle_time; set.dns_client_socket_path = *_storage->user->set->base_dir == '\0' ? "" : t_strconcat(_storage->user->set->base_dir, "/", diff -r 9c69df65af7b -r 2fc74b72817b src/lib-storage/list/mailbox-list-fs-iter.c --- a/src/lib-storage/list/mailbox-list-fs-iter.c Mon Aug 20 10:54:04 2012 +0300 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Mon Aug 20 11:09:42 2012 +0300 @@ -49,6 +49,7 @@ struct list_dir_context *dir; unsigned int inbox_found:1; + unsigned int list_inbox_inbox:1; }; From dovecot at dovecot.org Mon Aug 20 16:14:00 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 20 Aug 2012 16:14:00 +0300 Subject: dovecot-2.2: i_stream_create_seekable_path() created memory corr... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e3f8be1bd93a changeset: 14940:e3f8be1bd93a user: Timo Sirainen date: Mon Aug 20 16:13:49 2012 +0300 description: i_stream_create_seekable_path() created memory corruption diffstat: src/lib/istream-seekable.c | 24 ++++++++++++++++-------- 1 files changed, 16 insertions(+), 8 deletions(-) diffs (51 lines): diff -r 2fc74b72817b -r e3f8be1bd93a src/lib/istream-seekable.c --- a/src/lib/istream-seekable.c Mon Aug 20 11:09:42 2012 +0300 +++ b/src/lib/istream-seekable.c Mon Aug 20 16:13:49 2012 +0300 @@ -392,20 +392,25 @@ return i_stream_create(&sstream->istream, NULL, -1); } +static bool inputs_are_seekable(struct istream *input[]) +{ + unsigned int count; + + for (count = 0; input[count] != NULL; count++) { + if (!input[count]->seekable) + return FALSE; + } + return TRUE; +} + struct istream * i_stream_create_seekable(struct istream *input[], size_t max_buffer_size, int (*fd_callback)(const char **path_r, void *context), void *context) { - unsigned int count; - /* If all input streams are seekable, use concat istream instead */ - for (count = 0; input[count] != NULL; count++) { - if (!input[count]->seekable) - break; - } - if (input[count] == NULL) + if (inputs_are_seekable(input)) return i_stream_create_concat(input); return i_streams_merge(input, max_buffer_size, fd_callback, context); @@ -445,10 +450,13 @@ struct seekable_istream *sstream; struct istream *stream; + if (inputs_are_seekable(input)) + return i_stream_create_concat(input); + stream = i_stream_create_seekable(input, max_buffer_size, seekable_fd_callback, i_strdup(temp_path_prefix)); - sstream = (struct seekable_istream *)stream; + sstream = (struct seekable_istream *)stream->real_stream; sstream->free_context = TRUE; return stream; } From dovecot at dovecot.org Tue Aug 21 10:06:38 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 21 Aug 2012 10:06:38 +0300 Subject: dovecot-2.2: dict redis: Fixed dict_lookup() to skip all previou... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/bf727e0b721a changeset: 14941:bf727e0b721a user: Timo Sirainen date: Tue Aug 21 10:02:44 2012 +0300 description: dict redis: Fixed dict_lookup() to skip all previous pending replies. diffstat: src/lib-dict/dict-redis.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (14 lines): diff -r e3f8be1bd93a -r bf727e0b721a src/lib-dict/dict-redis.c --- a/src/lib-dict/dict-redis.c Mon Aug 20 16:13:49 2012 +0300 +++ b/src/lib-dict/dict-redis.c Tue Aug 21 10:02:44 2012 +0300 @@ -439,7 +439,9 @@ str_truncate(dict->conn.last_reply, 0); redis_input_state_add(dict, REDIS_INPUT_STATE_GET); - io_loop_run(dict->ioloop); + do { + io_loop_run(dict->ioloop); + } while (array_count(&dict->input_states) > 0); } timeout_remove(&to); } From dovecot at dovecot.org Tue Aug 21 10:18:48 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 21 Aug 2012 10:18:48 +0300 Subject: dovecot-2.2: imap: Fixed command output locking. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/eea4d286185a changeset: 14942:eea4d286185a user: Timo Sirainen date: Tue Aug 21 10:18:38 2012 +0300 description: imap: Fixed command output locking. diffstat: src/imap/cmd-idle.c | 2 +- src/imap/imap-client.c | 11 ++++------- src/imap/imap-client.h | 1 - src/imap/imap-fetch.c | 5 +++-- src/imap/imap-sync.c | 4 ++-- src/imap/main.c | 2 +- 6 files changed, 11 insertions(+), 14 deletions(-) diffs (127 lines): diff -r bf727e0b721a -r eea4d286185a src/imap/cmd-idle.c --- a/src/imap/cmd-idle.c Tue Aug 21 10:02:44 2012 +0300 +++ b/src/imap/cmd-idle.c Tue Aug 21 10:18:38 2012 +0300 @@ -115,7 +115,7 @@ static void keepalive_timeout(struct cmd_idle_context *ctx) { - if (ctx->client->output_locked) { + if (ctx->client->output_cmd_lock != NULL) { /* it's busy sending output */ return; } diff -r bf727e0b721a -r eea4d286185a src/imap/imap-client.c --- a/src/imap/imap-client.c Tue Aug 21 10:02:44 2012 +0300 +++ b/src/imap/imap-client.c Tue Aug 21 10:18:38 2012 +0300 @@ -31,7 +31,7 @@ static void client_idle_timeout(struct client *client) { - if (!client->output_locked) + if (client->output_cmd_lock == NULL) client_send_line(client, "* BYE Disconnected for inactivity."); client_destroy(client, "Disconnected for inactivity"); } @@ -574,10 +574,7 @@ *_cmd = NULL; - if (client->output_cmd_lock == cmd) { - i_assert(client->disconnected); - client->output_cmd_lock = NULL; - } + i_assert(client->output_cmd_lock == NULL); /* reset input idle time because command output might have taken a long time and we don't want to disconnect client immediately then */ @@ -801,7 +798,7 @@ /* beginning a new command */ if (client->command_queue_size >= CLIENT_COMMAND_QUEUE_MAX_SIZE || - client->output_locked) { + client->output_cmd_lock != NULL) { /* wait for some of the commands to finish */ *remove_io_r = TRUE; return FALSE; @@ -907,7 +904,7 @@ client->output_cmd_lock->temp_executed = TRUE; client_output_cmd(client->output_cmd_lock); } - while (!client->output_locked) { + while (client->output_cmd_lock == NULL) { /* go through the entire commands list every time in case multiple commands were freed. temp_executed keeps track of which messages we've called so far */ diff -r bf727e0b721a -r eea4d286185a src/imap/imap-client.h --- a/src/imap/imap-client.h Tue Aug 21 10:02:44 2012 +0300 +++ b/src/imap/imap-client.h Tue Aug 21 10:18:38 2012 +0300 @@ -152,7 +152,6 @@ unsigned int mailbox_examined:1; unsigned int anvil_sent:1; unsigned int tls_compression:1; - unsigned int output_locked:1; unsigned int input_skip_line:1; /* skip all the data until we've found a new line */ unsigned int modseqs_sent_since_sync:1; diff -r bf727e0b721a -r eea4d286185a src/imap/imap-fetch.c --- a/src/imap/imap-fetch.c Tue Aug 21 10:02:44 2012 +0300 +++ b/src/imap/imap-fetch.c Tue Aug 21 10:18:38 2012 +0300 @@ -569,7 +569,7 @@ { int ret; - i_assert(!ctx->client->output_locked || + i_assert(ctx->client->output_cmd_lock == NULL || ctx->client->output_cmd_lock == cmd); ret = imap_fetch_more_int(ctx, cmd->cancel); @@ -586,7 +586,6 @@ client_disconnect(ctx->client, "Failed to cancel FETCH"); ctx->client->output_cmd_lock = NULL; } - ctx->client->output_locked = ctx->client->output_cmd_lock != NULL; return ret; } @@ -618,6 +617,8 @@ state->failed = TRUE; } } + ctx->client->output_cmd_lock = NULL; + if (state->cur_str != NULL) str_free(&state->cur_str); diff -r bf727e0b721a -r eea4d286185a src/imap/imap-sync.c --- a/src/imap/imap-sync.c Tue Aug 21 10:02:44 2012 +0300 +++ b/src/imap/imap-sync.c Tue Aug 21 10:18:38 2012 +0300 @@ -764,7 +764,7 @@ { struct client *client = cmd->client; - i_assert(!client->output_locked); + i_assert(client->output_cmd_lock == NULL); if (cmd->cancel) return TRUE; @@ -837,7 +837,7 @@ { struct client_command_context *cmd, *first_expunge, *first_nonexpunge; - if (client->output_locked) { + if (client->output_cmd_lock != NULL) { /* wait until we can send output to client */ return FALSE; } diff -r bf727e0b721a -r eea4d286185a src/imap/main.c --- a/src/imap/main.c Tue Aug 21 10:02:44 2012 +0300 +++ b/src/imap/main.c Tue Aug 21 10:18:38 2012 +0300 @@ -85,7 +85,7 @@ static void client_kill_idle(struct client *client) { - if (client->output_locked) + if (client->output_cmd_lock != NULL) return; client_send_line(client, "* BYE Server shutting down."); From dovecot at dovecot.org Wed Aug 22 07:50:15 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 22 Aug 2012 07:50:15 +0300 Subject: dovecot-2.1: auth: Unregister SCRAM-SHA-1 at deinit. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/9523b967a30e changeset: 14674:9523b967a30e user: Timo Sirainen date: Wed Aug 22 07:49:55 2012 +0300 description: auth: Unregister SCRAM-SHA-1 at deinit. diffstat: src/auth/mech.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r f68f5aca440e -r 9523b967a30e src/auth/mech.c --- a/src/auth/mech.c Sun Aug 19 12:53:06 2012 +0300 +++ b/src/auth/mech.c Wed Aug 22 07:49:55 2012 +0300 @@ -205,6 +205,7 @@ #endif } mech_unregister_module(&mech_otp); + mech_unregister_module(&mech_scram_sha1); mech_unregister_module(&mech_skey); mech_unregister_module(&mech_rpa); mech_unregister_module(&mech_anonymous); From dovecot at dovecot.org Wed Aug 22 10:18:58 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 22 Aug 2012 10:18:58 +0300 Subject: dovecot-2.2: Added i_stream_create_range() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/34e4c04ae679 changeset: 14943:34e4c04ae679 user: Timo Sirainen date: Wed Aug 22 10:18:08 2012 +0300 description: Added i_stream_create_range() diffstat: src/lib/istream-limit.c | 12 ++++++++++++ src/lib/istream.h | 2 ++ 2 files changed, 14 insertions(+), 0 deletions(-) diffs (31 lines): diff -r eea4d286185a -r 34e4c04ae679 src/lib/istream-limit.c --- a/src/lib/istream-limit.c Tue Aug 21 10:18:38 2012 +0300 +++ b/src/lib/istream-limit.c Wed Aug 22 10:18:08 2012 +0300 @@ -127,3 +127,15 @@ return i_stream_create(&lstream->istream, input, i_stream_get_fd(input)); } + +struct istream *i_stream_create_range(struct istream *input, + uoff_t v_offset, uoff_t v_size) +{ + uoff_t orig_offset = input->v_offset; + struct istream *ret; + + input->v_offset = v_offset; + ret = i_stream_create_limit(input, v_size); + input->v_offset = orig_offset; + return ret; +} diff -r eea4d286185a -r 34e4c04ae679 src/lib/istream.h --- a/src/lib/istream.h Tue Aug 21 10:18:38 2012 +0300 +++ b/src/lib/istream.h Wed Aug 22 10:18:08 2012 +0300 @@ -32,6 +32,8 @@ bool autoclose_fd); struct istream *i_stream_create_from_data(const void *data, size_t size); struct istream *i_stream_create_limit(struct istream *input, uoff_t v_size); +struct istream *i_stream_create_range(struct istream *input, + uoff_t v_offset, uoff_t v_size); /* Set name (e.g. path) for input stream. */ void i_stream_set_name(struct istream *stream, const char *name); From dovecot at dovecot.org Wed Aug 22 10:18:58 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 22 Aug 2012 10:18:58 +0300 Subject: dovecot-2.2: istream-attachment-connector: Avoid seeking in the ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9cefc52d688f changeset: 14944:9cefc52d688f user: Timo Sirainen date: Wed Aug 22 10:18:44 2012 +0300 description: istream-attachment-connector: Avoid seeking in the base stream, it may not be seekable. diffstat: src/lib-mail/istream-attachment-connector.c | 16 ++++++++++------ 1 files changed, 10 insertions(+), 6 deletions(-) diffs (51 lines): diff -r 34e4c04ae679 -r 9cefc52d688f src/lib-mail/istream-attachment-connector.c --- a/src/lib-mail/istream-attachment-connector.c Wed Aug 22 10:18:08 2012 +0300 +++ b/src/lib-mail/istream-attachment-connector.c Wed Aug 22 10:18:44 2012 +0300 @@ -11,7 +11,7 @@ struct istream_attachment_connector { pool_t pool; struct istream *base_input; - uoff_t msg_size; + uoff_t base_input_offset, msg_size; uoff_t encoded_offset; ARRAY(struct istream *) streams; @@ -27,6 +27,7 @@ conn = p_new(pool, struct istream_attachment_connector, 1); conn->pool = pool; conn->base_input = base_input; + conn->base_input_offset = base_input->v_offset; conn->msg_size = msg_size; p_array_init(&conn->streams, pool, 8); i_stream_ref(conn->base_input); @@ -64,10 +65,11 @@ if (base_prefix_size > 0) { /* add a part of the base message before the attachment */ - input = i_stream_create_limit(conn->base_input, + input = i_stream_create_range(conn->base_input, + conn->base_input_offset, base_prefix_size); array_append(&conn->streams, &input, 1); - i_stream_skip(conn->base_input, base_prefix_size); + conn->base_input_offset += base_prefix_size; conn->encoded_offset += base_prefix_size; } conn->encoded_offset += encoded_size; @@ -95,11 +97,13 @@ *_conn = NULL; - if (conn->base_input->v_offset != conn->msg_size) { - i_assert(conn->base_input->v_offset < conn->msg_size); + if (conn->base_input_offset != conn->msg_size) { + i_assert(conn->base_input_offset < conn->msg_size); trailer_size = conn->msg_size - conn->encoded_offset; - input = i_stream_create_limit(conn->base_input, trailer_size); + input = i_stream_create_range(conn->base_input, + conn->base_input_offset, + trailer_size); array_append(&conn->streams, &input, 1); } array_append_zero(&conn->streams); From dovecot at dovecot.org Wed Aug 22 11:43:26 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 22 Aug 2012 11:43:26 +0300 Subject: dovecot-2.2: istream-attachment-extractor didn't return hash str... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ab486673638c changeset: 14945:ab486673638c user: Timo Sirainen date: Wed Aug 22 11:43:15 2012 +0300 description: istream-attachment-extractor didn't return hash strings correctly. diffstat: src/lib-mail/istream-attachment-extractor.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 9cefc52d688f -r ab486673638c src/lib-mail/istream-attachment-extractor.c --- a/src/lib-mail/istream-attachment-extractor.c Wed Aug 22 10:18:44 2012 +0300 +++ b/src/lib-mail/istream-attachment-extractor.c Wed Aug 22 11:43:15 2012 +0300 @@ -469,6 +469,7 @@ info.base64_blocks_per_line = part->base64_line_blocks; info.base64_have_crlf = part->base64_have_crlf; /* base64-decoder updated the hash, use it */ + str_truncate(digest_str, 0); hash_format_write(astream->set.hash_format, digest_str); info.hash = str_c(digest_str); } else { From dovecot at dovecot.org Wed Aug 22 11:44:51 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 22 Aug 2012 11:44:51 +0300 Subject: dovecot-2.2: Added a test for istream-attachment-extractor hash ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/edcdab7cccfd changeset: 14946:edcdab7cccfd user: Timo Sirainen date: Wed Aug 22 11:44:46 2012 +0300 description: Added a test for istream-attachment-extractor hash size diffstat: src/lib-mail/test-istream-attachment.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r ab486673638c -r edcdab7cccfd src/lib-mail/test-istream-attachment.c --- a/src/lib-mail/test-istream-attachment.c Wed Aug 22 11:43:15 2012 +0300 +++ b/src/lib-mail/test-istream-attachment.c Wed Aug 22 11:44:46 2012 +0300 @@ -97,6 +97,7 @@ a->start_offset = info->start_offset; a->encoded_size = info->encoded_size; a->base64_blocks_per_line = info->base64_blocks_per_line; + test_assert(strlen(info->hash) == 160/8*2); /* sha1 size */ *output_r = o_stream_create_buffer(attachment_data); if (o_stream_seek(*output_r, a->buffer_offset) < 0) From dovecot at dovecot.org Wed Aug 22 15:13:33 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 22 Aug 2012 15:13:33 +0300 Subject: dovecot-2.2: istream-concat bugfixes Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8377786d750a changeset: 14947:8377786d750a user: Timo Sirainen date: Wed Aug 22 15:13:21 2012 +0300 description: istream-concat bugfixes diffstat: src/lib/istream-concat.c | 46 +++++++++++++++++++++++++++++----------------- 1 files changed, 29 insertions(+), 17 deletions(-) diffs (85 lines): diff -r edcdab7cccfd -r 8377786d750a src/lib/istream-concat.c --- a/src/lib/istream-concat.c Wed Aug 22 11:44:46 2012 +0300 +++ b/src/lib/istream-concat.c Wed Aug 22 15:13:21 2012 +0300 @@ -86,7 +86,8 @@ { struct concat_istream *cstream = (struct concat_istream *)stream; const unsigned char *data; - size_t size, pos, cur_pos, bytes_skipped; + size_t size, data_size, cur_data_pos, new_pos, bytes_skipped; + size_t new_bytes_count; ssize_t ret; bool last_stream; @@ -114,13 +115,13 @@ stream->pos -= bytes_skipped; stream->skip -= bytes_skipped; - cur_pos = stream->pos - stream->skip - cstream->prev_stream_left; - data = i_stream_get_data(cstream->cur_input, &pos); - if (pos > cur_pos) - ret = 0; - else { + i_assert(stream->pos >= stream->skip + cstream->prev_stream_left); + cur_data_pos = stream->pos - (stream->skip + cstream->prev_stream_left); + + data = i_stream_get_data(cstream->cur_input, &data_size); + if (data_size <= cur_data_pos) { /* need to read more */ - i_assert(cur_pos == pos); + i_assert(cur_data_pos == data_size); ret = i_stream_read(cstream->cur_input); if (ret == -2 || ret == 0) return ret; @@ -144,30 +145,41 @@ stream->istream.eof = cstream->cur_input->eof && last_stream; i_assert(ret != -1 || stream->istream.eof); - data = i_stream_get_data(cstream->cur_input, &pos); + data = i_stream_get_data(cstream->cur_input, &data_size); } if (cstream->prev_stream_left == 0) { + /* we can point directly to the current stream's buffers */ stream->buffer = data; stream->pos -= stream->skip; stream->skip = 0; - } else if (pos == cur_pos) { + new_pos = data_size; + } else if (data_size == cur_data_pos) { + /* nothing new read */ + i_assert(ret == 0 || ret == -1); stream->buffer = stream->w_buffer; + new_pos = stream->pos; } else { + /* we still have some of the previous stream left. merge the + new data with it. */ + i_assert(data_size > cur_data_pos); + new_bytes_count = data_size - cur_data_pos; + if (!i_stream_try_alloc(stream, new_bytes_count, &size)) { + stream->buffer = stream->w_buffer; + return -2; + } stream->buffer = stream->w_buffer; - if (!i_stream_try_alloc(stream, pos - cur_pos, &size)) - return -2; - if (pos > size) - pos = size; + if (new_bytes_count > size) + new_bytes_count = size; memcpy(stream->w_buffer + stream->pos, - data + cur_pos, pos - cur_pos); + data + cur_data_pos, new_bytes_count); + new_pos = stream->pos + new_bytes_count; } - pos += stream->skip + cstream->prev_stream_left; - ret = pos > stream->pos ? (ssize_t)(pos - stream->pos) : + ret = new_pos > stream->pos ? (ssize_t)(new_pos - stream->pos) : (ret == 0 ? 0 : -1); - stream->pos = pos; + stream->pos = new_pos; cstream->prev_skip = stream->skip; return ret; } From dovecot at dovecot.org Wed Aug 22 15:17:59 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 22 Aug 2012 15:17:59 +0300 Subject: dovecot-2.1: istream-concat bugfixes Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/c6fe6a77defd changeset: 14675:c6fe6a77defd user: Timo Sirainen date: Wed Aug 22 15:17:53 2012 +0300 description: istream-concat bugfixes diffstat: src/lib/istream-concat.c | 18 +++++++++++------- 1 files changed, 11 insertions(+), 7 deletions(-) diffs (40 lines): diff -r 9523b967a30e -r c6fe6a77defd src/lib/istream-concat.c --- a/src/lib/istream-concat.c Wed Aug 22 07:49:55 2012 +0300 +++ b/src/lib/istream-concat.c Wed Aug 22 15:17:53 2012 +0300 @@ -87,7 +87,7 @@ { struct concat_istream *cstream = (struct concat_istream *)stream; const unsigned char *data; - size_t size, pos, cur_pos, bytes_skipped; + size_t size, pos, cur_pos, bytes_skipped, new_bytes_count; ssize_t ret; bool last_stream; @@ -154,17 +154,21 @@ stream->skip = 0; } else if (pos == cur_pos) { stream->buffer = stream->w_buffer; + pos = stream->pos; } else { + new_bytes_count = pos - cur_pos; + if (!i_stream_get_buffer_space(stream, new_bytes_count, &size)) { + stream->buffer = stream->w_buffer; + return -2; + } stream->buffer = stream->w_buffer; - if (!i_stream_get_buffer_space(stream, pos - cur_pos, &size)) - return -2; - if (pos > size) - pos = size; + if (new_bytes_count > size) + new_bytes_count = size; memcpy(stream->w_buffer + stream->pos, - data + cur_pos, pos - cur_pos); + data + cur_pos, new_bytes_count); + pos = stream->pos + new_bytes_count; } - pos += stream->skip + cstream->prev_stream_left; ret = pos > stream->pos ? (ssize_t)(pos - stream->pos) : (ret == 0 ? 0 : -1); From dovecot at dovecot.org Wed Aug 22 15:18:45 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 22 Aug 2012 15:18:45 +0300 Subject: dovecot-2.2: istream-base64: Fixed returning -2 too early. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5cf1cedb75e6 changeset: 14948:5cf1cedb75e6 user: Timo Sirainen date: Wed Aug 22 15:18:39 2012 +0300 description: istream-base64: Fixed returning -2 too early. diffstat: src/lib/istream-base64-decoder.c | 2 +- src/lib/istream-base64-encoder.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diffs (24 lines): diff -r 8377786d750a -r 5cf1cedb75e6 src/lib/istream-base64-decoder.c --- a/src/lib/istream-base64-decoder.c Wed Aug 22 15:13:21 2012 +0300 +++ b/src/lib/istream-base64-decoder.c Wed Aug 22 15:18:39 2012 +0300 @@ -90,7 +90,7 @@ post_count = stream->pos - stream->skip; } while (ret == 0 && pre_count == post_count); - if (ret < 0) + if (ret < 0 && pre_count == post_count) return ret; i_assert(post_count > pre_count); diff -r 8377786d750a -r 5cf1cedb75e6 src/lib/istream-base64-encoder.c --- a/src/lib/istream-base64-encoder.c Wed Aug 22 15:13:21 2012 +0300 +++ b/src/lib/istream-base64-encoder.c Wed Aug 22 15:18:39 2012 +0300 @@ -116,7 +116,7 @@ post_count = stream->pos - stream->skip; } while (ret == 0 && pre_count == post_count); - if (ret < 0) + if (ret < 0 && pre_count == post_count) return ret; i_assert(post_count > pre_count); From dovecot at dovecot.org Wed Aug 22 15:19:27 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 22 Aug 2012 15:19:27 +0300 Subject: dovecot-2.2: lib-storage: Added mail_save_copy_default_metadata() Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5b89c50164de changeset: 14949:5b89c50164de user: Timo Sirainen date: Wed Aug 22 15:19:19 2012 +0300 description: lib-storage: Added mail_save_copy_default_metadata() diffstat: src/lib-storage/mail-copy.c | 40 ++++++++++++++++++++++++---------------- src/lib-storage/mail-copy.h | 5 +++++ 2 files changed, 29 insertions(+), 16 deletions(-) diffs (76 lines): diff -r 5cf1cedb75e6 -r 5b89c50164de src/lib-storage/mail-copy.c --- a/src/lib-storage/mail-copy.c Wed Aug 22 15:18:39 2012 +0300 +++ b/src/lib-storage/mail-copy.c Wed Aug 22 15:19:19 2012 +0300 @@ -20,26 +20,12 @@ t_strdup_printf("%s (%s)", errstr, func)); } -static int -mail_storage_try_copy(struct mail_save_context **_ctx, struct mail *mail) +int mail_save_copy_default_metadata(struct mail_save_context *ctx, + struct mail *mail) { - struct mail_save_context *ctx = *_ctx; - struct mail_private *pmail = (struct mail_private *)mail; - struct istream *input; const char *from_envelope, *guid; time_t received_date; - ctx->copying_via_save = TRUE; - - /* we need to open the file in any case. caching metadata is unlikely - to help anything. */ - pmail->v.set_uid_cache_updates(mail, TRUE); - - if (mail_get_stream(mail, NULL, NULL, &input) < 0) { - mail_copy_set_failed(ctx, mail, "stream"); - return -1; - } - if (ctx->received_date == (time_t)-1) { if (mail_get_received_date(mail, &received_date) < 0) { mail_copy_set_failed(ctx, mail, "received-date"); @@ -64,6 +50,28 @@ if (*guid != '\0') mailbox_save_set_guid(ctx, guid); } + return 0; +} + +static int +mail_storage_try_copy(struct mail_save_context **_ctx, struct mail *mail) +{ + struct mail_save_context *ctx = *_ctx; + struct mail_private *pmail = (struct mail_private *)mail; + struct istream *input; + + ctx->copying_via_save = TRUE; + + /* we need to open the file in any case. caching metadata is unlikely + to help anything. */ + pmail->v.set_uid_cache_updates(mail, TRUE); + + if (mail_get_stream(mail, NULL, NULL, &input) < 0) { + mail_copy_set_failed(ctx, mail, "stream"); + return -1; + } + if (mail_save_copy_default_metadata(ctx, mail) < 0) + return -1; if (mailbox_save_begin(_ctx, input) < 0) return -1; diff -r 5cf1cedb75e6 -r 5b89c50164de src/lib-storage/mail-copy.h --- a/src/lib-storage/mail-copy.h Wed Aug 22 15:18:39 2012 +0300 +++ b/src/lib-storage/mail-copy.h Wed Aug 22 15:19:19 2012 +0300 @@ -7,6 +7,11 @@ int mail_storage_copy(struct mail_save_context *ctx, struct mail *mail); +/* If save context already doesn't have some metadata fields set, copy them + from the given mail (e.g. received date, from envelope, guid). */ +int mail_save_copy_default_metadata(struct mail_save_context *ctx, + struct mail *mail); + /* Returns TRUE if mail can be copied using hard linking from src to dest. (Assuming the storage itself supports this.) */ bool mail_storage_copy_can_use_hardlink(struct mailbox *src, From dovecot at dovecot.org Wed Aug 22 16:55:44 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 22 Aug 2012 16:55:44 +0300 Subject: dovecot-2.2: Made PKG_STATEDIR configurable with state_dir setting. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/543852ebb327 changeset: 14950:543852ebb327 user: Timo Sirainen date: Wed Aug 22 16:55:27 2012 +0300 description: Made PKG_STATEDIR configurable with state_dir setting. Based on patch by Chris Webb. Normally this isn't needed, since the data in the state_dir can be shared across multiple Dovecot instances, but in some specific use cases this may be useful (e.g. users running their own Dovecots). diffstat: src/config/Makefile.am | 1 + src/doveadm/doveadm-instance.c | 13 +++++++++---- src/doveadm/doveadm-mount.c | 6 ++++-- src/doveadm/doveadm-settings.c | 1 + src/doveadm/doveadm-settings.h | 1 + src/doveadm/doveadm.c | 4 ++++ src/lib-master/master-instance.h | 2 +- src/lib-master/master-service-settings.c | 2 ++ src/lib-master/master-service-settings.h | 1 + src/lib-master/master-service-ssl.c | 4 ++-- src/lib-master/master-service.c | 6 ++++-- src/login-common/ssl-proxy-openssl.c | 3 +-- src/master/main.c | 11 +++++++---- src/master/master-settings.c | 6 ++++-- src/master/master-settings.h | 1 + src/replication/replicator/replicator.c | 19 ++++++++++++++----- src/ssl-params/main.c | 10 ++++++++-- 17 files changed, 65 insertions(+), 26 deletions(-) diffs (truncated from 378 to 300 lines): diff -r 5b89c50164de -r 543852ebb327 src/config/Makefile.am --- a/src/config/Makefile.am Wed Aug 22 15:19:19 2012 +0300 +++ b/src/config/Makefile.am Wed Aug 22 16:55:27 2012 +0300 @@ -9,6 +9,7 @@ -I$(top_srcdir)/src/lib-settings \ -I$(top_srcdir)/src/lib-master \ -DPKG_RUNDIR=\""$(rundir)"\" \ + -DPKG_STATEDIR=\""$(statedir)"\" \ -DPKG_LIBEXECDIR=\""$(pkglibexecdir)"\" \ -DEXAMPLE_CONFIG_DIR=\""$(exampledir)"\" \ -DMODULEDIR=\""$(moduledir)"\" \ diff -r 5b89c50164de -r 543852ebb327 src/doveadm/doveadm-instance.c --- a/src/doveadm/doveadm-instance.c Wed Aug 22 15:19:19 2012 +0300 +++ b/src/doveadm/doveadm-instance.c Wed Aug 22 16:55:27 2012 +0300 @@ -2,6 +2,7 @@ #include "lib.h" #include "master-instance.h" +#include "master-service-settings.h" #include "doveadm.h" #include "doveadm-print.h" @@ -48,7 +49,7 @@ struct master_instance_list *list; struct master_instance_list_iter *iter; const struct master_instance *inst; - const char *pidfile_path; + const char *instance_path, *pidfile_path; bool show_config = FALSE; int c; @@ -71,7 +72,9 @@ doveadm_print_header_simple("running"); } - list = master_instance_list_init(MASTER_INSTANCE_PATH); + instance_path = t_strconcat(service_set->state_dir, + "/"MASTER_INSTANCE_FNAME, NULL); + list = master_instance_list_init(instance_path); iter = master_instance_list_iterate_init(list); while ((inst = master_instance_iterate_list_next(iter)) != NULL) { if (argv[0] != NULL && strcmp(argv[0], inst->name) != 0) @@ -99,13 +102,15 @@ { struct master_instance_list *list; const struct master_instance *inst; - const char *base_dir; + const char *base_dir, *instance_path; int ret; if (argc != 2) instance_cmd_help(cmd_instance_remove); - list = master_instance_list_init(MASTER_INSTANCE_PATH); + instance_path = t_strconcat(service_set->state_dir, + "/"MASTER_INSTANCE_FNAME, NULL); + list = master_instance_list_init(instance_path); inst = master_instance_list_find_by_name(list, argv[1]); base_dir = inst != NULL ? inst->base_dir : argv[1]; if ((ret = master_instance_list_remove(list, base_dir)) < 0) { diff -r 5b89c50164de -r 543852ebb327 src/doveadm/doveadm-mount.c --- a/src/doveadm/doveadm-mount.c Wed Aug 22 15:19:19 2012 +0300 +++ b/src/doveadm/doveadm-mount.c Wed Aug 22 16:55:27 2012 +0300 @@ -1,6 +1,7 @@ /* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "master-service-settings.h" #include "mountpoint-list.h" #include "doveadm.h" #include "doveadm-print.h" @@ -13,8 +14,9 @@ { const char *perm_path, *state_path; - perm_path = t_strconcat(PKG_STATEDIR"/"MOUNTPOINT_LIST_FNAME, NULL); - state_path = t_strconcat(doveadm_settings->base_dir, + perm_path = t_strconcat(service_set->state_dir, + "/"MOUNTPOINT_LIST_FNAME, NULL); + state_path = t_strconcat(service_set->base_dir, "/"MOUNTPOINT_LIST_FNAME, NULL); return mountpoint_list_init(perm_path, state_path); } diff -r 5b89c50164de -r 543852ebb327 src/doveadm/doveadm-settings.c --- a/src/doveadm/doveadm-settings.c Wed Aug 22 15:19:19 2012 +0300 +++ b/src/doveadm/doveadm-settings.c Wed Aug 22 16:55:27 2012 +0300 @@ -102,6 +102,7 @@ }; struct doveadm_settings *doveadm_settings; +const struct master_service_settings *service_set; static void fix_base_path(struct doveadm_settings *set, pool_t pool, const char **str) diff -r 5b89c50164de -r 543852ebb327 src/doveadm/doveadm-settings.h --- a/src/doveadm/doveadm-settings.h Wed Aug 22 15:19:19 2012 +0300 +++ b/src/doveadm/doveadm-settings.h Wed Aug 22 16:55:27 2012 +0300 @@ -18,5 +18,6 @@ extern const struct setting_parser_info doveadm_setting_parser_info; extern struct doveadm_settings *doveadm_settings; +extern const struct master_service_settings *service_set; #endif diff -r 5b89c50164de -r 543852ebb327 src/doveadm/doveadm.c --- a/src/doveadm/doveadm.c Wed Aug 22 15:19:19 2012 +0300 +++ b/src/doveadm/doveadm.c Wed Aug 22 16:55:27 2012 +0300 @@ -261,6 +261,10 @@ &output, &error) < 0) i_fatal("Error reading configuration: %s", error); + service_set = master_service_settings_get(master_service); + service_set = settings_dup(&master_service_setting_parser_info, + service_set, pool_datastack_create()); + set = master_service_settings_get_others(master_service)[0]; doveadm_settings = settings_dup(&doveadm_setting_parser_info, set, pool_datastack_create()); diff -r 5b89c50164de -r 543852ebb327 src/lib-master/master-instance.h --- a/src/lib-master/master-instance.h Wed Aug 22 15:19:19 2012 +0300 +++ b/src/lib-master/master-instance.h Wed Aug 22 16:55:27 2012 +0300 @@ -1,7 +1,7 @@ #ifndef MASTER_INSTANCE_H #define MASTER_INSTANCE_H -#define MASTER_INSTANCE_PATH PKG_STATEDIR"/instances" +#define MASTER_INSTANCE_FNAME "instances" struct master_instance_list; diff -r 5b89c50164de -r 543852ebb327 src/lib-master/master-service-settings.c --- a/src/lib-master/master-service-settings.c Wed Aug 22 15:19:19 2012 +0300 +++ b/src/lib-master/master-service-settings.c Wed Aug 22 16:55:27 2012 +0300 @@ -35,6 +35,7 @@ static const struct setting_define master_service_setting_defines[] = { DEF(SET_STR, base_dir), + DEF(SET_STR, state_dir), DEF(SET_STR, log_path), DEF(SET_STR, info_log_path), DEF(SET_STR, debug_log_path), @@ -50,6 +51,7 @@ static const struct master_service_settings master_service_default_settings = { .base_dir = PKG_RUNDIR, + .state_dir = PKG_STATEDIR, .log_path = "syslog", .info_log_path = "", .debug_log_path = "", diff -r 5b89c50164de -r 543852ebb327 src/lib-master/master-service-settings.h --- a/src/lib-master/master-service-settings.h Wed Aug 22 15:19:19 2012 +0300 +++ b/src/lib-master/master-service-settings.h Wed Aug 22 16:55:27 2012 +0300 @@ -12,6 +12,7 @@ struct master_service_settings { const char *base_dir; + const char *state_dir; const char *log_path; const char *info_log_path; const char *debug_log_path; diff -r 5b89c50164de -r 543852ebb327 src/lib-master/master-service-ssl.c --- a/src/lib-master/master-service-ssl.c Wed Aug 22 15:19:19 2012 +0300 +++ b/src/lib-master/master-service-ssl.c Wed Aug 22 16:55:27 2012 +0300 @@ -50,8 +50,8 @@ if (ret < 0) i_error("read(%s) failed: %m", path); else if (ssl_iostream_context_import_params(service->ssl_ctx, buf) < 0) { - i_error("Corrupted SSL parameters file: " - PKG_STATEDIR"/ssl-parameters.dat - disabling SSL %u", (int)buf->used); + i_error("Corrupted SSL parameters file in state_dir: " + "ssl-parameters.dat - disabling SSL %u", (int)buf->used); ret = -1; } i_close_fd(&fd); diff -r 5b89c50164de -r 543852ebb327 src/lib-master/master-service.c --- a/src/lib-master/master-service.c Wed Aug 22 15:19:19 2012 +0300 +++ b/src/lib-master/master-service.c Wed Aug 22 16:55:27 2012 +0300 @@ -332,9 +332,11 @@ { struct master_instance_list *list; const struct master_instance *inst; - const char *path; + const char *instance_path, *path; - list = master_instance_list_init(MASTER_INSTANCE_PATH); + instance_path = t_strconcat(master_service->set->state_dir, + "/"MASTER_INSTANCE_FNAME, NULL); + list = master_instance_list_init(instance_path); inst = master_instance_list_find_by_name(list, name); if (inst != NULL) { path = t_strdup_printf("%s/dovecot.conf", inst->base_dir); diff -r 5b89c50164de -r 543852ebb327 src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Wed Aug 22 15:19:19 2012 +0300 +++ b/src/login-common/ssl-proxy-openssl.c Wed Aug 22 16:55:27 2012 +0300 @@ -154,8 +154,7 @@ static void ssl_params_corrupted(void) { - i_fatal("Corrupted SSL parameters file: " - PKG_STATEDIR"/ssl-parameters.dat"); + i_fatal("Corrupted SSL parameters file in state_dir: ssl-parameters.dat"); } static void read_next(struct ssl_parameters *params, void *data, size_t size) diff -r 5b89c50164de -r 543852ebb327 src/master/main.c --- a/src/master/main.c Wed Aug 22 15:19:19 2012 +0300 +++ b/src/master/main.c Wed Aug 22 16:55:27 2012 +0300 @@ -313,7 +313,7 @@ struct mountpoint_list *mountpoints; const char *perm_path, *state_path; - perm_path = t_strconcat(PKG_STATEDIR"/"MOUNTPOINT_LIST_FNAME, NULL); + perm_path = t_strconcat(set->state_dir, "/"MOUNTPOINT_LIST_FNAME, NULL); state_path = t_strconcat(set->base_dir, "/"MOUNTPOINT_LIST_FNAME, NULL); mountpoints = mountpoint_list_init(perm_path, state_path); @@ -342,9 +342,12 @@ instance_update_now, list); } -static void instance_update(void) +static void instance_update(const struct master_settings *set) { - instances = master_instance_list_init(MASTER_INSTANCE_PATH); + const char *path; + + path = t_strconcat(set->state_dir, "/"MASTER_INSTANCE_FNAME, NULL); + instances = master_instance_list_init(path); instance_update_now(instances); } @@ -540,7 +543,7 @@ create_pid_file(pidfile_path); create_config_symlink(set); mountpoints_update(set); - instance_update(); + instance_update(set); services_monitor_start(services); } diff -r 5b89c50164de -r 543852ebb327 src/master/master-settings.c --- a/src/master/master-settings.c Wed Aug 22 15:19:19 2012 +0300 +++ b/src/master/master-settings.c Wed Aug 22 16:55:27 2012 +0300 @@ -171,6 +171,7 @@ static const struct setting_define master_setting_defines[] = { DEF(SET_STR, base_dir), + DEF(SET_STR, state_dir), DEF(SET_STR, libexec_dir), DEF(SET_STR, instance_name), DEF(SET_STR, import_environment), @@ -211,6 +212,7 @@ static const struct master_settings master_default_settings = { .base_dir = PKG_RUNDIR, + .state_dir = PKG_STATEDIR, .libexec_dir = PKG_LIBEXECDIR, .instance_name = PACKAGE, .import_environment = "TZ" ENV_SYSTEMD ENV_GDB, @@ -736,8 +738,8 @@ } /* Make sure our permanent state directory exists */ - if (mkdir_parents(PKG_STATEDIR, 0755) < 0 && errno != EEXIST) - i_fatal("mkdir(%s) failed: %m", PKG_STATEDIR); + if (mkdir_parents(set->state_dir, 0755) < 0 && errno != EEXIST) + i_fatal("mkdir(%s) failed: %m", set->state_dir); login_dir = t_strconcat(set->base_dir, "/login", NULL); if (settings_have_auth_unix_listeners_in(set, login_dir)) { diff -r 5b89c50164de -r 543852ebb327 src/master/master-settings.h --- a/src/master/master-settings.h Wed Aug 22 15:19:19 2012 +0300 +++ b/src/master/master-settings.h Wed Aug 22 16:55:27 2012 +0300 @@ -5,6 +5,7 @@ struct master_settings { const char *base_dir; + const char *state_dir; const char *libexec_dir; const char *instance_name; const char *import_environment; diff -r 5b89c50164de -r 543852ebb327 src/replication/replicator/replicator.c --- a/src/replication/replicator/replicator.c Wed Aug 22 15:19:19 2012 +0300 +++ b/src/replication/replicator/replicator.c Wed Aug 22 16:55:27 2012 +0300 @@ -13,10 +13,11 @@ #define REPLICATOR_AUTH_SERVICE_NAME "replicator" #define REPLICATOR_DB_DUMP_INTERVAL_MSECS (1000*60*15) -#define REPLICATOR_DB_PATH PKG_STATEDIR"/replicator.db" +#define REPLICATOR_DB_FNAME "replicator.db" static struct replicator_queue *queue; static struct replicator_brain *brain; +static const struct master_service_settings *service_set; static const struct replicator_settings *set; static struct timeout *to_dump; @@ -32,7 +33,7 @@ struct auth_master_user_list_ctx *ctx; struct auth_user_info user_info; From dovecot at dovecot.org Wed Aug 22 17:42:13 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 22 Aug 2012 17:42:13 +0300 Subject: dovecot-2.1: configure: Removed OpenBSD /dev/arandom checking. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/3765e8948f1c changeset: 14676:3765e8948f1c user: Timo Sirainen date: Wed Aug 22 17:42:06 2012 +0300 description: configure: Removed OpenBSD /dev/arandom checking. Patch by Brad Smith "The use of arandom was never a requirement for Dovecot and I had submitted the use of arandom due to ports policy to do so anyway." diffstat: configure.in | 14 +++----------- 1 files changed, 3 insertions(+), 11 deletions(-) diffs (28 lines): diff -r c6fe6a77defd -r 3765e8948f1c configure.in --- a/configure.in Wed Aug 22 15:17:53 2012 +0300 +++ b/configure.in Wed Aug 22 17:42:06 2012 +0300 @@ -951,21 +951,13 @@ AC_DEFINE_UNQUOTED(MEM_ALIGN_SIZE, $mem_align, Required memory alignment) dnl * find random source -AC_MSG_CHECKING([for OpenBSD /dev/arandom]) -if test -c /dev/arandom; then +AC_MSG_CHECKING([for /dev/urandom]) +if test -c /dev/urandom || test -s /dev/urandom; then AC_MSG_RESULT(yes) - AC_DEFINE(DEV_URANDOM_PATH, "/dev/arandom", Path to /dev/urandom) + AC_DEFINE(DEV_URANDOM_PATH, "/dev/urandom", Path to /dev/urandom) have_random_source=yes else AC_MSG_RESULT(no) - AC_MSG_CHECKING([for /dev/urandom]) - if test -c /dev/urandom || test -s /dev/urandom; then - AC_MSG_RESULT(yes) - AC_DEFINE(DEV_URANDOM_PATH, "/dev/urandom", Path to /dev/urandom) - have_random_source=yes - else - AC_MSG_RESULT(no) - fi fi if test "$have_random_source" != "yes"; then From dovecot at dovecot.org Thu Aug 23 11:26:25 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Aug 2012 11:26:25 +0300 Subject: dovecot-2.2: Increased initial memory pool size Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d0441efd0efc changeset: 14951:d0441efd0efc user: Timo Sirainen date: Thu Aug 23 11:26:13 2012 +0300 description: Increased initial memory pool size diffstat: src/lib-mail/istream-attachment-extractor.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 543852ebb327 -r d0441efd0efc src/lib-mail/istream-attachment-extractor.c --- a/src/lib-mail/istream-attachment-extractor.c Wed Aug 22 16:55:27 2012 +0300 +++ b/src/lib-mail/istream-attachment-extractor.c Thu Aug 23 11:26:13 2012 +0300 @@ -673,7 +673,7 @@ astream->istream.istream.blocking = input->blocking; astream->istream.istream.seekable = FALSE; - astream->pool = pool_alloconly_create("istream attachment", 512); + astream->pool = pool_alloconly_create("istream attachment", 1024); astream->parser = message_parser_init(astream->pool, input, 0, MESSAGE_PARSER_FLAG_INCLUDE_MULTIPART_BLOCKS | MESSAGE_PARSER_FLAG_INCLUDE_BOUNDARIES); From dovecot at dovecot.org Thu Aug 23 11:54:57 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Aug 2012 11:54:57 +0300 Subject: dovecot-2.2: lib-storage: Moved per-mail data in struct mail_sav... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b966759dd48c changeset: 14952:b966759dd48c user: Timo Sirainen date: Thu Aug 23 11:54:46 2012 +0300 description: lib-storage: Moved per-mail data in struct mail_save_context to separate struct. This fixes previous save leaking metadata to the next save. diffstat: src/lib-storage/index/cydir/cydir-save.c | 28 ++++---- src/lib-storage/index/dbox-common/dbox-save.c | 49 ++++++++------- src/lib-storage/index/dbox-multi/mdbox-save.c | 6 +- src/lib-storage/index/dbox-single/sdbox-copy.c | 2 +- src/lib-storage/index/dbox-single/sdbox-save.c | 8 +- src/lib-storage/index/imapc/imapc-save.c | 25 ++++--- src/lib-storage/index/index-attachment.c | 82 ++++++++++++++----------- src/lib-storage/index/index-mail.c | 5 +- src/lib-storage/index/index-storage.c | 7 +- src/lib-storage/index/maildir/maildir-save.c | 73 +++++++++++----------- src/lib-storage/index/mbox/mbox-save.c | 29 ++++---- src/lib-storage/mail-copy.c | 10 +- src/lib-storage/mail-storage-private.h | 15 +++- src/lib-storage/mail-storage.c | 42 ++++++------ src/plugins/acl/acl-mailbox.c | 4 +- src/plugins/lazy-expunge/lazy-expunge-plugin.c | 2 +- src/plugins/virtual/virtual-save.c | 15 ++-- src/plugins/zlib/zlib-plugin.c | 8 +- 18 files changed, 216 insertions(+), 194 deletions(-) diffs (truncated from 1180 to 300 lines): diff -r d0441efd0efc -r b966759dd48c src/lib-storage/index/cydir/cydir-save.c --- a/src/lib-storage/index/cydir/cydir-save.c Thu Aug 23 11:26:13 2012 +0300 +++ b/src/lib-storage/index/cydir/cydir-save.c Thu Aug 23 11:54:46 2012 +0300 @@ -90,9 +90,9 @@ path = cydir_get_save_path(ctx, ctx->mail_count); ctx->fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0660); if (ctx->fd != -1) { - _ctx->output = + _ctx->data.output = o_stream_create_fd_file(ctx->fd, 0, FALSE); - o_stream_cork(_ctx->output); + o_stream_cork(_ctx->data.output); } else { mail_storage_set_critical(trans->box->storage, "open(%s) failed: %m", path); @@ -103,17 +103,17 @@ return -1; /* add to index */ - save_flags = _ctx->flags & ~MAIL_RECENT; + save_flags = _ctx->data.flags & ~MAIL_RECENT; mail_index_append(ctx->trans, 0, &ctx->seq); mail_index_update_flags(ctx->trans, ctx->seq, MODIFY_REPLACE, save_flags); - if (_ctx->keywords != NULL) { + if (_ctx->data.keywords != NULL) { mail_index_update_keywords(ctx->trans, ctx->seq, - MODIFY_REPLACE, _ctx->keywords); + MODIFY_REPLACE, _ctx->data.keywords); } - if (_ctx->min_modseq != 0) { + if (_ctx->data.min_modseq != 0) { mail_index_update_modseq(ctx->trans, ctx->seq, - _ctx->min_modseq); + _ctx->data.min_modseq); } if (_ctx->dest_mail == NULL) { @@ -138,7 +138,7 @@ return -1; do { - if (o_stream_send_istream(_ctx->output, ctx->input) < 0) { + if (o_stream_send_istream(_ctx->data.output, ctx->input) < 0) { if (!mail_storage_set_error_from_errno(storage)) { mail_storage_set_critical(storage, "write(%s) failed: %m", @@ -162,7 +162,7 @@ struct stat st; int ret = 0; - if (o_stream_nfinish(ctx->ctx.output) < 0) { + if (o_stream_nfinish(ctx->ctx.data.output) < 0) { mail_storage_set_critical(storage, "write(%s) failed: %m", path); ret = -1; } @@ -175,9 +175,9 @@ } } - if (ctx->ctx.received_date == (time_t)-1) { + if (ctx->ctx.data.received_date == (time_t)-1) { if (fstat(ctx->fd, &st) == 0) - ctx->ctx.received_date = st.st_mtime; + ctx->ctx.data.received_date = st.st_mtime; else { mail_storage_set_critical(storage, "fstat(%s) failed: %m", path); @@ -187,7 +187,7 @@ struct utimbuf ut; ut.actime = ioloop_time; - ut.modtime = ctx->ctx.received_date; + ut.modtime = ctx->ctx.data.received_date; if (utime(path, &ut) < 0) { mail_storage_set_critical(storage, "utime(%s) failed: %m", path); @@ -195,7 +195,7 @@ } } - o_stream_destroy(&ctx->ctx.output); + o_stream_destroy(&ctx->ctx.data.output); if (close(ctx->fd) < 0) { mail_storage_set_critical(storage, "close(%s) failed: %m", path); @@ -227,7 +227,7 @@ } index_mail_cache_parse_deinit(_ctx->dest_mail, - _ctx->received_date, !ctx->failed); + _ctx->data.received_date, !ctx->failed); if (ctx->input != NULL) i_stream_unref(&ctx->input); diff -r d0441efd0efc -r b966759dd48c src/lib-storage/index/dbox-common/dbox-save.c --- a/src/lib-storage/index/dbox-common/dbox-save.c Thu Aug 23 11:26:13 2012 +0300 +++ b/src/lib-storage/index/dbox-common/dbox-save.c Thu Aug 23 11:54:46 2012 +0300 @@ -13,19 +13,20 @@ void dbox_save_add_to_index(struct dbox_save_context *ctx) { + struct mail_save_data *mdata = &ctx->ctx.data; enum mail_flags save_flags; - save_flags = ctx->ctx.flags & ~MAIL_RECENT; - mail_index_append(ctx->trans, ctx->ctx.uid, &ctx->seq); + save_flags = mdata->flags & ~MAIL_RECENT; + mail_index_append(ctx->trans, mdata->uid, &ctx->seq); mail_index_update_flags(ctx->trans, ctx->seq, MODIFY_REPLACE, save_flags); - if (ctx->ctx.keywords != NULL) { + if (mdata->keywords != NULL) { mail_index_update_keywords(ctx->trans, ctx->seq, - MODIFY_REPLACE, ctx->ctx.keywords); + MODIFY_REPLACE, mdata->keywords); } - if (ctx->ctx.min_modseq != 0) { + if (mdata->min_modseq != 0) { mail_index_update_modseq(ctx->trans, ctx->seq, - ctx->ctx.min_modseq); + mdata->min_modseq); } } @@ -59,10 +60,10 @@ o_stream_get_name(ctx->dbox_output)); ctx->failed = TRUE; } - _ctx->output = ctx->dbox_output; + _ctx->data.output = ctx->dbox_output; - if (_ctx->received_date == (time_t)-1) - _ctx->received_date = ioloop_time; + if (_ctx->data.received_date == (time_t)-1) + _ctx->data.received_date = ioloop_time; index_attachment_save_begin(_ctx, storage->attachment_fs, ctx->input); } @@ -74,15 +75,15 @@ if (ctx->failed) return -1; - if (_ctx->attach != NULL) + if (_ctx->data.attach != NULL) return index_attachment_save_continue(_ctx); do { - if (o_stream_send_istream(_ctx->output, ctx->input) < 0) { + if (o_stream_send_istream(_ctx->data.output, ctx->input) < 0) { if (!mail_storage_set_error_from_errno(storage)) { mail_storage_set_critical(storage, "write(%s) failed: %m", - o_stream_get_name(_ctx->output)); + o_stream_get_name(_ctx->data.output)); } ctx->failed = TRUE; return -1; @@ -98,25 +99,26 @@ void dbox_save_end(struct dbox_save_context *ctx) { + struct mail_save_data *mdata = &ctx->ctx.data; struct ostream *dbox_output = ctx->dbox_output; - if (ctx->ctx.attach != NULL) { + if (mdata->attach != NULL) { if (index_attachment_save_finish(&ctx->ctx) < 0) ctx->failed = TRUE; } - if (o_stream_nfinish(ctx->ctx.output) < 0) { + if (o_stream_nfinish(mdata->output) < 0) { mail_storage_set_critical(ctx->ctx.transaction->box->storage, "write(%s) failed: %m", - o_stream_get_name(ctx->ctx.output)); + o_stream_get_name(mdata->output)); ctx->failed = TRUE; } - if (ctx->ctx.output == dbox_output) + if (mdata->output == dbox_output) return; /* e.g. zlib plugin had changed this */ o_stream_ref(dbox_output); - o_stream_destroy(&ctx->ctx.output); - ctx->ctx.output = dbox_output; + o_stream_destroy(&mdata->output); + mdata->output = dbox_output; } void dbox_save_write_metadata(struct mail_save_context *_ctx, @@ -125,6 +127,7 @@ guid_128_t guid_128) { struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx; + struct mail_save_data *mdata = &ctx->ctx.data; struct dbox_metadata_header metadata_hdr; const char *guid; string_t *str; @@ -145,18 +148,18 @@ (unsigned long long)ctx->input->v_offset); } str_printfa(str, "%c%lx\n", DBOX_METADATA_RECEIVED_TIME, - (unsigned long)_ctx->received_date); + (unsigned long)mdata->received_date); if (mail_get_virtual_size(_ctx->dest_mail, &vsize) < 0) i_unreached(); str_printfa(str, "%c%llx\n", DBOX_METADATA_VIRTUAL_SIZE, (unsigned long long)vsize); - if (_ctx->pop3_uidl != NULL) { - i_assert(strchr(_ctx->pop3_uidl, '\n') == NULL); + if (mdata->pop3_uidl != NULL) { + i_assert(strchr(mdata->pop3_uidl, '\n') == NULL); str_printfa(str, "%c%s\n", DBOX_METADATA_POP3_UIDL, - _ctx->pop3_uidl); + mdata->pop3_uidl); } - guid = _ctx->guid; + guid = mdata->guid; if (guid != NULL) mail_generate_guid_128_hash(guid, guid_128); else { diff -r d0441efd0efc -r b966759dd48c src/lib-storage/index/dbox-multi/mdbox-save.c --- a/src/lib-storage/index/dbox-multi/mdbox-save.c Thu Aug 23 11:26:13 2012 +0300 +++ b/src/lib-storage/index/dbox-multi/mdbox-save.c Thu Aug 23 11:54:46 2012 +0300 @@ -199,8 +199,8 @@ return -1; dbox_save_end(&ctx->ctx); - index_mail_cache_parse_deinit(_ctx->dest_mail, - _ctx->received_date, !ctx->ctx.failed); + index_mail_cache_parse_deinit(_ctx->dest_mail, _ctx->data.received_date, + !ctx->ctx.failed); mail = array_idx_modifiable(&ctx->mails, array_count(&ctx->mails) - 1); if (!ctx->ctx.failed) T_BEGIN { @@ -421,7 +421,7 @@ if (mail->box->storage != _ctx->transaction->box->storage || _ctx->transaction->box->disable_reflink_copy_to || - _ctx->guid != NULL) + _ctx->data.guid != NULL) return mail_storage_copy(_ctx, mail); src_mbox = (struct mdbox_mailbox *)mail->box; diff -r d0441efd0efc -r b966759dd48c src/lib-storage/index/dbox-single/sdbox-copy.c --- a/src/lib-storage/index/dbox-single/sdbox-copy.c Thu Aug 23 11:26:13 2012 +0300 +++ b/src/lib-storage/index/dbox-single/sdbox-copy.c Thu Aug 23 11:54:46 2012 +0300 @@ -150,7 +150,7 @@ ctx->finished = TRUE; if (mail_storage_copy_can_use_hardlink(mail->box, &mbox->box) && - _ctx->guid == NULL) { + _ctx->data.guid == NULL) { T_BEGIN { ret = sdbox_copy_hardlink(_ctx, mail); } T_END; diff -r d0441efd0efc -r b966759dd48c src/lib-storage/index/dbox-single/sdbox-save.c --- a/src/lib-storage/index/dbox-single/sdbox-save.c Thu Aug 23 11:26:13 2012 +0300 +++ b/src/lib-storage/index/dbox-single/sdbox-save.c Thu Aug 23 11:54:46 2012 +0300 @@ -174,16 +174,16 @@ if (ctx->ctx.dbox_output == NULL) return -1; - if (_ctx->save_date != (time_t)-1) { + if (_ctx->data.save_date != (time_t)-1) { /* we can't change ctime, but we can add the date to cache */ struct index_mail *mail = (struct index_mail *)_ctx->dest_mail; - uint32_t t = _ctx->save_date; + uint32_t t = _ctx->data.save_date; index_mail_cache_add(mail, MAIL_CACHE_SAVE_DATE, &t, sizeof(t)); } - index_mail_cache_parse_deinit(_ctx->dest_mail, - _ctx->received_date, !ctx->ctx.failed); + index_mail_cache_parse_deinit(_ctx->dest_mail, _ctx->data.received_date, + !ctx->ctx.failed); files = array_idx_modifiable(&ctx->files, array_count(&ctx->files) - 1); diff -r d0441efd0efc -r b966759dd48c src/lib-storage/index/imapc/imapc-save.c --- a/src/lib-storage/index/imapc/imapc-save.c Thu Aug 23 11:26:13 2012 +0300 +++ b/src/lib-storage/index/imapc/imapc-save.c Thu Aug 23 11:54:46 2012 +0300 @@ -79,8 +79,8 @@ ctx->finished = FALSE; ctx->temp_path = i_strdup(path); ctx->input = i_stream_create_crlf(input); - _ctx->output = o_stream_create_fd_file(ctx->fd, 0, FALSE); - o_stream_cork(_ctx->output); + _ctx->data.output = o_stream_create_fd_file(ctx->fd, 0, FALSE); + o_stream_cork(_ctx->data.output); return 0; } @@ -92,7 +92,7 @@ if (ctx->failed) return -1; From dovecot at dovecot.org Thu Aug 23 11:57:02 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Aug 2012 11:57:02 +0300 Subject: dovecot-2.1: lib-storage: Make sure a save context doesn't leak ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/7bdbca7b0913 changeset: 14677:7bdbca7b0913 user: Timo Sirainen date: Thu Aug 23 11:56:56 2012 +0300 description: lib-storage: Make sure a save context doesn't leak metadata to the next save. diffstat: src/lib-storage/index/index-storage.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diffs (18 lines): diff -r 3765e8948f1c -r 7bdbca7b0913 src/lib-storage/index/index-storage.c --- a/src/lib-storage/index/index-storage.c Wed Aug 22 17:42:06 2012 +0300 +++ b/src/lib-storage/index/index-storage.c Thu Aug 23 11:56:56 2012 +0300 @@ -616,6 +616,14 @@ i_free_and_null(ctx->guid); i_free_and_null(ctx->pop3_uidl); index_attachment_save_free(ctx); + + ctx->flags = 0; + ctx->keywords = NULL; + ctx->min_modseq = 0; + ctx->received_date = ctx->save_date = 0; + ctx->received_tz_offset = 0; + ctx->uid = 0; + ctx->pop3_order = 0; } static void From dovecot at dovecot.org Thu Aug 23 15:29:54 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Aug 2012 15:29:54 +0300 Subject: dovecot-2.2: Compiler warning fix Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9bda1b81c16c changeset: 14953:9bda1b81c16c user: Timo Sirainen date: Thu Aug 23 15:29:43 2012 +0300 description: Compiler warning fix diffstat: src/lib/istream-concat.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (14 lines): diff -r b966759dd48c -r 9bda1b81c16c src/lib/istream-concat.c --- a/src/lib/istream-concat.c Thu Aug 23 11:54:46 2012 +0300 +++ b/src/lib/istream-concat.c Thu Aug 23 15:29:43 2012 +0300 @@ -119,7 +119,9 @@ cur_data_pos = stream->pos - (stream->skip + cstream->prev_stream_left); data = i_stream_get_data(cstream->cur_input, &data_size); - if (data_size <= cur_data_pos) { + if (data_size <= cur_data_pos) + ret = 0; + else { /* need to read more */ i_assert(cur_data_pos == data_size); ret = i_stream_read(cstream->cur_input); From dovecot at dovecot.org Thu Aug 23 21:29:54 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Aug 2012 21:29:54 +0300 Subject: dovecot-2.1: doveadm: Added "copy" command. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/9d35aca14c81 changeset: 14678:9d35aca14c81 user: Timo Sirainen date: Thu Aug 23 21:29:40 2012 +0300 description: doveadm: Added "copy" command. diffstat: src/doveadm/Makefile.am | 2 +- src/doveadm/doveadm-mail-copymove.c | 159 ++++++++++++++++++++++++++++++++++++ src/doveadm/doveadm-mail-move.c | 144 -------------------------------- src/doveadm/doveadm-mail.c | 1 + src/doveadm/doveadm-mail.h | 1 + 5 files changed, 162 insertions(+), 145 deletions(-) diffs (truncated from 345 to 300 lines): diff -r 7bdbca7b0913 -r 9d35aca14c81 src/doveadm/Makefile.am --- a/src/doveadm/Makefile.am Thu Aug 23 11:56:56 2012 +0300 +++ b/src/doveadm/Makefile.am Thu Aug 23 21:29:40 2012 +0300 @@ -74,7 +74,7 @@ doveadm-mail-iter.c \ doveadm-mail-mailbox.c \ doveadm-mail-mailbox-status.c \ - doveadm-mail-move.c \ + doveadm-mail-copymove.c \ doveadm-mailbox-list-iter.c \ doveadm-mail-search.c \ doveadm-mail-server.c \ diff -r 7bdbca7b0913 -r 9d35aca14c81 src/doveadm/doveadm-mail-copymove.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doveadm/doveadm-mail-copymove.c Thu Aug 23 21:29:40 2012 +0300 @@ -0,0 +1,159 @@ +/* Copyright (c) 2011-2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "mail-storage.h" +#include "mail-namespace.h" +#include "doveadm-print.h" +#include "doveadm-mailbox-list-iter.h" +#include "doveadm-mail-iter.h" +#include "doveadm-mail.h" + +#include + +struct copy_cmd_context { + struct doveadm_mail_cmd_context ctx; + + const char *destname; + bool move; +}; + +static int +cmd_copy_box(struct copy_cmd_context *ctx, struct mailbox *destbox, + const struct mailbox_info *info) +{ + struct doveadm_mail_iter *iter; + struct mailbox_transaction_context *trans; + struct mailbox_transaction_context *desttrans; + struct mail_save_context *save_ctx; + struct mail *mail; + int ret = 0; + + if (doveadm_mail_iter_init(&ctx->ctx, info, ctx->ctx.search_args, 0, + NULL, &trans, &iter) < 0) + return -1; + + /* use a separately committed transaction for each mailbox. + this guarantees that mails aren't expunged without actually having + been copied. */ + desttrans = mailbox_transaction_begin(destbox, + MAILBOX_TRANSACTION_FLAG_EXTERNAL); + + while (doveadm_mail_iter_next(iter, &mail)) { + save_ctx = mailbox_save_alloc(desttrans); + mailbox_save_copy_flags(save_ctx, mail); + if (mailbox_copy(&save_ctx, mail) == 0) { + if (ctx->move) + mail_expunge(mail); + } else { + i_error("Copying message UID %u from '%s' failed: %s", + mail->uid, info->name, + mailbox_get_last_error(destbox, NULL)); + doveadm_mail_failed_mailbox(&ctx->ctx, destbox); + ret = -1; + } + } + + if (mailbox_transaction_commit(&desttrans) < 0) { + i_error("Committing %s mails failed: %s", + ctx->move ? "moved" : "copied", + mailbox_get_last_error(destbox, NULL)); + doveadm_mail_failed_mailbox(&ctx->ctx, destbox); + /* rollback expunges */ + doveadm_mail_iter_deinit_rollback(&iter); + ret = -1; + } else { + if (doveadm_mail_iter_deinit_sync(&iter) < 0) + ret = -1; + } + return ret; +} + +static int +cmd_copy_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) +{ + struct copy_cmd_context *ctx = (struct copy_cmd_context *)_ctx; + const enum mailbox_list_iter_flags iter_flags = + MAILBOX_LIST_ITER_RAW_LIST | + MAILBOX_LIST_ITER_NO_AUTO_BOXES | + MAILBOX_LIST_ITER_RETURN_NO_FLAGS; + struct doveadm_mailbox_list_iter *iter; + struct mail_namespace *ns; + struct mailbox *destbox; + const struct mailbox_info *info; + int ret = 0; + + ns = mail_namespace_find(user->namespaces, ctx->destname); + if (ns == NULL) { + i_fatal_status(DOVEADM_EX_NOTFOUND, + "Can't find namespace for: %s", ctx->destname); + } + + destbox = mailbox_alloc(ns->list, ctx->destname, MAILBOX_FLAG_SAVEONLY); + if (mailbox_open(destbox) < 0) { + i_error("Can't open mailbox '%s': %s", ctx->destname, + mailbox_get_last_error(destbox, NULL)); + doveadm_mail_failed_mailbox(&ctx->ctx, destbox); + mailbox_free(&destbox); + return -1; + } + + iter = doveadm_mailbox_list_iter_init(_ctx, user, _ctx->search_args, + iter_flags); + while ((info = doveadm_mailbox_list_iter_next(iter)) != NULL) T_BEGIN { + if (cmd_copy_box(ctx, destbox, info) < 0) + ret = -1; + } T_END; + if (doveadm_mailbox_list_iter_deinit(&iter) < 0) + ret = -1; + + if (mailbox_sync(destbox, 0) < 0) { + i_error("Syncing mailbox '%s' failed: %s", ctx->destname, + mailbox_get_last_error(destbox, NULL)); + doveadm_mail_failed_mailbox(&ctx->ctx, destbox); + ret = -1; + } + mailbox_free(&destbox); + return ret; + +} + +static void cmd_copy_init(struct doveadm_mail_cmd_context *_ctx, + const char *const args[]) +{ + struct copy_cmd_context *ctx = (struct copy_cmd_context *)_ctx; + const char *destname = args[0], *cmdname = ctx->move ? "move" : "copy"; + + if (destname == NULL || args[1] == NULL) + doveadm_mail_help_name(cmdname); + + ctx->destname = p_strdup(ctx->ctx.pool, destname); + ctx->ctx.search_args = doveadm_mail_build_search_args(args + 1); + expunge_search_args_check(ctx->ctx.search_args, cmdname); +} + +static struct doveadm_mail_cmd_context *cmd_copy_alloc(void) +{ + struct copy_cmd_context *ctx; + + ctx = doveadm_mail_cmd_alloc(struct copy_cmd_context); + ctx->ctx.v.init = cmd_copy_init; + ctx->ctx.v.run = cmd_copy_run; + doveadm_print_init(DOVEADM_PRINT_TYPE_FLOW); + return &ctx->ctx; +} + +static struct doveadm_mail_cmd_context *cmd_move_alloc(void) +{ + struct copy_cmd_context *ctx; + + ctx = (struct copy_cmd_context *)cmd_copy_alloc(); + ctx->move = TRUE; + return &ctx->ctx; +} + +struct doveadm_mail_cmd cmd_copy = { + cmd_copy_alloc, "copy", " " +}; +struct doveadm_mail_cmd cmd_move = { + cmd_move_alloc, "move", " " +}; diff -r 7bdbca7b0913 -r 9d35aca14c81 src/doveadm/doveadm-mail-move.c --- a/src/doveadm/doveadm-mail-move.c Thu Aug 23 11:56:56 2012 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,144 +0,0 @@ -/* Copyright (c) 2011-2012 Dovecot authors, see the included COPYING file */ - -#include "lib.h" -#include "mail-storage.h" -#include "mail-namespace.h" -#include "doveadm-print.h" -#include "doveadm-mailbox-list-iter.h" -#include "doveadm-mail-iter.h" -#include "doveadm-mail.h" - -#include - -struct move_cmd_context { - struct doveadm_mail_cmd_context ctx; - - const char *destname; -}; - -static int -cmd_move_box(struct move_cmd_context *ctx, struct mailbox *destbox, - const struct mailbox_info *info) -{ - struct doveadm_mail_iter *iter; - struct mailbox_transaction_context *trans; - struct mailbox_transaction_context *desttrans; - struct mail_save_context *save_ctx; - struct mail *mail; - int ret = 0; - - if (doveadm_mail_iter_init(&ctx->ctx, info, ctx->ctx.search_args, 0, - NULL, &trans, &iter) < 0) - return -1; - - /* use a separately committed transaction for each mailbox. - this guarantees that mails aren't expunged without actually having - been copied. */ - desttrans = mailbox_transaction_begin(destbox, - MAILBOX_TRANSACTION_FLAG_EXTERNAL); - - while (doveadm_mail_iter_next(iter, &mail)) { - save_ctx = mailbox_save_alloc(desttrans); - mailbox_save_copy_flags(save_ctx, mail); - if (mailbox_copy(&save_ctx, mail) == 0) - mail_expunge(mail); - else { - i_error("Copying message UID %u from '%s' failed: %s", - mail->uid, info->name, - mailbox_get_last_error(destbox, NULL)); - doveadm_mail_failed_mailbox(&ctx->ctx, destbox); - ret = -1; - } - } - - if (mailbox_transaction_commit(&desttrans) < 0) { - i_error("Committing moved mails failed: %s", - mailbox_get_last_error(destbox, NULL)); - doveadm_mail_failed_mailbox(&ctx->ctx, destbox); - /* rollback expunges */ - doveadm_mail_iter_deinit_rollback(&iter); - ret = -1; - } else { - if (doveadm_mail_iter_deinit_sync(&iter) < 0) - ret = -1; - } - return ret; -} - -static int -cmd_move_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) -{ - struct move_cmd_context *ctx = (struct move_cmd_context *)_ctx; - const enum mailbox_list_iter_flags iter_flags = - MAILBOX_LIST_ITER_RAW_LIST | - MAILBOX_LIST_ITER_NO_AUTO_BOXES | - MAILBOX_LIST_ITER_RETURN_NO_FLAGS; - struct doveadm_mailbox_list_iter *iter; - struct mail_namespace *ns; - struct mailbox *destbox; - const struct mailbox_info *info; - int ret = 0; - - ns = mail_namespace_find(user->namespaces, ctx->destname); - if (ns == NULL) { - i_fatal_status(DOVEADM_EX_NOTFOUND, - "Can't find namespace for: %s", ctx->destname); - } - - destbox = mailbox_alloc(ns->list, ctx->destname, MAILBOX_FLAG_SAVEONLY); - if (mailbox_open(destbox) < 0) { - i_error("Can't open mailbox '%s': %s", ctx->destname, - mailbox_get_last_error(destbox, NULL)); - doveadm_mail_failed_mailbox(&ctx->ctx, destbox); - mailbox_free(&destbox); - return -1; - } - - iter = doveadm_mailbox_list_iter_init(_ctx, user, _ctx->search_args, - iter_flags); - while ((info = doveadm_mailbox_list_iter_next(iter)) != NULL) T_BEGIN { - if (cmd_move_box(ctx, destbox, info) < 0) - ret = -1; - } T_END; - if (doveadm_mailbox_list_iter_deinit(&iter) < 0) - ret = -1; - - if (mailbox_sync(destbox, 0) < 0) { - i_error("Syncing mailbox '%s' failed: %s", ctx->destname, - mailbox_get_last_error(destbox, NULL)); - doveadm_mail_failed_mailbox(&ctx->ctx, destbox); - ret = -1; - } - mailbox_free(&destbox); - return ret; - -} - -static void cmd_move_init(struct doveadm_mail_cmd_context *_ctx, - const char *const args[]) -{ - struct move_cmd_context *ctx = (struct move_cmd_context *)_ctx; - const char *destname = args[0]; From dovecot at dovecot.org Thu Aug 23 21:49:26 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Aug 2012 21:49:26 +0300 Subject: dovecot-2.2: imap IDLE: Time "still here" packet sends based on ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8d7f9e2d726c changeset: 14954:8d7f9e2d726c user: Timo Sirainen date: Thu Aug 23 21:49:15 2012 +0300 description: imap IDLE: Time "still here" packet sends based on client IP address if possible. diffstat: src/imap/cmd-idle.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 40 insertions(+), 2 deletions(-) diffs (66 lines): diff -r 9bda1b81c16c -r 8d7f9e2d726c src/imap/cmd-idle.c --- a/src/imap/cmd-idle.c Thu Aug 23 15:29:43 2012 +0300 +++ b/src/imap/cmd-idle.c Thu Aug 23 21:49:15 2012 +0300 @@ -1,6 +1,7 @@ /* Copyright (c) 2002-2012 Dovecot authors, see the included COPYING file */ #include "imap-common.h" +#include "network.h" #include "ioloop.h" #include "istream.h" #include "ostream.h" @@ -160,15 +161,52 @@ } } +static bool remote_ip_is_usable(const struct ip_addr *ip) +{ + unsigned int addr; + + if (ip->family == 0) + return FALSE; + if (ip->family == AF_INET) { + addr = ip->u.ip4.s_addr; + if (addr >= 167772160 && addr <= 184549375) + return FALSE; /* 10/8 */ + if (addr >= 3232235520 && addr <= 3232301055) + return FALSE; /* 192.168/16 */ + if (addr >= 2130706432 && addr <= 2147483647) + return FALSE; /* 127/8 */ + } + return TRUE; +} + static void idle_add_keepalive_timeout(struct cmd_idle_context *ctx) { unsigned int interval = ctx->client->set->imap_idle_notify_interval; + unsigned int client_hash; if (interval == 0) return; - interval -= (time(NULL) + - crc32_str(ctx->client->user->username)) % interval; + /* set the interval so that the client gets the keepalive notifications + at exactly the same time for all the connections. this helps to + reduce battery usage in mobile devices. but we don't really want to + send this notification for everyone at the same time, because it + would cause huge peaks of activity. + + basing the notifications on the username works well for one account, + but basing it on the IP address allows the client to get all of the + notifications at the same time for multiple accounts as well (of + course assuming Dovecot is running on all the servers :) + + one potential downside to using IP is that if a proxy hides the + client's IP address notifications are sent to everyone at the same + time, but this can be avoided by using a properly configured Dovecot + proxy. we'll also try to avoid this by not doing it for the commonly + used intranet IP ranges. */ + client_hash = remote_ip_is_usable(ctx->client->user->remote_ip) ? + net_ip_hash(ctx->client->user->remote_ip) : + crc32_str(ctx->client->user->username); + interval -= (time(NULL) + client_hash) % interval; if (ctx->keepalive_to != NULL) timeout_remove(&ctx->keepalive_to); From dovecot at dovecot.org Thu Aug 23 22:21:54 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Aug 2012 22:21:54 +0300 Subject: dovecot-2.1: mbox: Fixed listing mailboxes under INBOX directory. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/b8173f8a1447 changeset: 14679:b8173f8a1447 user: Timo Sirainen date: Thu Aug 23 22:21:42 2012 +0300 description: mbox: Fixed listing mailboxes under INBOX directory. diffstat: src/lib-storage/list/mailbox-list-fs-iter.c | 21 +++++++++++++++++---- 1 files changed, 17 insertions(+), 4 deletions(-) diffs (48 lines): diff -r 9d35aca14c81 -r b8173f8a1447 src/lib-storage/list/mailbox-list-fs-iter.c --- a/src/lib-storage/list/mailbox-list-fs-iter.c Thu Aug 23 21:29:40 2012 +0300 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Thu Aug 23 22:21:42 2012 +0300 @@ -49,6 +49,7 @@ struct list_dir_context *dir; unsigned int inbox_found:1; + unsigned int inbox_has_children:1; unsigned int list_inbox_inbox:1; }; @@ -584,9 +585,13 @@ return FALSE; inbox_flags_set(ctx, 0); - /* we got here because we didn't see INBOX among other mailboxes, - which means it has no children. */ - ctx->info.flags |= MAILBOX_NOCHILDREN; + if (ctx->inbox_has_children) + ctx->info.flags |= MAILBOX_CHILDREN; + else { + /* we got here because we didn't see INBOX among other mailboxes, + which means it has no children. */ + ctx->info.flags |= MAILBOX_NOCHILDREN; + } return TRUE; } @@ -651,10 +656,18 @@ (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) { /* either this is user's INBOX, or it's a naming conflict */ if (!list_file_is_any_inbox(ctx, storage_name)) { - if (subdir != NULL) { + if (subdir == NULL) { + /* no children */ + } else if ((ctx->ctx.list->flags & + MAILBOX_LIST_FLAG_MAILBOX_FILES) == 0) { /* skip its children also */ ctx->dir = dir; pool_unref(&subdir->pool); + } else if ((ctx->info.flags & MAILBOX_NOINFERIORS) == 0) { + /* INBOX itself is \NoInferiors, but this INBOX + is a directory, and we can make INBOX have + children using it. */ + ctx->inbox_has_children = TRUE; } return 0; } From dovecot at dovecot.org Thu Aug 23 22:57:11 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Aug 2012 22:57:11 +0300 Subject: dovecot-2.1: lib-storage: Verify that namespace prefix is valid ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/565605200989 changeset: 14680:565605200989 user: Timo Sirainen date: Thu Aug 23 22:33:23 2012 +0300 description: lib-storage: Verify that namespace prefix is valid UTF8 string. diffstat: src/lib-storage/mail-storage-settings.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r b8173f8a1447 -r 565605200989 src/lib-storage/mail-storage-settings.c --- a/src/lib-storage/mail-storage-settings.c Thu Aug 23 22:21:42 2012 +0300 +++ b/src/lib-storage/mail-storage-settings.c Thu Aug 23 22:33:23 2012 +0300 @@ -444,6 +444,11 @@ name); return FALSE; } + if (!uni_utf8_str_is_valid(name)) { + *error_r = t_strdup_printf("Namespace prefix not valid UTF8: %s", + name); + return FALSE; + } if (ns->alias_for != NULL) { if (array_is_created(&ns->user_set->namespaces)) { From dovecot at dovecot.org Thu Aug 23 22:57:11 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Aug 2012 22:57:11 +0300 Subject: dovecot-2.1: imap: Fixes to handling UTF-8 namespace prefixes Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/ade94fde249e changeset: 14681:ade94fde249e user: Timo Sirainen date: Thu Aug 23 22:56:56 2012 +0300 description: imap: Fixes to handling UTF-8 namespace prefixes diffstat: src/imap/cmd-list.c | 27 ++++++++++++++++++++++++--- src/imap/cmd-namespace.c | 11 ++++++++++- src/imap/imap-commands-util.c | 21 ++++++++++----------- 3 files changed, 44 insertions(+), 15 deletions(-) diffs (145 lines): diff -r 565605200989 -r ade94fde249e src/imap/cmd-list.c --- a/src/imap/cmd-list.c Thu Aug 23 22:33:23 2012 +0300 +++ b/src/imap/cmd-list.c Thu Aug 23 22:56:56 2012 +0300 @@ -230,6 +230,19 @@ return ret; } +static const char *ns_prefix_mutf7(struct mail_namespace *ns) +{ + string_t *str; + + if (*ns->prefix == '\0') + return ""; + + str = t_str_new(64); + if (imap_utf8_to_utf7(ns->prefix, str) < 0) + i_panic("Namespace prefix not UTF-8: %s", ns->prefix); + return str_c(str); +} + static const char *ns_get_listed_prefix(struct cmd_list_context *ctx) { struct imap_match_glob *glob; @@ -285,7 +298,7 @@ unsigned int len; enum mailbox_info_flags flags; const char *name; - string_t *str; + string_t *str, *mutf7_name; bool same_ns, ends_with_sep; char ns_sep = mail_namespace_get_sep(ctx->ns); @@ -364,7 +377,11 @@ str_append(str, ") "); list_reply_append_ns_sep_param(str, ns_sep); str_append_c(str, ' '); - imap_quote_append_string(str, name, FALSE); + + mutf7_name = t_str_new(64); + if (imap_utf8_to_utf7(name, mutf7_name) < 0) + i_panic("Namespace prefix not UTF-8: %s", name); + imap_quote_append_string(str, str_c(mutf7_name), FALSE); mailbox_childinfo2str(ctx, str, flags); client_send_line(ctx->cmd->client, str_c(str)); @@ -870,7 +887,7 @@ Otherwise we'll emulate UW-IMAP behavior. */ ns = mail_namespace_find_visible(client->user->namespaces, ref); if (ns != NULL) { - ns_prefix = ns->prefix; + ns_prefix = ns_prefix_mutf7(ns); ns_sep = mail_namespace_get_sep(ns); } else { ns_prefix = ""; @@ -938,6 +955,10 @@ return TRUE; } str = t_str_new(64); + if (imap_utf7_to_utf8(ctx->ref, str) == 0) + ctx->ref = p_strdup(cmd->pool, str_c(str)); + str_truncate(str, 0); + if (imap_arg_get_list_full(&args[1], &list_args, &arg_count)) { ctx->used_listext = TRUE; /* convert pattern list to string array */ diff -r 565605200989 -r ade94fde249e src/imap/cmd-namespace.c --- a/src/imap/cmd-namespace.c Thu Aug 23 22:33:23 2012 +0300 +++ b/src/imap/cmd-namespace.c Thu Aug 23 22:56:56 2012 +0300 @@ -2,6 +2,7 @@ #include "imap-common.h" #include "str.h" +#include "imap-utf7.h" #include "imap-quote.h" #include "imap-commands.h" #include "mail-namespace.h" @@ -9,6 +10,7 @@ static void list_namespaces(struct mail_namespace *ns, enum namespace_type type, string_t *str) { + string_t *mutf7_prefix = t_str_new(64); char ns_sep; bool found = FALSE; @@ -21,7 +23,14 @@ } ns_sep = mail_namespace_get_sep(ns); str_append_c(str, '('); - imap_quote_append_string(str, ns->prefix, FALSE); + + str_truncate(mutf7_prefix, 0); + if (imap_utf8_to_utf7(ns->prefix, mutf7_prefix) < 0) { + i_panic("LIST: Namespace prefix not UTF-8: %s", + ns->prefix); + } + + imap_quote_append_string(str, str_c(mutf7_prefix), FALSE); str_append(str, " \""); if (ns_sep == '\\') str_append_c(str, '\\'); diff -r 565605200989 -r ade94fde249e src/imap/imap-commands-util.c --- a/src/imap/imap-commands-util.c Thu Aug 23 22:33:23 2012 +0300 +++ b/src/imap/imap-commands-util.c Thu Aug 23 22:56:56 2012 +0300 @@ -19,10 +19,15 @@ { struct mail_namespace *namespaces = cmd->client->user->namespaces; struct mail_namespace *ns; - unsigned int name_len; string_t *utf8_name; - ns = mail_namespace_find(namespaces, *mailbox); + utf8_name = t_str_new(64); + if (imap_utf7_to_utf8(*mailbox, utf8_name) < 0) { + client_send_tagline(cmd, "NO Mailbox name is not valid mUTF-7"); + return NULL; + } + + ns = mail_namespace_find(namespaces, str_c(utf8_name)); if (ns == NULL) { client_send_tagline(cmd, t_strdup_printf( "NO Client tried to access nonexistent namespace. " @@ -31,20 +36,14 @@ return NULL; } - name_len = strlen(*mailbox); if ((cmd->client->set->parsed_workarounds & WORKAROUND_TB_EXTRA_MAILBOX_SEP) != 0 && - name_len > 0 && - (*mailbox)[name_len-1] == mail_namespace_get_sep(ns)) { + str_len(utf8_name) > 0 && + str_c(utf8_name)[str_len(utf8_name)-1] == mail_namespace_get_sep(ns)) { /* drop the extra trailing hierarchy separator */ - *mailbox = t_strndup(*mailbox, name_len-1); + str_truncate(utf8_name, str_len(utf8_name)-1); } - utf8_name = t_str_new(64); - if (imap_utf7_to_utf8(*mailbox, utf8_name) < 0) { - client_send_tagline(cmd, "NO Mailbox name is not valid mUTF-7"); - return NULL; - } *mailbox = str_c(utf8_name); return ns; } From dovecot at dovecot.org Thu Aug 23 23:46:28 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Aug 2012 23:46:28 +0300 Subject: dovecot-2.1: doveadm copy/move: Added "user" parameter to specif... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/6b61cc674eef changeset: 14682:6b61cc674eef user: Timo Sirainen date: Thu Aug 23 23:46:15 2012 +0300 description: doveadm copy/move: Added "user" parameter to specify the source user. diffstat: src/doveadm/doveadm-mail-copymove.c | 52 +++++++++++++++++++++++++++++++++--- src/doveadm/doveadm-mail.c | 2 + src/doveadm/doveadm-mail.h | 1 + 3 files changed, 50 insertions(+), 5 deletions(-) diffs (145 lines): diff -r ade94fde249e -r 6b61cc674eef src/doveadm/doveadm-mail-copymove.c --- a/src/doveadm/doveadm-mail-copymove.c Thu Aug 23 22:56:56 2012 +0300 +++ b/src/doveadm/doveadm-mail-copymove.c Thu Aug 23 23:46:15 2012 +0300 @@ -13,6 +13,9 @@ struct copy_cmd_context { struct doveadm_mail_cmd_context ctx; + struct mail_storage_service_user *source_service_user; + struct mail_user *source_user; + const char *destname; bool move; }; @@ -68,6 +71,22 @@ return ret; } +static void +cmd_copy_alloc_source_user(struct copy_cmd_context *ctx, const char *username) +{ + struct mail_storage_service_input input; + const char *error; + + input = ctx->ctx.storage_service_input; + input.username = username; + + if (mail_storage_service_lookup_next(ctx->ctx.storage_service, &input, + &ctx->source_service_user, + &ctx->source_user, + &error) < 0) + i_fatal("Couldn't lookup user %s: %s", input.username, error); +} + static int cmd_copy_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) { @@ -77,6 +96,7 @@ MAILBOX_LIST_ITER_NO_AUTO_BOXES | MAILBOX_LIST_ITER_RETURN_NO_FLAGS; struct doveadm_mailbox_list_iter *iter; + struct mail_user *src_user; struct mail_namespace *ns; struct mailbox *destbox; const struct mailbox_info *info; @@ -97,7 +117,8 @@ return -1; } - iter = doveadm_mailbox_list_iter_init(_ctx, user, _ctx->search_args, + src_user = ctx->source_user != NULL ? ctx->source_user : user; + iter = doveadm_mailbox_list_iter_init(_ctx, src_user, _ctx->search_args, iter_flags); while ((info = doveadm_mailbox_list_iter_next(iter)) != NULL) T_BEGIN { if (cmd_copy_box(ctx, destbox, info) < 0) @@ -114,7 +135,6 @@ } mailbox_free(&destbox); return ret; - } static void cmd_copy_init(struct doveadm_mail_cmd_context *_ctx, @@ -125,18 +145,40 @@ if (destname == NULL || args[1] == NULL) doveadm_mail_help_name(cmdname); + args++; + + if (args[0] != NULL && args[1] != NULL && + strcasecmp(args[0], "user") == 0) { + if ((_ctx->service_flags & + MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) == 0) + i_fatal("Use -u parameter to specify destination user"); + + cmd_copy_alloc_source_user(ctx, args[1]); + args += 2; + } ctx->destname = p_strdup(ctx->ctx.pool, destname); - ctx->ctx.search_args = doveadm_mail_build_search_args(args + 1); + _ctx->search_args = doveadm_mail_build_search_args(args); expunge_search_args_check(ctx->ctx.search_args, cmdname); } +static void cmd_copy_deinit(struct doveadm_mail_cmd_context *_ctx) +{ + struct copy_cmd_context *ctx = (struct copy_cmd_context *)_ctx; + + if (ctx->source_user != NULL) { + mail_storage_service_user_free(&ctx->source_service_user); + mail_user_unref(&ctx->source_user); + } +} + static struct doveadm_mail_cmd_context *cmd_copy_alloc(void) { struct copy_cmd_context *ctx; ctx = doveadm_mail_cmd_alloc(struct copy_cmd_context); ctx->ctx.v.init = cmd_copy_init; + ctx->ctx.v.deinit = cmd_copy_deinit; ctx->ctx.v.run = cmd_copy_run; doveadm_print_init(DOVEADM_PRINT_TYPE_FLOW); return &ctx->ctx; @@ -152,8 +194,8 @@ } struct doveadm_mail_cmd cmd_copy = { - cmd_copy_alloc, "copy", " " + cmd_copy_alloc, "copy", " [user ] " }; struct doveadm_mail_cmd cmd_move = { - cmd_move_alloc, "move", " " + cmd_move_alloc, "move", " [user ] " }; diff -r ade94fde249e -r 6b61cc674eef src/doveadm/doveadm-mail.c --- a/src/doveadm/doveadm-mail.c Thu Aug 23 22:56:56 2012 +0300 +++ b/src/doveadm/doveadm-mail.c Thu Aug 23 23:46:15 2012 +0300 @@ -323,6 +323,7 @@ i_assert(input->username != NULL); ctx->cur_username = input->username; + ctx->storage_service_input = *input; ctx->storage_service = mail_storage_service_init(master_service, NULL, ctx->service_flags); ctx->v.init(ctx, ctx->args); @@ -351,6 +352,7 @@ memset(&input, 0, sizeof(input)); input.service = "doveadm"; + ctx->storage_service_input = input; ctx->storage_service = mail_storage_service_init(master_service, NULL, ctx->service_flags); lib_signals_set_handler(SIGINT, 0, sig_die, NULL); diff -r ade94fde249e -r 6b61cc674eef src/doveadm/doveadm-mail.h --- a/src/doveadm/doveadm-mail.h Thu Aug 23 22:56:56 2012 +0300 +++ b/src/doveadm/doveadm-mail.h Thu Aug 23 23:46:15 2012 +0300 @@ -48,6 +48,7 @@ const struct doveadm_settings *set; enum mail_storage_service_flags service_flags; struct mail_storage_service_ctx *storage_service; + struct mail_storage_service_input storage_service_input; /* search args aren't set for all mail commands */ struct mail_search_args *search_args; From dovecot at dovecot.org Thu Aug 23 23:51:01 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 23 Aug 2012 23:51:01 +0300 Subject: dovecot-2.2: imap IDLE: Add also 172.168/12 to private networks. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/725a91613107 changeset: 14955:725a91613107 user: Timo Sirainen date: Thu Aug 23 23:50:55 2012 +0300 description: imap IDLE: Add also 172.168/12 to private networks. diffstat: src/imap/cmd-idle.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 8d7f9e2d726c -r 725a91613107 src/imap/cmd-idle.c --- a/src/imap/cmd-idle.c Thu Aug 23 21:49:15 2012 +0300 +++ b/src/imap/cmd-idle.c Thu Aug 23 23:50:55 2012 +0300 @@ -173,6 +173,8 @@ return FALSE; /* 10/8 */ if (addr >= 3232235520 && addr <= 3232301055) return FALSE; /* 192.168/16 */ + if (addr >= 2886729728 && addr <= 2887778303) + return FALSE; /* 172.16/12 */ if (addr >= 2130706432 && addr <= 2147483647) return FALSE; /* 127/8 */ } From dovecot at dovecot.org Fri Aug 24 02:23:14 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Aug 2012 02:23:14 +0300 Subject: dovecot-2.2: imap IDLE: Add also fc00::/7 (RFC 4193) to private ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/dc58905b5c9c changeset: 14956:dc58905b5c9c user: Pascal Volk date: Thu Aug 23 23:20:57 2012 +0000 description: imap IDLE: Add also fc00::/7 (RFC 4193) to private networks. diffstat: src/imap/cmd-idle.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diffs (18 lines): diff -r 725a91613107 -r dc58905b5c9c src/imap/cmd-idle.c --- a/src/imap/cmd-idle.c Thu Aug 23 23:50:55 2012 +0300 +++ b/src/imap/cmd-idle.c Thu Aug 23 23:20:57 2012 +0000 @@ -178,6 +178,14 @@ if (addr >= 2130706432 && addr <= 2147483647) return FALSE; /* 127/8 */ } +#ifdef HAVE_IPV6 + else if (ip->family == AF_INET6) { + addr = ip->u.ip6.s6_addr; + if (addr >= 334965454937798799971759379190646833152ULL && + addr <= 337623910929368631717566993311207522303ULL) + return FALSE; /* fc00::/7 */ + } +#endif return TRUE; } From dovecot at dovecot.org Fri Aug 24 09:42:14 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Aug 2012 09:42:14 +0300 Subject: dovecot-2.2: imap IDLE: Reverted the IPv6 change, it doesn't wor... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cdb2d4d89d5d changeset: 14957:cdb2d4d89d5d user: Timo Sirainen date: Fri Aug 24 09:41:55 2012 +0300 description: imap IDLE: Reverted the IPv6 change, it doesn't work like that. diffstat: src/imap/cmd-idle.c | 8 -------- 1 files changed, 0 insertions(+), 8 deletions(-) diffs (18 lines): diff -r dc58905b5c9c -r cdb2d4d89d5d src/imap/cmd-idle.c --- a/src/imap/cmd-idle.c Thu Aug 23 23:20:57 2012 +0000 +++ b/src/imap/cmd-idle.c Fri Aug 24 09:41:55 2012 +0300 @@ -178,14 +178,6 @@ if (addr >= 2130706432 && addr <= 2147483647) return FALSE; /* 127/8 */ } -#ifdef HAVE_IPV6 - else if (ip->family == AF_INET6) { - addr = ip->u.ip6.s6_addr; - if (addr >= 334965454937798799971759379190646833152ULL && - addr <= 337623910929368631717566993311207522303ULL) - return FALSE; /* fc00::/7 */ - } -#endif return TRUE; } From dovecot at dovecot.org Fri Aug 24 12:26:06 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Aug 2012 12:26:06 +0300 Subject: dovecot-2.1: auth: Make it clearer in debug messages if the repl... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/5590c1dc04cd changeset: 14683:5590c1dc04cd user: Timo Sirainen date: Fri Aug 24 12:25:55 2012 +0300 description: auth: Make it clearer in debug messages if the replies are passdb or userdb. diffstat: src/auth/auth-client-connection.c | 3 ++- src/auth/auth-master-connection.c | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diffs (43 lines): diff -r 6b61cc674eef -r 5590c1dc04cd src/auth/auth-client-connection.c --- a/src/auth/auth-client-connection.c Thu Aug 23 23:46:15 2012 +0300 +++ b/src/auth/auth-client-connection.c Fri Aug 24 12:25:55 2012 +0300 @@ -65,7 +65,8 @@ } if (conn->auth->set->debug) { - i_debug("client out: %s", conn->auth->set->debug_passwords ? + i_debug("client passdb out: %s", + conn->auth->set->debug_passwords ? cmd : reply_line_hide_pass(cmd)); } } diff -r 6b61cc674eef -r 5590c1dc04cd src/auth/auth-master-connection.c --- a/src/auth/auth-master-connection.c Thu Aug 23 23:46:15 2012 +0300 +++ b/src/auth/auth-master-connection.c Fri Aug 24 12:25:55 2012 +0300 @@ -79,7 +79,7 @@ reply_str = auth_stream_reply_export(reply); if (conn->auth->set->debug) { - i_debug("master out: %s", + i_debug("master userdb out: %s", auth_master_reply_hide_passwords(conn, reply_str)); } @@ -280,7 +280,7 @@ } if (conn->auth->set->debug) { - i_debug("master out: %s", + i_debug("userdb out: %s", auth_master_reply_hide_passwords(conn, str_c(str))); } @@ -342,7 +342,7 @@ } if (conn->auth->set->debug) - i_debug("master out: %s", str_c(str)); + i_debug("passdb out: %s", str_c(str)); str_append_c(str, '\n'); (void)o_stream_send(conn->output, str_data(str), str_len(str)); From dovecot at dovecot.org Fri Aug 24 15:12:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 24 Aug 2012 15:12:40 +0300 Subject: dovecot-2.1: auth: Don't add "master" to passdb reply if the pas... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/1bc8f7b823e7 changeset: 14684:1bc8f7b823e7 user: Timo Sirainen date: Fri Aug 24 15:12:32 2012 +0300 description: auth: Don't add "master" to passdb reply if the passdb itself already added it. diffstat: src/auth/auth-request-handler.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 5590c1dc04cd -r 1bc8f7b823e7 src/auth/auth-request-handler.c --- a/src/auth/auth-request-handler.c Fri Aug 24 12:25:55 2012 +0300 +++ b/src/auth/auth-request-handler.c Fri Aug 24 15:12:32 2012 +0300 @@ -186,7 +186,8 @@ auth_stream_reply_add(reply, "pass", request->mech_password); } - if (request->master_user != NULL) { + if (request->master_user != NULL && + auth_stream_reply_find(reply, "master") == NULL) { /* the master username needs to be forwarded */ auth_stream_reply_add(reply, "master", request->master_user); From dovecot at dovecot.org Sat Aug 25 01:41:59 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 25 Aug 2012 01:41:59 +0300 Subject: dovecot-2.2: imap IDLE: Added back fc00::/7 (RFC 4193) to privat... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7cbbac45ad49 changeset: 14958:7cbbac45ad49 user: Pascal Volk date: Fri Aug 24 19:44:43 2012 +0000 description: imap IDLE: Added back fc00::/7 (RFC 4193) to private networks. This time the check is done correctly. diffstat: src/imap/cmd-idle.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diffs (17 lines): diff -r cdb2d4d89d5d -r 7cbbac45ad49 src/imap/cmd-idle.c --- a/src/imap/cmd-idle.c Fri Aug 24 09:41:55 2012 +0300 +++ b/src/imap/cmd-idle.c Fri Aug 24 19:44:43 2012 +0000 @@ -178,6 +178,13 @@ if (addr >= 2130706432 && addr <= 2147483647) return FALSE; /* 127/8 */ } +#ifdef HAVE_IPV6 + else if (ip->family == AF_INET6) { + addr = ip->u.ip6.s6_addr[0]; + if (addr == 0xfc || addr == 0xfd) + return FALSE; /* fc00::/7 */ + } +#endif return TRUE; } From dovecot at dovecot.org Sat Aug 25 12:05:46 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 25 Aug 2012 12:05:46 +0300 Subject: dovecot-2.2: istream-concat: Bugfix Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/57efcf0957ea changeset: 14959:57efcf0957ea user: Timo Sirainen date: Sat Aug 25 12:05:34 2012 +0300 description: istream-concat: Bugfix diffstat: src/lib/istream-concat.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 7cbbac45ad49 -r 57efcf0957ea src/lib/istream-concat.c --- a/src/lib/istream-concat.c Fri Aug 24 19:44:43 2012 +0000 +++ b/src/lib/istream-concat.c Sat Aug 25 12:05:34 2012 +0300 @@ -119,7 +119,7 @@ cur_data_pos = stream->pos - (stream->skip + cstream->prev_stream_left); data = i_stream_get_data(cstream->cur_input, &data_size); - if (data_size <= cur_data_pos) + if (data_size > cur_data_pos) ret = 0; else { /* need to read more */ From dovecot at dovecot.org Sun Aug 26 19:17:48 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 26 Aug 2012 19:17:48 +0300 Subject: dovecot-2.1: dict redis: Fixed dict_lookup() to skip all previou... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/00f940201806 changeset: 14685:00f940201806 user: Timo Sirainen date: Tue Aug 21 10:02:44 2012 +0300 description: dict redis: Fixed dict_lookup() to skip all previous pending replies. diffstat: src/lib-dict/dict-redis.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (14 lines): diff -r 1bc8f7b823e7 -r 00f940201806 src/lib-dict/dict-redis.c --- a/src/lib-dict/dict-redis.c Fri Aug 24 15:12:32 2012 +0300 +++ b/src/lib-dict/dict-redis.c Tue Aug 21 10:02:44 2012 +0300 @@ -441,7 +441,9 @@ str_truncate(dict->conn.last_reply, 0); redis_input_state_add(dict, REDIS_INPUT_STATE_GET); - io_loop_run(dict->ioloop); + do { + io_loop_run(dict->ioloop); + } while (array_count(&dict->input_states) > 0); } timeout_remove(&to); } From dovecot at dovecot.org Sun Aug 26 19:23:56 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 26 Aug 2012 19:23:56 +0300 Subject: dovecot-2.1: dict-redis: Fixed infinite looping Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/db9fcdacba90 changeset: 14686:db9fcdacba90 user: Timo Sirainen date: Sun Aug 26 19:23:48 2012 +0300 description: dict-redis: Fixed infinite looping diffstat: src/lib-dict/dict-redis.c | 45 ++++++++++++++++++++------------------------- 1 files changed, 20 insertions(+), 25 deletions(-) diffs (105 lines): diff -r 00f940201806 -r db9fcdacba90 src/lib-dict/dict-redis.c --- a/src/lib-dict/dict-redis.c Tue Aug 21 10:02:44 2012 +0300 +++ b/src/lib-dict/dict-redis.c Sun Aug 26 19:23:48 2012 +0300 @@ -115,7 +115,7 @@ io_loop_destroy(&dict->ioloop); } -static void redis_input_get(struct redis_connection *conn) +static int redis_input_get(struct redis_connection *conn) { const unsigned char *data; size_t size; @@ -125,20 +125,20 @@ /* read the size first */ line = i_stream_next_line(conn->conn.input); if (line == NULL) - return; + return 0; if (strcmp(line, "$-1") == 0) { conn->value_received = TRUE; conn->value_not_found = TRUE; if (conn->dict->ioloop != NULL) io_loop_stop(conn->dict->ioloop); redis_input_state_remove(conn->dict); - return; + return 1; } if (line[0] != '$' || str_to_uint(line+1, &conn->bytes_left) < 0) { i_error("redis: Unexpected input (wanted $size): %s", line); redis_conn_destroy(&conn->conn); - return; + return 1; } conn->bytes_left += 2; /* include trailing CRLF */ } @@ -151,15 +151,17 @@ conn->bytes_left -= size; i_stream_skip(conn->conn.input, size); - if (conn->bytes_left == 0) { - /* reply fully read - drop trailing CRLF */ - conn->value_received = TRUE; - str_truncate(conn->last_reply, str_len(conn->last_reply)-2); + if (conn->bytes_left > 0) + return 0; - if (conn->dict->ioloop != NULL) - io_loop_stop(conn->dict->ioloop); - redis_input_state_remove(conn->dict); - } + /* reply fully read - drop trailing CRLF */ + conn->value_received = TRUE; + str_truncate(conn->last_reply, str_len(conn->last_reply)-2); + + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); + redis_input_state_remove(conn->dict); + return 1; } static int redis_conn_input_more(struct redis_connection *conn) @@ -174,16 +176,14 @@ states = array_get(&dict->input_states, &count); if (count == 0) { line = i_stream_next_line(conn->conn.input); - if (line == NULL) line = ""; - i_error("redis: Unexpected input (expected nothing): %s", - line); + if (line == NULL) + return 0; + i_error("redis: Unexpected input (expected nothing): %s", line); return -1; } state = states[0]; - if (state == REDIS_INPUT_STATE_GET) { - redis_input_get(conn); - return 1; - } + if (state == REDIS_INPUT_STATE_GET) + return redis_input_get(conn); line = i_stream_next_line(conn->conn.input); if (line == NULL) @@ -235,7 +235,6 @@ static void redis_conn_input(struct connection *_conn) { struct redis_connection *conn = (struct redis_connection *)_conn; - size_t size; int ret; switch (i_stream_read(_conn->input)) { @@ -248,11 +247,7 @@ break; } - while ((ret = redis_conn_input_more(conn)) > 0) { - i_stream_get_data(_conn->input, &size); - if (size == 0) - break; - } + while ((ret = redis_conn_input_more(conn)) > 0) ; if (ret < 0) redis_conn_destroy(_conn); } From dovecot at dovecot.org Tue Aug 28 13:24:35 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 28 Aug 2012 13:24:35 +0300 Subject: dovecot-2.1: lmtp proxy: Include session ID string in timeout re... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/bde62f77c65a changeset: 14687:bde62f77c65a user: Timo Sirainen date: Tue Aug 28 13:23:37 2012 +0300 description: lmtp proxy: Include session ID string in timeout reply text. diffstat: src/lmtp/commands.c | 1 + src/lmtp/lmtp-proxy.c | 10 ++++++---- src/lmtp/lmtp-proxy.h | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diffs (64 lines): diff -r db9fcdacba90 -r bde62f77c65a src/lmtp/commands.c --- a/src/lmtp/commands.c Sun Aug 26 19:23:48 2012 +0300 +++ b/src/lmtp/commands.c Tue Aug 28 13:23:37 2012 +0300 @@ -304,6 +304,7 @@ if (client->proxy == NULL) { client->proxy = lmtp_proxy_init(client->set->hostname, dns_client_socket_path, + client->state.session_id, client->output); if (client->state.mail_body_8bitmime) args = " BODY=8BITMIME"; diff -r db9fcdacba90 -r bde62f77c65a src/lmtp/lmtp-proxy.c --- a/src/lmtp/lmtp-proxy.c Sun Aug 26 19:23:48 2012 +0300 +++ b/src/lmtp/lmtp-proxy.c Tue Aug 28 13:23:37 2012 +0300 @@ -33,7 +33,7 @@ struct lmtp_proxy { pool_t pool; - const char *mail_from, *my_hostname; + const char *mail_from, *my_hostname, *session_id; const char *dns_client_socket_path; ARRAY_DEFINE(connections, struct lmtp_proxy_connection *); @@ -56,7 +56,7 @@ struct lmtp_proxy * lmtp_proxy_init(const char *my_hostname, const char *dns_client_socket_path, - struct ostream *client_output) + const char *session_id, struct ostream *client_output) { struct lmtp_proxy *proxy; pool_t pool; @@ -69,6 +69,7 @@ proxy->my_hostname = p_strdup(pool, my_hostname); proxy->client_output = client_output; proxy->dns_client_socket_path = p_strdup(pool, dns_client_socket_path); + proxy->session_id = p_strdup(pool, session_id); i_array_init(&proxy->rcpt_to, 32); i_array_init(&proxy->connections, 32); return proxy; @@ -264,8 +265,9 @@ const char *line; line = t_strdup_printf(ERRSTR_TEMP_REMOTE_FAILURE - " (timeout while waiting for reply to %s)", - lmtp_client_state_to_string(conn->client)); + " (timeout while waiting for reply to %s) <%s>", + lmtp_client_state_to_string(conn->client), + conn->proxy->session_id); lmtp_client_fail(conn->client, line); } diff -r db9fcdacba90 -r bde62f77c65a src/lmtp/lmtp-proxy.h --- a/src/lmtp/lmtp-proxy.h Sun Aug 26 19:23:48 2012 +0300 +++ b/src/lmtp/lmtp-proxy.h Tue Aug 28 13:23:37 2012 +0300 @@ -15,7 +15,7 @@ struct lmtp_proxy * lmtp_proxy_init(const char *my_hostname, const char *dns_client_socket_path, - struct ostream *client_output); + const char *session_id, struct ostream *client_output); void lmtp_proxy_deinit(struct lmtp_proxy **proxy); /* Set the "MAIL FROM:" line, including <> and options */ From dovecot at dovecot.org Tue Aug 28 14:46:26 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 28 Aug 2012 14:46:26 +0300 Subject: dovecot-2.2: lmtp proxy: Forward proxy_timeout to backend and se... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6d2a439a10a6 changeset: 14960:6d2a439a10a6 user: Timo Sirainen date: Tue Aug 28 14:46:16 2012 +0300 description: lmtp proxy: Forward proxy_timeout to backend and set mail_max_lock_timeout based on it. This automatically avoids duplicate mail deliveries caused by long lock waits. diffstat: src/lib-lda/lmtp-client.c | 4 ++++ src/lib-lda/lmtp-client.h | 6 +++++- src/lmtp/client.h | 1 + src/lmtp/commands.c | 25 ++++++++++++++++++++++--- src/lmtp/lmtp-proxy.c | 1 + 5 files changed, 33 insertions(+), 4 deletions(-) diffs (140 lines): diff -r 57efcf0957ea -r 6d2a439a10a6 src/lib-lda/lmtp-client.c --- a/src/lib-lda/lmtp-client.c Sat Aug 25 12:05:34 2012 +0300 +++ b/src/lib-lda/lmtp-client.c Tue Aug 28 14:46:16 2012 +0300 @@ -98,6 +98,7 @@ client->set.source_ip = set->source_ip; client->set.source_port = set->source_port; client->set.proxy_ttl_plus_1 = set->proxy_ttl_plus_1; + client->set.proxy_timeout_secs = set->proxy_timeout_secs; client->finish_callback = finish_callback; client->finish_context = context; client->fd = -1; @@ -435,6 +436,9 @@ if (client->set.proxy_ttl_plus_1 != 0 && str_array_icase_find(client->xclient_args, "TTL")) str_printfa(str, " TTL=%u", client->set.proxy_ttl_plus_1-1); + if (client->set.proxy_timeout_secs != 0 && + str_array_icase_find(client->xclient_args, "TIMEOUT")) + str_printfa(str, " TIMEOUT=%u", client->set.proxy_timeout_secs); if (str_len(str) == empty_len) return FALSE; diff -r 57efcf0957ea -r 6d2a439a10a6 src/lib-lda/lmtp-client.h --- a/src/lib-lda/lmtp-client.h Sat Aug 25 12:05:34 2012 +0300 +++ b/src/lib-lda/lmtp-client.h Tue Aug 28 14:46:16 2012 +0300 @@ -18,11 +18,15 @@ const char *dns_client_socket_path; /* if remote server supports XCLIENT capability, - send the these as ADDR/PORT */ + send the these as ADDR/PORT/TTL/TIMEOUT */ struct ip_addr source_ip; unsigned int source_port; /* send TTL as this -1, so the default 0 means "don't send it" */ unsigned int proxy_ttl_plus_1; + /* remote is notified that the connection is going to be closed after + this many seconds, so it should try to keep lock waits and such + lower than this. */ + unsigned int proxy_timeout_secs; }; /* reply contains the reply coming from remote server, or NULL diff -r 57efcf0957ea -r 6d2a439a10a6 src/lmtp/client.h --- a/src/lmtp/client.h Sat Aug 25 12:05:34 2012 +0300 +++ b/src/lmtp/client.h Tue Aug 28 14:46:16 2012 +0300 @@ -63,6 +63,7 @@ struct istream *dot_input; struct lmtp_proxy *proxy; unsigned int proxy_ttl; + unsigned int proxy_timeout_secs; unsigned int disconnected:1; }; diff -r 57efcf0957ea -r 6d2a439a10a6 src/lmtp/commands.c --- a/src/lmtp/commands.c Sat Aug 25 12:05:34 2012 +0300 +++ b/src/lmtp/commands.c Tue Aug 28 14:46:16 2012 +0300 @@ -12,6 +12,7 @@ #include "istream-dot.h" #include "safe-mkstemp.h" #include "restrict-access.h" +#include "settings-parser.h" #include "master-service.h" #include "rfc822-parser.h" #include "message-date.h" @@ -69,7 +70,7 @@ client_state_reset(client); client_send_line(client, "250-%s", client->my_domain); if (client_is_trusted(client)) - client_send_line(client, "250-XCLIENT ADDR PORT TTL"); + client_send_line(client, "250-XCLIENT ADDR PORT TTL TIMEOUT"); client_send_line(client, "250-8BITMIME"); client_send_line(client, "250-ENHANCEDSTATUSCODES"); client_send_line(client, "250 PIPELINING"); @@ -573,14 +574,28 @@ struct mail_storage *storage; const struct mail_storage_service_input *input; struct mail_namespace *ns; + struct setting_parser_context *set_parser; void **sets; - const char *error, *username; + const char *line, *error, *username; enum mail_error mail_error; int ret; input = mail_storage_service_user_get_input(rcpt->service_user); username = t_strdup(input->username); + set_parser = mail_storage_service_user_get_settings_parser(rcpt->service_user); + if (client->proxy_timeout_secs > 0) { + /* set lock timeout waits to be less than when proxy has + advertised that it's going to timeout the connection. + this avoids duplicate deliveries in case the delivery + succeeds after the proxy has already disconnected from us. */ + line = t_strdup_printf("mail_max_lock_timeout=%u", + client->proxy_timeout_secs <= 1 ? 1 : + client->proxy_timeout_secs-1); + if (settings_parse_line(set_parser, line) < 0) + i_unreached(); + } + i_set_failure_prefix(t_strdup_printf("lmtp(%s, %s): ", my_pid, username)); if (mail_storage_service_next(storage_service, rcpt->service_user, @@ -1000,7 +1015,7 @@ { const char *const *tmp; struct ip_addr remote_ip; - unsigned int remote_port = 0, ttl = -1U; + unsigned int remote_port = 0, ttl = -1U, timeout_secs = 0; bool args_ok = TRUE; if (!client_is_trusted(client)) { @@ -1019,6 +1034,9 @@ } else if (strncasecmp(*tmp, "TTL=", 4) == 0) { if (str_to_uint(*tmp + 4, &ttl) < 0) args_ok = FALSE; + } else if (strncasecmp(*tmp, "TIMEOUT=", 8) == 0) { + if (str_to_uint(*tmp + 8, &timeout_secs) < 0) + args_ok = FALSE; } } if (!args_ok) { @@ -1034,6 +1052,7 @@ client->remote_port = remote_port; if (ttl != -1U) client->proxy_ttl = ttl; + client->proxy_timeout_secs = timeout_secs; client_send_line(client, "220 %s %s", client->my_domain, client->lmtp_set->login_greeting); return 0; diff -r 57efcf0957ea -r 6d2a439a10a6 src/lmtp/lmtp-proxy.c --- a/src/lmtp/lmtp-proxy.c Sat Aug 25 12:05:34 2012 +0300 +++ b/src/lmtp/lmtp-proxy.c Tue Aug 28 14:46:16 2012 +0300 @@ -136,6 +136,7 @@ client_set.source_ip = proxy->set.source_ip; client_set.source_port = proxy->set.source_port; client_set.proxy_ttl_plus_1 = proxy->set.proxy_ttl+1; + client_set.proxy_timeout_secs = set->timeout_msecs/1000; conn = p_new(proxy->pool, struct lmtp_proxy_connection, 1); conn->proxy = proxy; From dovecot at dovecot.org Tue Aug 28 15:57:30 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 28 Aug 2012 15:57:30 +0300 Subject: dovecot-2.1: imapc: max_idle_time setting didn't actually work. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/7e7364926540 changeset: 14688:7e7364926540 user: Timo Sirainen date: Tue Aug 28 15:57:22 2012 +0300 description: imapc: max_idle_time setting didn't actually work. diffstat: src/lib-imap-client/imapc-client.c | 1 + src/lib-imap-client/imapc-connection.c | 2 ++ 2 files changed, 3 insertions(+), 0 deletions(-) diffs (23 lines): diff -r bde62f77c65a -r 7e7364926540 src/lib-imap-client/imapc-client.c --- a/src/lib-imap-client/imapc-client.c Tue Aug 28 13:23:37 2012 +0300 +++ b/src/lib-imap-client/imapc-client.c Tue Aug 28 15:57:22 2012 +0300 @@ -57,6 +57,7 @@ client->set.temp_path_prefix = p_strdup(pool, set->temp_path_prefix); client->set.rawlog_dir = p_strdup(pool, set->rawlog_dir); + client->set.max_idle_time = set->max_idle_time; if (set->ssl_mode != IMAPC_CLIENT_SSL_MODE_NONE) { client->set.ssl_mode = set->ssl_mode; diff -r bde62f77c65a -r 7e7364926540 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Tue Aug 28 13:23:37 2012 +0300 +++ b/src/lib-imap-client/imapc-connection.c Tue Aug 28 15:57:22 2012 +0300 @@ -1280,6 +1280,8 @@ struct stat st; int fd; + i_assert(conn->client->set.max_idle_time > 0); + conn->prev_connect_idx = (conn->prev_connect_idx+1) % conn->ips_count; ip = &conn->ips[conn->prev_connect_idx]; fd = net_connect_ip(ip, conn->client->set.port, NULL); From dovecot at dovecot.org Tue Aug 28 18:53:36 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 28 Aug 2012 18:53:36 +0300 Subject: dovecot-2.1: dict file: Fixed corruption with large values. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/6e53209030f6 changeset: 14689:6e53209030f6 user: Timo Sirainen date: Tue Aug 28 18:53:30 2012 +0300 description: dict file: Fixed corruption with large values. Patch by Ewald Dieterich. diffstat: src/lib-dict/dict-file.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diffs (20 lines): diff -r 7e7364926540 -r 6e53209030f6 src/lib-dict/dict-file.c --- a/src/lib-dict/dict-file.c Tue Aug 28 15:57:22 2012 +0300 +++ b/src/lib-dict/dict-file.c Tue Aug 28 18:53:30 2012 +0300 @@ -186,9 +186,14 @@ if (dict->fd != -1) { input = i_stream_create_fd(dict->fd, (size_t)-1, FALSE); - while ((key = i_stream_read_next_line(input)) != NULL && - (value = i_stream_read_next_line(input)) != NULL) { + + while ((key = i_stream_read_next_line(input)) != NULL) { + /* strdup() before the second read */ key = p_strdup(dict->hash_pool, key); + + if ((value = i_stream_read_next_line(input)) == NULL) + break; + value = p_strdup(dict->hash_pool, value); hash_table_insert(dict->hash, key, value); } From dovecot at dovecot.org Tue Aug 28 19:06:15 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 28 Aug 2012 19:06:15 +0300 Subject: dovecot-2.1: imapc: If imapc_list_prefix=INBOX, don't treat INBO... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/eb57a7280b01 changeset: 14690:eb57a7280b01 user: Timo Sirainen date: Tue Aug 28 19:06:01 2012 +0300 description: imapc: If imapc_list_prefix=INBOX, don't treat INBOX/INBOX as the INBOX itself. diffstat: src/lib-storage/index/imapc/imapc-list.c | 12 ++++++++++-- 1 files changed, 10 insertions(+), 2 deletions(-) diffs (37 lines): diff -r 6e53209030f6 -r eb57a7280b01 src/lib-storage/index/imapc/imapc-list.c --- a/src/lib-storage/index/imapc/imapc-list.c Tue Aug 28 18:53:30 2012 +0300 +++ b/src/lib-storage/index/imapc/imapc-list.c Tue Aug 28 19:06:01 2012 +0300 @@ -345,6 +345,7 @@ { struct imapc_command *cmd; struct imapc_simple_context ctx; + struct mailbox_node *node; const char *pattern; i_assert(list->sep != '\0'); @@ -364,16 +365,23 @@ mailbox_tree_deinit(&list->mailboxes); list->mailboxes = mailbox_tree_init(list->sep); mailbox_tree_set_parents_nonexistent(list->mailboxes); + imapc_simple_run(&ctx); if ((list->list.ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) { /* INBOX always exists in IMAP server. since this namespace is marked with inbox=yes, show the INBOX even if imapc_list_prefix doesn't match it */ bool created; - (void)mailbox_tree_get(list->mailboxes, "INBOX", &created); + node = mailbox_tree_get(list->mailboxes, "INBOX", &created); + if (*list->storage->set->imapc_list_prefix != '\0') { + /* this listing didn't include the INBOX itself, but + might have included its children. make sure there + aren't any extra flags in it (especially + \NonExistent) */ + node->flags &= MAILBOX_CHILDREN; + } } - imapc_simple_run(&ctx); if (ctx.ret == 0) { list->refreshed_mailboxes = TRUE; imapc_list_delete_unused_indexes(list); From dovecot at dovecot.org Tue Aug 28 22:16:16 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 28 Aug 2012 22:16:16 +0300 Subject: dovecot-2.2: mdbox: Replaced non-error-checking i_stream_stat() ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cbe8fe1b44f0 changeset: 14961:cbe8fe1b44f0 user: Timo Sirainen date: Tue Aug 28 22:15:49 2012 +0300 description: mdbox: Replaced non-error-checking i_stream_stat() with potentially faster i_stream_get_size(). diffstat: src/lib-storage/index/dbox-multi/mdbox-save.c | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-) diffs (20 lines): diff -r 6d2a439a10a6 -r cbe8fe1b44f0 src/lib-storage/index/dbox-multi/mdbox-save.c --- a/src/lib-storage/index/dbox-multi/mdbox-save.c Tue Aug 28 14:46:16 2012 +0300 +++ b/src/lib-storage/index/dbox-multi/mdbox-save.c Tue Aug 28 22:15:49 2012 +0300 @@ -132,14 +132,12 @@ /* get the size of the mail to be saved, if possible */ if (i_stream_get_size(input, TRUE, &mail_size) <= 0) { - const struct stat *st; - /* we couldn't find out the exact size. fallback to non-exact, maybe it'll give something useful. the mail size is used only to figure out if it's causing mdbox file to grow too large. */ - st = i_stream_stat(input, FALSE); - mail_size = st->st_size > 0 ? st->st_size : 0; + if (i_stream_get_size(input, FALSE, &mail_size) <= 0) + mail_size = 0; } if (mdbox_map_append_next(ctx->append_ctx, mail_size, 0, &ctx->cur_file_append, From dovecot at dovecot.org Tue Aug 28 22:16:16 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 28 Aug 2012 22:16:16 +0300 Subject: dovecot-2.2: istream-chain: Removed default get_size() implement... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/bb0533bca649 changeset: 14962:bb0533bca649 user: Timo Sirainen date: Tue Aug 28 22:15:57 2012 +0300 description: istream-chain: Removed default get_size() implementation and panicing on stat() This works around crashes in mdbox/quota code. Patch by Stephan Bosch. diffstat: src/lib/istream-chain.c | 12 +----------- 1 files changed, 1 insertions(+), 11 deletions(-) diffs (33 lines): diff -r cbe8fe1b44f0 -r bb0533bca649 src/lib/istream-chain.c --- a/src/lib/istream-chain.c Tue Aug 28 22:15:49 2012 +0300 +++ b/src/lib/istream-chain.c Tue Aug 28 22:15:57 2012 +0300 @@ -237,20 +237,11 @@ static const struct stat * i_stream_chain_stat(struct istream_private *stream ATTR_UNUSED, - bool exact ATTR_UNUSED) + bool exact ATTR_UNUSED) { - i_panic("istream_chain(): stat() not supported"); return NULL; } -static int -i_stream_chain_get_size(struct istream_private *stream ATTR_UNUSED, - bool exact ATTR_UNUSED, uoff_t *size_r ATTR_UNUSED) -{ - i_panic("istream_chain(): get_size() not supported"); - return -1; -} - struct istream *i_stream_create_chain(struct istream_chain **chain_r) { struct chain_istream *cstream; @@ -265,7 +256,6 @@ cstream->istream.read = i_stream_chain_read; cstream->istream.stat = i_stream_chain_stat; - cstream->istream.get_size = i_stream_chain_get_size; cstream->istream.istream.readable_fd = FALSE; cstream->istream.istream.blocking = FALSE; From dovecot at dovecot.org Tue Aug 28 22:41:19 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 28 Aug 2012 22:41:19 +0300 Subject: dovecot-2.2: o_stream_send_istream(): Get input stream size with... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3cba27563159 changeset: 14963:3cba27563159 user: Timo Sirainen date: Tue Aug 28 22:20:17 2012 +0300 description: o_stream_send_istream(): Get input stream size with i_stream_get_size() instead of _stat(). diffstat: src/lib/ostream-file.c | 24 +++++++++++------------- 1 files changed, 11 insertions(+), 13 deletions(-) diffs (65 lines): diff -r bb0533bca649 -r 3cba27563159 src/lib/ostream-file.c --- a/src/lib/ostream-file.c Tue Aug 28 22:15:57 2012 +0300 +++ b/src/lib/ostream-file.c Tue Aug 28 22:20:17 2012 +0300 @@ -677,17 +677,15 @@ struct istream *instream, int in_fd) { struct file_ostream *foutstream = (struct file_ostream *)outstream; - const struct stat *st; uoff_t start_offset; uoff_t in_size, offset, send_size, v_offset; ssize_t ret; - st = i_stream_stat(instream, TRUE); - if (st == NULL) { - outstream->ostream.stream_errno = instream->stream_errno; + if ((ret = i_stream_get_size(instream, TRUE, &in_size)) <= 0) { + outstream->ostream.stream_errno = ret == 0 ? ESPIPE : + instream->stream_errno; return -1; } - in_size = st->st_size; o_stream_socket_cork(foutstream); @@ -815,18 +813,18 @@ struct istream *instream, bool same_stream) { struct file_ostream *foutstream = (struct file_ostream *)outstream; - const struct stat *st; + uoff_t in_size; off_t in_abs_offset, ret; if (same_stream) { /* copying data within same fd. we'll have to be careful with seeks and overlapping writes. */ - st = i_stream_stat(instream, TRUE); - if (st == NULL) { - outstream->ostream.stream_errno = instream->stream_errno; + if ((ret = i_stream_get_size(instream, TRUE, &in_size)) <= 0) { + outstream->ostream.stream_errno = ret == 0 ? ESPIPE : + instream->stream_errno; return -1; } - i_assert(instream->v_offset <= (uoff_t)st->st_size); + i_assert(instream->v_offset <= in_size); in_abs_offset = instream->real_stream->abs_start_offset + instream->v_offset; @@ -834,13 +832,13 @@ if (ret == 0) { /* copying data over itself. we don't really need to do that, just fake it. */ - return st->st_size - instream->v_offset; + return in_size - instream->v_offset; } - if (ret > 0 && st->st_size > ret) { + if (ret > 0 && in_size > (uoff_t)ret) { /* overlapping */ i_assert(instream->seekable); return io_stream_copy_backwards(outstream, instream, - st->st_size); + in_size); } } From dovecot at dovecot.org Tue Aug 28 22:41:19 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 28 Aug 2012 22:41:19 +0300 Subject: dovecot-2.2: i_stream_stat() API changed. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6d2be8d8891c changeset: 14964:6d2be8d8891c user: Timo Sirainen date: Tue Aug 28 22:40:57 2012 +0300 description: i_stream_stat() API changed. This fixes also one missing error check. diffstat: src/lib-compression/istream-bzlib.c | 18 +++++++--------- src/lib-compression/istream-zlib.c | 18 +++++++--------- src/lib-fs/fs-sis.c | 3 +- src/lib-mail/istream-header-filter.c | 14 +++++++----- src/lib-storage/index/maildir/maildir-mail.c | 3 +- src/lib-storage/index/mbox/istream-raw-mbox.c | 9 +++---- src/lib-storage/index/mbox/mbox-sync.c | 12 +++------- src/lib-storage/index/raw/raw-mail.c | 3 +- src/lib-storage/list/subscription-file.c | 2 +- src/lib/istream-chain.c | 8 ------- src/lib/istream-concat.c | 10 ++++---- src/lib/istream-file.c | 9 +++---- src/lib/istream-limit.c | 12 ++++------ src/lib/istream-mmap.c | 7 +---- src/lib/istream-private.h | 2 +- src/lib/istream-seekable.c | 11 ++++++--- src/lib/istream-sized.c | 9 +++---- src/lib/istream-tee.c | 8 +++++- src/lib/istream.c | 29 +++++++++++++++----------- src/lib/istream.h | 4 +- 20 files changed, 90 insertions(+), 101 deletions(-) diffs (truncated from 624 to 300 lines): diff -r 3cba27563159 -r 6d2be8d8891c src/lib-compression/istream-bzlib.c --- a/src/lib-compression/istream-bzlib.c Tue Aug 28 22:20:17 2012 +0300 +++ b/src/lib-compression/istream-bzlib.c Tue Aug 28 22:40:57 2012 +0300 @@ -264,25 +264,24 @@ zstream->marked = TRUE; } -static const struct stat * +static int i_stream_bzlib_stat(struct istream_private *stream, bool exact) { struct bzlib_istream *zstream = (struct bzlib_istream *) stream; const struct stat *st; size_t size; - st = i_stream_stat(stream->parent, exact); - if (st == NULL) - return NULL; + if (i_stream_stat(stream->parent, exact, &st) < 0) + return -1; + stream->statbuf = *st; /* when exact=FALSE always return the parent stat's size, even if we know the exact value. this is necessary because otherwise e.g. mbox code can see two different values and think that a compressed mbox file keeps changing. */ if (!exact) - return st; + return 0; - stream->statbuf = *st; if (zstream->stream_size == (uoff_t)-1) { uoff_t old_offset = stream->istream.v_offset; @@ -293,10 +292,10 @@ i_stream_seek(&stream->istream, old_offset); if (zstream->stream_size == (uoff_t)-1) - return NULL; + return -1; } stream->statbuf.st_size = zstream->stream_size; - return &stream->statbuf; + return 0; } static void i_stream_bzlib_sync(struct istream_private *stream) @@ -304,8 +303,7 @@ struct bzlib_istream *zstream = (struct bzlib_istream *) stream; const struct stat *st; - st = i_stream_stat(stream->parent, FALSE); - if (st != NULL) { + if (i_stream_stat(stream->parent, FALSE, &st) < 0) { if (memcmp(&zstream->last_parent_statbuf, st, sizeof(*st)) == 0) { /* a compressed file doesn't change unexpectedly, diff -r 3cba27563159 -r 6d2be8d8891c src/lib-compression/istream-zlib.c --- a/src/lib-compression/istream-zlib.c Tue Aug 28 22:20:17 2012 +0300 +++ b/src/lib-compression/istream-zlib.c Tue Aug 28 22:40:57 2012 +0300 @@ -423,25 +423,24 @@ zstream->marked = TRUE; } -static const struct stat * +static int i_stream_zlib_stat(struct istream_private *stream, bool exact) { struct zlib_istream *zstream = (struct zlib_istream *) stream; const struct stat *st; size_t size; - st = i_stream_stat(stream->parent, exact); - if (st == NULL) - return NULL; + if (i_stream_stat(stream->parent, exact, &st) < 0) + return -1; + stream->statbuf = *st; /* when exact=FALSE always return the parent stat's size, even if we know the exact value. this is necessary because otherwise e.g. mbox code can see two different values and think that a compressed mbox file keeps changing. */ if (!exact) - return st; + return 0; - stream->statbuf = *st; if (zstream->stream_size == (uoff_t)-1) { uoff_t old_offset = stream->istream.v_offset; @@ -452,10 +451,10 @@ i_stream_seek(&stream->istream, old_offset); if (zstream->stream_size == (uoff_t)-1) - return NULL; + return -1; } stream->statbuf.st_size = zstream->stream_size; - return &stream->statbuf; + return 0; } static void i_stream_zlib_sync(struct istream_private *stream) @@ -463,8 +462,7 @@ struct zlib_istream *zstream = (struct zlib_istream *) stream; const struct stat *st; - st = i_stream_stat(stream->parent, FALSE); - if (st != NULL) { + if (i_stream_stat(stream->parent, FALSE, &st) < 0) { if (memcmp(&zstream->last_parent_statbuf, st, sizeof(*st)) == 0) { /* a compressed file doesn't change unexpectedly, diff -r 3cba27563159 -r 6d2be8d8891c src/lib-fs/fs-sis.c --- a/src/lib-fs/fs-sis.c Tue Aug 28 22:20:17 2012 +0300 +++ b/src/lib-fs/fs-sis.c Tue Aug 28 22:40:57 2012 +0300 @@ -158,7 +158,8 @@ const struct stat *st; struct stat st2; - st = i_stream_stat(file->hash_input, FALSE); + if (i_stream_stat(file->hash_input, FALSE, &st) < 0) + return FALSE; /* we can use the existing file */ if (fs_link(file->super->fs, file->hash_path, path) < 0) { diff -r 3cba27563159 -r 6d2be8d8891c src/lib-mail/istream-header-filter.c --- a/src/lib-mail/istream-header-filter.c Tue Aug 28 22:20:17 2012 +0300 +++ b/src/lib-mail/istream-header-filter.c Tue Aug 28 22:40:57 2012 +0300 @@ -492,7 +492,7 @@ i_panic("istream-header-filter sync() not implemented"); } -static const struct stat * +static int i_stream_header_filter_stat(struct istream_private *stream, bool exact) { struct header_filter_istream *mstream = @@ -500,19 +500,21 @@ const struct stat *st; uoff_t old_offset; - st = i_stream_stat(stream->parent, exact); - if (st == NULL || st->st_size == -1 || !exact) - return st; + if (i_stream_stat(stream->parent, exact, &st) < 0) + return -1; + stream->statbuf = *st; + if (stream->statbuf.st_size == -1 || !exact) + return 0; + /* fix the filtered header size */ old_offset = stream->istream.v_offset; skip_header(mstream); - stream->statbuf = *st; stream->statbuf.st_size -= (off_t)mstream->header_size.physical_size - (off_t)mstream->header_size.virtual_size; i_stream_seek(&stream->istream, old_offset); - return &stream->statbuf; + return 0; } #undef i_stream_create_header_filter diff -r 3cba27563159 -r 6d2be8d8891c src/lib-storage/index/maildir/maildir-mail.c --- a/src/lib-storage/index/maildir/maildir-mail.c Tue Aug 28 22:20:17 2012 +0300 +++ b/src/lib-storage/index/maildir/maildir-mail.c Tue Aug 28 22:40:57 2012 +0300 @@ -125,8 +125,7 @@ if (imail->data.stream != NULL) { mail->transaction->stats.fstat_lookup_count++; - stp = i_stream_stat(imail->data.stream, FALSE); - if (stp == NULL) + if (i_stream_stat(imail->data.stream, FALSE, &stp) < 0) return -1; *st_r = *stp; } else if (!mail->saving) { diff -r 3cba27563159 -r 6d2be8d8891c src/lib-storage/index/mbox/istream-raw-mbox.c --- a/src/lib-storage/index/mbox/istream-raw-mbox.c Tue Aug 28 22:20:17 2012 +0300 +++ b/src/lib-storage/index/mbox/istream-raw-mbox.c Tue Aug 28 22:40:57 2012 +0300 @@ -406,21 +406,20 @@ rstream->input_peak_offset = 0; } -static const struct stat * +static int i_stream_raw_mbox_stat(struct istream_private *stream, bool exact) { const struct stat *st; struct raw_mbox_istream *rstream = (struct raw_mbox_istream *)stream; - st = i_stream_stat(stream->parent, exact); - if (st == NULL) - return NULL; + if (i_stream_stat(stream->parent, exact, &st) < 0) + return -1; stream->statbuf = *st; stream->statbuf.st_size = !exact && rstream->seeked && rstream->mail_size != (uoff_t)-1 ? (off_t)rstream->mail_size : -1; - return &stream->statbuf; + return 0; } struct istream *i_stream_create_raw_mbox(struct istream *input) diff -r 3cba27563159 -r 6d2be8d8891c src/lib-storage/index/mbox/mbox-sync.c --- a/src/lib-storage/index/mbox/mbox-sync.c Tue Aug 28 22:20:17 2012 +0300 +++ b/src/lib-storage/index/mbox/mbox-sync.c Tue Aug 28 22:40:57 2012 +0300 @@ -1427,8 +1427,7 @@ const struct stat *st; uint32_t first_recent_uid, seq, seq2; - st = i_stream_stat(sync_ctx->file_input, FALSE); - if (st == NULL) { + if (i_stream_stat(sync_ctx->file_input, FALSE, &st) < 0) { mbox_set_syscall_error(sync_ctx->mbox, "i_stream_stat()"); return -1; } @@ -1456,8 +1455,7 @@ return -1; } - st = i_stream_stat(sync_ctx->file_input, FALSE); - if (st == NULL) { + if (i_stream_stat(sync_ctx->file_input, FALSE, &st) < 0) { mbox_set_syscall_error(sync_ctx->mbox, "i_stream_stat()"); return -1; @@ -1562,8 +1560,7 @@ unsigned int i; int ret, partial; - st = i_stream_stat(sync_ctx->file_input, FALSE); - if (st == NULL) { + if (i_stream_stat(sync_ctx->file_input, FALSE, &st) < 0) { mbox_set_syscall_error(sync_ctx->mbox, "i_stream_stat()"); return -1; } @@ -1706,8 +1703,7 @@ if (mbox->mbox_file_stream != NULL && mbox->mbox_fd == -1) { /* read-only stream */ - st = i_stream_stat(mbox->mbox_file_stream, FALSE); - if (st == NULL) { + if (i_stream_stat(mbox->mbox_file_stream, FALSE, &st) < 0) { if (errno == ENOENT) { mailbox_set_deleted(&mbox->box); return 0; diff -r 3cba27563159 -r 6d2be8d8891c src/lib-storage/index/raw/raw-mail.c --- a/src/lib-storage/index/raw/raw-mail.c Tue Aug 28 22:20:17 2012 +0300 +++ b/src/lib-storage/index/raw/raw-mail.c Tue Aug 28 22:40:57 2012 +0300 @@ -20,8 +20,7 @@ } mail->transaction->stats.fstat_lookup_count++; - st = i_stream_stat(mail->box->input, TRUE); - if (st == NULL) { + if (i_stream_stat(mail->box->input, TRUE, &st) < 0) { mail_storage_set_critical(mail->box->storage, "stat(%s) failed: %m", i_stream_get_name(mail->box->input)); diff -r 3cba27563159 -r 6d2be8d8891c src/lib-storage/list/subscription-file.c --- a/src/lib-storage/list/subscription-file.c Tue Aug 28 22:20:17 2012 +0300 +++ b/src/lib-storage/list/subscription-file.c Tue Aug 28 22:40:57 2012 +0300 @@ -244,7 +244,7 @@ if (ctx->failed) return -1; - if ((st = i_stream_stat(ctx->input, FALSE)) == NULL) { + if (i_stream_stat(ctx->input, FALSE, &st) < 0) { ctx->failed = TRUE; return -1; } diff -r 3cba27563159 -r 6d2be8d8891c src/lib/istream-chain.c --- a/src/lib/istream-chain.c Tue Aug 28 22:20:17 2012 +0300 +++ b/src/lib/istream-chain.c Tue Aug 28 22:40:57 2012 +0300 @@ -235,13 +235,6 @@ return ret; } -static const struct stat * -i_stream_chain_stat(struct istream_private *stream ATTR_UNUSED, - bool exact ATTR_UNUSED) -{ - return NULL; -} - struct istream *i_stream_create_chain(struct istream_chain **chain_r) { struct chain_istream *cstream; @@ -255,7 +248,6 @@ i_stream_chain_set_max_buffer_size; cstream->istream.read = i_stream_chain_read; - cstream->istream.stat = i_stream_chain_stat; cstream->istream.istream.readable_fd = FALSE; From pigeonhole at rename-it.nl Wed Aug 29 00:07:42 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 28 Aug 2012 23:07:42 +0200 Subject: dovecot-2.2-pigeonhole: Adjusted to changes in Dovecot istream API. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/0eafbad49e41 changeset: 1657:0eafbad49e41 user: Stephan Bosch date: Tue Aug 28 23:07:36 2012 +0200 description: Adjusted to changes in Dovecot istream API. diffstat: src/lib-managesieve/managesieve-parser.c | 10 ++++++++-- src/lib-sieve/edit-mail.c | 15 +++++++-------- src/lib-sieve/sieve-lexer.c | 4 ++-- 3 files changed, 17 insertions(+), 12 deletions(-) diffs (80 lines): diff -r 6ccbfb64bea5 -r 0eafbad49e41 src/lib-managesieve/managesieve-parser.c --- a/src/lib-managesieve/managesieve-parser.c Mon Aug 20 09:13:32 2012 +0200 +++ b/src/lib-managesieve/managesieve-parser.c Tue Aug 28 23:07:36 2012 +0200 @@ -712,10 +712,16 @@ return ret; } -static const struct stat *quoted_string_istream_stat +static int quoted_string_istream_stat (struct istream_private *stream, bool exact) { - return i_stream_stat(stream->parent, exact); + const struct stat *st; + + if (i_stream_stat(stream->parent, exact, &st) < 0) + return -1; + + stream->statbuf = *st; + return 0; } static struct istream *quoted_string_istream_create diff -r 6ccbfb64bea5 -r 0eafbad49e41 src/lib-sieve/edit-mail.c --- a/src/lib-sieve/edit-mail.c Mon Aug 20 09:13:32 2012 +0200 +++ b/src/lib-sieve/edit-mail.c Tue Aug 28 23:07:36 2012 +0200 @@ -1710,7 +1710,7 @@ i_panic("edit-mail istream sync() not implemented"); } -static const struct stat * +static int edit_mail_istream_stat(struct istream_private *stream, bool exact) { struct edit_mail_istream *edstream = @@ -1719,16 +1719,16 @@ const struct stat *st; /* Stat the original stream */ - st = i_stream_stat(stream->parent, exact); - if (st == NULL || st->st_size == -1 || !exact) - return st; + if (i_stream_stat(stream->parent, exact, &st) < 0) + return -1; - /* Adjust stat data */ stream->statbuf = *st; + if (st->st_size == -1 || !exact) + return 0; if ( !edmail->headers_parsed ) { if ( !edmail->modified ) - return &stream->statbuf; + return 0; } else { stream->statbuf.st_size = edmail->wrapped_body_size.physical_size + ( edmail->eoh_crlf ? 2 : 1 ); @@ -1736,8 +1736,7 @@ stream->statbuf.st_size += edmail->hdr_size.physical_size + edmail->body_size.physical_size; - - return &stream->statbuf; + return 0; } struct istream *edit_mail_istream_create diff -r 6ccbfb64bea5 -r 0eafbad49e41 src/lib-sieve/sieve-lexer.c --- a/src/lib-sieve/sieve-lexer.c Mon Aug 20 09:13:32 2012 +0200 +++ b/src/lib-sieve/sieve-lexer.c Tue Aug 28 23:07:36 2012 +0200 @@ -76,8 +76,8 @@ return NULL; /* Check script size */ - st = i_stream_stat(stream, TRUE); - if ( st != NULL && st->st_size > 0 && svinst->max_script_size > 0 && + if ( i_stream_stat(stream, TRUE, &st) >= 0 && st->st_size > 0 && + svinst->max_script_size > 0 && (uoff_t)st->st_size > svinst->max_script_size ) { sieve_error(ehandler, sieve_script_name(script), "sieve script is too large (max %"PRIuSIZE_T" bytes)", From dovecot at dovecot.org Wed Aug 29 08:56:54 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 08:56:54 +0300 Subject: dovecot-2.2: Reverted some of the last hash table changes. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9ae214349fac changeset: 14965:9ae214349fac user: Timo Sirainen date: Wed Aug 29 08:56:40 2012 +0300 description: Reverted some of the last hash table changes. They caused hash table operations to dereference pointers, which caused a compiler error if the type wasn't known. diffstat: src/lib/hash-decl.h | 3 +++ src/lib/hash.h | 19 +++++++++---------- 2 files changed, 12 insertions(+), 10 deletions(-) diffs (77 lines): diff -r 6d2be8d8891c -r 9ae214349fac src/lib/hash-decl.h --- a/src/lib/hash-decl.h Tue Aug 28 22:40:57 2012 +0300 +++ b/src/lib/hash-decl.h Wed Aug 29 08:56:40 2012 +0300 @@ -4,7 +4,10 @@ #define HASH_TABLE_UNION(key_type, value_type) { \ struct hash_table *_table; \ key_type _key; \ + key_type *_keyp; \ + const key_type _const_key; \ value_type _value; \ + value_type *_valuep; \ } #define HASH_TABLE_DEFINE_TYPE(name, key_type, value_type) \ diff -r 6d2be8d8891c -r 9ae214349fac src/lib/hash.h --- a/src/lib/hash.h Tue Aug 28 22:40:57 2012 +0300 +++ b/src/lib/hash.h Wed Aug 29 08:56:40 2012 +0300 @@ -31,13 +31,12 @@ !__builtin_types_compatible_p(typeof(&key_cmp_cb), \ int (*)(typeof((*table)._key), typeof((*table)._key))) && \ !__builtin_types_compatible_p(typeof(&key_cmp_cb), \ - int (*)(typeof(const typeof(*(*table)._key) *), \ - typeof(const typeof(*(*table)._key) *)))); \ + int (*)(typeof((*table)._const_key), typeof((*table)._const_key)))); \ (void)COMPILE_ERROR_IF_TRUE( \ !__builtin_types_compatible_p(typeof(&hash_cb), \ unsigned int (*)(typeof((*table)._key))) && \ !__builtin_types_compatible_p(typeof(&hash_cb), \ - unsigned int (*)(typeof(const typeof(*(*table)._key) *)))); \ + unsigned int (*)(typeof((*table)._const_key)))); \ hash_table_create(&(*table)._table, pool, size, \ (hash_callback_t *)hash_cb, \ (hash_cmp_callback_t *)key_cmp_cb);}) @@ -78,17 +77,17 @@ void *hash_table_lookup(const struct hash_table *table, const void *key) ATTR_PURE; #define hash_table_lookup(table, key) \ HASH_VALUE_CAST(table)hash_table_lookup((table)._table, \ - (const void *)((const char *)(key) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE(*(table)._key, *key))) + (const void *)((const char *)(key) + COMPILE_ERROR_IF_TYPES2_NOT_COMPATIBLE((table)._key, (table)._const_key, key))) bool hash_table_lookup_full(const struct hash_table *table, const void *lookup_key, void **orig_key_r, void **value_r); #define hash_table_lookup_full(table, lookup_key, orig_key_r, value_r) \ hash_table_lookup_full((table)._table, \ - (void *)((const char *)(lookup_key) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE(*(table)._key, *lookup_key)), \ - (void **)(void *)((orig_key_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._key, *orig_key_r) + \ + (void *)((const char *)(lookup_key) + COMPILE_ERROR_IF_TYPES2_NOT_COMPATIBLE((table)._const_key, (table)._key, lookup_key)), \ + (void **)(void *)((orig_key_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._keyp, orig_key_r) + \ COMPILE_ERROR_IF_TRUE(sizeof(*orig_key_r) != sizeof(void *))), \ - (void **)(void *)((value_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._value, *value_r) + \ + (void **)(void *)((value_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._valuep, value_r) + \ COMPILE_ERROR_IF_TRUE(sizeof(*value_r) != sizeof(void *)))) /* Insert/update node in hash table. The difference is that hash_table_insert() @@ -107,7 +106,7 @@ void hash_table_remove(struct hash_table *table, const void *key); #define hash_table_remove(table, key) \ hash_table_remove((table)._table, \ - (const void *)((const char *)(key) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE(*(table)._key, *key))) + (const void *)((const char *)(key) + COMPILE_ERROR_IF_TYPES2_NOT_COMPATIBLE((table)._const_key, (table)._key, key))) unsigned int hash_table_count(const struct hash_table *table) ATTR_PURE; #define hash_table_count(table) \ hash_table_count((table)._table) @@ -122,10 +121,10 @@ void **key_r, void **value_r); #define hash_table_iterate(ctx, table, key_r, value_r) \ hash_table_iterate(ctx, \ - (void **)(void *)((key_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._key, *key_r) + \ + (void **)(void *)((key_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._keyp, key_r) + \ COMPILE_ERROR_IF_TRUE(sizeof(*key_r) != sizeof(void *)) + \ COMPILE_ERROR_IF_TRUE(sizeof(*value_r) != sizeof(void *))), \ - (void **)(void *)((value_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._value, *value_r))) + (void **)(void *)((value_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._valuep, value_r))) void hash_table_iterate_deinit(struct hash_iterate_context **ctx); /* Hash table isn't resized, and removed nodes aren't removed from From dovecot at dovecot.org Wed Aug 29 16:19:12 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 16:19:12 +0300 Subject: dovecot-2.2: str_*printfa(): Avoid growing underlying buffer if ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fff00bb85ae4 changeset: 14966:fff00bb85ae4 user: Timo Sirainen date: Wed Aug 29 16:12:08 2012 +0300 description: str_*printfa(): Avoid growing underlying buffer if possible. diffstat: src/lib/str.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r 9ae214349fac -r fff00bb85ae4 src/lib/str.c --- a/src/lib/str.c Wed Aug 29 08:56:40 2012 +0300 +++ b/src/lib/str.c Wed Aug 29 16:12:08 2012 +0300 @@ -145,6 +145,11 @@ init_size += SNPRINTF_INITIAL_EXTRA_SIZE; /* @UNSAFE */ + if (init_size > buffer_get_size(str)) { + /* avoid growing buffer larger if possible. this is also + required if buffer isn't dynamically growing. */ + init_size = buffer_get_size(str); + } tmp = buffer_get_space_unsafe(str, pos, init_size); ret = vsnprintf(tmp, init_size, fmt, args); i_assert(ret >= 0); From dovecot at dovecot.org Wed Aug 29 16:19:12 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 16:19:12 +0300 Subject: dovecot-2.2: iostream-rawlog: Added possibility to save input/ou... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8ce6d41d2d41 changeset: 14967:8ce6d41d2d41 user: Timo Sirainen date: Wed Aug 29 16:18:56 2012 +0300 description: iostream-rawlog: Added possibility to save input/output to the same file. diffstat: src/lib/iostream-rawlog-private.h | 15 +++- src/lib/iostream-rawlog.c | 161 ++++++++++++++++++++++++++++++------- src/lib/iostream-rawlog.h | 9 ++ src/lib/istream-rawlog.c | 5 +- src/lib/istream-rawlog.h | 2 +- src/lib/ostream-rawlog.c | 5 +- src/lib/ostream-rawlog.h | 2 +- 7 files changed, 156 insertions(+), 43 deletions(-) diffs (truncated from 357 to 300 lines): diff -r fff00bb85ae4 -r 8ce6d41d2d41 src/lib/iostream-rawlog-private.h --- a/src/lib/iostream-rawlog-private.h Wed Aug 29 16:12:08 2012 +0300 +++ b/src/lib/iostream-rawlog-private.h Wed Aug 29 16:18:56 2012 +0300 @@ -1,16 +1,27 @@ #ifndef IOSTREAM_RAWLOG_PRIVATE_H #define IOSTREAM_RAWLOG_PRIVATE_H +#define IOSTREAM_RAWLOG_MAX_PREFIX_LEN 3 + +enum iostream_rawlog_flags { + IOSTREAM_RAWLOG_FLAG_AUTOCLOSE = 0x01, + IOSTREAM_RAWLOG_FLAG_BUFFERED = 0x02 +}; + struct rawlog_iostream { struct iostream_private *iostream; + enum iostream_rawlog_flags flags; char *rawlog_path; int rawlog_fd; + buffer_t *buffer; - bool autoclose_fd; - bool write_timestamp; + bool input; + bool line_continued; }; +void iostream_rawlog_init(struct rawlog_iostream *rstream, + enum iostream_rawlog_flags flags, bool input); void iostream_rawlog_write(struct rawlog_iostream *rstream, const unsigned char *data, size_t size); void iostream_rawlog_close(struct rawlog_iostream *rstream); diff -r fff00bb85ae4 -r 8ce6d41d2d41 src/lib/iostream-rawlog.c --- a/src/lib/iostream-rawlog.c Wed Aug 29 16:12:08 2012 +0300 +++ b/src/lib/iostream-rawlog.c Wed Aug 29 16:18:56 2012 +0300 @@ -3,19 +3,23 @@ #include "lib.h" #include "hostpid.h" #include "ioloop.h" +#include "buffer.h" +#include "str.h" #include "write-full.h" #include "time-util.h" #include "istream.h" #include "ostream.h" +#include "iostream-private.h" +#include "iostream-rawlog-private.h" #include "istream-rawlog.h" #include "ostream-rawlog.h" -#include "iostream-private.h" -#include "iostream-rawlog-private.h" #include "iostream-rawlog.h" #include #include +#define RAWLOG_MAX_LINE_LEN 8192 + static void rawlog_write(struct rawlog_iostream *rstream, const void *data, size_t size) { @@ -29,43 +33,98 @@ } } -static void rawlog_write_timestamp(struct rawlog_iostream *rstream) +static void +rawlog_write_timestamp(struct rawlog_iostream *rstream, bool line_ends) { - char buf[MAX_INT_STRLEN + 6 + 2]; + unsigned char data[MAX_INT_STRLEN + 6 + 1 + 3]; + buffer_t buf; - if (i_snprintf(buf, sizeof(buf), "%lu.%06u ", - (unsigned long)ioloop_timeval.tv_sec, - (unsigned int)ioloop_timeval.tv_usec) < 0) - i_unreached(); - rawlog_write(rstream, buf, strlen(buf)); + buffer_create_data(&buf, data, sizeof(data)); + str_printfa(&buf, "%lu.%06u ", + (unsigned long)ioloop_timeval.tv_sec, + (unsigned int)ioloop_timeval.tv_usec); + if ((rstream->flags & IOSTREAM_RAWLOG_FLAG_BUFFERED) != 0) { + str_append_c(&buf, rstream->input ? 'I' : 'O'); + str_append_c(&buf, line_ends ? ':' : '>'); + str_append_c(&buf, ' '); + } + rawlog_write(rstream, buf.data, buf.used); +} + +void iostream_rawlog_init(struct rawlog_iostream *rstream, + enum iostream_rawlog_flags flags, bool input) +{ + rstream->flags = flags; + rstream->input = input; + if ((rstream->flags & IOSTREAM_RAWLOG_FLAG_BUFFERED) != 0) + rstream->buffer = buffer_create_dynamic(default_pool, 1024); +} + +static void +iostream_rawlog_write_unbuffered(struct rawlog_iostream *rstream, + const unsigned char *data, size_t size) +{ + size_t i, start; + + if (!rstream->line_continued) + rawlog_write_timestamp(rstream, TRUE); + + for (start = 0, i = 1; i < size; i++) { + if (data[i-1] == '\n') { + rawlog_write(rstream, data + start, i - start); + rawlog_write_timestamp(rstream, TRUE); + start = i; + } + } + if (start != size) + rawlog_write(rstream, data + start, size - start); + rstream->line_continued = data[size-1] != '\n'; } void iostream_rawlog_write(struct rawlog_iostream *rstream, const unsigned char *data, size_t size) { - size_t i, start; + const unsigned char *p; + size_t pos; + bool line_ends; i_assert(size > 0); io_loop_time_refresh(); - if (rstream->write_timestamp) - rawlog_write_timestamp(rstream); + if ((rstream->flags & IOSTREAM_RAWLOG_FLAG_BUFFERED) == 0) { + iostream_rawlog_write_unbuffered(rstream, data, size); + return; + } - for (start = 0, i = 1; i < size; i++) { - if (data[i-1] == '\n') { - rawlog_write(rstream, data + start, i - start); - rawlog_write_timestamp(rstream); - start = i; + do { + p = memchr(data, '\n', size); + if (p != NULL) { + line_ends = TRUE; + pos = p-data + 1; + } else if (rstream->buffer->used + size < RAWLOG_MAX_LINE_LEN) { + buffer_append(rstream->buffer, data, size); + return; + } else { + line_ends = FALSE; + pos = size; } - } - if (start != size) - rawlog_write(rstream, data + start, size - start); - rstream->write_timestamp = data[size-1] == '\n'; + + rawlog_write_timestamp(rstream, line_ends); + if (rstream->buffer->used > 0) { + rawlog_write(rstream, rstream->buffer->data, + rstream->buffer->used); + } + rawlog_write(rstream, data, pos); + + data += pos; + size -= pos; + } while (size > 0); } void iostream_rawlog_close(struct rawlog_iostream *rstream) { - if (rstream->autoclose_fd && rstream->rawlog_fd != -1) { + if ((rstream->flags & IOSTREAM_RAWLOG_FLAG_AUTOCLOSE) != 0 && + rstream->rawlog_fd != -1) { if (close(rstream->rawlog_fd) < 0) { i_error("rawlog_istream.close(%s) failed: %m", rstream->rawlog_path); @@ -73,31 +132,39 @@ } rstream->rawlog_fd = -1; i_free_and_null(rstream->rawlog_path); + if (rstream->buffer != NULL) + buffer_free(&rstream->buffer); } int iostream_rawlog_create(const char *dir, struct istream **input, struct ostream **output) { static unsigned int counter = 0; - const char *timestamp, *in_path, *out_path; + const char *timestamp, *prefix; + + timestamp = t_strflocaltime("%Y%m%d-%H%M%S", ioloop_time); + + counter++; + prefix = t_strdup_printf("%s/%s.%s.%u", dir, timestamp, my_pid, counter); + return iostream_rawlog_create_prefix(prefix, input, output); +} + +int iostream_rawlog_create_prefix(const char *prefix, struct istream **input, + struct ostream **output) +{ + const char *in_path, *out_path; struct istream *old_input; struct ostream *old_output; int in_fd, out_fd; - timestamp = t_strflocaltime("%Y%m%d-%H%M%S", ioloop_time); - - counter++; - in_path = t_strdup_printf("%s/%s.%s.%u.in", - dir, timestamp, my_pid, counter); - out_path = t_strdup_printf("%s/%s.%s.%u.out", - dir, timestamp, my_pid, counter); - + in_path = t_strdup_printf("%s.in", prefix); in_fd = open(in_path, O_CREAT | O_APPEND | O_WRONLY, 0600); if (in_fd == -1) { i_error("creat(%s) failed: %m", in_path); return -1; } + out_path = t_strdup_printf("%s.out", prefix); out_fd = open(out_path, O_CREAT | O_APPEND | O_WRONLY, 0600); if (out_fd == -1) { i_error("creat(%s) failed: %m", out_path); @@ -108,9 +175,37 @@ old_input = *input; old_output = *output; - *input = i_stream_create_rawlog(old_input, in_path, in_fd, TRUE); - *output = o_stream_create_rawlog(old_output, out_path, out_fd, TRUE); + *input = i_stream_create_rawlog(old_input, in_path, in_fd, + IOSTREAM_RAWLOG_FLAG_AUTOCLOSE); + *output = o_stream_create_rawlog(old_output, out_path, out_fd, + IOSTREAM_RAWLOG_FLAG_AUTOCLOSE); i_stream_unref(&old_input); o_stream_unref(&old_output); return 0; } + +int iostream_rawlog_create_path(const char *path, struct istream **input, + struct ostream **output) +{ + struct istream *old_input; + struct ostream *old_output; + int fd; + + fd = open(path, O_CREAT | O_APPEND | O_WRONLY, 0600); + if (fd == -1) { + i_error("creat(%s) failed: %m", path); + return -1; + } + + old_input = *input; + old_output = *output; + *input = i_stream_create_rawlog(old_input, path, fd, + IOSTREAM_RAWLOG_FLAG_AUTOCLOSE | + IOSTREAM_RAWLOG_FLAG_BUFFERED); + *output = o_stream_create_rawlog(old_output, path, fd, + IOSTREAM_RAWLOG_FLAG_AUTOCLOSE | + IOSTREAM_RAWLOG_FLAG_BUFFERED); + i_stream_unref(&old_input); + o_stream_unref(&old_output); + return 0; +} diff -r fff00bb85ae4 -r 8ce6d41d2d41 src/lib/iostream-rawlog.h --- a/src/lib/iostream-rawlog.h Wed Aug 29 16:12:08 2012 +0300 +++ b/src/lib/iostream-rawlog.h Wed Aug 29 16:18:56 2012 +0300 @@ -1,8 +1,17 @@ #ifndef IOSTREAM_RAWLOG_H #define IOSTREAM_RAWLOG_H +/* Create rawlog *.in and *.out files to the given directory. */ int ATTR_NOWARN_UNUSED_RESULT iostream_rawlog_create(const char *dir, struct istream **input, struct ostream **output); +/* Create rawlog prefix.in and prefix.out files. */ +int ATTR_NOWARN_UNUSED_RESULT +iostream_rawlog_create_prefix(const char *prefix, struct istream **input, + struct ostream **output); +/* Create rawlog path, writing both input and output to the same file. */ +int ATTR_NOWARN_UNUSED_RESULT +iostream_rawlog_create_path(const char *path, struct istream **input, + struct ostream **output); #endif diff -r fff00bb85ae4 -r 8ce6d41d2d41 src/lib/istream-rawlog.c --- a/src/lib/istream-rawlog.c Wed Aug 29 16:12:08 2012 +0300 +++ b/src/lib/istream-rawlog.c Wed Aug 29 16:18:56 2012 +0300 @@ -71,7 +71,7 @@ struct istream * i_stream_create_rawlog(struct istream *input, const char *rawlog_path, - int rawlog_fd, bool autoclose_fd) + int rawlog_fd, enum iostream_rawlog_flags flags) From dovecot at dovecot.org Wed Aug 29 16:45:37 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 16:45:37 +0300 Subject: dovecot-2.2: iostream_rawlog_create_path(): Avoid double-closing... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/407ea0cd54ee changeset: 14968:407ea0cd54ee user: Timo Sirainen date: Wed Aug 29 16:45:25 2012 +0300 description: iostream_rawlog_create_path(): Avoid double-closing the rawlog fd diffstat: src/lib/iostream-rawlog.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diffs (11 lines): diff -r 8ce6d41d2d41 -r 407ea0cd54ee src/lib/iostream-rawlog.c --- a/src/lib/iostream-rawlog.c Wed Aug 29 16:18:56 2012 +0300 +++ b/src/lib/iostream-rawlog.c Wed Aug 29 16:45:25 2012 +0300 @@ -200,7 +200,6 @@ old_input = *input; old_output = *output; *input = i_stream_create_rawlog(old_input, path, fd, - IOSTREAM_RAWLOG_FLAG_AUTOCLOSE | IOSTREAM_RAWLOG_FLAG_BUFFERED); *output = o_stream_create_rawlog(old_output, path, fd, IOSTREAM_RAWLOG_FLAG_AUTOCLOSE | From dovecot at dovecot.org Wed Aug 29 16:55:44 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 16:55:44 +0300 Subject: dovecot-2.2: imap CATENATE: Do one more mailbox_save_continue() ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/bce550bb2b23 changeset: 14969:bce550bb2b23 user: Timo Sirainen date: Wed Aug 29 16:55:33 2012 +0300 description: imap CATENATE: Do one more mailbox_save_continue() after adding EOF to stream. Fixes a crash with external mail attachments (mail_attachment_dir). diffstat: src/imap/cmd-append.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diffs (17 lines): diff -r 407ea0cd54ee -r bce550bb2b23 src/imap/cmd-append.c --- a/src/imap/cmd-append.c Wed Aug 29 16:45:25 2012 +0300 +++ b/src/imap/cmd-append.c Wed Aug 29 16:55:33 2012 +0300 @@ -353,7 +353,12 @@ i_stream_unref(&ctx->input); ctx->catenate = FALSE; - if (mailbox_save_finish(&ctx->save_ctx) < 0) { + /* do mailbox_save_continue() once more after appending EOF, + to finish any pending reads */ + if (mailbox_save_continue(ctx->save_ctx) < 0) { + mailbox_save_cancel(&ctx->save_ctx); + ctx->failed = TRUE; + } else if (mailbox_save_finish(&ctx->save_ctx) < 0) { ctx->failed = TRUE; client_send_storage_error(cmd, ctx->storage); } From dovecot at dovecot.org Wed Aug 29 17:15:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 17:15:40 +0300 Subject: dovecot-2.2: dbox: Don't try to finish saving attachments if sav... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8ee60c857513 changeset: 14970:8ee60c857513 user: Timo Sirainen date: Wed Aug 29 17:15:34 2012 +0300 description: dbox: Don't try to finish saving attachments if saving has already failed. Fixes an assert crash with failed CATENATE. diffstat: src/lib-storage/index/dbox-common/dbox-save.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r bce550bb2b23 -r 8ee60c857513 src/lib-storage/index/dbox-common/dbox-save.c --- a/src/lib-storage/index/dbox-common/dbox-save.c Wed Aug 29 16:55:33 2012 +0300 +++ b/src/lib-storage/index/dbox-common/dbox-save.c Wed Aug 29 17:15:34 2012 +0300 @@ -102,7 +102,7 @@ struct mail_save_data *mdata = &ctx->ctx.data; struct ostream *dbox_output = ctx->dbox_output; - if (mdata->attach != NULL) { + if (mdata->attach != NULL && !ctx->failed) { if (index_attachment_save_finish(&ctx->ctx) < 0) ctx->failed = TRUE; } From dovecot at dovecot.org Wed Aug 29 18:35:13 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 18:35:13 +0300 Subject: dovecot-2.2: imap: Added asserts to make sure a tagline isn't se... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/075dcb7eac58 changeset: 14971:075dcb7eac58 user: Timo Sirainen date: Wed Aug 29 18:32:01 2012 +0300 description: imap: Added asserts to make sure a tagline isn't sent twice to the same command. diffstat: src/imap/imap-client.c | 3 +++ src/imap/imap-client.h | 1 + 2 files changed, 4 insertions(+), 0 deletions(-) diffs (24 lines): diff -r 8ee60c857513 -r 075dcb7eac58 src/imap/imap-client.c --- a/src/imap/imap-client.c Wed Aug 29 17:15:34 2012 +0300 +++ b/src/imap/imap-client.c Wed Aug 29 18:32:01 2012 +0300 @@ -340,6 +340,9 @@ if (client->output->closed || cmd->cancel) return; + i_assert(!cmd->tagline_sent); + cmd->tagline_sent = TRUE; + if (tag == NULL || *tag == '\0') tag = "*"; diff -r 8ee60c857513 -r 075dcb7eac58 src/imap/imap-client.h --- a/src/imap/imap-client.h Wed Aug 29 17:15:34 2012 +0300 +++ b/src/imap/imap-client.h Wed Aug 29 18:32:01 2012 +0300 @@ -79,6 +79,7 @@ unsigned int search_save_result:1; /* search result is being updated */ unsigned int search_save_result_used:1; /* command uses search save */ unsigned int temp_executed:1; /* temporary execution state tracking */ + unsigned int tagline_sent:1; }; struct imap_client_vfuncs { From dovecot at dovecot.org Wed Aug 29 18:35:13 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 18:35:13 +0300 Subject: dovecot-2.2: imap: Various fixes to APPEND error handling. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/20ad509a559a changeset: 14972:20ad509a559a user: Timo Sirainen date: Wed Aug 29 18:32:13 2012 +0300 description: imap: Various fixes to APPEND error handling. diffstat: src/imap/cmd-append.c | 240 +++++++++++++++++++++++-------------------------- 1 files changed, 112 insertions(+), 128 deletions(-) diffs (truncated from 521 to 300 lines): diff -r 075dcb7eac58 -r 20ad509a559a src/imap/cmd-append.c --- a/src/imap/cmd-append.c Wed Aug 29 18:32:01 2012 +0300 +++ b/src/imap/cmd-append.c Wed Aug 29 18:32:13 2012 +0300 @@ -50,7 +50,7 @@ static void cmd_append_finish(struct cmd_append_context *ctx); static bool cmd_append_continue_message(struct client_command_context *cmd); -static bool cmd_append_continue_parsing(struct client_command_context *cmd); +static bool cmd_append_parse_new_msg(struct client_command_context *cmd); static const char *get_disconnect_reason(struct cmd_append_context *ctx) { @@ -147,56 +147,6 @@ mailbox_free(&ctx->box); } -static bool cmd_append_continue_cancel(struct client_command_context *cmd) -{ - struct cmd_append_context *ctx = cmd->context; - - if (cmd->cancel) { - cmd_append_finish(ctx); - return TRUE; - } - - (void)i_stream_read(ctx->litinput); - i_stream_skip(ctx->litinput, i_stream_get_data_size(ctx->litinput)); - - if (cmd->client->input->closed) { - cmd_append_finish(ctx); - return TRUE; - } - - if (ctx->litinput->v_offset == ctx->literal_size) { - /* finished, but with MULTIAPPEND and LITERAL+ we may get - more messages. */ - i_stream_unref(&ctx->litinput); - - ctx->message_input = FALSE; - imap_parser_reset(ctx->save_parser); - cmd->func = cmd_append_continue_parsing; - return cmd_append_continue_parsing(cmd); - } - - return FALSE; -} - -static bool cmd_append_cancel(struct cmd_append_context *ctx, bool nonsync) -{ - ctx->failed = TRUE; - - if (!nonsync) { - cmd_append_finish(ctx); - return TRUE; - } - - /* we have to read the nonsynced literal so we don't treat the message - data as commands. */ - ctx->litinput = i_stream_create_limit(ctx->client->input, ctx->literal_size); - - ctx->message_input = TRUE; - ctx->cmd->func = cmd_append_continue_cancel; - ctx->cmd->context = ctx; - return cmd_append_continue_cancel(ctx->cmd); -} - static int cmd_append_catenate_url(struct client_command_context *cmd, const char *caturl) { @@ -207,6 +157,9 @@ const char *error; int ret; + if (ctx->failed) + return -1; + ret = imap_msgpart_url_parse(cmd->client->user, cmd->client->mailbox, caturl, &mpurl, &error); if (ret < 0) { @@ -275,24 +228,22 @@ return ret; } -static int cmd_append_catenate_text(struct client_command_context *cmd) +static void cmd_append_catenate_text(struct client_command_context *cmd) { struct cmd_append_context *ctx = cmd->context; - uoff_t newsize; - newsize = ctx->cat_msg_size + ctx->literal_size; - if (newsize < ctx->cat_msg_size) { + if (ctx->literal_size > (uoff_t)-1 - ctx->cat_msg_size && + !ctx->failed) { client_send_tagline(cmd, "NO [TOOBIG] Composed message grows too big."); - return -1; + ctx->failed = TRUE; } /* save the mail */ - ctx->cat_msg_size = newsize; + ctx->cat_msg_size += ctx->literal_size; ctx->litinput = i_stream_create_limit(cmd->client->input, ctx->literal_size); i_stream_chain_append(ctx->catchain, ctx->litinput); - return 0; } static int @@ -304,9 +255,6 @@ *nonsync_r = FALSE; - if (ctx->failed) - return -1; - /* Handle URLs until a TEXT literal is encountered */ while (imap_arg_get_atom(args, &catpart)) { const char *caturl; @@ -316,21 +264,26 @@ args++; if (!imap_arg_get_astring(args, &caturl)) break; - if (cmd_append_catenate_url(cmd, caturl) < 0) - return -1; + if (cmd_append_catenate_url(cmd, caturl) < 0) { + /* delay failure until we can stop + parsing input */ + ctx->failed = TRUE; + } } else if (strcasecmp(catpart, "TEXT") == 0) { /* TEXT */ args++; if (!imap_arg_get_literal_size(args, &ctx->literal_size)) break; - if (args->literal8 && !ctx->binary_input) { + if (args->literal8 && !ctx->binary_input && + !ctx->failed) { client_send_tagline(cmd, "NO ["IMAP_RESP_CODE_UNKNOWN_CTE"] " "Binary input allowed only when the first part is binary."); - return -1; + ctx->failed = TRUE; } *nonsync_r = args->type == IMAP_ARG_LITERAL_SIZE_NONSYNC; - return cmd_append_catenate_text(cmd) < 0 ? -1 : 1; + cmd_append_catenate_text(cmd); + return 1; } else { break; } @@ -342,6 +295,7 @@ return 0; } client_send_command_error(cmd, "Invalid arguments."); + cmd->client->input_skip_line = TRUE; return -1; } @@ -352,15 +306,19 @@ i_stream_chain_append_eof(ctx->catchain); i_stream_unref(&ctx->input); ctx->catenate = FALSE; + ctx->catchain = NULL; - /* do mailbox_save_continue() once more after appending EOF, - to finish any pending reads */ - if (mailbox_save_continue(ctx->save_ctx) < 0) { - mailbox_save_cancel(&ctx->save_ctx); - ctx->failed = TRUE; - } else if (mailbox_save_finish(&ctx->save_ctx) < 0) { - ctx->failed = TRUE; - client_send_storage_error(cmd, ctx->storage); + if (ctx->save_ctx == NULL) { + /* APPEND has already failed */ + i_assert(ctx->failed); + } else { + /* do mailbox_save_continue() once more after appending EOF, + to finish any pending reads */ + (void)mailbox_save_continue(ctx->save_ctx); + if (mailbox_save_finish(&ctx->save_ctx) < 0) { + client_send_storage_error(cmd, ctx->storage); + ctx->failed = TRUE; + } } } @@ -374,22 +332,22 @@ int ret; if (cmd->cancel) { + /* cancel the command immediately (disconnection) */ cmd_append_finish(ctx); return TRUE; } + /* we're parsing inside CATENATE (..) list after handling a TEXT part */ ret = imap_parser_read_args(ctx->save_parser, 0, IMAP_PARSE_FLAG_LITERAL_SIZE | IMAP_PARSE_FLAG_LITERAL8 | IMAP_PARSE_FLAG_INSIDE_LIST, &args); if (ret == -1) { - if (!ctx->failed) { - msg = imap_parser_get_error(ctx->save_parser, &fatal); - if (fatal) - client_disconnect_with_error(client, msg); - else - client_send_command_error(cmd, msg); - } + msg = imap_parser_get_error(ctx->save_parser, &fatal); + if (fatal) + client_disconnect_with_error(client, msg); + else if (!ctx->failed) + client_send_command_error(cmd, msg); client->input_skip_line = TRUE; cmd_append_finish(ctx); return TRUE; @@ -400,8 +358,9 @@ } if ((ret = cmd_append_catenate(cmd, args, &nonsync)) < 0) { - client->input_skip_line = TRUE; - return cmd_append_cancel(ctx, nonsync); + /* invalid parameters, abort immediately */ + cmd_append_finish(ctx); + return TRUE; } if (ret == 0) { @@ -410,8 +369,8 @@ /* last catenate part */ imap_parser_reset(ctx->save_parser); - cmd->func = cmd_append_continue_parsing; - return cmd_append_continue_parsing(cmd); + cmd->func = cmd_append_parse_new_msg; + return cmd_append_parse_new_msg(cmd); } /* TEXT */ @@ -420,12 +379,18 @@ client->input_skip_line = TRUE; if (!nonsync) { + if (ctx->failed) { + /* tagline was already sent, we can abort here */ + cmd_append_finish(ctx); + return TRUE; + } o_stream_nsend(client->output, "+ OK\r\n", 6); o_stream_nflush(client->output); o_stream_uncork(client->output); o_stream_cork(client->output); } + i_assert(ctx->litinput != NULL); ctx->message_input = TRUE; cmd->func = cmd_append_continue_message; return cmd_append_continue_message(cmd); @@ -462,6 +427,7 @@ (*args)++; } + /* | CATENATE (..) */ valid = FALSE; *nonsync_r = FALSE; ctx->catenate = FALSE; @@ -485,17 +451,15 @@ if (!valid) { client->input_skip_line = TRUE; - client_send_command_error(cmd, "Invalid arguments."); + if (!ctx->failed) + client_send_command_error(cmd, "Invalid arguments."); return -1; } - if (ctx->failed) { - /* we failed earlier, make sure we just eat nonsync-literal - if it's given. */ - return -1; - } - - if (flags_list != NULL) { + if (flags_list == NULL || ctx->failed) { + flags = 0; + keywords = NULL; + } else { if (!client_parse_mail_flags(cmd, flags_list, &flags, &keywords_list)) return -1; @@ -503,21 +467,19 @@ keywords = NULL; else if (mailbox_keywords_create(ctx->box, keywords_list, &keywords) < 0) { + /* invalid keywords - delay failure */ client_send_storage_error(cmd, ctx->storage); - return -1; + ctx->failed = TRUE; } From dovecot at dovecot.org Wed Aug 29 18:35:13 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 18:35:13 +0300 Subject: dovecot-2.2: imap: Send BAD replies with client_send_command_err... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3f83a27a72b8 changeset: 14973:3f83a27a72b8 user: Timo Sirainen date: Wed Aug 29 18:34:43 2012 +0300 description: imap: Send BAD replies with client_send_command_error() diffstat: src/imap/cmd-cancelupdate.c | 4 ++-- src/imap/cmd-uid.c | 4 ++-- src/imap/imap-commands-util.c | 5 ++--- src/imap/imap-status.c | 4 ++-- 4 files changed, 8 insertions(+), 9 deletions(-) diffs (62 lines): diff -r 20ad509a559a -r 3f83a27a72b8 src/imap/cmd-cancelupdate.c --- a/src/imap/cmd-cancelupdate.c Wed Aug 29 18:32:13 2012 +0300 +++ b/src/imap/cmd-cancelupdate.c Wed Aug 29 18:34:43 2012 +0300 @@ -29,13 +29,13 @@ for (i = 0; args[i].type == IMAP_ARG_STRING; i++) ; if (!IMAP_ARG_IS_EOL(&args[i]) || i == 0) { - client_send_tagline(cmd, "BAD Invalid parameters."); + client_send_command_error(cmd, "Invalid parameters."); return TRUE; } while (imap_arg_get_quoted(args, &tag)) { if (!client_search_update_cancel(cmd->client, tag)) { - client_send_tagline(cmd, "BAD Unknown tag."); + client_send_tagline(cmd, "NO Unknown tag."); return TRUE; } args++; diff -r 20ad509a559a -r 3f83a27a72b8 src/imap/cmd-uid.c --- a/src/imap/cmd-uid.c Wed Aug 29 18:32:13 2012 +0300 +++ b/src/imap/cmd-uid.c Wed Aug 29 18:34:43 2012 +0300 @@ -15,8 +15,8 @@ command = command_find(t_strconcat("UID ", cmd_name, NULL)); if (command == NULL) { - client_send_tagline(cmd, t_strconcat( - "BAD Unknown UID command ", cmd_name, NULL)); + client_send_command_error(cmd, t_strconcat( + "Unknown UID command ", cmd_name, NULL)); return TRUE; } diff -r 20ad509a559a -r 3f83a27a72b8 src/imap/imap-commands-util.c --- a/src/imap/imap-commands-util.c Wed Aug 29 18:32:13 2012 +0300 +++ b/src/imap/imap-commands-util.c Wed Aug 29 18:34:43 2012 +0300 @@ -218,9 +218,8 @@ if (flag != 0 && flag != MAIL_RECENT) *flags_r |= flag; else { - client_send_tagline(cmd, t_strconcat( - "BAD Invalid system flag ", - atom, NULL)); + client_send_command_error(cmd, t_strconcat( + "Invalid system flag ", atom, NULL)); return FALSE; } } else { diff -r 20ad509a559a -r 3f83a27a72b8 src/imap/imap-status.c --- a/src/imap/imap-status.c Wed Aug 29 18:32:13 2012 +0300 +++ b/src/imap/imap-status.c Wed Aug 29 18:34:43 2012 +0300 @@ -46,8 +46,8 @@ else if (strcmp(item, "X-GUID") == 0) metadata |= MAILBOX_METADATA_GUID; else { - client_send_tagline(cmd, t_strconcat( - "BAD Invalid status item ", item, NULL)); + client_send_command_error(cmd, t_strconcat( + "Invalid status item ", item, NULL)); return -1; } } From dovecot at dovecot.org Wed Aug 29 19:07:54 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 19:07:54 +0300 Subject: dovecot-2.2: imap: More APPEND error handling fixes. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/bfd4e6e08f72 changeset: 14974:bfd4e6e08f72 user: Timo Sirainen date: Wed Aug 29 19:07:47 2012 +0300 description: imap: More APPEND error handling fixes. diffstat: src/imap/cmd-append.c | 13 +++++++++---- 1 files changed, 9 insertions(+), 4 deletions(-) diffs (38 lines): diff -r 3f83a27a72b8 -r bfd4e6e08f72 src/imap/cmd-append.c --- a/src/imap/cmd-append.c Wed Aug 29 18:34:43 2012 +0300 +++ b/src/imap/cmd-append.c Wed Aug 29 19:07:47 2012 +0300 @@ -294,7 +294,8 @@ /* ")" */ return 0; } - client_send_command_error(cmd, "Invalid arguments."); + if (!ctx->failed) + client_send_command_error(cmd, "Invalid arguments."); cmd->client->input_skip_line = TRUE; return -1; } @@ -308,9 +309,10 @@ ctx->catenate = FALSE; ctx->catchain = NULL; - if (ctx->save_ctx == NULL) { + if (ctx->failed) { /* APPEND has already failed */ - i_assert(ctx->failed); + if (ctx->save_ctx != NULL) + mailbox_save_cancel(&ctx->save_ctx); } else { /* do mailbox_save_continue() once more after appending EOF, to finish any pending reads */ @@ -730,7 +732,10 @@ /* finished */ i_stream_unref(&ctx->litinput); - if (ctx->save_ctx == NULL) { + if (ctx->failed) { + if (ctx->save_ctx != NULL) + mailbox_save_cancel(&ctx->save_ctx); + } else if (ctx->save_ctx == NULL) { /* failed above */ client_send_storage_error(cmd, ctx->storage); ctx->failed = TRUE; From dovecot at dovecot.org Wed Aug 29 20:00:22 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 20:00:22 +0300 Subject: dovecot-2.2: istream-chain: Unreference also the last stream whe... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/03e0b100243d changeset: 14975:03e0b100243d user: Timo Sirainen date: Wed Aug 29 19:59:42 2012 +0300 description: istream-chain: Unreference also the last stream when it reaches EOF. diffstat: src/lib/istream-chain.c | 41 ++++++++++++++++------------------------- 1 files changed, 16 insertions(+), 25 deletions(-) diffs (90 lines): diff -r bfd4e6e08f72 -r 03e0b100243d src/lib/istream-chain.c --- a/src/lib/istream-chain.c Wed Aug 29 19:07:47 2012 +0300 +++ b/src/lib/istream-chain.c Wed Aug 29 19:59:42 2012 +0300 @@ -10,8 +10,8 @@ struct istream_chain_link { struct istream_chain_link *prev, *next; - uoff_t start_offset; struct istream *stream; + bool eof; }; struct istream_chain { @@ -39,11 +39,10 @@ link = i_new(struct istream_chain_link, 1); link->stream = stream; + link->eof = stream == NULL; - if (stream != NULL) { + if (stream != NULL) i_stream_ref(stream); - link->start_offset = stream->v_offset; - } if (chain->head == NULL && stream != NULL) { if (chain->stream->istream.max_buffer_size == 0) { @@ -113,9 +112,10 @@ DLLIST2_REMOVE(&cstream->chain.head, &cstream->chain.tail, link); i_free(link); + /* a) we have more streams, b) we have EOF, c) we need to wait + for more streams */ link = cstream->chain.head; - i_assert(link == NULL || link->stream != NULL); - if (link != NULL) + if (link != NULL && link->stream != NULL) i_stream_seek(link->stream, 0); /* we already verified that the data size is less than the @@ -142,9 +142,8 @@ const unsigned char *data; size_t size, pos, cur_pos, bytes_skipped; ssize_t ret; - bool last_stream; - if (link != NULL && link->stream == NULL) { + if (link != NULL && link->eof) { stream->istream.eof = TRUE; return -1; } @@ -183,29 +182,21 @@ /* need to read more */ i_assert(cur_pos == pos); ret = i_stream_read(link->stream); - if (ret == -2 || ret == 0) { + if (ret == -2 || ret == 0) return ret; - } - if (ret == -1 && link->stream->stream_errno != 0) { - stream->istream.stream_errno = - link->stream->stream_errno; - return -1; - } - - /* we either read something or we're at EOF */ - last_stream = link->next != NULL && link->next->stream == NULL; - if (ret == -1 && !last_stream) { - if (stream->pos >= stream->max_buffer_size) - return -2; - + if (ret == -1) { + if (link->stream->stream_errno != 0) { + stream->istream.stream_errno = + link->stream->stream_errno; + return -1; + } + /* EOF of this stream, go to next stream */ i_stream_chain_read_next(cstream); cstream->prev_skip = stream->skip; return i_stream_chain_read(stream); } - - stream->istream.eof = link->stream->eof && last_stream; - i_assert(ret != -1 || stream->istream.eof); + /* we read something */ data = i_stream_get_data(link->stream, &pos); } From dovecot at dovecot.org Wed Aug 29 20:00:22 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 20:00:22 +0300 Subject: dovecot-2.2: imap: CATENATE fix Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8d95535af98e changeset: 14976:8d95535af98e user: Timo Sirainen date: Wed Aug 29 20:00:03 2012 +0300 description: imap: CATENATE fix diffstat: src/imap/cmd-append.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diffs (16 lines): diff -r 03e0b100243d -r 8d95535af98e src/imap/cmd-append.c --- a/src/imap/cmd-append.c Wed Aug 29 19:59:42 2012 +0300 +++ b/src/imap/cmd-append.c Wed Aug 29 20:00:03 2012 +0300 @@ -729,7 +729,11 @@ if (ctx->litinput->eof || client->input->closed) { bool all_written = ctx->litinput->v_offset == ctx->literal_size; - /* finished */ + /* finished - do one more read, to make sure istream-chain + unreferences its stream, which is needed for litinput's + unreferencing to seek the client->input to correct + position */ + (void)i_stream_read(ctx->input); i_stream_unref(&ctx->litinput); if (ctx->failed) { From dovecot at dovecot.org Wed Aug 29 20:16:18 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 20:16:18 +0300 Subject: dovecot-2.2: imap: Fixed crashes in THREAD=ORDEREDSUBJECT Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1309de301a2e changeset: 14977:1309de301a2e user: Timo Sirainen date: Wed Aug 29 20:16:13 2012 +0300 description: imap: Fixed crashes in THREAD=ORDEREDSUBJECT diffstat: src/imap/cmd-thread.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) diffs (33 lines): diff -r 8d95535af98e -r 1309de301a2e src/imap/cmd-thread.c --- a/src/imap/cmd-thread.c Wed Aug 29 20:00:03 2012 +0300 +++ b/src/imap/cmd-thread.c Wed Aug 29 20:16:13 2012 +0300 @@ -178,7 +178,8 @@ const struct orderedsubject_thread *thread; struct orderedsubject_thread *cur_thread = NULL; uint32_t num; - int ret; + bool reply_or_fw; + int ret, tz; prev_subject = str_new(default_pool, 128); @@ -193,7 +194,8 @@ subject = ""; T_BEGIN { base_subject = imap_get_base_subject_cased( - pool_datastack_create(), subject, NULL); + pool_datastack_create(), subject, + &reply_or_fw); if (strcmp(str_c(prev_subject), base_subject) != 0) { /* thread changed */ cur_thread = NULL; @@ -206,7 +208,8 @@ /* starting a new thread. get the first message's date */ cur_thread = array_append_space(&threads); - if (mail_get_date(mail, &cur_thread->timestamp, NULL) == 0 && + if (mail_get_date(mail, &cur_thread->timestamp, + &tz) == 0 && cur_thread->timestamp == 0) { (void)mail_get_received_date(mail, &cur_thread->timestamp); From pigeonhole at rename-it.nl Wed Aug 29 20:35:25 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Wed, 29 Aug 2012 19:35:25 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: fixed edit-mail istream to wo... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/061d4993b509 changeset: 1658:061d4993b509 user: Stephan Bosch date: Wed Aug 29 19:35:17 2012 +0200 description: lib-sieve: fixed edit-mail istream to work with latest Dovecot. Testsuite failed with an assertion, because the stream returned -2 at an unexpected time. I've restructured the buffering implementation to prevent this. The testsuite succeeds now, but this needs to be tested more thoroughly. diffstat: src/lib-sieve/edit-mail.c | 248 ++++++++++++++++++++++++++++++++++----------- 1 files changed, 188 insertions(+), 60 deletions(-) diffs (truncated from 325 to 300 lines): diff -r 0eafbad49e41 -r 061d4993b509 src/lib-sieve/edit-mail.c --- a/src/lib-sieve/edit-mail.c Tue Aug 28 23:07:36 2012 +0200 +++ b/src/lib-sieve/edit-mail.c Wed Aug 29 19:35:17 2012 +0200 @@ -1466,7 +1466,7 @@ struct _header_field_index *cur_header; - unsigned int read_header; + unsigned int header_read:1; }; static void edit_mail_istream_destroy(struct iostream_private *stream) @@ -1478,17 +1478,146 @@ pool_unref(&edstream->pool); } +static ssize_t merge_from_parent +(struct edit_mail_istream *edstream, uoff_t parent_v_offset, + uoff_t parent_end_v_offset, uoff_t copy_v_offset) +{ + struct istream_private *stream = &edstream->istream; + uoff_t v_offset = stream->istream.v_offset; + buffer_t *buffer = edstream->buffer; + const unsigned char *data; + size_t pos, cur_pos; + ssize_t ret; + + if (v_offset < copy_v_offset) { + i_assert(stream->skip == 0); + if (buffer->used < copy_v_offset - v_offset) { + copy_v_offset = v_offset + buffer->used; + } + } + + /* If we are still merging it with our local buffer, we need to update the + * parent seek offset to point to where we left of. + */ + if (v_offset < copy_v_offset) { + parent_v_offset += buffer->used - (copy_v_offset - v_offset) + stream->pos; + if (parent_v_offset >= parent_end_v_offset) + return 0; + cur_pos = 0; + } else { + buffer_set_used_size(buffer, 0); + stream->pos -= stream->skip; + stream->skip = 0; + cur_pos = stream->pos; + } + + i_stream_seek(stream->parent, parent_v_offset); + + /* Read from parent */ + data = i_stream_get_data(stream->parent, &pos); + if (pos > cur_pos) + ret = 0; + else do { + if ((ret = i_stream_read(stream->parent)) == -2) + return -2; + + stream->istream.stream_errno = stream->parent->stream_errno; + stream->istream.eof = stream->parent->eof; + data = i_stream_get_data(stream->parent, &pos); + /* check again, in case the parent stream had been seeked + backwards and the previous read() didn't get us far + enough. */ + } while (pos <= cur_pos && ret > 0); + + /* Don't read beyond parent end offset */ + if (pos > (parent_end_v_offset - parent_v_offset)) + pos = parent_end_v_offset - parent_v_offset; + + if (v_offset < copy_v_offset) { + /* Merging with our local buffer; copying data from parent */ + if (pos > 0) { + ret = (ssize_t)(pos); + buffer_append(buffer, data, pos); + stream->buffer = buffer_get_data(buffer, &pos); + i_assert(ret > 0); + stream->pos = pos; + } else { + ret = (ret == 0 ? 0 : -1); + } + } else { + /* Just passing buffers from parent; no copying */ + ret = pos > stream->pos ? (ssize_t)(pos - stream->pos) : + (ret == 0 ? 0 : -1); + stream->buffer = data; + stream->pos = pos; + } + + i_assert(ret != -1 || stream->istream.eof || + stream->istream.stream_errno != 0); + return ret; +} + +static ssize_t merge_modified_headers(struct edit_mail_istream *edstream) +{ + struct istream_private *stream = &edstream->istream; + struct edit_mail *edmail = edstream->mail; + size_t pos; + ssize_t ret = 0; + + if (edstream->cur_header != NULL) { + /* Merge remaining parent buffer, if any */ + if (edstream->buffer->used == 0 && stream->skip < stream->pos ) { + buffer_append(edstream->buffer, + stream->buffer + stream->skip, stream->pos - stream->skip); + } + + /* Add modified headers to buffer */ + while ( edstream->cur_header != NULL && edstream->buffer->used < 1024 ) { + buffer_append(edstream->buffer, edstream->cur_header->field->data, + edstream->cur_header->field->size); + + edstream->cur_header = edstream->cur_header->next; + + /* Stop at end of prepended headers if original header is left unparsed */ + if ( !edmail->headers_parsed + && edstream->cur_header == edmail->header_fields_appended ) + edstream->cur_header = NULL; + } + + if ( edstream->buffer->used > 0 ) { + /* Output current buffer */ + stream->buffer = buffer_get_data(edstream->buffer, &pos); + ret = (ssize_t)pos + stream->skip - stream->pos; + i_assert( ret >= 0 ); + stream->pos = pos; + stream->skip = 0; + + if ( ret != 0 ) + return ret; + + if ( edstream->buffer->used >= 1024 ) + return -2; + } + } + return 0; +} + static ssize_t edit_mail_istream_read(struct istream_private *stream) { struct edit_mail_istream *edstream = (struct edit_mail_istream *)stream; struct edit_mail *edmail = edstream->mail; - uoff_t parent_v_offset, hdr_size, v_offset = stream->istream.v_offset; - size_t pos; + uoff_t parent_v_offset, parent_end_v_offset, copy_v_offset; + uoff_t v_offset = stream->istream.v_offset; + uoff_t prep_hdr_size, hdr_size; ssize_t ret = 0; + if (stream->istream.eof) + return -1; + if ( edstream->buffer->used > 0 ) { if ( stream->skip > 0 ) { + /* Remove skipped data from buffer */ buffer_copy (edstream->buffer, 0, edstream->buffer, stream->skip, (size_t)-1); stream->pos -= stream->skip; @@ -1497,93 +1626,88 @@ } } - if ( edstream->buffer->used > 0 || stream->pos - stream->skip == 0 ) { - if ( edstream->cur_header != NULL ) { - while ( edstream->cur_header != NULL && edstream->buffer->used < 1024 ) { - buffer_append(edstream->buffer, edstream->cur_header->field->data, - edstream->cur_header->field->size); - - edstream->cur_header = edstream->cur_header->next; - - if ( !edmail->headers_parsed - && edstream->cur_header == edmail->header_fields_appended ) - edstream->cur_header = NULL; - } - } + /* Merge prepended headers */ + if (edstream->cur_header != NULL) { + if ( (ret=merge_modified_headers(edstream)) != 0 ) + return ret; } - if ( edstream->buffer->used > 0 ) { - stream->buffer = buffer_get_data(edstream->buffer, &pos); - ret = (ssize_t)pos + stream->skip - stream->pos; - i_assert( ret >= 0 ); - stream->pos = pos; - stream->skip = 0; - - if ( ret == 0 ) - return -2; - - return ret; - } - - if ( !edmail->headers_parsed && edmail->header_fields_appended != NULL ) { + if ( !edmail->headers_parsed && !edstream->header_read && + edmail->header_fields_appended != NULL ) { /* Output headers from original stream */ - /* At what offset does the header end (not including LF of final empty line) + /* Size of the prepended header */ + prep_hdr_size = edmail->hdr_size.physical_size - + edmail->appended_hdr_size.physical_size; + + /* Offset of header end or appended header * Any final CR is dealt with later */ - hdr_size = edmail->wrapped_hdr_size.physical_size + - edmail->hdr_size.physical_size - - edmail->appended_hdr_size.physical_size - 1; + hdr_size = prep_hdr_size + edmail->wrapped_hdr_size.physical_size; - if ( v_offset < hdr_size ) { + if ( v_offset < hdr_size - 1 ) { parent_v_offset = stream->parent_start_offset + - (v_offset + edmail->appended_hdr_size.physical_size - - edmail->hdr_size.physical_size); + (v_offset - prep_hdr_size); + parent_end_v_offset = stream->parent_start_offset + + edmail->wrapped_hdr_size.physical_size - 1; + copy_v_offset = prep_hdr_size; - i_stream_seek(stream->parent, parent_v_offset); - - if ( (ret=i_stream_read_copy_from_parent(&stream->istream)) < 0 ) + if ( (ret=merge_from_parent(edstream, parent_v_offset, + parent_end_v_offset, copy_v_offset)) < 0 ) { return ret; + } if ( stream->pos >= hdr_size - 1 - v_offset ) { - /* Truncate buffer from original mail strictly to header */ - ret -= stream->pos - (hdr_size - v_offset); - stream->pos = hdr_size - v_offset; - /* Strip final CR too when it is present */ if ( stream->buffer[stream->pos-1] == '\r' ) { stream->pos--; ret--; + if (edstream->buffer->used > 0) + buffer_set_used_size(edstream->buffer, edstream->buffer->used-1); } i_assert(ret >= 0); + edstream->header_read = TRUE; edstream->cur_header = edmail->header_fields_appended; - if ( ret == 0 ) - return -2; } - return ret; + if (ret != 0) + return ret; + } + + /* Merge Appended headers */ + if (edstream->cur_header != NULL) { + if ( (ret=merge_modified_headers(edstream)) != 0 ) + return ret; } } - if ( !edmail->headers_parsed ) { - if ( v_offset < edmail->hdr_size.physical_size ) - return -2; + /* Header does not come from original mail at all */ + if ( edmail->headers_parsed ) { + parent_v_offset = stream->parent_start_offset + + (v_offset - edmail->hdr_size.physical_size) + + edmail->wrapped_hdr_size.physical_size - ( edmail->eoh_crlf ? 2 : 1); + copy_v_offset = edmail->hdr_size.physical_size; + /* Header comes partially from original mail and headers are added between + header and body. + */ + } else if (edmail->header_fields_appended != NULL) { + parent_v_offset = stream->parent_start_offset + + (v_offset - edmail->hdr_size.physical_size); + copy_v_offset = edmail->hdr_size.physical_size + + edmail->wrapped_hdr_size.physical_size; + + /* Header comes partially from original mail, but headers are only prepended. + */ + } else { parent_v_offset = stream->parent_start_offset + (v_offset - edmail->hdr_size.physical_size); - } else { - if ( v_offset < edmail->hdr_size.physical_size ) - return -2; - - parent_v_offset = stream->parent_start_offset - + edmail->wrapped_hdr_size.physical_size - + (v_offset - edmail->hdr_size.physical_size) - - ( edmail->eoh_crlf ? 2 : 1); + copy_v_offset = edmail->hdr_size.physical_size; } From dovecot at dovecot.org Wed Aug 29 21:08:20 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 21:08:20 +0300 Subject: dovecot-2.2: imap-parser: Removed filling missing parameters wit... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f6a9e6d7e5bd changeset: 14978:f6a9e6d7e5bd user: Timo Sirainen date: Wed Aug 29 21:04:09 2012 +0300 description: imap-parser: Removed filling missing parameters with NILs. No code was relying on this behavior. diffstat: src/lib-imap/imap-parser.c | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-) diffs (15 lines): diff -r 1309de301a2e -r f6a9e6d7e5bd src/lib-imap/imap-parser.c --- a/src/lib-imap/imap-parser.c Wed Aug 29 20:16:13 2012 +0300 +++ b/src/lib-imap/imap-parser.c Wed Aug 29 21:04:09 2012 +0300 @@ -621,11 +621,6 @@ return -1; } - /* fill the missing parameters with NILs */ - while (count > array_count(&parser->root_list)) { - arg = array_append_space(&parser->root_list); - arg->type = IMAP_ARG_NIL; - } arg = array_append_space(&parser->root_list); arg->type = IMAP_ARG_EOL; From dovecot at dovecot.org Wed Aug 29 21:08:20 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 21:08:20 +0300 Subject: dovecot-2.2: imap-parser: Allow calling imap_parser_read_args() ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e0a3812771fd changeset: 14979:e0a3812771fd user: Timo Sirainen date: Wed Aug 29 21:04:45 2012 +0300 description: imap-parser: Allow calling imap_parser_read_args() multiple times with larger count parameter. diffstat: src/lib-imap/imap-parser.c | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-) diffs (44 lines): diff -r f6a9e6d7e5bd -r e0a3812771fd src/lib-imap/imap-parser.c --- a/src/lib-imap/imap-parser.c Wed Aug 29 21:04:09 2012 +0300 +++ b/src/lib-imap/imap-parser.c Wed Aug 29 21:04:45 2012 +0300 @@ -49,6 +49,7 @@ unsigned int literal8:1; unsigned int literal_size_return:1; unsigned int eol:1; + unsigned int args_added_extra_eol:1; unsigned int fatal_error:1; }; @@ -110,6 +111,7 @@ parser->literal_skip_crlf = FALSE; parser->eol = FALSE; + parser->args_added_extra_eol = FALSE; parser->literal_size_return = FALSE; } @@ -624,6 +626,11 @@ arg = array_append_space(&parser->root_list); arg->type = IMAP_ARG_EOL; + if (!parser->eol) + parser->args_added_extra_eol = TRUE; + else + i_assert(!parser->literal_size_return); + *args_r = array_get(&parser->root_list, &count); return ret; } @@ -634,10 +641,11 @@ { parser->flags = flags; - if (parser->literal_size_return) { + if (parser->args_added_extra_eol) { /* delete EOL */ array_delete(&parser->root_list, array_count(&parser->root_list)-1, 1); + parser->args_added_extra_eol = FALSE; parser->literal_size_return = FALSE; } From dovecot at dovecot.org Wed Aug 29 21:08:20 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 21:08:20 +0300 Subject: dovecot-2.2: imap: Allow very long MULTIAPPEND CATENATE lines th... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c73086239699 changeset: 14980:c73086239699 user: Timo Sirainen date: Wed Aug 29 21:08:08 2012 +0300 description: imap: Allow very long MULTIAPPEND CATENATE lines that contain only URLs. diffstat: src/imap/cmd-append.c | 40 ++++++++++++++++++++++++++++++++++------ 1 files changed, 34 insertions(+), 6 deletions(-) diffs (70 lines): diff -r e0a3812771fd -r c73086239699 src/imap/cmd-append.c --- a/src/imap/cmd-append.c Wed Aug 29 21:04:45 2012 +0300 +++ b/src/imap/cmd-append.c Wed Aug 29 21:08:08 2012 +0300 @@ -339,7 +339,10 @@ return TRUE; } - /* we're parsing inside CATENATE (..) list after handling a TEXT part */ + /* we're parsing inside CATENATE (..) list after handling a TEXT part. + it's fine that this would need to fully fit into input buffer + (although clients attempting to DoS could simply insert an extra + {1+} between the URLs) */ ret = imap_parser_read_args(ctx->save_parser, 0, IMAP_PARSE_FLAG_LITERAL_SIZE | IMAP_PARSE_FLAG_LITERAL8 | @@ -603,12 +606,33 @@ return cmd_sync(cmd, sync_flags, imap_flags, str_c(msg)); } +static bool cmd_append_args_can_stop(const struct imap_arg *args) +{ + if (args->type == IMAP_ARG_EOL) + return TRUE; + + /* [(flags)] ["internal date"] | CATENATE (..) */ + if (args->type == IMAP_ARG_LIST) + args++; + if (args->type == IMAP_ARG_STRING) + args++; + + if (args->type == IMAP_ARG_LITERAL_SIZE || + args->type == IMAP_ARG_LITERAL_SIZE_NONSYNC) + return TRUE; + if (imap_arg_atom_equals(args, "CATENATE") && + args[1].type == IMAP_ARG_LIST) + return TRUE; + return FALSE; +} + static bool cmd_append_parse_new_msg(struct client_command_context *cmd) { struct client *client = cmd->client; struct cmd_append_context *ctx = cmd->context; const struct imap_arg *args; const char *msg; + unsigned int arg_min_count; bool fatal, nonsync; int ret; @@ -624,11 +648,15 @@ /* if error occurs, the CRLF is already read. */ client->input_skip_line = FALSE; - /* parse the entire line up to the first message literal - FIXME: we could do with less with CATENATE.. */ - ret = imap_parser_read_args(ctx->save_parser, 0, - IMAP_PARSE_FLAG_LITERAL_SIZE | - IMAP_PARSE_FLAG_LITERAL8, &args); + /* parse the entire line up to the first message literal, or in case + the input buffer is full of MULTIAPPEND CATENATE URLs, parse at + least until the beginning of the next message */ + arg_min_count = 1; + do { + ret = imap_parser_read_args(ctx->save_parser, arg_min_count++, + IMAP_PARSE_FLAG_LITERAL_SIZE | + IMAP_PARSE_FLAG_LITERAL8, &args); + } while (ret > 0 && !cmd_append_args_can_stop(args)); if (ret == -1) { if (!ctx->failed) { msg = imap_parser_get_error(ctx->save_parser, &fatal); From dovecot at dovecot.org Wed Aug 29 22:42:43 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 22:42:43 +0300 Subject: dovecot-2.2: NEWS updated Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7ac168e566b3 changeset: 14981:7ac168e566b3 user: Timo Sirainen date: Wed Aug 29 22:42:26 2012 +0300 description: NEWS updated diffstat: NEWS | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+), 0 deletions(-) diffs (28 lines): diff -r c73086239699 -r 7ac168e566b3 NEWS --- a/NEWS Wed Aug 29 21:08:08 2012 +0300 +++ b/NEWS Wed Aug 29 22:42:26 2012 +0300 @@ -1,3 +1,24 @@ +v2.2.UNSTABLE 2012-xx-xx Timo Sirainen + + * "doveadm auth" command was renamed to "doveadm auth test" + + + Implemented IMAP MOVE and BINARY extensions + + Implemented IMAP CATENATE extension (by Stephan Bosch) + + Implemented IMAP NOTIFY extension. Requires mailbox_list_index=yes + to be enabled. + + Improved mailbox list indexes. They should be usable now, although + still disabled by default. + + Redesigned and rewritten dsync. The new design makes the syncing + faster, more reliable and more featureful. The new dsync protocol + isn't backwards compatible with old dsync versions (but is designed + to be forwards compatible with future versions). + + All mailbox formats now support per-user message flags for shared + mailboxes by using a private index. It can be enabled by adding + :INDEXPVT= to mail location. This should be used instead of + :INDEX also for Maildir/mbox to improve performance. + + LMTP proxy: Implemented XCLIENT extension for passing remote IP + address through proxy. + v2.1.9 2012-08-01 Timo Sirainen * mail-log plugin: Log mailbox names with UTF-8 everywhere From dovecot at dovecot.org Wed Aug 29 23:14:07 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 23:14:07 +0300 Subject: dovecot-2.2: imap-parser: Fixed imap_parser_read_last_literal() ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6c0ba0348e85 changeset: 14982:6c0ba0348e85 user: Timo Sirainen date: Wed Aug 29 23:13:56 2012 +0300 description: imap-parser: Fixed imap_parser_read_last_literal() to work again diffstat: src/lib-imap/imap-parser.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 7ac168e566b3 -r 6c0ba0348e85 src/lib-imap/imap-parser.c --- a/src/lib-imap/imap-parser.c Wed Aug 29 22:42:26 2012 +0300 +++ b/src/lib-imap/imap-parser.c Wed Aug 29 23:13:56 2012 +0300 @@ -735,6 +735,7 @@ /* delete EOL */ array_delete(&parser->root_list, array_count(&parser->root_list)-1, 1); + parser->args_added_extra_eol = FALSE; /* delete literal size */ array_delete(list, array_count(list)-1, 1); From dovecot at dovecot.org Wed Aug 29 23:16:12 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 23:16:12 +0300 Subject: dovecot-2.2: imap: Don't hang with zero size CATENATE TEXT parts. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c9dbd649a78e changeset: 14983:c9dbd649a78e user: Timo Sirainen date: Wed Aug 29 23:15:56 2012 +0300 description: imap: Don't hang with zero size CATENATE TEXT parts. diffstat: src/imap/cmd-append.c | 14 +++++++++++--- 1 files changed, 11 insertions(+), 3 deletions(-) diffs (24 lines): diff -r 6c0ba0348e85 -r c9dbd649a78e src/imap/cmd-append.c --- a/src/imap/cmd-append.c Wed Aug 29 23:13:56 2012 +0300 +++ b/src/imap/cmd-append.c Wed Aug 29 23:15:56 2012 +0300 @@ -241,9 +241,17 @@ /* save the mail */ ctx->cat_msg_size += ctx->literal_size; - ctx->litinput = i_stream_create_limit(cmd->client->input, - ctx->literal_size); - i_stream_chain_append(ctx->catchain, ctx->litinput); + if (ctx->literal_size == 0) { + /* zero length literal. RFC doesn't explicitly specify + what should be done with this, so we'll simply + handle it by skipping the empty text part. */ + ctx->litinput = i_stream_create_from_data("", 0); + ctx->litinput->eof = TRUE; + } else { + ctx->litinput = i_stream_create_limit(cmd->client->input, + ctx->literal_size); + i_stream_chain_append(ctx->catchain, ctx->litinput); + } } static int From dovecot at dovecot.org Wed Aug 29 23:16:12 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 29 Aug 2012 23:16:12 +0300 Subject: dovecot-2.2: Minor code cleanup Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/09de25ccacb4 changeset: 14984:09de25ccacb4 user: Timo Sirainen date: Wed Aug 29 23:16:05 2012 +0300 description: Minor code cleanup diffstat: src/imap/cmd-append.c | 18 ++++++++++-------- 1 files changed, 10 insertions(+), 8 deletions(-) diffs (42 lines): diff -r c9dbd649a78e -r 09de25ccacb4 src/imap/cmd-append.c --- a/src/imap/cmd-append.c Wed Aug 29 23:15:56 2012 +0300 +++ b/src/imap/cmd-append.c Wed Aug 29 23:16:05 2012 +0300 @@ -147,6 +147,14 @@ mailbox_free(&ctx->box); } +static void cmd_append_send_literal_continue(struct client *client) +{ + o_stream_nsend(client->output, "+ OK\r\n", 6); + o_stream_nflush(client->output); + o_stream_uncork(client->output); + o_stream_cork(client->output); +} + static int cmd_append_catenate_url(struct client_command_context *cmd, const char *caturl) { @@ -397,10 +405,7 @@ cmd_append_finish(ctx); return TRUE; } - o_stream_nsend(client->output, "+ OK\r\n", 6); - o_stream_nflush(client->output); - o_stream_uncork(client->output); - o_stream_cork(client->output); + cmd_append_send_literal_continue(client); } i_assert(ctx->litinput != NULL); @@ -716,10 +721,7 @@ cmd_append_finish(ctx); return TRUE; } - o_stream_nsend(client->output, "+ OK\r\n", 6); - o_stream_nflush(client->output); - o_stream_uncork(client->output); - o_stream_cork(client->output); + cmd_append_send_literal_continue(client); } i_assert(ctx->litinput != NULL); From dovecot at dovecot.org Thu Aug 30 18:45:00 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 18:45:00 +0300 Subject: dovecot-2.2: imap: Fixed MULTIAPPEND CATENATE that contained onl... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e4c09527aa9e changeset: 14985:e4c09527aa9e user: Timo Sirainen date: Thu Aug 30 18:44:43 2012 +0300 description: imap: Fixed MULTIAPPEND CATENATE that contained only URLs diffstat: src/imap/cmd-append.c | 46 ++++++++++++++++++++++------------------------ 1 files changed, 22 insertions(+), 24 deletions(-) diffs (96 lines): diff -r 09de25ccacb4 -r e4c09527aa9e src/imap/cmd-append.c --- a/src/imap/cmd-append.c Wed Aug 29 23:16:05 2012 +0300 +++ b/src/imap/cmd-append.c Thu Aug 30 18:44:43 2012 +0300 @@ -416,7 +416,7 @@ static int cmd_append_handle_args(struct client_command_context *cmd, - const struct imap_arg **args, bool *nonsync_r) + const struct imap_arg *args, bool *nonsync_r) { struct client *client = cmd->client; struct cmd_append_context *ctx = cmd->context; @@ -432,26 +432,26 @@ bool valid; /* [] */ - if (!imap_arg_get_list(*args, &flags_list)) + if (!imap_arg_get_list(args, &flags_list)) flags_list = NULL; else - (*args)++; + args++; /* [] */ - if ((*args)->type != IMAP_ARG_STRING) + if (args->type != IMAP_ARG_STRING) internal_date_str = NULL; else { - internal_date_str = imap_arg_as_astring(*args); - (*args)++; + internal_date_str = imap_arg_as_astring(args); + args++; } /* | CATENATE (..) */ valid = FALSE; *nonsync_r = FALSE; ctx->catenate = FALSE; - if (imap_arg_atom_equals(*args, "CATENATE")) { - (*args)++; - if (imap_arg_get_list(*args, &cat_list)) { + if (imap_arg_atom_equals(args, "CATENATE")) { + args++; + if (imap_arg_get_list(args, &cat_list)) { valid = TRUE; ctx->catenate = TRUE; } @@ -461,11 +461,13 @@ ctx->binary_input = imap_arg_atom_equals(&cat_list[0], "TEXT") && cat_list[1].literal8; - } else if (imap_arg_get_literal_size(*args, &ctx->literal_size)) { - *nonsync_r = (*args)->type == IMAP_ARG_LITERAL_SIZE_NONSYNC; - ctx->binary_input = (*args)->literal8; + } else if (imap_arg_get_literal_size(args, &ctx->literal_size)) { + *nonsync_r = args->type == IMAP_ARG_LITERAL_SIZE_NONSYNC; + ctx->binary_input = args->literal8; valid = TRUE; } + /* we parsed the args only up to here. */ + i_assert(IMAP_ARG_IS_EOL(&args[1])); if (!valid) { client->input_skip_line = TRUE; @@ -691,23 +693,19 @@ return cmd_append_finish_parsing(cmd); } - /* Handle one or more messages (MULTIAPPEND) while they only contain - CATENATE URLs (i.e. no TEXT input from client) */ - while ((ret = cmd_append_handle_args(cmd, &args, &nonsync)) == 0) { - cmd_append_finish_catenate(cmd); - - args++; - if (IMAP_ARG_IS_EOL(args)) { - /* last message */ - return cmd_append_finish_parsing(cmd); - } - } - + ret = cmd_append_handle_args(cmd, args, &nonsync); if (ret < 0) { /* invalid parameters, abort immediately */ cmd_append_finish(ctx); return TRUE; } + if (ret == 0) { + /* CATENATE contained only URLs. Finish it and see if there + are more messsages. */ + cmd_append_finish_catenate(cmd); + imap_parser_reset(ctx->save_parser); + return cmd_append_parse_new_msg(cmd); + } if (!ctx->catenate) { /* after literal comes CRLF, if we fail make sure From dovecot at dovecot.org Thu Aug 30 21:12:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 21:12:40 +0300 Subject: dovecot-2.2: Moved most of the IMAP LIST code to lib-storage. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5ffcde8baa8a changeset: 14986:5ffcde8baa8a user: Timo Sirainen date: Thu Aug 30 21:12:23 2012 +0300 description: Moved most of the IMAP LIST code to lib-storage. Also removed MAILBOX_LIST_ITER_SHOW_EXISTING_PARENT flag, since there wasn't any clearly good way to handle it. Some clients got confused when they saw that foo/ mailbox was returned with \Noselect flag. Either they thought that the mailbox was named foo/ or that foo was \Noselect. Pretty much the only sane way to handle this would be to not make return \Noselect and to treat foo and foo/ as equivalent in all commands, but that might cause trouble with ACLs and similar checks.. diffstat: src/imap/cmd-list.c | 658 ++------------------------- src/lib-storage/list/mailbox-list-fs-iter.c | 17 +- src/lib-storage/mailbox-list-iter.c | 411 +++++++++++++--- src/lib-storage/mailbox-list.h | 4 - 4 files changed, 379 insertions(+), 711 deletions(-) diffs (truncated from 1351 to 300 lines): diff -r e4c09527aa9e -r 5ffcde8baa8a src/imap/cmd-list.c --- a/src/imap/cmd-list.c Thu Aug 30 18:44:43 2012 +0300 +++ b/src/imap/cmd-list.c Thu Aug 30 21:12:23 2012 +0300 @@ -14,24 +14,15 @@ struct cmd_list_context { struct client_command_context *cmd; - const char *ref; - const char *const *patterns; + struct mail_user *user; + enum mailbox_list_iter_flags list_flags; struct imap_status_items status_items; - enum mailbox_info_flags inbox_flags; - struct mail_namespace *ns; struct mailbox_list_iterate_context *list_iter; - ARRAY(struct mail_namespace *) ns_prefixes_listed; - unsigned int lsub:1; unsigned int lsub_no_unsubscribed:1; - unsigned int inbox_found:1; - unsigned int seen_inbox_namespace:1; - unsigned int cur_ns_match_inbox:1; - unsigned int cur_ns_send_prefix:1; - unsigned int cur_ns_skip_trailing_sep:1; unsigned int used_listext:1; unsigned int used_status:1; }; @@ -164,90 +155,6 @@ return TRUE; } -static enum mailbox_info_flags -list_get_inbox_flags(struct cmd_list_context *ctx) -{ - struct mail_namespace *ns; - struct mailbox_list_iterate_context *list_iter; - const struct mailbox_info *info; - enum mailbox_info_flags flags = MAILBOX_UNMARKED; - - if (ctx->seen_inbox_namespace && - (ctx->ns->flags & NAMESPACE_FLAG_INBOX_USER) == 0) { - /* INBOX doesn't exist. use the default INBOX flags */ - return flags; - } - - /* find the INBOX flags */ - ns = mail_namespace_find_inbox(ctx->cmd->client->user->namespaces); - list_iter = mailbox_list_iter_init(ns->list, "INBOX", 0); - info = mailbox_list_iter_next(list_iter); - if (info != NULL) { - i_assert(strcasecmp(info->vname, "INBOX") == 0); - flags = info->flags; - } - (void)mailbox_list_iter_deinit(&list_iter); - return flags; -} - -static bool list_namespace_has_children(struct cmd_list_context *ctx) -{ - enum mailbox_list_iter_flags list_flags = - MAILBOX_LIST_ITER_RETURN_NO_FLAGS; - struct mailbox_list_iterate_context *list_iter; - const struct mailbox_info *info; - bool ret = FALSE; - - if ((ctx->list_flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0) - list_flags |= MAILBOX_LIST_ITER_SELECT_SUBSCRIBED; - - list_iter = mailbox_list_iter_init(ctx->ns->list, - t_strconcat(ctx->ns->prefix, "%", NULL), list_flags); - info = mailbox_list_iter_next(list_iter); - if (info != NULL) - ret = TRUE; - if (mailbox_list_iter_deinit(&list_iter) < 0) { - /* safer to answer TRUE in error conditions */ - ret = TRUE; - } - return ret; -} - -static const char *ns_get_listed_prefix(struct cmd_list_context *ctx) -{ - struct imap_match_glob *glob; - enum imap_match_result match; - const char *ns_prefix, *p; - bool inboxcase; - unsigned int skip_len; - - skip_len = strlen(ctx->ref); - if (strncmp(ctx->ns->prefix, ctx->ref, skip_len) != 0) - skip_len = 0; - - inboxcase = strncasecmp(ctx->ns->prefix, "INBOX", 5) == 0 && - ctx->ns->prefix[5] == mail_namespace_get_sep(ctx->ns); - glob = imap_match_init_multiple(pool_datastack_create(), - ctx->patterns, inboxcase, - mail_namespace_get_sep(ctx->ns)); - ns_prefix = ctx->ns->prefix + skip_len; - match = imap_match(glob, ns_prefix); - if (match == IMAP_MATCH_YES) { - return !ctx->cur_ns_skip_trailing_sep ? ctx->ns->prefix : - t_strndup(ctx->ns->prefix, strlen(ctx->ns->prefix)-1); - } - - while ((match & IMAP_MATCH_PARENT) != 0) { - p = strrchr(ns_prefix, mail_namespace_get_sep(ctx->ns)); - i_assert(p != NULL); - ns_prefix = t_strdup_until(ns_prefix, p); - match = imap_match(glob, ns_prefix); - } - i_assert(match == IMAP_MATCH_YES); - return t_strconcat(t_strndup(ctx->ns->prefix, skip_len), - ns_prefix, NULL); -} - static void list_reply_append_ns_sep_param(string_t *str, char sep) { str_append_c(str, '"'); @@ -259,101 +166,6 @@ } static void -list_namespace_send_prefix(struct cmd_list_context *ctx, bool have_children) -{ - struct mail_namespace *const *listed; - const struct mailbox_settings *mailbox_set; - struct mailbox *box; - enum mailbox_existence existence; - unsigned int len; - enum mailbox_info_flags flags; - const char *name; - string_t *str; - bool same_ns, ends_with_sep; - char ns_sep = mail_namespace_get_sep(ctx->ns); - - ctx->cur_ns_send_prefix = FALSE; - - /* see if we already listed this as a valid mailbox in another - namespace */ - array_foreach(&ctx->ns_prefixes_listed, listed) { - if (*listed == ctx->ns) - return; - } - - name = ns_get_listed_prefix(ctx); - len = strlen(ctx->ns->prefix); - ends_with_sep = ctx->ns->prefix[len-1] == ns_sep; - - /* we may be listing namespace's parent. in such case we always want to - set the name as nonexistent. */ - same_ns = strcmp(name, ctx->ns->prefix) == 0 || - (strncmp(name, ctx->ns->prefix, len - 1) == 0 && ends_with_sep); - if (len == 6 && strncasecmp(ctx->ns->prefix, "INBOX", len-1) == 0 && - ends_with_sep) { - /* INBOX namespace needs to be handled specially. */ - if (ctx->inbox_found) { - /* we're just now going to send it */ - return; - } - - ctx->inbox_found = TRUE; - flags = list_get_inbox_flags(ctx); - } else if (!same_ns) { - /* parent */ - flags = MAILBOX_NONEXISTENT; - } else { - /* see if namespace prefix is selectable */ - box = mailbox_alloc(ctx->ns->list, name, 0); - if (mailbox_exists(box, TRUE, &existence) == 0 && - existence == MAILBOX_EXISTENCE_SELECT) - flags = MAILBOX_SELECT; - else - flags = MAILBOX_NONEXISTENT; - mailbox_free(&box); - } - - if ((flags & MAILBOX_CHILDREN) == 0) { - if (have_children || list_namespace_has_children(ctx)) { - flags |= MAILBOX_CHILDREN; - flags &= ~MAILBOX_NOCHILDREN; - } else { - flags |= MAILBOX_NOCHILDREN; - } - } - - if ((ctx->ns->flags & NAMESPACE_FLAG_LIST_CHILDREN) != 0 || - (ctx->list_flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0) { - if (have_children) { - /* children are going to be listed. */ - return; - } - if ((flags & MAILBOX_CHILDREN) == 0) { - /* namespace has no children. don't show it. */ - return; - } - /* namespace has children but they don't match the list - pattern. the prefix itself matches though, so show it. */ - } - - str = t_str_new(128); - str_printfa(str, "* %s (", ctx->lsub ? "LSUB" : "LIST"); - if (ctx->lsub) - flags |= MAILBOX_NONEXISTENT; - mailbox_set = (ctx->list_flags & MAILBOX_LIST_ITER_RETURN_SPECIALUSE) == 0 ? NULL : - mailbox_settings_find(ctx->cmd->client->user, name); - mailbox_flags2str(ctx, str, mailbox_set == NULL ? NULL : - mailbox_set->special_use, flags); - str_append(str, ") "); - list_reply_append_ns_sep_param(str, ns_sep); - str_append_c(str, ' '); - imap_quote_append_string(str, name, FALSE); - mailbox_childinfo2str(ctx, str, flags); - - client_send_line(ctx->cmd->client, str_c(str)); -} - -static void list_send_status(struct cmd_list_context *ctx, const char *name, const char *mutf7_name, enum mailbox_info_flags flags) { @@ -372,7 +184,7 @@ /* if we're listing subscriptions and there are subscriptions=no namespaces, ctx->ns may not point to correct one */ - ns = mail_namespace_find(ctx->ns->user->namespaces, name); + ns = mail_namespace_find(ctx->user->namespaces, name); if (imap_status_get(ctx->cmd, ns, name, &ctx->status_items, &result) < 0) { client_send_line(ctx->cmd->client, @@ -384,71 +196,26 @@ &ctx->status_items, &result); } -static bool list_has_empty_prefix_ns(struct mail_user *user) +static bool cmd_list_continue(struct client_command_context *cmd) { - struct mail_namespace *ns; - - ns = mail_namespace_find_prefix(user->namespaces, ""); - return ns != NULL && (ns->flags & (NAMESPACE_FLAG_LIST_PREFIX | - NAMESPACE_FLAG_LIST_CHILDREN)) != 0; -} - -static int -list_namespace_mailboxes(struct cmd_list_context *ctx) -{ + struct cmd_list_context *ctx = cmd->context; const struct mailbox_info *info; - struct mail_namespace *ns; enum mailbox_info_flags flags; string_t *str, *mutf7_name; const char *name; int ret = 0; + if (cmd->cancel) { + if (ctx->list_iter != NULL) + (void)mailbox_list_iter_deinit(&ctx->list_iter); + return TRUE; + } str = t_str_new(256); mutf7_name = t_str_new(128); while ((info = mailbox_list_iter_next(ctx->list_iter)) != NULL) { name = info->vname; flags = info->flags; - if (strcasecmp(name, "INBOX") == 0) { - if (ctx->inbox_found) { - /* we already listed this at the beginning - of handling INBOX/ namespace */ - continue; - } - if ((ctx->ns->flags & NAMESPACE_FLAG_INBOX_USER) == 0) { - /* INBOX is in non-empty prefix namespace, - and we're now listing prefixless namespace - that contains INBOX. There's no way we can - show this mailbox. */ - ctx->inbox_flags = flags & - (MAILBOX_CHILDREN|MAILBOX_NOCHILDREN); - continue; - } - - if (*info->ns->prefix != '\0' && - list_has_empty_prefix_ns(info->ns->user)) { - /* INBOX is in its own namespace, while a - namespace with prefix="" has its children. */ - flags &= ~(MAILBOX_CHILDREN|MAILBOX_NOCHILDREN| - MAILBOX_NOINFERIORS); - flags |= ctx->inbox_flags; - } - ctx->inbox_found = TRUE; - } - if (ctx->cur_ns_send_prefix) - list_namespace_send_prefix(ctx, TRUE); - - /* if there's a list=yes namespace with this name, list it as - having children */ - ns = mail_namespace_find_prefix_nosep(ctx->ns, name); From dovecot at dovecot.org Thu Aug 30 21:56:54 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 21:56:54 +0300 Subject: dovecot-2.1: layout=fs mailbox listing: Fix to prefix=INBOX/ han... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/67235781cc08 changeset: 14691:67235781cc08 user: Timo Sirainen date: Thu Aug 30 21:56:43 2012 +0300 description: layout=fs mailbox listing: Fix to prefix=INBOX/ handling diffstat: src/lib-storage/list/mailbox-list-fs-iter.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r eb57a7280b01 -r 67235781cc08 src/lib-storage/list/mailbox-list-fs-iter.c --- a/src/lib-storage/list/mailbox-list-fs-iter.c Tue Aug 28 19:06:01 2012 +0300 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Thu Aug 30 21:56:43 2012 +0300 @@ -400,6 +400,7 @@ if (p == last+1 && *pattern == ns_sep) root = "/"; else if ((ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0 && + ns->prefix_len == 6 && strcasecmp(prefix_vname, "INBOX") == 0 && strncasecmp(ns->prefix, pattern, ns->prefix_len) == 0) { /* special case: Namespace prefix is INBOX/ and From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: auth: Unregister SCRAM-SHA-1 at deinit. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9523b967a30e changeset: 14987:9523b967a30e user: Timo Sirainen date: Wed Aug 22 07:49:55 2012 +0300 description: auth: Unregister SCRAM-SHA-1 at deinit. diffstat: src/auth/mech.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r f68f5aca440e -r 9523b967a30e src/auth/mech.c --- a/src/auth/mech.c Sun Aug 19 12:53:06 2012 +0300 +++ b/src/auth/mech.c Wed Aug 22 07:49:55 2012 +0300 @@ -205,6 +205,7 @@ #endif } mech_unregister_module(&mech_otp); + mech_unregister_module(&mech_scram_sha1); mech_unregister_module(&mech_skey); mech_unregister_module(&mech_rpa); mech_unregister_module(&mech_anonymous); From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: istream-concat bugfixes Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c6fe6a77defd changeset: 14988:c6fe6a77defd user: Timo Sirainen date: Wed Aug 22 15:17:53 2012 +0300 description: istream-concat bugfixes diffstat: src/lib/istream-concat.c | 18 +++++++++++------- 1 files changed, 11 insertions(+), 7 deletions(-) diffs (40 lines): diff -r 9523b967a30e -r c6fe6a77defd src/lib/istream-concat.c --- a/src/lib/istream-concat.c Wed Aug 22 07:49:55 2012 +0300 +++ b/src/lib/istream-concat.c Wed Aug 22 15:17:53 2012 +0300 @@ -87,7 +87,7 @@ { struct concat_istream *cstream = (struct concat_istream *)stream; const unsigned char *data; - size_t size, pos, cur_pos, bytes_skipped; + size_t size, pos, cur_pos, bytes_skipped, new_bytes_count; ssize_t ret; bool last_stream; @@ -154,17 +154,21 @@ stream->skip = 0; } else if (pos == cur_pos) { stream->buffer = stream->w_buffer; + pos = stream->pos; } else { + new_bytes_count = pos - cur_pos; + if (!i_stream_get_buffer_space(stream, new_bytes_count, &size)) { + stream->buffer = stream->w_buffer; + return -2; + } stream->buffer = stream->w_buffer; - if (!i_stream_get_buffer_space(stream, pos - cur_pos, &size)) - return -2; - if (pos > size) - pos = size; + if (new_bytes_count > size) + new_bytes_count = size; memcpy(stream->w_buffer + stream->pos, - data + cur_pos, pos - cur_pos); + data + cur_pos, new_bytes_count); + pos = stream->pos + new_bytes_count; } - pos += stream->skip + cstream->prev_stream_left; ret = pos > stream->pos ? (ssize_t)(pos - stream->pos) : (ret == 0 ? 0 : -1); From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: configure: Removed OpenBSD /dev/arandom checking. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3765e8948f1c changeset: 14989:3765e8948f1c user: Timo Sirainen date: Wed Aug 22 17:42:06 2012 +0300 description: configure: Removed OpenBSD /dev/arandom checking. Patch by Brad Smith "The use of arandom was never a requirement for Dovecot and I had submitted the use of arandom due to ports policy to do so anyway." diffstat: configure.in | 14 +++----------- 1 files changed, 3 insertions(+), 11 deletions(-) diffs (28 lines): diff -r c6fe6a77defd -r 3765e8948f1c configure.in --- a/configure.in Wed Aug 22 15:17:53 2012 +0300 +++ b/configure.in Wed Aug 22 17:42:06 2012 +0300 @@ -951,21 +951,13 @@ AC_DEFINE_UNQUOTED(MEM_ALIGN_SIZE, $mem_align, Required memory alignment) dnl * find random source -AC_MSG_CHECKING([for OpenBSD /dev/arandom]) -if test -c /dev/arandom; then +AC_MSG_CHECKING([for /dev/urandom]) +if test -c /dev/urandom || test -s /dev/urandom; then AC_MSG_RESULT(yes) - AC_DEFINE(DEV_URANDOM_PATH, "/dev/arandom", Path to /dev/urandom) + AC_DEFINE(DEV_URANDOM_PATH, "/dev/urandom", Path to /dev/urandom) have_random_source=yes else AC_MSG_RESULT(no) - AC_MSG_CHECKING([for /dev/urandom]) - if test -c /dev/urandom || test -s /dev/urandom; then - AC_MSG_RESULT(yes) - AC_DEFINE(DEV_URANDOM_PATH, "/dev/urandom", Path to /dev/urandom) - have_random_source=yes - else - AC_MSG_RESULT(no) - fi fi if test "$have_random_source" != "yes"; then From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: lib-storage: Make sure a save context doesn't leak ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7bdbca7b0913 changeset: 14990:7bdbca7b0913 user: Timo Sirainen date: Thu Aug 23 11:56:56 2012 +0300 description: lib-storage: Make sure a save context doesn't leak metadata to the next save. diffstat: src/lib-storage/index/index-storage.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diffs (18 lines): diff -r 3765e8948f1c -r 7bdbca7b0913 src/lib-storage/index/index-storage.c --- a/src/lib-storage/index/index-storage.c Wed Aug 22 17:42:06 2012 +0300 +++ b/src/lib-storage/index/index-storage.c Thu Aug 23 11:56:56 2012 +0300 @@ -616,6 +616,14 @@ i_free_and_null(ctx->guid); i_free_and_null(ctx->pop3_uidl); index_attachment_save_free(ctx); + + ctx->flags = 0; + ctx->keywords = NULL; + ctx->min_modseq = 0; + ctx->received_date = ctx->save_date = 0; + ctx->received_tz_offset = 0; + ctx->uid = 0; + ctx->pop3_order = 0; } static void From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: doveadm: Added "copy" command. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9d35aca14c81 changeset: 14991:9d35aca14c81 user: Timo Sirainen date: Thu Aug 23 21:29:40 2012 +0300 description: doveadm: Added "copy" command. diffstat: src/doveadm/Makefile.am | 2 +- src/doveadm/doveadm-mail-copymove.c | 159 ++++++++++++++++++++++++++++++++++++ src/doveadm/doveadm-mail-move.c | 144 -------------------------------- src/doveadm/doveadm-mail.c | 1 + src/doveadm/doveadm-mail.h | 1 + 5 files changed, 162 insertions(+), 145 deletions(-) diffs (truncated from 345 to 300 lines): diff -r 7bdbca7b0913 -r 9d35aca14c81 src/doveadm/Makefile.am --- a/src/doveadm/Makefile.am Thu Aug 23 11:56:56 2012 +0300 +++ b/src/doveadm/Makefile.am Thu Aug 23 21:29:40 2012 +0300 @@ -74,7 +74,7 @@ doveadm-mail-iter.c \ doveadm-mail-mailbox.c \ doveadm-mail-mailbox-status.c \ - doveadm-mail-move.c \ + doveadm-mail-copymove.c \ doveadm-mailbox-list-iter.c \ doveadm-mail-search.c \ doveadm-mail-server.c \ diff -r 7bdbca7b0913 -r 9d35aca14c81 src/doveadm/doveadm-mail-copymove.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doveadm/doveadm-mail-copymove.c Thu Aug 23 21:29:40 2012 +0300 @@ -0,0 +1,159 @@ +/* Copyright (c) 2011-2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "mail-storage.h" +#include "mail-namespace.h" +#include "doveadm-print.h" +#include "doveadm-mailbox-list-iter.h" +#include "doveadm-mail-iter.h" +#include "doveadm-mail.h" + +#include + +struct copy_cmd_context { + struct doveadm_mail_cmd_context ctx; + + const char *destname; + bool move; +}; + +static int +cmd_copy_box(struct copy_cmd_context *ctx, struct mailbox *destbox, + const struct mailbox_info *info) +{ + struct doveadm_mail_iter *iter; + struct mailbox_transaction_context *trans; + struct mailbox_transaction_context *desttrans; + struct mail_save_context *save_ctx; + struct mail *mail; + int ret = 0; + + if (doveadm_mail_iter_init(&ctx->ctx, info, ctx->ctx.search_args, 0, + NULL, &trans, &iter) < 0) + return -1; + + /* use a separately committed transaction for each mailbox. + this guarantees that mails aren't expunged without actually having + been copied. */ + desttrans = mailbox_transaction_begin(destbox, + MAILBOX_TRANSACTION_FLAG_EXTERNAL); + + while (doveadm_mail_iter_next(iter, &mail)) { + save_ctx = mailbox_save_alloc(desttrans); + mailbox_save_copy_flags(save_ctx, mail); + if (mailbox_copy(&save_ctx, mail) == 0) { + if (ctx->move) + mail_expunge(mail); + } else { + i_error("Copying message UID %u from '%s' failed: %s", + mail->uid, info->name, + mailbox_get_last_error(destbox, NULL)); + doveadm_mail_failed_mailbox(&ctx->ctx, destbox); + ret = -1; + } + } + + if (mailbox_transaction_commit(&desttrans) < 0) { + i_error("Committing %s mails failed: %s", + ctx->move ? "moved" : "copied", + mailbox_get_last_error(destbox, NULL)); + doveadm_mail_failed_mailbox(&ctx->ctx, destbox); + /* rollback expunges */ + doveadm_mail_iter_deinit_rollback(&iter); + ret = -1; + } else { + if (doveadm_mail_iter_deinit_sync(&iter) < 0) + ret = -1; + } + return ret; +} + +static int +cmd_copy_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) +{ + struct copy_cmd_context *ctx = (struct copy_cmd_context *)_ctx; + const enum mailbox_list_iter_flags iter_flags = + MAILBOX_LIST_ITER_RAW_LIST | + MAILBOX_LIST_ITER_NO_AUTO_BOXES | + MAILBOX_LIST_ITER_RETURN_NO_FLAGS; + struct doveadm_mailbox_list_iter *iter; + struct mail_namespace *ns; + struct mailbox *destbox; + const struct mailbox_info *info; + int ret = 0; + + ns = mail_namespace_find(user->namespaces, ctx->destname); + if (ns == NULL) { + i_fatal_status(DOVEADM_EX_NOTFOUND, + "Can't find namespace for: %s", ctx->destname); + } + + destbox = mailbox_alloc(ns->list, ctx->destname, MAILBOX_FLAG_SAVEONLY); + if (mailbox_open(destbox) < 0) { + i_error("Can't open mailbox '%s': %s", ctx->destname, + mailbox_get_last_error(destbox, NULL)); + doveadm_mail_failed_mailbox(&ctx->ctx, destbox); + mailbox_free(&destbox); + return -1; + } + + iter = doveadm_mailbox_list_iter_init(_ctx, user, _ctx->search_args, + iter_flags); + while ((info = doveadm_mailbox_list_iter_next(iter)) != NULL) T_BEGIN { + if (cmd_copy_box(ctx, destbox, info) < 0) + ret = -1; + } T_END; + if (doveadm_mailbox_list_iter_deinit(&iter) < 0) + ret = -1; + + if (mailbox_sync(destbox, 0) < 0) { + i_error("Syncing mailbox '%s' failed: %s", ctx->destname, + mailbox_get_last_error(destbox, NULL)); + doveadm_mail_failed_mailbox(&ctx->ctx, destbox); + ret = -1; + } + mailbox_free(&destbox); + return ret; + +} + +static void cmd_copy_init(struct doveadm_mail_cmd_context *_ctx, + const char *const args[]) +{ + struct copy_cmd_context *ctx = (struct copy_cmd_context *)_ctx; + const char *destname = args[0], *cmdname = ctx->move ? "move" : "copy"; + + if (destname == NULL || args[1] == NULL) + doveadm_mail_help_name(cmdname); + + ctx->destname = p_strdup(ctx->ctx.pool, destname); + ctx->ctx.search_args = doveadm_mail_build_search_args(args + 1); + expunge_search_args_check(ctx->ctx.search_args, cmdname); +} + +static struct doveadm_mail_cmd_context *cmd_copy_alloc(void) +{ + struct copy_cmd_context *ctx; + + ctx = doveadm_mail_cmd_alloc(struct copy_cmd_context); + ctx->ctx.v.init = cmd_copy_init; + ctx->ctx.v.run = cmd_copy_run; + doveadm_print_init(DOVEADM_PRINT_TYPE_FLOW); + return &ctx->ctx; +} + +static struct doveadm_mail_cmd_context *cmd_move_alloc(void) +{ + struct copy_cmd_context *ctx; + + ctx = (struct copy_cmd_context *)cmd_copy_alloc(); + ctx->move = TRUE; + return &ctx->ctx; +} + +struct doveadm_mail_cmd cmd_copy = { + cmd_copy_alloc, "copy", " " +}; +struct doveadm_mail_cmd cmd_move = { + cmd_move_alloc, "move", " " +}; diff -r 7bdbca7b0913 -r 9d35aca14c81 src/doveadm/doveadm-mail-move.c --- a/src/doveadm/doveadm-mail-move.c Thu Aug 23 11:56:56 2012 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,144 +0,0 @@ -/* Copyright (c) 2011-2012 Dovecot authors, see the included COPYING file */ - -#include "lib.h" -#include "mail-storage.h" -#include "mail-namespace.h" -#include "doveadm-print.h" -#include "doveadm-mailbox-list-iter.h" -#include "doveadm-mail-iter.h" -#include "doveadm-mail.h" - -#include - -struct move_cmd_context { - struct doveadm_mail_cmd_context ctx; - - const char *destname; -}; - -static int -cmd_move_box(struct move_cmd_context *ctx, struct mailbox *destbox, - const struct mailbox_info *info) -{ - struct doveadm_mail_iter *iter; - struct mailbox_transaction_context *trans; - struct mailbox_transaction_context *desttrans; - struct mail_save_context *save_ctx; - struct mail *mail; - int ret = 0; - - if (doveadm_mail_iter_init(&ctx->ctx, info, ctx->ctx.search_args, 0, - NULL, &trans, &iter) < 0) - return -1; - - /* use a separately committed transaction for each mailbox. - this guarantees that mails aren't expunged without actually having - been copied. */ - desttrans = mailbox_transaction_begin(destbox, - MAILBOX_TRANSACTION_FLAG_EXTERNAL); - - while (doveadm_mail_iter_next(iter, &mail)) { - save_ctx = mailbox_save_alloc(desttrans); - mailbox_save_copy_flags(save_ctx, mail); - if (mailbox_copy(&save_ctx, mail) == 0) - mail_expunge(mail); - else { - i_error("Copying message UID %u from '%s' failed: %s", - mail->uid, info->name, - mailbox_get_last_error(destbox, NULL)); - doveadm_mail_failed_mailbox(&ctx->ctx, destbox); - ret = -1; - } - } - - if (mailbox_transaction_commit(&desttrans) < 0) { - i_error("Committing moved mails failed: %s", - mailbox_get_last_error(destbox, NULL)); - doveadm_mail_failed_mailbox(&ctx->ctx, destbox); - /* rollback expunges */ - doveadm_mail_iter_deinit_rollback(&iter); - ret = -1; - } else { - if (doveadm_mail_iter_deinit_sync(&iter) < 0) - ret = -1; - } - return ret; -} - -static int -cmd_move_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) -{ - struct move_cmd_context *ctx = (struct move_cmd_context *)_ctx; - const enum mailbox_list_iter_flags iter_flags = - MAILBOX_LIST_ITER_RAW_LIST | - MAILBOX_LIST_ITER_NO_AUTO_BOXES | - MAILBOX_LIST_ITER_RETURN_NO_FLAGS; - struct doveadm_mailbox_list_iter *iter; - struct mail_namespace *ns; - struct mailbox *destbox; - const struct mailbox_info *info; - int ret = 0; - - ns = mail_namespace_find(user->namespaces, ctx->destname); - if (ns == NULL) { - i_fatal_status(DOVEADM_EX_NOTFOUND, - "Can't find namespace for: %s", ctx->destname); - } - - destbox = mailbox_alloc(ns->list, ctx->destname, MAILBOX_FLAG_SAVEONLY); - if (mailbox_open(destbox) < 0) { - i_error("Can't open mailbox '%s': %s", ctx->destname, - mailbox_get_last_error(destbox, NULL)); - doveadm_mail_failed_mailbox(&ctx->ctx, destbox); - mailbox_free(&destbox); - return -1; - } - - iter = doveadm_mailbox_list_iter_init(_ctx, user, _ctx->search_args, - iter_flags); - while ((info = doveadm_mailbox_list_iter_next(iter)) != NULL) T_BEGIN { - if (cmd_move_box(ctx, destbox, info) < 0) - ret = -1; - } T_END; - if (doveadm_mailbox_list_iter_deinit(&iter) < 0) - ret = -1; - - if (mailbox_sync(destbox, 0) < 0) { - i_error("Syncing mailbox '%s' failed: %s", ctx->destname, - mailbox_get_last_error(destbox, NULL)); - doveadm_mail_failed_mailbox(&ctx->ctx, destbox); - ret = -1; - } - mailbox_free(&destbox); - return ret; - -} - -static void cmd_move_init(struct doveadm_mail_cmd_context *_ctx, - const char *const args[]) -{ - struct move_cmd_context *ctx = (struct move_cmd_context *)_ctx; - const char *destname = args[0]; From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: lib-storage: Verify that namespace prefix is valid ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/565605200989 changeset: 14993:565605200989 user: Timo Sirainen date: Thu Aug 23 22:33:23 2012 +0300 description: lib-storage: Verify that namespace prefix is valid UTF8 string. diffstat: src/lib-storage/mail-storage-settings.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r b8173f8a1447 -r 565605200989 src/lib-storage/mail-storage-settings.c --- a/src/lib-storage/mail-storage-settings.c Thu Aug 23 22:21:42 2012 +0300 +++ b/src/lib-storage/mail-storage-settings.c Thu Aug 23 22:33:23 2012 +0300 @@ -444,6 +444,11 @@ name); return FALSE; } + if (!uni_utf8_str_is_valid(name)) { + *error_r = t_strdup_printf("Namespace prefix not valid UTF8: %s", + name); + return FALSE; + } if (ns->alias_for != NULL) { if (array_is_created(&ns->user_set->namespaces)) { From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: mbox: Fixed listing mailboxes under INBOX directory. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b8173f8a1447 changeset: 14992:b8173f8a1447 user: Timo Sirainen date: Thu Aug 23 22:21:42 2012 +0300 description: mbox: Fixed listing mailboxes under INBOX directory. diffstat: src/lib-storage/list/mailbox-list-fs-iter.c | 21 +++++++++++++++++---- 1 files changed, 17 insertions(+), 4 deletions(-) diffs (48 lines): diff -r 9d35aca14c81 -r b8173f8a1447 src/lib-storage/list/mailbox-list-fs-iter.c --- a/src/lib-storage/list/mailbox-list-fs-iter.c Thu Aug 23 21:29:40 2012 +0300 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Thu Aug 23 22:21:42 2012 +0300 @@ -49,6 +49,7 @@ struct list_dir_context *dir; unsigned int inbox_found:1; + unsigned int inbox_has_children:1; unsigned int list_inbox_inbox:1; }; @@ -584,9 +585,13 @@ return FALSE; inbox_flags_set(ctx, 0); - /* we got here because we didn't see INBOX among other mailboxes, - which means it has no children. */ - ctx->info.flags |= MAILBOX_NOCHILDREN; + if (ctx->inbox_has_children) + ctx->info.flags |= MAILBOX_CHILDREN; + else { + /* we got here because we didn't see INBOX among other mailboxes, + which means it has no children. */ + ctx->info.flags |= MAILBOX_NOCHILDREN; + } return TRUE; } @@ -651,10 +656,18 @@ (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) { /* either this is user's INBOX, or it's a naming conflict */ if (!list_file_is_any_inbox(ctx, storage_name)) { - if (subdir != NULL) { + if (subdir == NULL) { + /* no children */ + } else if ((ctx->ctx.list->flags & + MAILBOX_LIST_FLAG_MAILBOX_FILES) == 0) { /* skip its children also */ ctx->dir = dir; pool_unref(&subdir->pool); + } else if ((ctx->info.flags & MAILBOX_NOINFERIORS) == 0) { + /* INBOX itself is \NoInferiors, but this INBOX + is a directory, and we can make INBOX have + children using it. */ + ctx->inbox_has_children = TRUE; } return 0; } From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: imap: Fixes to handling UTF-8 namespace prefixes Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ade94fde249e changeset: 14994:ade94fde249e user: Timo Sirainen date: Thu Aug 23 22:56:56 2012 +0300 description: imap: Fixes to handling UTF-8 namespace prefixes diffstat: src/imap/cmd-list.c | 27 ++++++++++++++++++++++++--- src/imap/cmd-namespace.c | 11 ++++++++++- src/imap/imap-commands-util.c | 21 ++++++++++----------- 3 files changed, 44 insertions(+), 15 deletions(-) diffs (145 lines): diff -r 565605200989 -r ade94fde249e src/imap/cmd-list.c --- a/src/imap/cmd-list.c Thu Aug 23 22:33:23 2012 +0300 +++ b/src/imap/cmd-list.c Thu Aug 23 22:56:56 2012 +0300 @@ -230,6 +230,19 @@ return ret; } +static const char *ns_prefix_mutf7(struct mail_namespace *ns) +{ + string_t *str; + + if (*ns->prefix == '\0') + return ""; + + str = t_str_new(64); + if (imap_utf8_to_utf7(ns->prefix, str) < 0) + i_panic("Namespace prefix not UTF-8: %s", ns->prefix); + return str_c(str); +} + static const char *ns_get_listed_prefix(struct cmd_list_context *ctx) { struct imap_match_glob *glob; @@ -285,7 +298,7 @@ unsigned int len; enum mailbox_info_flags flags; const char *name; - string_t *str; + string_t *str, *mutf7_name; bool same_ns, ends_with_sep; char ns_sep = mail_namespace_get_sep(ctx->ns); @@ -364,7 +377,11 @@ str_append(str, ") "); list_reply_append_ns_sep_param(str, ns_sep); str_append_c(str, ' '); - imap_quote_append_string(str, name, FALSE); + + mutf7_name = t_str_new(64); + if (imap_utf8_to_utf7(name, mutf7_name) < 0) + i_panic("Namespace prefix not UTF-8: %s", name); + imap_quote_append_string(str, str_c(mutf7_name), FALSE); mailbox_childinfo2str(ctx, str, flags); client_send_line(ctx->cmd->client, str_c(str)); @@ -870,7 +887,7 @@ Otherwise we'll emulate UW-IMAP behavior. */ ns = mail_namespace_find_visible(client->user->namespaces, ref); if (ns != NULL) { - ns_prefix = ns->prefix; + ns_prefix = ns_prefix_mutf7(ns); ns_sep = mail_namespace_get_sep(ns); } else { ns_prefix = ""; @@ -938,6 +955,10 @@ return TRUE; } str = t_str_new(64); + if (imap_utf7_to_utf8(ctx->ref, str) == 0) + ctx->ref = p_strdup(cmd->pool, str_c(str)); + str_truncate(str, 0); + if (imap_arg_get_list_full(&args[1], &list_args, &arg_count)) { ctx->used_listext = TRUE; /* convert pattern list to string array */ diff -r 565605200989 -r ade94fde249e src/imap/cmd-namespace.c --- a/src/imap/cmd-namespace.c Thu Aug 23 22:33:23 2012 +0300 +++ b/src/imap/cmd-namespace.c Thu Aug 23 22:56:56 2012 +0300 @@ -2,6 +2,7 @@ #include "imap-common.h" #include "str.h" +#include "imap-utf7.h" #include "imap-quote.h" #include "imap-commands.h" #include "mail-namespace.h" @@ -9,6 +10,7 @@ static void list_namespaces(struct mail_namespace *ns, enum namespace_type type, string_t *str) { + string_t *mutf7_prefix = t_str_new(64); char ns_sep; bool found = FALSE; @@ -21,7 +23,14 @@ } ns_sep = mail_namespace_get_sep(ns); str_append_c(str, '('); - imap_quote_append_string(str, ns->prefix, FALSE); + + str_truncate(mutf7_prefix, 0); + if (imap_utf8_to_utf7(ns->prefix, mutf7_prefix) < 0) { + i_panic("LIST: Namespace prefix not UTF-8: %s", + ns->prefix); + } + + imap_quote_append_string(str, str_c(mutf7_prefix), FALSE); str_append(str, " \""); if (ns_sep == '\\') str_append_c(str, '\\'); diff -r 565605200989 -r ade94fde249e src/imap/imap-commands-util.c --- a/src/imap/imap-commands-util.c Thu Aug 23 22:33:23 2012 +0300 +++ b/src/imap/imap-commands-util.c Thu Aug 23 22:56:56 2012 +0300 @@ -19,10 +19,15 @@ { struct mail_namespace *namespaces = cmd->client->user->namespaces; struct mail_namespace *ns; - unsigned int name_len; string_t *utf8_name; - ns = mail_namespace_find(namespaces, *mailbox); + utf8_name = t_str_new(64); + if (imap_utf7_to_utf8(*mailbox, utf8_name) < 0) { + client_send_tagline(cmd, "NO Mailbox name is not valid mUTF-7"); + return NULL; + } + + ns = mail_namespace_find(namespaces, str_c(utf8_name)); if (ns == NULL) { client_send_tagline(cmd, t_strdup_printf( "NO Client tried to access nonexistent namespace. " @@ -31,20 +36,14 @@ return NULL; } - name_len = strlen(*mailbox); if ((cmd->client->set->parsed_workarounds & WORKAROUND_TB_EXTRA_MAILBOX_SEP) != 0 && - name_len > 0 && - (*mailbox)[name_len-1] == mail_namespace_get_sep(ns)) { + str_len(utf8_name) > 0 && + str_c(utf8_name)[str_len(utf8_name)-1] == mail_namespace_get_sep(ns)) { /* drop the extra trailing hierarchy separator */ - *mailbox = t_strndup(*mailbox, name_len-1); + str_truncate(utf8_name, str_len(utf8_name)-1); } - utf8_name = t_str_new(64); - if (imap_utf7_to_utf8(*mailbox, utf8_name) < 0) { - client_send_tagline(cmd, "NO Mailbox name is not valid mUTF-7"); - return NULL; - } *mailbox = str_c(utf8_name); return ns; } From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: doveadm copy/move: Added "user" parameter to specif... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6b61cc674eef changeset: 14995:6b61cc674eef user: Timo Sirainen date: Thu Aug 23 23:46:15 2012 +0300 description: doveadm copy/move: Added "user" parameter to specify the source user. diffstat: src/doveadm/doveadm-mail-copymove.c | 52 +++++++++++++++++++++++++++++++++--- src/doveadm/doveadm-mail.c | 2 + src/doveadm/doveadm-mail.h | 1 + 3 files changed, 50 insertions(+), 5 deletions(-) diffs (145 lines): diff -r ade94fde249e -r 6b61cc674eef src/doveadm/doveadm-mail-copymove.c --- a/src/doveadm/doveadm-mail-copymove.c Thu Aug 23 22:56:56 2012 +0300 +++ b/src/doveadm/doveadm-mail-copymove.c Thu Aug 23 23:46:15 2012 +0300 @@ -13,6 +13,9 @@ struct copy_cmd_context { struct doveadm_mail_cmd_context ctx; + struct mail_storage_service_user *source_service_user; + struct mail_user *source_user; + const char *destname; bool move; }; @@ -68,6 +71,22 @@ return ret; } +static void +cmd_copy_alloc_source_user(struct copy_cmd_context *ctx, const char *username) +{ + struct mail_storage_service_input input; + const char *error; + + input = ctx->ctx.storage_service_input; + input.username = username; + + if (mail_storage_service_lookup_next(ctx->ctx.storage_service, &input, + &ctx->source_service_user, + &ctx->source_user, + &error) < 0) + i_fatal("Couldn't lookup user %s: %s", input.username, error); +} + static int cmd_copy_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) { @@ -77,6 +96,7 @@ MAILBOX_LIST_ITER_NO_AUTO_BOXES | MAILBOX_LIST_ITER_RETURN_NO_FLAGS; struct doveadm_mailbox_list_iter *iter; + struct mail_user *src_user; struct mail_namespace *ns; struct mailbox *destbox; const struct mailbox_info *info; @@ -97,7 +117,8 @@ return -1; } - iter = doveadm_mailbox_list_iter_init(_ctx, user, _ctx->search_args, + src_user = ctx->source_user != NULL ? ctx->source_user : user; + iter = doveadm_mailbox_list_iter_init(_ctx, src_user, _ctx->search_args, iter_flags); while ((info = doveadm_mailbox_list_iter_next(iter)) != NULL) T_BEGIN { if (cmd_copy_box(ctx, destbox, info) < 0) @@ -114,7 +135,6 @@ } mailbox_free(&destbox); return ret; - } static void cmd_copy_init(struct doveadm_mail_cmd_context *_ctx, @@ -125,18 +145,40 @@ if (destname == NULL || args[1] == NULL) doveadm_mail_help_name(cmdname); + args++; + + if (args[0] != NULL && args[1] != NULL && + strcasecmp(args[0], "user") == 0) { + if ((_ctx->service_flags & + MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) == 0) + i_fatal("Use -u parameter to specify destination user"); + + cmd_copy_alloc_source_user(ctx, args[1]); + args += 2; + } ctx->destname = p_strdup(ctx->ctx.pool, destname); - ctx->ctx.search_args = doveadm_mail_build_search_args(args + 1); + _ctx->search_args = doveadm_mail_build_search_args(args); expunge_search_args_check(ctx->ctx.search_args, cmdname); } +static void cmd_copy_deinit(struct doveadm_mail_cmd_context *_ctx) +{ + struct copy_cmd_context *ctx = (struct copy_cmd_context *)_ctx; + + if (ctx->source_user != NULL) { + mail_storage_service_user_free(&ctx->source_service_user); + mail_user_unref(&ctx->source_user); + } +} + static struct doveadm_mail_cmd_context *cmd_copy_alloc(void) { struct copy_cmd_context *ctx; ctx = doveadm_mail_cmd_alloc(struct copy_cmd_context); ctx->ctx.v.init = cmd_copy_init; + ctx->ctx.v.deinit = cmd_copy_deinit; ctx->ctx.v.run = cmd_copy_run; doveadm_print_init(DOVEADM_PRINT_TYPE_FLOW); return &ctx->ctx; @@ -152,8 +194,8 @@ } struct doveadm_mail_cmd cmd_copy = { - cmd_copy_alloc, "copy", " " + cmd_copy_alloc, "copy", " [user ] " }; struct doveadm_mail_cmd cmd_move = { - cmd_move_alloc, "move", " " + cmd_move_alloc, "move", " [user ] " }; diff -r ade94fde249e -r 6b61cc674eef src/doveadm/doveadm-mail.c --- a/src/doveadm/doveadm-mail.c Thu Aug 23 22:56:56 2012 +0300 +++ b/src/doveadm/doveadm-mail.c Thu Aug 23 23:46:15 2012 +0300 @@ -323,6 +323,7 @@ i_assert(input->username != NULL); ctx->cur_username = input->username; + ctx->storage_service_input = *input; ctx->storage_service = mail_storage_service_init(master_service, NULL, ctx->service_flags); ctx->v.init(ctx, ctx->args); @@ -351,6 +352,7 @@ memset(&input, 0, sizeof(input)); input.service = "doveadm"; + ctx->storage_service_input = input; ctx->storage_service = mail_storage_service_init(master_service, NULL, ctx->service_flags); lib_signals_set_handler(SIGINT, 0, sig_die, NULL); diff -r ade94fde249e -r 6b61cc674eef src/doveadm/doveadm-mail.h --- a/src/doveadm/doveadm-mail.h Thu Aug 23 22:56:56 2012 +0300 +++ b/src/doveadm/doveadm-mail.h Thu Aug 23 23:46:15 2012 +0300 @@ -48,6 +48,7 @@ const struct doveadm_settings *set; enum mail_storage_service_flags service_flags; struct mail_storage_service_ctx *storage_service; + struct mail_storage_service_input storage_service_input; /* search args aren't set for all mail commands */ struct mail_search_args *search_args; From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: auth: Make it clearer in debug messages if the repl... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5590c1dc04cd changeset: 14996:5590c1dc04cd user: Timo Sirainen date: Fri Aug 24 12:25:55 2012 +0300 description: auth: Make it clearer in debug messages if the replies are passdb or userdb. diffstat: src/auth/auth-client-connection.c | 3 ++- src/auth/auth-master-connection.c | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diffs (43 lines): diff -r 6b61cc674eef -r 5590c1dc04cd src/auth/auth-client-connection.c --- a/src/auth/auth-client-connection.c Thu Aug 23 23:46:15 2012 +0300 +++ b/src/auth/auth-client-connection.c Fri Aug 24 12:25:55 2012 +0300 @@ -65,7 +65,8 @@ } if (conn->auth->set->debug) { - i_debug("client out: %s", conn->auth->set->debug_passwords ? + i_debug("client passdb out: %s", + conn->auth->set->debug_passwords ? cmd : reply_line_hide_pass(cmd)); } } diff -r 6b61cc674eef -r 5590c1dc04cd src/auth/auth-master-connection.c --- a/src/auth/auth-master-connection.c Thu Aug 23 23:46:15 2012 +0300 +++ b/src/auth/auth-master-connection.c Fri Aug 24 12:25:55 2012 +0300 @@ -79,7 +79,7 @@ reply_str = auth_stream_reply_export(reply); if (conn->auth->set->debug) { - i_debug("master out: %s", + i_debug("master userdb out: %s", auth_master_reply_hide_passwords(conn, reply_str)); } @@ -280,7 +280,7 @@ } if (conn->auth->set->debug) { - i_debug("master out: %s", + i_debug("userdb out: %s", auth_master_reply_hide_passwords(conn, str_c(str))); } @@ -342,7 +342,7 @@ } if (conn->auth->set->debug) - i_debug("master out: %s", str_c(str)); + i_debug("passdb out: %s", str_c(str)); str_append_c(str, '\n'); (void)o_stream_send(conn->output, str_data(str), str_len(str)); From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: auth: Don't add "master" to passdb reply if the pas... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1bc8f7b823e7 changeset: 14997:1bc8f7b823e7 user: Timo Sirainen date: Fri Aug 24 15:12:32 2012 +0300 description: auth: Don't add "master" to passdb reply if the passdb itself already added it. diffstat: src/auth/auth-request-handler.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 5590c1dc04cd -r 1bc8f7b823e7 src/auth/auth-request-handler.c --- a/src/auth/auth-request-handler.c Fri Aug 24 12:25:55 2012 +0300 +++ b/src/auth/auth-request-handler.c Fri Aug 24 15:12:32 2012 +0300 @@ -186,7 +186,8 @@ auth_stream_reply_add(reply, "pass", request->mech_password); } - if (request->master_user != NULL) { + if (request->master_user != NULL && + auth_stream_reply_find(reply, "master") == NULL) { /* the master username needs to be forwarded */ auth_stream_reply_add(reply, "master", request->master_user); From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: dict redis: Fixed dict_lookup() to skip all previou... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/00f940201806 changeset: 14998:00f940201806 user: Timo Sirainen date: Tue Aug 21 10:02:44 2012 +0300 description: dict redis: Fixed dict_lookup() to skip all previous pending replies. diffstat: src/lib-dict/dict-redis.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (14 lines): diff -r 1bc8f7b823e7 -r 00f940201806 src/lib-dict/dict-redis.c --- a/src/lib-dict/dict-redis.c Fri Aug 24 15:12:32 2012 +0300 +++ b/src/lib-dict/dict-redis.c Tue Aug 21 10:02:44 2012 +0300 @@ -441,7 +441,9 @@ str_truncate(dict->conn.last_reply, 0); redis_input_state_add(dict, REDIS_INPUT_STATE_GET); - io_loop_run(dict->ioloop); + do { + io_loop_run(dict->ioloop); + } while (array_count(&dict->input_states) > 0); } timeout_remove(&to); } From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: dict-redis: Fixed infinite looping Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/db9fcdacba90 changeset: 14999:db9fcdacba90 user: Timo Sirainen date: Sun Aug 26 19:23:48 2012 +0300 description: dict-redis: Fixed infinite looping diffstat: src/lib-dict/dict-redis.c | 45 ++++++++++++++++++++------------------------- 1 files changed, 20 insertions(+), 25 deletions(-) diffs (105 lines): diff -r 00f940201806 -r db9fcdacba90 src/lib-dict/dict-redis.c --- a/src/lib-dict/dict-redis.c Tue Aug 21 10:02:44 2012 +0300 +++ b/src/lib-dict/dict-redis.c Sun Aug 26 19:23:48 2012 +0300 @@ -115,7 +115,7 @@ io_loop_destroy(&dict->ioloop); } -static void redis_input_get(struct redis_connection *conn) +static int redis_input_get(struct redis_connection *conn) { const unsigned char *data; size_t size; @@ -125,20 +125,20 @@ /* read the size first */ line = i_stream_next_line(conn->conn.input); if (line == NULL) - return; + return 0; if (strcmp(line, "$-1") == 0) { conn->value_received = TRUE; conn->value_not_found = TRUE; if (conn->dict->ioloop != NULL) io_loop_stop(conn->dict->ioloop); redis_input_state_remove(conn->dict); - return; + return 1; } if (line[0] != '$' || str_to_uint(line+1, &conn->bytes_left) < 0) { i_error("redis: Unexpected input (wanted $size): %s", line); redis_conn_destroy(&conn->conn); - return; + return 1; } conn->bytes_left += 2; /* include trailing CRLF */ } @@ -151,15 +151,17 @@ conn->bytes_left -= size; i_stream_skip(conn->conn.input, size); - if (conn->bytes_left == 0) { - /* reply fully read - drop trailing CRLF */ - conn->value_received = TRUE; - str_truncate(conn->last_reply, str_len(conn->last_reply)-2); + if (conn->bytes_left > 0) + return 0; - if (conn->dict->ioloop != NULL) - io_loop_stop(conn->dict->ioloop); - redis_input_state_remove(conn->dict); - } + /* reply fully read - drop trailing CRLF */ + conn->value_received = TRUE; + str_truncate(conn->last_reply, str_len(conn->last_reply)-2); + + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); + redis_input_state_remove(conn->dict); + return 1; } static int redis_conn_input_more(struct redis_connection *conn) @@ -174,16 +176,14 @@ states = array_get(&dict->input_states, &count); if (count == 0) { line = i_stream_next_line(conn->conn.input); - if (line == NULL) line = ""; - i_error("redis: Unexpected input (expected nothing): %s", - line); + if (line == NULL) + return 0; + i_error("redis: Unexpected input (expected nothing): %s", line); return -1; } state = states[0]; - if (state == REDIS_INPUT_STATE_GET) { - redis_input_get(conn); - return 1; - } + if (state == REDIS_INPUT_STATE_GET) + return redis_input_get(conn); line = i_stream_next_line(conn->conn.input); if (line == NULL) @@ -235,7 +235,6 @@ static void redis_conn_input(struct connection *_conn) { struct redis_connection *conn = (struct redis_connection *)_conn; - size_t size; int ret; switch (i_stream_read(_conn->input)) { @@ -248,11 +247,7 @@ break; } - while ((ret = redis_conn_input_more(conn)) > 0) { - i_stream_get_data(_conn->input, &size); - if (size == 0) - break; - } + while ((ret = redis_conn_input_more(conn)) > 0) ; if (ret < 0) redis_conn_destroy(_conn); } From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: lmtp proxy: Include session ID string in timeout re... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/bde62f77c65a changeset: 15000:bde62f77c65a user: Timo Sirainen date: Tue Aug 28 13:23:37 2012 +0300 description: lmtp proxy: Include session ID string in timeout reply text. diffstat: src/lmtp/commands.c | 1 + src/lmtp/lmtp-proxy.c | 10 ++++++---- src/lmtp/lmtp-proxy.h | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diffs (64 lines): diff -r db9fcdacba90 -r bde62f77c65a src/lmtp/commands.c --- a/src/lmtp/commands.c Sun Aug 26 19:23:48 2012 +0300 +++ b/src/lmtp/commands.c Tue Aug 28 13:23:37 2012 +0300 @@ -304,6 +304,7 @@ if (client->proxy == NULL) { client->proxy = lmtp_proxy_init(client->set->hostname, dns_client_socket_path, + client->state.session_id, client->output); if (client->state.mail_body_8bitmime) args = " BODY=8BITMIME"; diff -r db9fcdacba90 -r bde62f77c65a src/lmtp/lmtp-proxy.c --- a/src/lmtp/lmtp-proxy.c Sun Aug 26 19:23:48 2012 +0300 +++ b/src/lmtp/lmtp-proxy.c Tue Aug 28 13:23:37 2012 +0300 @@ -33,7 +33,7 @@ struct lmtp_proxy { pool_t pool; - const char *mail_from, *my_hostname; + const char *mail_from, *my_hostname, *session_id; const char *dns_client_socket_path; ARRAY_DEFINE(connections, struct lmtp_proxy_connection *); @@ -56,7 +56,7 @@ struct lmtp_proxy * lmtp_proxy_init(const char *my_hostname, const char *dns_client_socket_path, - struct ostream *client_output) + const char *session_id, struct ostream *client_output) { struct lmtp_proxy *proxy; pool_t pool; @@ -69,6 +69,7 @@ proxy->my_hostname = p_strdup(pool, my_hostname); proxy->client_output = client_output; proxy->dns_client_socket_path = p_strdup(pool, dns_client_socket_path); + proxy->session_id = p_strdup(pool, session_id); i_array_init(&proxy->rcpt_to, 32); i_array_init(&proxy->connections, 32); return proxy; @@ -264,8 +265,9 @@ const char *line; line = t_strdup_printf(ERRSTR_TEMP_REMOTE_FAILURE - " (timeout while waiting for reply to %s)", - lmtp_client_state_to_string(conn->client)); + " (timeout while waiting for reply to %s) <%s>", + lmtp_client_state_to_string(conn->client), + conn->proxy->session_id); lmtp_client_fail(conn->client, line); } diff -r db9fcdacba90 -r bde62f77c65a src/lmtp/lmtp-proxy.h --- a/src/lmtp/lmtp-proxy.h Sun Aug 26 19:23:48 2012 +0300 +++ b/src/lmtp/lmtp-proxy.h Tue Aug 28 13:23:37 2012 +0300 @@ -15,7 +15,7 @@ struct lmtp_proxy * lmtp_proxy_init(const char *my_hostname, const char *dns_client_socket_path, - struct ostream *client_output); + const char *session_id, struct ostream *client_output); void lmtp_proxy_deinit(struct lmtp_proxy **proxy); /* Set the "MAIL FROM:" line, including <> and options */ From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: imapc: max_idle_time setting didn't actually work. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7e7364926540 changeset: 15001:7e7364926540 user: Timo Sirainen date: Tue Aug 28 15:57:22 2012 +0300 description: imapc: max_idle_time setting didn't actually work. diffstat: src/lib-imap-client/imapc-client.c | 1 + src/lib-imap-client/imapc-connection.c | 2 ++ 2 files changed, 3 insertions(+), 0 deletions(-) diffs (23 lines): diff -r bde62f77c65a -r 7e7364926540 src/lib-imap-client/imapc-client.c --- a/src/lib-imap-client/imapc-client.c Tue Aug 28 13:23:37 2012 +0300 +++ b/src/lib-imap-client/imapc-client.c Tue Aug 28 15:57:22 2012 +0300 @@ -57,6 +57,7 @@ client->set.temp_path_prefix = p_strdup(pool, set->temp_path_prefix); client->set.rawlog_dir = p_strdup(pool, set->rawlog_dir); + client->set.max_idle_time = set->max_idle_time; if (set->ssl_mode != IMAPC_CLIENT_SSL_MODE_NONE) { client->set.ssl_mode = set->ssl_mode; diff -r bde62f77c65a -r 7e7364926540 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Tue Aug 28 13:23:37 2012 +0300 +++ b/src/lib-imap-client/imapc-connection.c Tue Aug 28 15:57:22 2012 +0300 @@ -1280,6 +1280,8 @@ struct stat st; int fd; + i_assert(conn->client->set.max_idle_time > 0); + conn->prev_connect_idx = (conn->prev_connect_idx+1) % conn->ips_count; ip = &conn->ips[conn->prev_connect_idx]; fd = net_connect_ip(ip, conn->client->set.port, NULL); From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: dict file: Fixed corruption with large values. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6e53209030f6 changeset: 15002:6e53209030f6 user: Timo Sirainen date: Tue Aug 28 18:53:30 2012 +0300 description: dict file: Fixed corruption with large values. Patch by Ewald Dieterich. diffstat: src/lib-dict/dict-file.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diffs (20 lines): diff -r 7e7364926540 -r 6e53209030f6 src/lib-dict/dict-file.c --- a/src/lib-dict/dict-file.c Tue Aug 28 15:57:22 2012 +0300 +++ b/src/lib-dict/dict-file.c Tue Aug 28 18:53:30 2012 +0300 @@ -186,9 +186,14 @@ if (dict->fd != -1) { input = i_stream_create_fd(dict->fd, (size_t)-1, FALSE); - while ((key = i_stream_read_next_line(input)) != NULL && - (value = i_stream_read_next_line(input)) != NULL) { + + while ((key = i_stream_read_next_line(input)) != NULL) { + /* strdup() before the second read */ key = p_strdup(dict->hash_pool, key); + + if ((value = i_stream_read_next_line(input)) == NULL) + break; + value = p_strdup(dict->hash_pool, value); hash_table_insert(dict->hash, key, value); } From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: imapc: If imapc_list_prefix=INBOX, don't treat INBO... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/eb57a7280b01 changeset: 15003:eb57a7280b01 user: Timo Sirainen date: Tue Aug 28 19:06:01 2012 +0300 description: imapc: If imapc_list_prefix=INBOX, don't treat INBOX/INBOX as the INBOX itself. diffstat: src/lib-storage/index/imapc/imapc-list.c | 12 ++++++++++-- 1 files changed, 10 insertions(+), 2 deletions(-) diffs (37 lines): diff -r 6e53209030f6 -r eb57a7280b01 src/lib-storage/index/imapc/imapc-list.c --- a/src/lib-storage/index/imapc/imapc-list.c Tue Aug 28 18:53:30 2012 +0300 +++ b/src/lib-storage/index/imapc/imapc-list.c Tue Aug 28 19:06:01 2012 +0300 @@ -345,6 +345,7 @@ { struct imapc_command *cmd; struct imapc_simple_context ctx; + struct mailbox_node *node; const char *pattern; i_assert(list->sep != '\0'); @@ -364,16 +365,23 @@ mailbox_tree_deinit(&list->mailboxes); list->mailboxes = mailbox_tree_init(list->sep); mailbox_tree_set_parents_nonexistent(list->mailboxes); + imapc_simple_run(&ctx); if ((list->list.ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) { /* INBOX always exists in IMAP server. since this namespace is marked with inbox=yes, show the INBOX even if imapc_list_prefix doesn't match it */ bool created; - (void)mailbox_tree_get(list->mailboxes, "INBOX", &created); + node = mailbox_tree_get(list->mailboxes, "INBOX", &created); + if (*list->storage->set->imapc_list_prefix != '\0') { + /* this listing didn't include the INBOX itself, but + might have included its children. make sure there + aren't any extra flags in it (especially + \NonExistent) */ + node->flags &= MAILBOX_CHILDREN; + } } - imapc_simple_run(&ctx); if (ctx.ret == 0) { list->refreshed_mailboxes = TRUE; imapc_list_delete_unused_indexes(list); From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: layout=fs mailbox listing: Fix to prefix=INBOX/ han... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/67235781cc08 changeset: 15004:67235781cc08 user: Timo Sirainen date: Thu Aug 30 21:56:43 2012 +0300 description: layout=fs mailbox listing: Fix to prefix=INBOX/ handling diffstat: src/lib-storage/list/mailbox-list-fs-iter.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r eb57a7280b01 -r 67235781cc08 src/lib-storage/list/mailbox-list-fs-iter.c --- a/src/lib-storage/list/mailbox-list-fs-iter.c Tue Aug 28 19:06:01 2012 +0300 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Thu Aug 30 21:56:43 2012 +0300 @@ -400,6 +400,7 @@ if (p == last+1 && *pattern == ns_sep) root = "/"; else if ((ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0 && + ns->prefix_len == 6 && strcasecmp(prefix_vname, "INBOX") == 0 && strncasecmp(ns->prefix, pattern, ns->prefix_len) == 0) { /* special case: Namespace prefix is INBOX/ and From dovecot at dovecot.org Thu Aug 30 22:05:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 30 Aug 2012 22:05:17 +0300 Subject: dovecot-2.2: Merged changes from v2.1 tree. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1f95d4fe29c7 changeset: 15005:1f95d4fe29c7 user: Timo Sirainen date: Thu Aug 30 22:05:02 2012 +0300 description: Merged changes from v2.1 tree. diffstat: configure.in | 14 +- src/auth/auth-client-connection.c | 3 +- src/auth/auth-master-connection.c | 6 +- src/auth/auth-request-handler.c | 3 +- src/auth/mech.c | 1 + src/doveadm/Makefile.am | 2 +- src/doveadm/doveadm-mail-copymove.c | 201 ++++++++++++++++++++++++++++ src/doveadm/doveadm-mail-move.c | 144 -------------------- src/doveadm/doveadm-mail.c | 3 + src/doveadm/doveadm-mail.h | 2 + src/imap/cmd-list.c | 19 ++- src/imap/cmd-namespace.c | 11 +- src/imap/imap-commands-util.c | 21 +- src/lib-dict/dict-file.c | 9 +- src/lib-dict/dict-redis.c | 43 ++--- src/lib-imap-client/imapc-client.c | 1 + src/lib-imap-client/imapc-connection.c | 2 + src/lib-storage/index/imapc/imapc-list.c | 12 +- src/lib-storage/list/mailbox-list-fs-iter.c | 22 ++- src/lib-storage/mail-storage-settings.c | 5 + src/lmtp/commands.c | 1 + src/lmtp/lmtp-proxy.c | 6 +- src/lmtp/lmtp-proxy.h | 1 + 23 files changed, 325 insertions(+), 207 deletions(-) diffs (truncated from 921 to 300 lines): diff -r 5ffcde8baa8a -r 1f95d4fe29c7 configure.in --- a/configure.in Thu Aug 30 21:12:23 2012 +0300 +++ b/configure.in Thu Aug 30 22:05:02 2012 +0300 @@ -953,21 +953,13 @@ AC_DEFINE_UNQUOTED(MEM_ALIGN_SIZE, $mem_align, Required memory alignment) dnl * find random source -AC_MSG_CHECKING([for OpenBSD /dev/arandom]) -if test -c /dev/arandom; then +AC_MSG_CHECKING([for /dev/urandom]) +if test -c /dev/urandom || test -s /dev/urandom; then AC_MSG_RESULT(yes) - AC_DEFINE(DEV_URANDOM_PATH, "/dev/arandom", Path to /dev/urandom) + AC_DEFINE(DEV_URANDOM_PATH, "/dev/urandom", Path to /dev/urandom) have_random_source=yes else AC_MSG_RESULT(no) - AC_MSG_CHECKING([for /dev/urandom]) - if test -c /dev/urandom || test -s /dev/urandom; then - AC_MSG_RESULT(yes) - AC_DEFINE(DEV_URANDOM_PATH, "/dev/urandom", Path to /dev/urandom) - have_random_source=yes - else - AC_MSG_RESULT(no) - fi fi if test "$have_random_source" != "yes"; then diff -r 5ffcde8baa8a -r 1f95d4fe29c7 src/auth/auth-client-connection.c --- a/src/auth/auth-client-connection.c Thu Aug 30 21:12:23 2012 +0300 +++ b/src/auth/auth-client-connection.c Thu Aug 30 22:05:02 2012 +0300 @@ -65,7 +65,8 @@ } if (conn->auth->set->debug) { - i_debug("client out: %s", conn->auth->set->debug_passwords ? + i_debug("client passdb out: %s", + conn->auth->set->debug_passwords ? cmd : reply_line_hide_pass(cmd)); } } diff -r 5ffcde8baa8a -r 1f95d4fe29c7 src/auth/auth-master-connection.c --- a/src/auth/auth-master-connection.c Thu Aug 30 21:12:23 2012 +0300 +++ b/src/auth/auth-master-connection.c Thu Aug 30 22:05:02 2012 +0300 @@ -79,7 +79,7 @@ reply_str = auth_stream_reply_export(reply); if (conn->auth->set->debug) { - i_debug("master out: %s", + i_debug("master userdb out: %s", auth_master_reply_hide_passwords(conn, reply_str)); } @@ -280,7 +280,7 @@ } if (conn->auth->set->debug) { - i_debug("master out: %s", + i_debug("userdb out: %s", auth_master_reply_hide_passwords(conn, str_c(str))); } @@ -342,7 +342,7 @@ } if (conn->auth->set->debug) - i_debug("master out: %s", str_c(str)); + i_debug("passdb out: %s", str_c(str)); str_append_c(str, '\n'); o_stream_nsend(conn->output, str_data(str), str_len(str)); diff -r 5ffcde8baa8a -r 1f95d4fe29c7 src/auth/auth-request-handler.c --- a/src/auth/auth-request-handler.c Thu Aug 30 21:12:23 2012 +0300 +++ b/src/auth/auth-request-handler.c Thu Aug 30 22:05:02 2012 +0300 @@ -185,7 +185,8 @@ auth_stream_reply_add(reply, "pass", request->mech_password); } - if (request->master_user != NULL) { + if (request->master_user != NULL && + auth_stream_reply_find(reply, "master") == NULL) { /* the master username needs to be forwarded */ auth_stream_reply_add(reply, "master", request->master_user); diff -r 5ffcde8baa8a -r 1f95d4fe29c7 src/auth/mech.c --- a/src/auth/mech.c Thu Aug 30 21:12:23 2012 +0300 +++ b/src/auth/mech.c Thu Aug 30 22:05:02 2012 +0300 @@ -205,6 +205,7 @@ #endif } mech_unregister_module(&mech_otp); + mech_unregister_module(&mech_scram_sha1); mech_unregister_module(&mech_skey); mech_unregister_module(&mech_rpa); mech_unregister_module(&mech_anonymous); diff -r 5ffcde8baa8a -r 1f95d4fe29c7 src/doveadm/Makefile.am --- a/src/doveadm/Makefile.am Thu Aug 30 21:12:23 2012 +0300 +++ b/src/doveadm/Makefile.am Thu Aug 30 22:05:02 2012 +0300 @@ -73,7 +73,7 @@ doveadm-mail-iter.c \ doveadm-mail-mailbox.c \ doveadm-mail-mailbox-status.c \ - doveadm-mail-move.c \ + doveadm-mail-copymove.c \ doveadm-mailbox-list-iter.c \ doveadm-mail-search.c \ doveadm-mail-server.c \ diff -r 5ffcde8baa8a -r 1f95d4fe29c7 src/doveadm/doveadm-mail-copymove.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doveadm/doveadm-mail-copymove.c Thu Aug 30 22:05:02 2012 +0300 @@ -0,0 +1,201 @@ +/* Copyright (c) 2011-2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "mail-storage.h" +#include "mail-namespace.h" +#include "doveadm-print.h" +#include "doveadm-mailbox-list-iter.h" +#include "doveadm-mail-iter.h" +#include "doveadm-mail.h" + +#include + +struct copy_cmd_context { + struct doveadm_mail_cmd_context ctx; + + struct mail_storage_service_user *source_service_user; + struct mail_user *source_user; + + const char *destname; + bool move; +}; + +static int +cmd_copy_box(struct copy_cmd_context *ctx, struct mailbox *destbox, + const struct mailbox_info *info) +{ + struct doveadm_mail_iter *iter; + struct mailbox_transaction_context *trans; + struct mailbox_transaction_context *desttrans; + struct mail_save_context *save_ctx; + struct mail *mail; + int ret = 0; + + if (doveadm_mail_iter_init(&ctx->ctx, info, ctx->ctx.search_args, 0, + NULL, &trans, &iter) < 0) + return -1; + + /* use a separately committed transaction for each mailbox. + this guarantees that mails aren't expunged without actually having + been copied. */ + desttrans = mailbox_transaction_begin(destbox, + MAILBOX_TRANSACTION_FLAG_EXTERNAL); + + while (doveadm_mail_iter_next(iter, &mail)) { + save_ctx = mailbox_save_alloc(desttrans); + mailbox_save_copy_flags(save_ctx, mail); + if (mailbox_copy(&save_ctx, mail) == 0) { + if (ctx->move) + mail_expunge(mail); + } else { + i_error("Copying message UID %u from '%s' failed: %s", + mail->uid, info->vname, + mailbox_get_last_error(destbox, NULL)); + doveadm_mail_failed_mailbox(&ctx->ctx, destbox); + ret = -1; + } + } + + if (mailbox_transaction_commit(&desttrans) < 0) { + i_error("Committing %s mails failed: %s", + ctx->move ? "moved" : "copied", + mailbox_get_last_error(destbox, NULL)); + doveadm_mail_failed_mailbox(&ctx->ctx, destbox); + /* rollback expunges */ + doveadm_mail_iter_deinit_rollback(&iter); + ret = -1; + } else { + if (doveadm_mail_iter_deinit_sync(&iter) < 0) + ret = -1; + } + return ret; +} + +static void +cmd_copy_alloc_source_user(struct copy_cmd_context *ctx, const char *username) +{ + struct mail_storage_service_input input; + const char *error; + + input = ctx->ctx.storage_service_input; + input.username = username; + + if (mail_storage_service_lookup_next(ctx->ctx.storage_service, &input, + &ctx->source_service_user, + &ctx->source_user, + &error) < 0) + i_fatal("Couldn't lookup user %s: %s", input.username, error); +} + +static int +cmd_copy_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) +{ + struct copy_cmd_context *ctx = (struct copy_cmd_context *)_ctx; + const enum mailbox_list_iter_flags iter_flags = + MAILBOX_LIST_ITER_RAW_LIST | + MAILBOX_LIST_ITER_NO_AUTO_BOXES | + MAILBOX_LIST_ITER_RETURN_NO_FLAGS; + struct doveadm_mailbox_list_iter *iter; + struct mail_user *src_user; + struct mail_namespace *ns; + struct mailbox *destbox; + const struct mailbox_info *info; + int ret = 0; + + ns = mail_namespace_find(user->namespaces, ctx->destname); + if (ns == NULL) { + i_fatal_status(DOVEADM_EX_NOTFOUND, + "Can't find namespace for: %s", ctx->destname); + } + + destbox = mailbox_alloc(ns->list, ctx->destname, MAILBOX_FLAG_SAVEONLY); + if (mailbox_open(destbox) < 0) { + i_error("Can't open mailbox '%s': %s", ctx->destname, + mailbox_get_last_error(destbox, NULL)); + doveadm_mail_failed_mailbox(&ctx->ctx, destbox); + mailbox_free(&destbox); + return -1; + } + + src_user = ctx->source_user != NULL ? ctx->source_user : user; + iter = doveadm_mailbox_list_iter_init(_ctx, src_user, _ctx->search_args, + iter_flags); + while ((info = doveadm_mailbox_list_iter_next(iter)) != NULL) T_BEGIN { + if (cmd_copy_box(ctx, destbox, info) < 0) + ret = -1; + } T_END; + if (doveadm_mailbox_list_iter_deinit(&iter) < 0) + ret = -1; + + if (mailbox_sync(destbox, 0) < 0) { + i_error("Syncing mailbox '%s' failed: %s", ctx->destname, + mailbox_get_last_error(destbox, NULL)); + doveadm_mail_failed_mailbox(&ctx->ctx, destbox); + ret = -1; + } + mailbox_free(&destbox); + return ret; +} + +static void cmd_copy_init(struct doveadm_mail_cmd_context *_ctx, + const char *const args[]) +{ + struct copy_cmd_context *ctx = (struct copy_cmd_context *)_ctx; + const char *destname = args[0], *cmdname = ctx->move ? "move" : "copy"; + + if (destname == NULL || args[1] == NULL) + doveadm_mail_help_name(cmdname); + args++; + + if (args[0] != NULL && args[1] != NULL && + strcasecmp(args[0], "user") == 0) { + if ((_ctx->service_flags & + MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) == 0) + i_fatal("Use -u parameter to specify destination user"); + + cmd_copy_alloc_source_user(ctx, args[1]); + args += 2; + } + + ctx->destname = p_strdup(ctx->ctx.pool, destname); + _ctx->search_args = doveadm_mail_build_search_args(args); + expunge_search_args_check(ctx->ctx.search_args, cmdname); +} + +static void cmd_copy_deinit(struct doveadm_mail_cmd_context *_ctx) +{ + struct copy_cmd_context *ctx = (struct copy_cmd_context *)_ctx; + + if (ctx->source_user != NULL) { + mail_storage_service_user_free(&ctx->source_service_user); + mail_user_unref(&ctx->source_user); + } +} + +static struct doveadm_mail_cmd_context *cmd_copy_alloc(void) +{ + struct copy_cmd_context *ctx; + + ctx = doveadm_mail_cmd_alloc(struct copy_cmd_context); + ctx->ctx.v.init = cmd_copy_init; + ctx->ctx.v.deinit = cmd_copy_deinit; + ctx->ctx.v.run = cmd_copy_run; + doveadm_print_init(DOVEADM_PRINT_TYPE_FLOW); + return &ctx->ctx; +} + +static struct doveadm_mail_cmd_context *cmd_move_alloc(void) +{ + struct copy_cmd_context *ctx; From dovecot at dovecot.org Fri Aug 31 14:15:06 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 31 Aug 2012 14:15:06 +0300 Subject: dovecot-2.2: lib-storage: Fixed listing list=children namespaces... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/db28fea9b8db changeset: 15006:db28fea9b8db user: Timo Sirainen date: Fri Aug 31 14:14:50 2012 +0300 description: lib-storage: Fixed listing list=children namespaces that had child namespaces. diffstat: src/lib-storage/mailbox-list-iter.c | 27 ++++++++++++++++++++++----- 1 files changed, 22 insertions(+), 5 deletions(-) diffs (56 lines): diff -r 1f95d4fe29c7 -r db28fea9b8db src/lib-storage/mailbox-list-iter.c --- a/src/lib-storage/mailbox-list-iter.c Thu Aug 30 22:05:02 2012 +0300 +++ b/src/lib-storage/mailbox-list-iter.c Fri Aug 31 14:14:50 2012 +0300 @@ -52,6 +52,9 @@ static bool ns_match_next(struct ns_list_iterate_context *ctx, struct mail_namespace *ns, const char *pattern); +static int mailbox_list_match_anything(struct ns_list_iterate_context *ctx, + struct mail_namespace *ns, + const char *prefix); struct mailbox_list_iterate_context * mailbox_list_iter_init(struct mailbox_list *list, const char *pattern, @@ -329,15 +332,29 @@ } static bool -ns_prefix_has_child_namespaces(struct mail_namespace *namespaces, - const char *prefix) +ns_prefix_is_visible(struct ns_list_iterate_context *ctx, + struct mail_namespace *ns) +{ + if ((ns->flags & NAMESPACE_FLAG_LIST_PREFIX) != 0) + return TRUE; + if ((ns->flags & NAMESPACE_FLAG_LIST_CHILDREN) != 0) { + if (mailbox_list_match_anything(ctx, ns, ns->prefix)) + return TRUE; + } + return FALSE; +} + +static bool +ns_prefix_has_visible_child_namespace(struct ns_list_iterate_context *ctx, + const char *prefix) { struct mail_namespace *ns; unsigned int prefix_len = strlen(prefix); - for (ns = namespaces; ns != NULL; ns = ns->next) { + for (ns = ctx->namespaces; ns != NULL; ns = ns->next) { if (ns->prefix_len > prefix_len && - strncmp(ns->prefix, prefix, prefix_len) == 0) + strncmp(ns->prefix, prefix, prefix_len) == 0 && + ns_prefix_is_visible(ctx, ns)) return TRUE; } return FALSE; @@ -370,7 +387,7 @@ const char *pattern; int ret; - if (ns_prefix_has_child_namespaces(ctx->namespaces, prefix)) + if (ns_prefix_has_visible_child_namespace(ctx, prefix)) return 1; pattern = t_strconcat(prefix, "%", NULL); From dovecot at dovecot.org Fri Aug 31 15:25:36 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 31 Aug 2012 15:25:36 +0300 Subject: dovecot-2.2: istream-chain/concat: Various fixes. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/96716652b364 changeset: 15007:96716652b364 user: Timo Sirainen date: Fri Aug 31 15:25:20 2012 +0300 description: istream-chain/concat: Various fixes. Also made the chain code look more like concat code. They should be merged at some point. diffstat: src/lib/istream-chain.c | 52 +++++++++++++++++++++++++++++------------------ src/lib/istream-concat.c | 5 ++- 2 files changed, 35 insertions(+), 22 deletions(-) diffs (145 lines): diff -r db28fea9b8db -r 96716652b364 src/lib/istream-chain.c --- a/src/lib/istream-chain.c Fri Aug 31 14:14:50 2012 +0300 +++ b/src/lib/istream-chain.c Fri Aug 31 15:25:20 2012 +0300 @@ -127,12 +127,12 @@ i_assert(size >= data_size); } - cstream->prev_stream_left = data_size; memcpy(cstream->istream.w_buffer, data, data_size); i_stream_skip(prev_input, data_size); i_stream_unref(&prev_input); cstream->istream.skip = 0; cstream->istream.pos = data_size; + cstream->prev_stream_left = data_size; } static ssize_t i_stream_chain_read(struct istream_private *stream) @@ -140,7 +140,8 @@ struct chain_istream *cstream = (struct chain_istream *)stream; struct istream_chain_link *link = cstream->chain.head; const unsigned char *data; - size_t size, pos, cur_pos, bytes_skipped; + size_t size, data_size, cur_data_pos, new_pos, bytes_skipped; + size_t new_bytes_count; ssize_t ret; if (link != NULL && link->eof) { @@ -153,7 +154,6 @@ if (cstream->prev_stream_left == 0) { /* no need to worry about buffers, skip everything */ - i_assert(cstream->prev_skip == 0); } else if (bytes_skipped < cstream->prev_stream_left) { /* we're still skipping inside buffer */ cstream->prev_stream_left -= bytes_skipped; @@ -163,24 +163,26 @@ bytes_skipped -= cstream->prev_stream_left; cstream->prev_stream_left = 0; } - stream->pos -= bytes_skipped; stream->skip -= bytes_skipped; + stream->buffer += bytes_skipped; + cstream->prev_skip = stream->skip; if (link == NULL) { i_assert(bytes_skipped == 0); return 0; } - i_stream_skip(link->stream, bytes_skipped); - cur_pos = stream->pos - stream->skip - cstream->prev_stream_left; - data = i_stream_get_data(link->stream, &pos); - if (pos > cur_pos) + i_assert(stream->pos >= stream->skip + cstream->prev_stream_left); + cur_data_pos = stream->pos - (stream->skip + cstream->prev_stream_left); + + data = i_stream_get_data(link->stream, &data_size); + if (data_size > cur_data_pos) ret = 0; else { /* need to read more */ - i_assert(cur_pos == pos); + i_assert(cur_data_pos == data_size); ret = i_stream_read(link->stream); if (ret == -2 || ret == 0) return ret; @@ -197,31 +199,41 @@ return i_stream_chain_read(stream); } /* we read something */ - data = i_stream_get_data(link->stream, &pos); + data = i_stream_get_data(link->stream, &data_size); } if (cstream->prev_stream_left == 0) { + /* we can point directly to the current stream's buffers */ stream->buffer = data; stream->pos -= stream->skip; stream->skip = 0; - } else if (pos == cur_pos) { + new_pos = data_size; + } else if (data_size == cur_data_pos) { + /* nothing new read */ + i_assert(ret == 0 || ret == -1); stream->buffer = stream->w_buffer; + new_pos = stream->pos; } else { + /* we still have some of the previous stream left. merge the + new data with it. */ + i_assert(data_size > cur_data_pos); + new_bytes_count = data_size - cur_data_pos; + if (!i_stream_try_alloc(stream, new_bytes_count, &size)) { + stream->buffer = stream->w_buffer; + return -2; + } stream->buffer = stream->w_buffer; - if (!i_stream_try_alloc(stream, pos - cur_pos, &size)) - return -2; - if (pos > size) - pos = size; + if (new_bytes_count > size) + new_bytes_count = size; memcpy(stream->w_buffer + stream->pos, - data + cur_pos, pos - cur_pos); + data + cur_data_pos, new_bytes_count); + new_pos = stream->pos + new_bytes_count; } - pos += stream->skip + cstream->prev_stream_left; - ret = pos > stream->pos ? (ssize_t)(pos - stream->pos) : + ret = new_pos > stream->pos ? (ssize_t)(new_pos - stream->pos) : (ret == 0 ? 0 : -1); - - stream->pos = pos; + stream->pos = new_pos; cstream->prev_skip = stream->skip; return ret; } diff -r db28fea9b8db -r 96716652b364 src/lib/istream-concat.c --- a/src/lib/istream-concat.c Fri Aug 31 14:14:50 2012 +0300 +++ b/src/lib/istream-concat.c Fri Aug 31 15:25:20 2012 +0300 @@ -101,7 +101,6 @@ if (cstream->prev_stream_left == 0) { /* no need to worry about buffers, skip everything */ - i_assert(cstream->prev_skip == 0); } else if (bytes_skipped < cstream->prev_stream_left) { /* we're still skipping inside buffer */ cstream->prev_stream_left -= bytes_skipped; @@ -111,9 +110,11 @@ bytes_skipped -= cstream->prev_stream_left; cstream->prev_stream_left = 0; } - i_stream_skip(cstream->cur_input, bytes_skipped); stream->pos -= bytes_skipped; stream->skip -= bytes_skipped; + stream->buffer += bytes_skipped; + cstream->prev_skip = stream->skip; + i_stream_skip(cstream->cur_input, bytes_skipped); i_assert(stream->pos >= stream->skip + cstream->prev_stream_left); cur_data_pos = stream->pos - (stream->skip + cstream->prev_stream_left); From dovecot at dovecot.org Fri Aug 31 16:17:29 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 31 Aug 2012 16:17:29 +0300 Subject: dovecot-2.1: lib-storage: Don't crash when trying to detect publ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/6b9db780b47d changeset: 14692:6b9db780b47d user: Timo Sirainen date: Fri Aug 31 16:17:23 2012 +0300 description: lib-storage: Don't crash when trying to detect public namespace's mail_location. Public namespaces have no owner. diffstat: src/lib-storage/index/dbox-multi/mdbox-storage.c | 3 ++- src/lib-storage/index/dbox-single/sdbox-storage.c | 3 ++- src/lib-storage/index/maildir/maildir-storage.c | 3 ++- src/lib-storage/index/mbox/mbox-storage.c | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diffs (52 lines): diff -r 67235781cc08 -r 6b9db780b47d src/lib-storage/index/dbox-multi/mdbox-storage.c --- a/src/lib-storage/index/dbox-multi/mdbox-storage.c Thu Aug 30 21:56:43 2012 +0300 +++ b/src/lib-storage/index/dbox-multi/mdbox-storage.c Fri Aug 31 16:17:23 2012 +0300 @@ -87,7 +87,8 @@ bool debug = ns->mail_set->mail_debug; const char *home, *path; - if (mail_user_get_home(ns->owner, &home) > 0) { + if (ns->owner != NULL && + mail_user_get_home(ns->owner, &home) > 0) { path = t_strconcat(home, "/mdbox", NULL); if (access(path, R_OK|W_OK|X_OK) == 0) { if (debug) diff -r 67235781cc08 -r 6b9db780b47d src/lib-storage/index/dbox-single/sdbox-storage.c --- a/src/lib-storage/index/dbox-single/sdbox-storage.c Thu Aug 30 21:56:43 2012 +0300 +++ b/src/lib-storage/index/dbox-single/sdbox-storage.c Fri Aug 31 16:17:23 2012 +0300 @@ -34,7 +34,8 @@ bool debug = ns->mail_set->mail_debug; const char *home, *path; - if (mail_user_get_home(ns->owner, &home) > 0) { + if (ns->owner != NULL && + mail_user_get_home(ns->owner, &home) > 0) { path = t_strconcat(home, "/sdbox", NULL); if (access(path, R_OK|W_OK|X_OK) == 0) { if (debug) diff -r 67235781cc08 -r 6b9db780b47d src/lib-storage/index/maildir/maildir-storage.c --- a/src/lib-storage/index/maildir/maildir-storage.c Thu Aug 30 21:56:43 2012 +0300 +++ b/src/lib-storage/index/maildir/maildir-storage.c Fri Aug 31 16:17:23 2012 +0300 @@ -97,7 +97,8 @@ /* we'll need to figure out the maildir location ourself. It's ~/Maildir unless we are chrooted. */ - if (mail_user_get_home(ns->owner, &home) > 0) { + if (ns->owner != NULL && + mail_user_get_home(ns->owner, &home) > 0) { path = t_strconcat(home, "/Maildir", NULL); if (access(path, R_OK|W_OK|X_OK) == 0) { if (debug) diff -r 67235781cc08 -r 6b9db780b47d src/lib-storage/index/mbox/mbox-storage.c --- a/src/lib-storage/index/mbox/mbox-storage.c Thu Aug 30 21:56:43 2012 +0300 +++ b/src/lib-storage/index/mbox/mbox-storage.c Fri Aug 31 16:17:23 2012 +0300 @@ -246,7 +246,8 @@ bool debug = ns->mail_set->mail_debug; const char *home, *path; - if (mail_user_get_home(ns->owner, &home) <= 0) { + if (ns->owner != NULL && + mail_user_get_home(ns->owner, &home) <= 0) { if (debug) i_debug("maildir: Home directory not set"); home = ""; From dovecot at dovecot.org Fri Aug 31 16:19:26 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 31 Aug 2012 16:19:26 +0300 Subject: dovecot-2.1: mbox: Fix to previous public namespace location det... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/5625ab0a3eed changeset: 14693:5625ab0a3eed user: Timo Sirainen date: Fri Aug 31 16:19:21 2012 +0300 description: mbox: Fix to previous public namespace location detection crashfix. diffstat: src/lib-storage/index/mbox/mbox-storage.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 6b9db780b47d -r 5625ab0a3eed src/lib-storage/index/mbox/mbox-storage.c --- a/src/lib-storage/index/mbox/mbox-storage.c Fri Aug 31 16:17:23 2012 +0300 +++ b/src/lib-storage/index/mbox/mbox-storage.c Fri Aug 31 16:19:21 2012 +0300 @@ -246,7 +246,7 @@ bool debug = ns->mail_set->mail_debug; const char *home, *path; - if (ns->owner != NULL && + if (ns->owner == NULL || mail_user_get_home(ns->owner, &home) <= 0) { if (debug) i_debug("maildir: Home directory not set");