You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3889 lines
133 KiB
3889 lines
133 KiB
# --- SDE-COPYRIGHT-NOTE-BEGIN --- |
|
# This copyright note is auto-generated by ./scripts/Create-CopyPatch. |
|
# |
|
# Filename: package/.../dovecot/dovecot-2.2.1-0000-upstream-fixes.patch |
|
# Copyright (C) 2013 The OpenSDE Project |
|
# |
|
# More information can be found in the files COPYING and README. |
|
# |
|
# This patch file is dual-licensed. It is available under the license the |
|
# patched project is licensed under, as long as it is an OpenSource license |
|
# as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms |
|
# of the GNU General Public License as published by the Free Software |
|
# Foundation; either version 2 of the License, or (at your option) any later |
|
# version. |
|
# --- SDE-COPYRIGHT-NOTE-END --- |
|
|
|
From a69bfa0e486d70db4ee6e7553bd7235d9707ff58 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Fri, 19 Apr 2013 14:29:23 +0300 |
|
Subject: [PATCH] Compiling fix for Sun compilers. I wish gcc/clang warned |
|
about these as well, as sometimes they indicate bugs. |
|
|
|
|
|
diff --git a/src/imap-urlauth/imap-urlauth-worker.c b/src/imap-urlauth/imap-urlauth-worker.c |
|
index ad02c81..6d94a8f 100644 |
|
--- a/src/imap-urlauth/imap-urlauth-worker.c |
|
+++ b/src/imap-urlauth/imap-urlauth-worker.c |
|
@@ -941,7 +941,7 @@ static void main_stdio_run(const char *access_user, |
|
{ |
|
bool debug; |
|
|
|
- debug = getenv("DEBUG"); |
|
+ debug = getenv("DEBUG") != NULL; |
|
access_user = access_user != NULL ? access_user : getenv("USER"); |
|
if (access_user == NULL && IS_STANDALONE()) |
|
access_user = getlogin(); |
|
diff --git a/src/lib/ioloop.c b/src/lib/ioloop.c |
|
index b89adcf..179507c 100644 |
|
--- a/src/lib/ioloop.c |
|
+++ b/src/lib/ioloop.c |
|
@@ -663,7 +663,7 @@ struct timeout *io_loop_move_timeout(struct timeout **_timeout) |
|
|
|
bool io_loop_have_ios(struct ioloop *ioloop) |
|
{ |
|
- return ioloop->io_files; |
|
+ return ioloop->io_files != NULL; |
|
} |
|
|
|
bool io_loop_have_immediate_timeouts(struct ioloop *ioloop) |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From d70baed80e47be3a7587901278dc74811f0a4873 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Sat, 20 Apr 2013 20:58:06 +0300 |
|
Subject: [PATCH] stats plugin: Fixed memory leak. |
|
|
|
|
|
diff --git a/src/plugins/stats/stats-plugin.c b/src/plugins/stats/stats-plugin.c |
|
index 27dae5b..ee4e9af 100644 |
|
--- a/src/plugins/stats/stats-plugin.c |
|
+++ b/src/plugins/stats/stats-plugin.c |
|
@@ -388,6 +388,7 @@ static void stats_transaction_free(struct stats_user *suser, |
|
|
|
trans_stats_add(&suser->session_stats.trans_stats, |
|
&strans->trans->stats); |
|
+ i_free(strans); |
|
} |
|
|
|
static int |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From ce10df9f5cc0dc658ece187606f403a814872696 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Sat, 20 Apr 2013 21:02:30 +0300 |
|
Subject: [PATCH] Fixed a memory leak. |
|
|
|
|
|
diff --git a/src/lib-mail/istream-attachment-connector.c b/src/lib-mail/istream-attachment-connector.c |
|
index 4fa6ebf..0cbedb2 100644 |
|
--- a/src/lib-mail/istream-attachment-connector.c |
|
+++ b/src/lib-mail/istream-attachment-connector.c |
|
@@ -88,6 +88,20 @@ int istream_attachment_connector_add(struct istream_attachment_connector *conn, |
|
return 0; |
|
} |
|
|
|
+static void |
|
+istream_attachment_connector_free(struct istream_attachment_connector *conn) |
|
+{ |
|
+ struct istream *const *streamp, *stream; |
|
+ |
|
+ array_foreach(&conn->streams, streamp) { |
|
+ stream = *streamp; |
|
+ if (stream != NULL) |
|
+ i_stream_unref(&stream); |
|
+ } |
|
+ i_stream_unref(&conn->base_input); |
|
+ pool_unref(&conn->pool); |
|
+} |
|
+ |
|
struct istream * |
|
istream_attachment_connector_finish(struct istream_attachment_connector **_conn) |
|
{ |
|
@@ -111,8 +125,7 @@ istream_attachment_connector_finish(struct istream_attachment_connector **_conn) |
|
inputs = array_idx_modifiable(&conn->streams, 0); |
|
input = i_stream_create_concat(inputs); |
|
|
|
- i_stream_unref(&conn->base_input); |
|
- pool_unref(&conn->pool); |
|
+ istream_attachment_connector_free(conn); |
|
return input; |
|
} |
|
|
|
@@ -122,6 +135,5 @@ void istream_attachment_connector_abort(struct istream_attachment_connector **_c |
|
|
|
*_conn = NULL; |
|
|
|
- i_stream_unref(&conn->base_input); |
|
- pool_unref(&conn->pool); |
|
+ istream_attachment_connector_free(conn); |
|
} |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From eada33e3bff7e25a7b952ebb08244aba86754e92 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Sat, 20 Apr 2013 21:57:47 +0300 |
|
Subject: [PATCH] lib-storage: Avoid wasting data stack during searches. |
|
|
|
|
|
diff --git a/src/lib-storage/index/index-search.c b/src/lib-storage/index/index-search.c |
|
index 0077115..9278b6d 100644 |
|
--- a/src/lib-storage/index/index-search.c |
|
+++ b/src/lib-storage/index/index-search.c |
|
@@ -1377,7 +1377,9 @@ static int search_match_next(struct index_search_context *ctx) |
|
} |
|
for (i = 0; i < n && ret < 0; i++) { |
|
ctx->cur_mail->lookup_abort = cache_lookups[i]; |
|
- ret = search_match_once(ctx); |
|
+ T_BEGIN { |
|
+ ret = search_match_once(ctx); |
|
+ } T_END; |
|
} |
|
ctx->cur_mail->lookup_abort = MAIL_LOOKUP_ABORT_NEVER; |
|
search_match_finish(ctx, ret); |
|
@@ -1556,7 +1558,9 @@ static int search_more_with_prefetching(struct index_search_context *ctx, |
|
int ret = 0; |
|
|
|
while ((mail = index_search_get_mail(ctx)) != NULL) { |
|
- ret = search_more_with_mail(ctx, mail); |
|
+ T_BEGIN { |
|
+ ret = search_more_with_mail(ctx, mail); |
|
+ } T_END; |
|
if (ret <= 0) |
|
break; |
|
|
|
@@ -1612,8 +1616,10 @@ static bool search_finish_prefetch(struct index_search_context *ctx, |
|
mail_search_args_result_deserialize(ctx->mail_ctx.args, |
|
imail->data.search_results->data, |
|
imail->data.search_results->used); |
|
- ret = search_match_once(ctx); |
|
- search_match_finish(ctx, ret); |
|
+ T_BEGIN { |
|
+ ret = search_match_once(ctx); |
|
+ search_match_finish(ctx, ret); |
|
+ } T_END; |
|
ctx->cur_mail = NULL; |
|
return ret > 0; |
|
} |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 7276e7875fca54d44fcccb7a371951ac9639d09b Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 22 Apr 2013 18:45:04 +0300 |
|
Subject: [PATCH] zlib: Keep the last read mail cached uncompressed in a temp |
|
file. This fixes performance problems with partial IMAP |
|
FETCH commands. |
|
|
|
|
|
diff --git a/src/plugins/zlib/zlib-plugin.c b/src/plugins/zlib/zlib-plugin.c |
|
index d54ea54..5076702 100644 |
|
--- a/src/plugins/zlib/zlib-plugin.c |
|
+++ b/src/plugins/zlib/zlib-plugin.c |
|
@@ -3,7 +3,9 @@ |
|
#include "lib.h" |
|
#include "array.h" |
|
#include "istream.h" |
|
+#include "istream-seekable.h" |
|
#include "ostream.h" |
|
+#include "str.h" |
|
#include "mail-user.h" |
|
#include "dbox-single/sdbox-storage.h" |
|
#include "dbox-multi/mdbox-storage.h" |
|
@@ -26,6 +28,7 @@ |
|
MODULE_CONTEXT(obj, zlib_user_module) |
|
|
|
#define MAX_INBUF_SIZE (1024*1024) |
|
+#define ZLIB_MAIL_CACHE_EXPIRE_MSECS (60*1000) |
|
|
|
struct zlib_transaction_context { |
|
union mailbox_transaction_module_context module_ctx; |
|
@@ -33,9 +36,19 @@ struct zlib_transaction_context { |
|
struct mail *tmp_mail; |
|
}; |
|
|
|
+struct zlib_mail_cache { |
|
+ struct timeout *to; |
|
+ struct mailbox *box; |
|
+ uint32_t uid; |
|
+ |
|
+ struct istream *input; |
|
+}; |
|
+ |
|
struct zlib_user { |
|
union mail_user_module_context module_ctx; |
|
|
|
+ struct zlib_mail_cache cache; |
|
+ |
|
const struct compression_handler *save_handler; |
|
unsigned int save_level; |
|
}; |
|
@@ -48,9 +61,58 @@ static MODULE_CONTEXT_DEFINE_INIT(zlib_storage_module, |
|
&mail_storage_module_register); |
|
static MODULE_CONTEXT_DEFINE_INIT(zlib_mail_module, &mail_module_register); |
|
|
|
+static void zlib_mail_cache_close(struct zlib_user *zuser) |
|
+{ |
|
+ struct zlib_mail_cache *cache = &zuser->cache; |
|
+ |
|
+ if (cache->to != NULL) |
|
+ timeout_remove(&cache->to); |
|
+ if (cache->input != NULL) |
|
+ i_stream_unref(&cache->input); |
|
+ memset(cache, 0, sizeof(*cache)); |
|
+} |
|
+ |
|
+static struct istream * |
|
+zlib_mail_cache_open(struct zlib_user *zuser, struct mail *mail, |
|
+ struct istream *input) |
|
+{ |
|
+ struct zlib_mail_cache *cache = &zuser->cache; |
|
+ struct istream *inputs[2]; |
|
+ string_t *temp_prefix = t_str_new(128); |
|
+ |
|
+ zlib_mail_cache_close(zuser); |
|
+ |
|
+ /* zlib istream is seekable, but very slow. create a seekable istream |
|
+ which we can use to quickly seek around in the stream that's been |
|
+ read so far. usually the partial IMAP FETCHes continue from where |
|
+ the previous left off, so this isn't strictly necessary, but with |
|
+ the way lib-imap-storage's CRLF-cache works it has to seek backwards |
|
+ somewhat, which causes a zlib stream reset. And the CRLF-cache isn't |
|
+ easy to fix.. */ |
|
+ input->seekable = FALSE; |
|
+ inputs[0] = input; |
|
+ inputs[1] = NULL; |
|
+ mail_user_set_get_temp_prefix(temp_prefix, mail->box->storage->user->set); |
|
+ input = i_stream_create_seekable_path(inputs, |
|
+ i_stream_get_max_buffer_size(inputs[0]), |
|
+ str_c(temp_prefix)); |
|
+ i_stream_unref(&inputs[0]); |
|
+ |
|
+ cache->to = timeout_add(ZLIB_MAIL_CACHE_EXPIRE_MSECS, |
|
+ zlib_mail_cache_close, zuser); |
|
+ cache->box = mail->box; |
|
+ cache->uid = mail->uid; |
|
+ cache->input = input; |
|
+ |
|
+ /* index-mail wants the stream to be destroyed at close, so create |
|
+ a new stream instead of just increasing reference. */ |
|
+ return i_stream_create_limit(cache->input, (uoff_t)-1); |
|
+} |
|
+ |
|
static int zlib_istream_opened(struct mail *_mail, struct istream **stream) |
|
{ |
|
struct zlib_user *zuser = ZLIB_USER_CONTEXT(_mail->box->storage->user); |
|
+ struct zlib_mail_cache *cache = &zuser->cache; |
|
struct mail_private *mail = (struct mail_private *)_mail; |
|
union mail_module_context *zmail = ZLIB_MAIL_CONTEXT(mail); |
|
struct istream *input; |
|
@@ -63,6 +125,15 @@ static int zlib_istream_opened(struct mail *_mail, struct istream **stream) |
|
if (_mail->saving && zuser->save_handler == NULL) |
|
return zmail->super.istream_opened(_mail, stream); |
|
|
|
+ if (cache->uid == _mail->uid && cache->box == _mail->box) { |
|
+ /* use the cached stream. when doing partial reads it should |
|
+ already be seeked into the wanted offset. */ |
|
+ i_stream_unref(stream); |
|
+ i_stream_seek(cache->input, 0); |
|
+ *stream = i_stream_create_limit(cache->input, (uoff_t)-1); |
|
+ return zmail->super.istream_opened(_mail, stream); |
|
+ } |
|
+ |
|
handler = compression_detect_handler(*stream); |
|
if (handler != NULL) { |
|
if (handler->create_istream == NULL) { |
|
@@ -75,6 +146,8 @@ static int zlib_istream_opened(struct mail *_mail, struct istream **stream) |
|
input = *stream; |
|
*stream = handler->create_istream(input, TRUE); |
|
i_stream_unref(&input); |
|
+ |
|
+ *stream = zlib_mail_cache_open(zuser, _mail, *stream); |
|
} |
|
return zmail->super.istream_opened(_mail, stream); |
|
} |
|
@@ -265,6 +338,16 @@ static int zlib_mailbox_open(struct mailbox *box) |
|
return zbox->super.open(box); |
|
} |
|
|
|
+static void zlib_mailbox_close(struct mailbox *box) |
|
+{ |
|
+ union mailbox_module_context *zbox = ZLIB_CONTEXT(box); |
|
+ struct zlib_user *zuser = ZLIB_USER_CONTEXT(box->storage->user); |
|
+ |
|
+ if (zuser->cache.box == box) |
|
+ zlib_mail_cache_close(zuser); |
|
+ zbox->super.close(box); |
|
+} |
|
+ |
|
static void zlib_mailbox_allocated(struct mailbox *box) |
|
{ |
|
struct mailbox_vfuncs *v = box->vlast; |
|
@@ -274,6 +357,7 @@ static void zlib_mailbox_allocated(struct mailbox *box) |
|
zbox->super = *v; |
|
box->vlast = &zbox->super; |
|
v->open = zlib_mailbox_open; |
|
+ v->close = zlib_mailbox_close; |
|
|
|
MODULE_CONTEXT_SET_SELF(box, zlib_storage_module, zbox); |
|
|
|
@@ -283,12 +367,24 @@ static void zlib_mailbox_allocated(struct mailbox *box) |
|
zlib_permail_alloc_init(box, v); |
|
} |
|
|
|
+static void zlib_mail_user_deinit(struct mail_user *user) |
|
+{ |
|
+ struct zlib_user *zuser = ZLIB_USER_CONTEXT(user); |
|
+ |
|
+ zlib_mail_cache_close(zuser); |
|
+ zuser->module_ctx.super.deinit(user); |
|
+} |
|
+ |
|
static void zlib_mail_user_created(struct mail_user *user) |
|
{ |
|
+ struct mail_user_vfuncs *v = user->vlast; |
|
struct zlib_user *zuser; |
|
const char *name; |
|
|
|
zuser = p_new(user->pool, struct zlib_user, 1); |
|
+ zuser->module_ctx.super = *v; |
|
+ user->vlast = &zuser->module_ctx.super; |
|
+ v->deinit = zlib_mail_user_deinit; |
|
|
|
name = mail_user_plugin_getenv(user, "zlib_save"); |
|
if (name != NULL && *name != '\0') { |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From f7c17f745db01d854f315ddcbc9955125b4161ef Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 22 Apr 2013 21:51:01 +0300 |
|
Subject: [PATCH] stats plugin: Use nonblocking open() for stats fifo. This |
|
fixes hangs in it. Alternative would be to use alarm(). |
|
|
|
|
|
diff --git a/src/plugins/stats/stats-connection.c b/src/plugins/stats/stats-connection.c |
|
index b98e864..da07e9b 100644 |
|
--- a/src/plugins/stats/stats-connection.c |
|
+++ b/src/plugins/stats/stats-connection.c |
|
@@ -23,7 +23,7 @@ static bool stats_connection_open(struct stats_connection *conn) |
|
if (conn->open_failed) |
|
return FALSE; |
|
|
|
- conn->fd = open(conn->path, O_WRONLY); |
|
+ conn->fd = open(conn->path, O_WRONLY | O_NONBLOCK); |
|
if (conn->fd == -1) { |
|
i_error("stats: open(%s) failed: %m", conn->path); |
|
conn->open_failed = TRUE; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 43afe64ef8b8d2af9576b9e5a60feb0ef62223f9 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 23 Apr 2013 13:28:17 +0300 |
|
Subject: [PATCH] OpenBSD compile fix: include sys/socket.h when checking for |
|
struct sockpeercred. |
|
|
|
|
|
diff --git a/configure.ac b/configure.ac |
|
index f06095f..a67d511 100644 |
|
--- a/configure.ac |
|
+++ b/configure.ac |
|
@@ -433,7 +433,7 @@ AC_CHECK_FUNCS(fcntl flock lockf inet_aton sigaction getpagesize madvise \ |
|
walkcontext dirfd clearenv malloc_usable_size glob fallocate \ |
|
posix_fadvise getpeereid getpeerucred) |
|
|
|
-AC_CHECK_TYPES([struct sockpeercred]) |
|
+AC_CHECK_TYPES([struct sockpeercred],,,[#include <sys/socket.h>]) |
|
|
|
AC_SEARCH_LIBS(clock_gettime, rt, [ |
|
AC_DEFINE(HAVE_CLOCK_GETTIME,, Define if you have the clock_gettime function) |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 4288a8d102d241c32c5d53609f9242cd13263077 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 23 Apr 2013 13:33:12 +0300 |
|
Subject: [PATCH] master: Fixed warning log message. |
|
|
|
|
|
diff --git a/src/master/master-settings.c b/src/master/master-settings.c |
|
index 29edf86..45e56ac 100644 |
|
--- a/src/master/master-settings.c |
|
+++ b/src/master/master-settings.c |
|
@@ -417,7 +417,7 @@ master_settings_verify(void *_set, pool_t pool, const char **error_r) |
|
const struct service_settings *default_service; |
|
#else |
|
rlim_t fd_limit; |
|
- const char *max_client_limit_source = "default_client_count"; |
|
+ const char *max_client_limit_source = "default_client_limit"; |
|
unsigned int max_client_limit = set->default_client_limit; |
|
#endif |
|
|
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 212c975ce882bcaebd49ff7d7ea8e1f109a25101 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 23 Apr 2013 13:47:46 +0300 |
|
Subject: [PATCH] fts-solr: Don't crash if fts_solr setting is invalid. |
|
|
|
|
|
diff --git a/src/plugins/fts-solr/fts-backend-solr-old.c b/src/plugins/fts-solr/fts-backend-solr-old.c |
|
index 9fd8094..1845849 100644 |
|
--- a/src/plugins/fts-solr/fts-backend-solr-old.c |
|
+++ b/src/plugins/fts-solr/fts-backend-solr-old.c |
|
@@ -229,11 +229,14 @@ fts_backend_solr_init(struct fts_backend *_backend, const char **error_r) |
|
{ |
|
struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend; |
|
struct fts_solr_user *fuser = FTS_SOLR_USER_CONTEXT(_backend->ns->user); |
|
- const struct fts_solr_settings *set = &fuser->set; |
|
const char *str; |
|
|
|
+ if (fuser == NULL) { |
|
+ *error_r = "Invalid fts_solr setting"; |
|
+ return -1; |
|
+ } |
|
if (solr_conn == NULL) { |
|
- if (solr_connection_init(set->url, set->debug, |
|
+ if (solr_connection_init(fuser->set.url, fuser->set.debug, |
|
&solr_conn, error_r) < 0) |
|
return -1; |
|
} |
|
diff --git a/src/plugins/fts-solr/fts-backend-solr.c b/src/plugins/fts-solr/fts-backend-solr.c |
|
index f7b335f..8af1707 100644 |
|
--- a/src/plugins/fts-solr/fts-backend-solr.c |
|
+++ b/src/plugins/fts-solr/fts-backend-solr.c |
|
@@ -158,10 +158,13 @@ static int |
|
fts_backend_solr_init(struct fts_backend *_backend, const char **error_r) |
|
{ |
|
struct fts_solr_user *fuser = FTS_SOLR_USER_CONTEXT(_backend->ns->user); |
|
- const struct fts_solr_settings *set = &fuser->set; |
|
|
|
+ if (fuser == NULL) { |
|
+ *error_r = "Invalid fts_solr setting"; |
|
+ return -1; |
|
+ } |
|
if (solr_conn == NULL) { |
|
- if (solr_connection_init(set->url, set->debug, |
|
+ if (solr_connection_init(fuser->set.url, fuser->set.debug, |
|
&solr_conn, error_r) < 0) |
|
return -1; |
|
} |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From efe39df75481a8c4579b70f24987eea075d0eeb8 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 23 Apr 2013 16:20:48 +0300 |
|
Subject: [PATCH] lib-http: Makefile fix |
|
|
|
|
|
diff --git a/src/lib-http/Makefile.am b/src/lib-http/Makefile.am |
|
index 5c19c58..4127a14 100644 |
|
--- a/src/lib-http/Makefile.am |
|
+++ b/src/lib-http/Makefile.am |
|
@@ -50,7 +50,7 @@ test_libs = \ |
|
$(MODULE_LIBS) |
|
|
|
test_deps = \ |
|
- $(noinst_LTLIBRARIES) |
|
+ $(noinst_LTLIBRARIES) \ |
|
../lib-test/libtest.la \ |
|
../lib/liblib.la |
|
|
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 7c55c5055f78c849716efce14072a652157f3200 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 23 Apr 2013 17:21:46 +0300 |
|
Subject: [PATCH] istream-seekable: Don't crash when seeking forwards past the |
|
data we haven't read yet. |
|
|
|
|
|
diff --git a/src/lib/istream-seekable.c b/src/lib/istream-seekable.c |
|
index a9c5d81..cf59138 100644 |
|
--- a/src/lib/istream-seekable.c |
|
+++ b/src/lib/istream-seekable.c |
|
@@ -345,6 +345,20 @@ i_stream_seekable_stat(struct istream_private *stream, bool exact) |
|
return 0; |
|
} |
|
|
|
+static void i_stream_seekable_seek(struct istream_private *stream, |
|
+ uoff_t v_offset, bool mark) |
|
+{ |
|
+ if (v_offset <= stream->istream.v_offset) { |
|
+ /* seeking backwards */ |
|
+ stream->istream.v_offset = v_offset; |
|
+ stream->skip = stream->pos = 0; |
|
+ } else { |
|
+ /* we can't skip over data we haven't yet read and written to |
|
+ our buffer/temp file */ |
|
+ i_stream_default_seek_nonseekable(stream, v_offset, mark); |
|
+ } |
|
+} |
|
+ |
|
struct istream * |
|
i_streams_merge(struct istream *input[], size_t max_buffer_size, |
|
int (*fd_callback)(const char **path_r, void *context), |
|
@@ -388,6 +402,7 @@ i_streams_merge(struct istream *input[], size_t max_buffer_size, |
|
|
|
sstream->istream.read = i_stream_seekable_read; |
|
sstream->istream.stat = i_stream_seekable_stat; |
|
+ sstream->istream.seek = i_stream_seekable_seek; |
|
|
|
sstream->istream.istream.readable_fd = FALSE; |
|
sstream->istream.istream.blocking = blocking; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From bd6b8ffcd0aef00aaa5b640d8e425fdcd0075993 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 23 Apr 2013 20:51:34 +0300 |
|
Subject: [PATCH] dbox: Close file's fd only after its istream is destroyed. |
|
For example zlib plugin keeps the stream open as a cache |
|
even after the dbox_file has been destroyed. |
|
|
|
|
|
diff --git a/src/lib-storage/index/dbox-common/dbox-file.c b/src/lib-storage/index/dbox-common/dbox-file.c |
|
index 2b36013..c714487 100644 |
|
--- a/src/lib-storage/index/dbox-common/dbox-file.c |
|
+++ b/src/lib-storage/index/dbox-common/dbox-file.c |
|
@@ -215,7 +215,7 @@ static int dbox_file_open_full(struct dbox_file *file, bool try_altpath, |
|
} |
|
} |
|
|
|
- file->input = i_stream_create_fd(file->fd, DBOX_READ_BLOCK_SIZE, FALSE); |
|
+ file->input = i_stream_create_fd(file->fd, DBOX_READ_BLOCK_SIZE, TRUE); |
|
i_stream_set_name(file->input, file->cur_path); |
|
i_stream_set_init_buffer_size(file->input, DBOX_READ_BLOCK_SIZE); |
|
return dbox_file_read_header(file); |
|
@@ -286,9 +286,12 @@ int dbox_file_header_write(struct dbox_file *file, struct ostream *output) |
|
void dbox_file_close(struct dbox_file *file) |
|
{ |
|
dbox_file_unlock(file); |
|
- if (file->input != NULL) |
|
+ if (file->input != NULL) { |
|
+ /* stream autocloses the fd when it gets destroyed. note that |
|
+ the stream may outlive the struct dbox_file. */ |
|
i_stream_unref(&file->input); |
|
- if (file->fd != -1) { |
|
+ file->fd = -1; |
|
+ } else if (file->fd != -1) { |
|
if (close(file->fd) < 0) |
|
dbox_file_set_syscall_error(file, "close()"); |
|
file->fd = -1; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 7e2d3faf969bcb9f65ae8a7860f4dfff28dd8f95 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 23 Apr 2013 20:53:53 +0300 |
|
Subject: [PATCH] istream-[b]zlib: Don't break if parent stream gets seeked in |
|
the middle of reads. |
|
|
|
|
|
diff --git a/src/lib-compression/istream-bzlib.c b/src/lib-compression/istream-bzlib.c |
|
index 2ad33dc..3937cb1 100644 |
|
--- a/src/lib-compression/istream-bzlib.c |
|
+++ b/src/lib-compression/istream-bzlib.c |
|
@@ -15,7 +15,7 @@ struct bzlib_istream { |
|
|
|
bz_stream zs; |
|
uoff_t eof_offset, stream_size; |
|
- size_t prev_size, high_pos; |
|
+ size_t high_pos; |
|
struct stat last_parent_statbuf; |
|
|
|
unsigned int log_errors:1; |
|
@@ -49,7 +49,7 @@ static ssize_t i_stream_bzlib_read(struct istream_private *stream) |
|
struct bzlib_istream *zstream = (struct bzlib_istream *)stream; |
|
const unsigned char *data; |
|
uoff_t high_offset; |
|
- size_t size; |
|
+ size_t size, out_size; |
|
int ret; |
|
|
|
high_offset = stream->istream.v_offset + (stream->pos - stream->skip); |
|
@@ -98,42 +98,36 @@ static ssize_t i_stream_bzlib_read(struct istream_private *stream) |
|
} |
|
} |
|
|
|
- if (zstream->zs.avail_in == 0) { |
|
- /* need to read more data. try to read a full CHUNK_SIZE */ |
|
- i_stream_skip(stream->parent, zstream->prev_size); |
|
- if (i_stream_read_data(stream->parent, &data, &size, |
|
- CHUNK_SIZE-1) == -1 && size == 0) { |
|
- if (stream->parent->stream_errno != 0) { |
|
- stream->istream.stream_errno = |
|
- stream->parent->stream_errno; |
|
- } else { |
|
- i_assert(stream->parent->eof); |
|
- if (zstream->log_errors) { |
|
- bzlib_read_error(zstream, |
|
- "unexpected EOF"); |
|
- } |
|
- stream->istream.stream_errno = EINVAL; |
|
- } |
|
- return -1; |
|
+ if (i_stream_read_data(stream->parent, &data, &size, 0) < 0) { |
|
+ if (stream->parent->stream_errno != 0) { |
|
+ stream->istream.stream_errno = |
|
+ stream->parent->stream_errno; |
|
+ } else { |
|
+ i_assert(stream->parent->eof); |
|
+ if (zstream->log_errors) |
|
+ bzlib_read_error(zstream, "unexpected EOF"); |
|
+ stream->istream.stream_errno = EINVAL; |
|
} |
|
- zstream->prev_size = size; |
|
- if (size == 0) { |
|
- /* no more input */ |
|
- i_assert(!stream->istream.blocking); |
|
- return 0; |
|
- } |
|
- |
|
- zstream->zs.next_in = (char *)data; |
|
- zstream->zs.avail_in = size; |
|
+ return -1; |
|
+ } |
|
+ if (size == 0) { |
|
+ /* no more input */ |
|
+ i_assert(!stream->istream.blocking); |
|
+ return 0; |
|
} |
|
|
|
- size = stream->buffer_size - stream->pos; |
|
+ zstream->zs.next_in = (char *)data; |
|
+ zstream->zs.avail_in = size; |
|
+ |
|
+ out_size = stream->buffer_size - stream->pos; |
|
zstream->zs.next_out = (char *)stream->w_buffer + stream->pos; |
|
- zstream->zs.avail_out = size; |
|
+ zstream->zs.avail_out = out_size; |
|
ret = BZ2_bzDecompress(&zstream->zs); |
|
|
|
- size -= zstream->zs.avail_out; |
|
- stream->pos += size; |
|
+ out_size -= zstream->zs.avail_out; |
|
+ stream->pos += out_size; |
|
+ |
|
+ i_stream_skip(stream->parent, size - zstream->zs.avail_in); |
|
|
|
switch (ret) { |
|
case BZ_OK: |
|
@@ -159,7 +153,7 @@ static ssize_t i_stream_bzlib_read(struct istream_private *stream) |
|
zstream->eof_offset = stream->istream.v_offset + |
|
(stream->pos - stream->skip); |
|
zstream->stream_size = zstream->eof_offset; |
|
- if (size == 0) { |
|
+ if (out_size == 0) { |
|
stream->istream.eof = TRUE; |
|
return -1; |
|
} |
|
@@ -167,11 +161,11 @@ static ssize_t i_stream_bzlib_read(struct istream_private *stream) |
|
default: |
|
i_fatal("BZ2_bzDecompress() failed with %d", ret); |
|
} |
|
- if (size == 0) { |
|
+ if (out_size == 0) { |
|
/* read more input */ |
|
return i_stream_bzlib_read(stream); |
|
} |
|
- return size; |
|
+ return out_size; |
|
} |
|
|
|
static void i_stream_bzlib_init(struct bzlib_istream *zstream) |
|
@@ -206,7 +200,6 @@ static void i_stream_bzlib_reset(struct bzlib_istream *zstream) |
|
stream->skip = stream->pos = 0; |
|
stream->istream.v_offset = 0; |
|
zstream->high_pos = 0; |
|
- zstream->prev_size = 0; |
|
|
|
(void)BZ2_bzDecompressEnd(&zstream->zs); |
|
i_stream_bzlib_init(zstream); |
|
diff --git a/src/lib-compression/istream-zlib.c b/src/lib-compression/istream-zlib.c |
|
index 021bfe0..c7ac2c4 100644 |
|
--- a/src/lib-compression/istream-zlib.c |
|
+++ b/src/lib-compression/istream-zlib.c |
|
@@ -122,6 +122,7 @@ static int i_stream_zlib_read_header(struct istream_private *stream) |
|
pos += 2; |
|
} |
|
i_stream_skip(stream->parent, pos); |
|
+ zstream->prev_size = 0; |
|
return 1; |
|
} |
|
|
|
@@ -172,7 +173,7 @@ static ssize_t i_stream_zlib_read(struct istream_private *stream) |
|
struct zlib_istream *zstream = (struct zlib_istream *)stream; |
|
const unsigned char *data; |
|
uoff_t high_offset; |
|
- size_t size; |
|
+ size_t size, out_size; |
|
int ret; |
|
|
|
high_offset = stream->istream.v_offset + (stream->pos - stream->skip); |
|
@@ -208,7 +209,6 @@ static ssize_t i_stream_zlib_read(struct istream_private *stream) |
|
if (ret <= 0) |
|
return ret; |
|
zstream->header_read = TRUE; |
|
- zstream->prev_size = 0; |
|
} |
|
|
|
if (stream->pos < zstream->high_pos) { |
|
@@ -248,44 +248,39 @@ static ssize_t i_stream_zlib_read(struct istream_private *stream) |
|
} |
|
} |
|
|
|
- if (zstream->zs.avail_in == 0) { |
|
- /* need to read more data. try to read a full CHUNK_SIZE */ |
|
- i_stream_skip(stream->parent, zstream->prev_size); |
|
- if (i_stream_read_data(stream->parent, &data, &size, |
|
- CHUNK_SIZE-1) == -1 && size == 0) { |
|
- if (stream->parent->stream_errno != 0) { |
|
- stream->istream.stream_errno = |
|
- stream->parent->stream_errno; |
|
- } else { |
|
- i_assert(stream->parent->eof); |
|
- if (zstream->log_errors) { |
|
- zlib_read_error(zstream, |
|
- "unexpected EOF"); |
|
- } |
|
- stream->istream.stream_errno = EPIPE; |
|
- } |
|
- return -1; |
|
- } |
|
- zstream->prev_size = size; |
|
- if (size == 0) { |
|
- /* no more input */ |
|
- i_assert(!stream->istream.blocking); |
|
- return 0; |
|
+ if (i_stream_read_data(stream->parent, &data, &size, 0) < 0) { |
|
+ if (stream->parent->stream_errno != 0) { |
|
+ stream->istream.stream_errno = |
|
+ stream->parent->stream_errno; |
|
+ } else { |
|
+ i_assert(stream->parent->eof); |
|
+ if (zstream->log_errors) |
|
+ zlib_read_error(zstream, "unexpected EOF"); |
|
+ stream->istream.stream_errno = EPIPE; |
|
} |
|
- |
|
- zstream->zs.next_in = (void *)data; |
|
- zstream->zs.avail_in = size; |
|
+ return -1; |
|
+ } |
|
+ if (size == 0) { |
|
+ /* no more input */ |
|
+ i_assert(!stream->istream.blocking); |
|
+ return 0; |
|
} |
|
|
|
- size = stream->buffer_size - stream->pos; |
|
+ zstream->zs.next_in = (void *)data; |
|
+ zstream->zs.avail_in = size; |
|
+ |
|
+ out_size = stream->buffer_size - stream->pos; |
|
zstream->zs.next_out = stream->w_buffer + stream->pos; |
|
- zstream->zs.avail_out = size; |
|
+ zstream->zs.avail_out = out_size; |
|
ret = inflate(&zstream->zs, Z_SYNC_FLUSH); |
|
|
|
- size -= zstream->zs.avail_out; |
|
+ out_size -= zstream->zs.avail_out; |
|
zstream->crc32 = crc32_data_more(zstream->crc32, |
|
- stream->w_buffer + stream->pos, size); |
|
- stream->pos += size; |
|
+ stream->w_buffer + stream->pos, |
|
+ out_size); |
|
+ stream->pos += out_size; |
|
+ |
|
+ i_stream_skip(stream->parent, size - zstream->zs.avail_in); |
|
|
|
switch (ret) { |
|
case Z_OK: |
|
@@ -307,10 +302,7 @@ static ssize_t i_stream_zlib_read(struct istream_private *stream) |
|
zstream->eof_offset = stream->istream.v_offset + |
|
(stream->pos - stream->skip); |
|
zstream->stream_size = zstream->eof_offset; |
|
- i_stream_skip(stream->parent, |
|
- zstream->prev_size - zstream->zs.avail_in); |
|
zstream->zs.avail_in = 0; |
|
- zstream->prev_size = 0; |
|
|
|
if (!zstream->trailer_read) { |
|
/* try to read and verify the trailer, we might not |
|
@@ -322,11 +314,11 @@ static ssize_t i_stream_zlib_read(struct istream_private *stream) |
|
default: |
|
i_fatal("inflate() failed with %d", ret); |
|
} |
|
- if (size == 0) { |
|
+ if (out_size == 0) { |
|
/* read more input */ |
|
return i_stream_zlib_read(stream); |
|
} |
|
- return size; |
|
+ return out_size; |
|
} |
|
|
|
static void i_stream_zlib_init(struct zlib_istream *zstream) |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 7e2ef0020ae79382577f9610d6ab3135bb604b56 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 23 Apr 2013 21:06:00 +0300 |
|
Subject: [PATCH] lib-storage: Fixed crash with mailbox_list_index=yes after |
|
re-reading index. |
|
|
|
|
|
diff --git a/src/lib-storage/list/mailbox-list-index.c b/src/lib-storage/list/mailbox-list-index.c |
|
index 1f2dbed..61391ea 100644 |
|
--- a/src/lib-storage/list/mailbox-list-index.c |
|
+++ b/src/lib-storage/list/mailbox-list-index.c |
|
@@ -27,8 +27,8 @@ void mailbox_list_index_reset(struct mailbox_list_index *ilist) |
|
{ |
|
i_assert(ilist->iter_refcount == 0); |
|
|
|
- hash_table_clear(ilist->mailbox_names, FALSE); |
|
- hash_table_clear(ilist->mailbox_hash, FALSE); |
|
+ hash_table_clear(ilist->mailbox_names, TRUE); |
|
+ hash_table_clear(ilist->mailbox_hash, TRUE); |
|
p_clear(ilist->mailbox_pool); |
|
ilist->mailbox_tree = NULL; |
|
ilist->highest_name_id = 0; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 249fc7092cf438ee9ca7e2f5cdeb4bd8ff5409e6 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 23 Apr 2013 21:06:34 +0300 |
|
Subject: [PATCH] maildir: Crashfix after dovecot-keywords file was re-read. |
|
|
|
|
|
diff --git a/src/lib-storage/index/maildir/maildir-keywords.c b/src/lib-storage/index/maildir/maildir-keywords.c |
|
index b45db1c..0a32c45 100644 |
|
--- a/src/lib-storage/index/maildir/maildir-keywords.c |
|
+++ b/src/lib-storage/index/maildir/maildir-keywords.c |
|
@@ -104,7 +104,7 @@ void maildir_keywords_deinit(struct maildir_keywords **_mk) |
|
static void maildir_keywords_clear(struct maildir_keywords *mk) |
|
{ |
|
array_clear(&mk->list); |
|
- hash_table_clear(mk->hash, FALSE); |
|
+ hash_table_clear(mk->hash, TRUE); |
|
p_clear(mk->pool); |
|
} |
|
|
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From c3df0aec4b12a7aea7fc0a1ec5ca58833862cbb0 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 23 Apr 2013 21:08:31 +0300 |
|
Subject: [PATCH] hash_table_clear(): Added a comment about API usage. |
|
|
|
|
|
diff --git a/src/lib/hash.h b/src/lib/hash.h |
|
index f0ccb67..ead59a1 100644 |
|
--- a/src/lib/hash.h |
|
+++ b/src/lib/hash.h |
|
@@ -68,8 +68,8 @@ void hash_table_destroy(struct hash_table **table); |
|
#define hash_table_destroy(table) \ |
|
hash_table_destroy(&(*table)._table) |
|
/* Remove all nodes from hash table. If free_collisions is TRUE, the |
|
- memory allocated from node_pool is freed, or discarded with |
|
- alloconly pools. */ |
|
+ memory allocated from node_pool is freed, or discarded with alloconly pools. |
|
+ WARNING: If you p_clear() the node_pool, the free_collisions must be TRUE. */ |
|
void hash_table_clear(struct hash_table *table, bool free_collisions); |
|
#define hash_table_clear(table, free_collisions) \ |
|
hash_table_clear((table)._table, free_collisions) |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From ffdf174645c18d779de5d503df0d7269be42317f Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 23 Apr 2013 21:31:52 +0300 |
|
Subject: [PATCH] lib-master: Added master_service_is_master_stopped() |
|
|
|
|
|
diff --git a/src/lib-master/master-service.c b/src/lib-master/master-service.c |
|
index 378bc63..a06b6e8 100644 |
|
--- a/src/lib-master/master-service.c |
|
+++ b/src/lib-master/master-service.c |
|
@@ -600,6 +600,11 @@ bool master_service_is_killed(struct master_service *service) |
|
return service->killed; |
|
} |
|
|
|
+bool master_service_is_master_stopped(struct master_service *service) |
|
+{ |
|
+ return service->io_status_error == NULL; |
|
+} |
|
+ |
|
void master_service_anvil_send(struct master_service *service, const char *cmd) |
|
{ |
|
ssize_t ret; |
|
diff --git a/src/lib-master/master-service.h b/src/lib-master/master-service.h |
|
index b975895..0ca002b 100644 |
|
--- a/src/lib-master/master-service.h |
|
+++ b/src/lib-master/master-service.h |
|
@@ -141,6 +141,9 @@ void master_service_stop(struct master_service *service); |
|
void master_service_stop_new_connections(struct master_service *service); |
|
/* Returns TRUE if we've received a SIGINT/SIGTERM and we've decided to stop. */ |
|
bool master_service_is_killed(struct master_service *service); |
|
+/* Returns TRUE if our master process is already stopped. This process may or |
|
+ may not be dying itself. */ |
|
+bool master_service_is_master_stopped(struct master_service *service); |
|
|
|
/* Send command to anvil process, if we have fd to it. */ |
|
void master_service_anvil_send(struct master_service *service, const char *cmd); |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 2598176e416438cbaccd65de471d229651786aec Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 23 Apr 2013 21:32:24 +0300 |
|
Subject: [PATCH] stats plugin: Don't try to send notifications to already |
|
dead stats process. |
|
|
|
|
|
diff --git a/src/plugins/stats/Makefile.am b/src/plugins/stats/Makefile.am |
|
index e7a46d5..a88fc3b 100644 |
|
--- a/src/plugins/stats/Makefile.am |
|
+++ b/src/plugins/stats/Makefile.am |
|
@@ -2,6 +2,7 @@ AM_CPPFLAGS = \ |
|
-I$(top_srcdir)/src/lib \ |
|
-I$(top_srcdir)/src/lib-settings \ |
|
-I$(top_srcdir)/src/lib-mail \ |
|
+ -I$(top_srcdir)/src/lib-master \ |
|
-I$(top_srcdir)/src/lib-index \ |
|
-I$(top_srcdir)/src/lib-storage |
|
|
|
diff --git a/src/plugins/stats/stats-connection.c b/src/plugins/stats/stats-connection.c |
|
index da07e9b..9560cc4 100644 |
|
--- a/src/plugins/stats/stats-connection.c |
|
+++ b/src/plugins/stats/stats-connection.c |
|
@@ -5,6 +5,7 @@ |
|
#include "net.h" |
|
#include "str.h" |
|
#include "strescape.h" |
|
+#include "master-service.h" |
|
#include "mail-storage.h" |
|
#include "stats-plugin.h" |
|
#include "stats-connection.h" |
|
@@ -71,6 +72,12 @@ void stats_connection_send(struct stats_connection *conn, const string_t *str) |
|
static bool pipe_warned = FALSE; |
|
ssize_t ret; |
|
|
|
+ /* if master process has been stopped (and restarted), don't even try |
|
+ to notify the stats process anymore. even if one exists, it doesn't |
|
+ know about us. */ |
|
+ if (master_service_is_master_stopped(master_service)) |
|
+ return; |
|
+ |
|
if (conn->fd == -1) { |
|
if (!stats_connection_open(conn)) |
|
return; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From ebc36aca877984a309ee676da1f88d0d9a87e0c2 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Thu, 2 May 2013 16:20:02 +0300 |
|
Subject: [PATCH] example-config: Typofix |
|
|
|
|
|
diff --git a/doc/example-config/dovecot.conf b/doc/example-config/dovecot.conf |
|
index 16b0b0b..5697661 100644 |
|
--- a/doc/example-config/dovecot.conf |
|
+++ b/doc/example-config/dovecot.conf |
|
@@ -47,7 +47,7 @@ |
|
# these networks. Typically you'd specify your IMAP proxy servers here. |
|
#login_trusted_networks = |
|
|
|
-# Sepace separated list of login access check sockets (e.g. tcpwrap) |
|
+# Space separated list of login access check sockets (e.g. tcpwrap) |
|
#login_access_sockets = |
|
|
|
# With proxy_maybe=yes if proxy destination matches any of these IPs, don't do |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From d47967d36496b7e75f3152f917b8e51ef88affd7 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Thu, 2 May 2013 18:11:56 +0300 |
|
Subject: [PATCH] imap: Fixed using literals for URLs in CATENATE. |
|
|
|
|
|
diff --git a/src/imap/cmd-append.c b/src/imap/cmd-append.c |
|
index 9153e52..b825692 100644 |
|
--- a/src/imap/cmd-append.c |
|
+++ b/src/imap/cmd-append.c |
|
@@ -349,6 +349,30 @@ static void cmd_append_finish_catenate(struct client_command_context *cmd) |
|
} |
|
} |
|
|
|
+static bool catenate_args_can_stop(struct cmd_append_context *ctx, |
|
+ const struct imap_arg *args) |
|
+{ |
|
+ /* eat away literal_sizes from URLs */ |
|
+ while (args->type != IMAP_ARG_EOL) { |
|
+ if (imap_arg_atom_equals(args, "TEXT")) |
|
+ return TRUE; |
|
+ if (!imap_arg_atom_equals(args, "URL")) { |
|
+ /* error - handle it later */ |
|
+ return TRUE; |
|
+ } |
|
+ args++; |
|
+ if (args->type == IMAP_ARG_LITERAL_SIZE || |
|
+ args->type == IMAP_ARG_LITERAL_SIZE_NONSYNC) { |
|
+ if (args->type == IMAP_ARG_LITERAL_SIZE) |
|
+ cmd_append_send_literal_continue(ctx->client); |
|
+ imap_parser_read_last_literal(ctx->save_parser); |
|
+ return FALSE; |
|
+ } |
|
+ args++; |
|
+ } |
|
+ return TRUE; |
|
+} |
|
+ |
|
static bool cmd_append_continue_catenate(struct client_command_context *cmd) |
|
{ |
|
struct client *client = cmd->client; |
|
@@ -368,10 +392,12 @@ static bool cmd_append_continue_catenate(struct client_command_context *cmd) |
|
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 | |
|
- IMAP_PARSE_FLAG_INSIDE_LIST, &args); |
|
+ do { |
|
+ ret = imap_parser_read_args(ctx->save_parser, 0, |
|
+ IMAP_PARSE_FLAG_LITERAL_SIZE | |
|
+ IMAP_PARSE_FLAG_LITERAL8 | |
|
+ IMAP_PARSE_FLAG_INSIDE_LIST, &args); |
|
+ } while (ret > 0 && !catenate_args_can_stop(ctx, args)); |
|
if (ret == -1) { |
|
msg = imap_parser_get_error(ctx->save_parser, &fatal); |
|
if (fatal) |
|
@@ -630,8 +656,11 @@ static bool cmd_append_finish_parsing(struct client_command_context *cmd) |
|
return cmd_sync(cmd, sync_flags, imap_flags, str_c(msg)); |
|
} |
|
|
|
-static bool cmd_append_args_can_stop(const struct imap_arg *args) |
|
+static bool cmd_append_args_can_stop(struct cmd_append_context *ctx, |
|
+ const struct imap_arg *args) |
|
{ |
|
+ const struct imap_arg *cat_list; |
|
+ |
|
if (args->type == IMAP_ARG_EOL) |
|
return TRUE; |
|
|
|
@@ -645,8 +674,8 @@ static bool cmd_append_args_can_stop(const struct imap_arg *args) |
|
args->type == IMAP_ARG_LITERAL_SIZE_NONSYNC) |
|
return TRUE; |
|
if (imap_arg_atom_equals(args, "CATENATE") && |
|
- args[1].type == IMAP_ARG_LIST) |
|
- return TRUE; |
|
+ imap_arg_get_list(&args[1], &cat_list)) |
|
+ return catenate_args_can_stop(ctx, cat_list); |
|
return FALSE; |
|
} |
|
|
|
@@ -680,7 +709,7 @@ static bool cmd_append_parse_new_msg(struct client_command_context *cmd) |
|
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)); |
|
+ } while (ret > 0 && !cmd_append_args_can_stop(ctx, args)); |
|
if (ret == -1) { |
|
if (!ctx->failed) { |
|
msg = imap_parser_get_error(ctx->save_parser, &fatal); |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From a2a529c6dbe1fc2b4e71e456c7cd3fc53b18bee7 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Thu, 2 May 2013 18:18:26 +0300 |
|
Subject: [PATCH] imap: Don't allow empty CATENATE () list. |
|
|
|
|
|
diff --git a/src/imap/cmd-append.c b/src/imap/cmd-append.c |
|
index b825692..a7e2b31 100644 |
|
--- a/src/imap/cmd-append.c |
|
+++ b/src/imap/cmd-append.c |
|
@@ -586,6 +586,10 @@ cmd_append_handle_args(struct client_command_context *cmd, |
|
if (cat_list == NULL) { |
|
/* normal APPEND */ |
|
return 1; |
|
+ } else if (cat_list->type == IMAP_ARG_EOL) { |
|
+ /* zero parts */ |
|
+ client_send_command_error(cmd, "Empty CATENATE list."); |
|
+ return -1; |
|
} else if ((ret = cmd_append_catenate(cmd, cat_list, nonsync_r)) < 0) { |
|
/* invalid parameters, abort immediately */ |
|
return -1; |
|
@@ -734,6 +738,8 @@ static bool cmd_append_parse_new_msg(struct client_command_context *cmd) |
|
ret = cmd_append_handle_args(cmd, args, &nonsync); |
|
if (ret < 0) { |
|
/* invalid parameters, abort immediately */ |
|
+ if (ctx->catenate) |
|
+ client->input_skip_line = TRUE; |
|
cmd_append_finish(ctx); |
|
return TRUE; |
|
} |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From b422c981522d9adda053424a5b837b1c5f06a991 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Thu, 2 May 2013 18:29:50 +0300 |
|
Subject: [PATCH] imap-urlauth-worker: Fixed a crash (by removing unnecessary |
|
code) |
|
|
|
|
|
diff --git a/src/imap-urlauth/imap-urlauth-worker.c b/src/imap-urlauth/imap-urlauth-worker.c |
|
index 6d94a8f..49a3d59 100644 |
|
--- a/src/imap-urlauth/imap-urlauth-worker.c |
|
+++ b/src/imap-urlauth/imap-urlauth-worker.c |
|
@@ -54,7 +54,7 @@ struct client { |
|
struct io *io, *ctrl_io; |
|
struct istream *input, *ctrl_input; |
|
struct ostream *output, *ctrl_output; |
|
- struct timeout *to_idle, *to_delay; |
|
+ struct timeout *to_idle; |
|
|
|
char *access_user; |
|
ARRAY_TYPE(string) access_apps; |
|
@@ -245,8 +245,6 @@ static void client_destroy(struct client *client) |
|
io_remove(&client->ctrl_io); |
|
if (client->to_idle != NULL) |
|
timeout_remove(&client->to_idle); |
|
- if (client->to_delay != NULL) |
|
- timeout_remove(&client->to_delay); |
|
|
|
if (client->input != NULL) |
|
i_stream_destroy(&client->input); |
|
@@ -605,7 +603,6 @@ client_handle_user_command(struct client *client, const char *cmd, |
|
i_debug("User %s doesn't exist", input.username); |
|
|
|
client_send_line(client, "NO"); |
|
- timeout_remove(&client->to_delay); |
|
return 1; |
|
} |
|
|
|
@@ -669,7 +666,7 @@ static bool client_handle_input(struct client *client) |
|
const char *line, *cmd, *error; |
|
int ret; |
|
|
|
- if (client->url != NULL || client->to_delay != NULL) { |
|
+ if (client->url != NULL) { |
|
/* we're still processing a URL. wait until it's |
|
finished. */ |
|
io_remove(&client->io); |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From c35d09cecd4de0fa69514814d26ead0cd8776972 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Thu, 2 May 2013 18:32:47 +0300 |
|
Subject: [PATCH] lib-imap-urlauth: Don't try to access garbage memory on |
|
error handling path. |
|
|
|
|
|
diff --git a/src/lib-imap-urlauth/imap-urlauth.c b/src/lib-imap-urlauth/imap-urlauth.c |
|
index 2a557a2..0019f0e 100644 |
|
--- a/src/lib-imap-urlauth/imap-urlauth.c |
|
+++ b/src/lib-imap-urlauth/imap-urlauth.c |
|
@@ -362,6 +362,7 @@ int imap_urlauth_fetch_parsed(struct imap_urlauth_context *uctx, |
|
unsigned char mailbox_key[IMAP_URLAUTH_KEY_LEN]; |
|
int ret; |
|
|
|
+ *mpurl_r = NULL; |
|
*error_r = NULL; |
|
*error_code_r = MAIL_ERROR_NONE; |
|
|
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 769728fec2c3a87695f3c26e5fc3773cb5618a9f Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Fri, 3 May 2013 17:17:15 +0300 |
|
Subject: [PATCH] quota-status: Return 554 instead of 552 on quota failures. |
|
This is because RFC 5321/2821 recommends that 552 is |
|
treated the same as 452. |
|
|
|
|
|
diff --git a/src/plugins/quota/quota-status.c b/src/plugins/quota/quota-status.c |
|
index 23a0070..bfac5e7 100644 |
|
--- a/src/plugins/quota/quota-status.c |
|
+++ b/src/plugins/quota/quota-status.c |
|
@@ -107,7 +107,7 @@ static void client_handle_request(struct quota_client *client) |
|
/* over quota */ |
|
value = mail_user_plugin_getenv(user, "quota_status_overquota"); |
|
if (value == NULL) |
|
- value = t_strdup_printf("552 5.2.2 %s\n\n", error); |
|
+ value = t_strdup_printf("554 5.2.2 %s\n\n", error); |
|
} |
|
mail_user_unref(&user); |
|
mail_storage_service_user_free(&service_user); |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From c366e44efb27db7c57dde1b4f3580b879a65a761 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 6 May 2013 14:58:55 +0300 |
|
Subject: [PATCH] acl: Mailbox creation ignored ACLs (due to API changes in |
|
v2.2). The created mailbox couldn't have been accessed |
|
however. |
|
|
|
|
|
diff --git a/src/plugins/acl/acl-mailbox.c b/src/plugins/acl/acl-mailbox.c |
|
index 6ed4bc9..1630af5 100644 |
|
--- a/src/plugins/acl/acl-mailbox.c |
|
+++ b/src/plugins/acl/acl-mailbox.c |
|
@@ -118,8 +118,23 @@ acl_mailbox_create(struct mailbox *box, const struct mailbox_update *update, |
|
struct acl_mailbox *abox = ACL_CONTEXT(box); |
|
int ret; |
|
|
|
- /* we already checked permissions in list.mailbox_create_dir(). |
|
- ignore ACLs in this mailbox until creation is complete, because |
|
+ /* we're looking up CREATE permission from our parent's rights */ |
|
+ ret = acl_mailbox_list_have_right(box->list, box->name, TRUE, |
|
+ ACL_STORAGE_RIGHT_CREATE, NULL); |
|
+ if (ret <= 0) { |
|
+ if (ret < 0) { |
|
+ mail_storage_set_internal_error(box->storage); |
|
+ return -1; |
|
+ } |
|
+ /* Note that if user didn't have LOOKUP permission to parent |
|
+ mailbox, this may reveal the mailbox's existence to user. |
|
+ Can't help it. */ |
|
+ mail_storage_set_error(box->storage, MAIL_ERROR_PERM, |
|
+ MAIL_ERRSTR_NO_PERMISSION); |
|
+ return -1; |
|
+ } |
|
+ |
|
+ /* ignore ACLs in this mailbox until creation is complete, because |
|
super.create() may call e.g. mailbox_open() which will fail since |
|
we haven't yet copied ACLs to this mailbox. */ |
|
abox->skip_acl_checks = TRUE; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 31e39a37524bd48fea0af0dc8169a7eb46231a29 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 6 May 2013 14:59:27 +0300 |
|
Subject: [PATCH] acl: Optionally get default ACL's for private/shared |
|
namespaces from user's INBOX. This probably should be the |
|
default always, but better not break anyone's existing |
|
setup until v2.3.0. So for now there's a setting for this: |
|
plugin { acl_defaults_from_inbox = yes } |
|
|
|
|
|
diff --git a/src/plugins/acl/acl-api-private.h b/src/plugins/acl/acl-api-private.h |
|
index 90a83eb..852dc31 100644 |
|
--- a/src/plugins/acl/acl-api-private.h |
|
+++ b/src/plugins/acl/acl-api-private.h |
|
@@ -81,6 +81,7 @@ extern const char *const all_mailbox_rights[]; |
|
const char *const * |
|
acl_backend_mask_get_names(struct acl_backend *backend, |
|
const struct acl_mask *mask, pool_t pool); |
|
+struct acl_object *acl_backend_get_default_object(struct acl_backend *backend); |
|
int acl_backend_get_default_rights(struct acl_backend *backend, |
|
const struct acl_mask **mask_r); |
|
void acl_rights_write_id(string_t *dest, const struct acl_rights *right); |
|
diff --git a/src/plugins/acl/acl-backend-vfile.c b/src/plugins/acl/acl-backend-vfile.c |
|
index ccf1655..ce8f2ae 100644 |
|
--- a/src/plugins/acl/acl-backend-vfile.c |
|
+++ b/src/plugins/acl/acl-backend-vfile.c |
|
@@ -284,7 +284,7 @@ acl_backend_vfile_object_init_parent(struct acl_backend *backend, |
|
} |
|
if (parent == NULL) { |
|
/* use the root */ |
|
- parent = ""; |
|
+ parent = acl_backend_get_default_object(backend)->name; |
|
} |
|
return acl_backend_vfile_object_init(backend, parent); |
|
} |
|
diff --git a/src/plugins/acl/acl-backend.c b/src/plugins/acl/acl-backend.c |
|
index c1b4451..3e562a6 100644 |
|
--- a/src/plugins/acl/acl-backend.c |
|
+++ b/src/plugins/acl/acl-backend.c |
|
@@ -4,6 +4,7 @@ |
|
#include "hash.h" |
|
#include "mail-storage-settings.h" |
|
#include "mailbox-list.h" |
|
+#include "mail-namespace.h" |
|
#include "mail-user.h" |
|
#include "acl-cache.h" |
|
#include "acl-api-private.h" |
|
@@ -157,17 +158,35 @@ unsigned int acl_backend_lookup_right(struct acl_backend *backend, |
|
return acl_cache_right_lookup(backend->cache, right); |
|
} |
|
|
|
+struct acl_object *acl_backend_get_default_object(struct acl_backend *backend) |
|
+{ |
|
+ struct mail_user *user = mailbox_list_get_user(backend->list); |
|
+ struct mail_namespace *ns = mailbox_list_get_namespace(backend->list); |
|
+ const char *default_name = ""; |
|
+ |
|
+ if (backend->default_aclobj != NULL) |
|
+ return backend->default_aclobj; |
|
+ |
|
+ /* FIXME: this should probably be made default in v2.3 */ |
|
+ if (mail_user_plugin_getenv(user, "acl_defaults_from_inbox") != NULL) { |
|
+ if (ns->type == MAIL_NAMESPACE_TYPE_PRIVATE || |
|
+ ns->type == MAIL_NAMESPACE_TYPE_SHARED) |
|
+ default_name = "INBOX"; |
|
+ } |
|
+ backend->default_aclobj = |
|
+ acl_object_init_from_name(backend, default_name); |
|
+ return backend->default_aclobj; |
|
+} |
|
+ |
|
int acl_backend_get_default_rights(struct acl_backend *backend, |
|
const struct acl_mask **mask_r) |
|
{ |
|
- if (backend->default_aclobj == NULL) { |
|
- backend->default_aclobj = |
|
- acl_object_init_from_name(backend, ""); |
|
- } |
|
- if (backend->v.object_refresh_cache(backend->default_aclobj) < 0) |
|
+ struct acl_object *aclobj = acl_backend_get_default_object(backend); |
|
+ |
|
+ if (backend->v.object_refresh_cache(aclobj) < 0) |
|
return -1; |
|
|
|
- *mask_r = acl_cache_get_my_rights(backend->cache, ""); |
|
+ *mask_r = acl_cache_get_my_rights(backend->cache, aclobj->name); |
|
if (*mask_r == NULL) |
|
*mask_r = backend->default_aclmask; |
|
return 0; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 0ee2c2bc34bee983d109094fe19dc6ac23b5660f Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 6 May 2013 15:04:57 +0300 |
|
Subject: [PATCH] namespace { prefix="" list=no } should never be listed. |
|
|
|
|
|
diff --git a/src/lib-storage/list/mailbox-list-iter.c b/src/lib-storage/list/mailbox-list-iter.c |
|
index 6abba65..da95178 100644 |
|
--- a/src/lib-storage/list/mailbox-list-iter.c |
|
+++ b/src/lib-storage/list/mailbox-list-iter.c |
|
@@ -256,6 +256,9 @@ static bool ns_match_next(struct ns_list_iterate_context *ctx, |
|
/* non-listable namespace matches only with exact prefix */ |
|
if (strncmp(ns->prefix, pattern, ns->prefix_len) != 0) |
|
return FALSE; |
|
+ /* prefix="" list=no is never listed */ |
|
+ if (ns->prefix_len == 0) |
|
+ return FALSE; |
|
} |
|
|
|
prefix_without_sep = t_strndup(ns->prefix, len); |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From dba8e2552b0e4fba4c41b99c7cc2e54bfe2cf492 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 6 May 2013 15:17:49 +0300 |
|
Subject: [PATCH] maildir++: Fixed mail_shared_explicit_inbox=no |
|
|
|
|
|
diff --git a/src/lib-storage/list/mailbox-list-maildir-iter.c b/src/lib-storage/list/mailbox-list-maildir-iter.c |
|
index 6e2df66..30506a0 100644 |
|
--- a/src/lib-storage/list/mailbox-list-maildir-iter.c |
|
+++ b/src/lib-storage/list/mailbox-list-maildir-iter.c |
|
@@ -372,6 +372,7 @@ maildir_fill_readdir(struct maildir_list_iterate_context *ctx, |
|
struct mail_namespace *ns = list->ns; |
|
DIR *dirp; |
|
struct dirent *d; |
|
+ const char *vname; |
|
int ret = 0; |
|
|
|
dirp = opendir(ctx->dir); |
|
@@ -409,8 +410,8 @@ maildir_fill_readdir(struct maildir_list_iterate_context *ctx, |
|
return maildir_fill_inbox(ctx, glob, "INBOX", update_only); |
|
} else if ((ns->flags & NAMESPACE_FLAG_INBOX_ANY) != 0) { |
|
/* show shared INBOX. */ |
|
- return maildir_fill_inbox(ctx, glob, |
|
- t_strconcat(ns->prefix, "INBOX", NULL), update_only); |
|
+ vname = mailbox_list_get_vname(ns->list, "INBOX"); |
|
+ return maildir_fill_inbox(ctx, glob, vname, update_only); |
|
} else { |
|
return 0; |
|
} |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From bbdd76d381da01400db1879fd7fa2e2cb8e5e38a Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 6 May 2013 16:43:29 +0300 |
|
Subject: [PATCH] lib-index: The previous assert-crashfix didn't actually fix |
|
the problem. |
|
|
|
|
|
diff --git a/src/lib-index/mail-transaction-log-view.c b/src/lib-index/mail-transaction-log-view.c |
|
index 852fe08..707ad6b 100644 |
|
--- a/src/lib-index/mail-transaction-log-view.c |
|
+++ b/src/lib-index/mail-transaction-log-view.c |
|
@@ -95,24 +95,18 @@ int mail_transaction_log_view_set(struct mail_transaction_log_view *view, |
|
} |
|
|
|
for (file = view->log->files; file != NULL; file = file->next) { |
|
- if (file->hdr.prev_file_seq == min_file_seq) |
|
+ if (file->hdr.prev_file_seq == max_file_seq) |
|
break; |
|
} |
|
- if (file != NULL && min_file_offset == file->hdr.prev_file_offset) { |
|
+ if (file != NULL && max_file_offset == file->hdr.prev_file_offset) { |
|
/* we can skip to the next file. we've delayed checking for |
|
min_file_seq <= max_file_seq until now, because it's not |
|
really an error to specify the same position twice (even if |
|
in "wrong" order) */ |
|
i_assert(min_file_seq <= max_file_seq || |
|
- file->hdr.file_seq <= max_file_seq); |
|
- min_file_seq = file->hdr.file_seq; |
|
- min_file_offset = 0; |
|
- |
|
- if (min_file_seq > max_file_seq) { |
|
- /* empty view */ |
|
- max_file_seq = min_file_seq; |
|
- max_file_offset = min_file_offset; |
|
- } |
|
+ min_file_seq <= file->hdr.file_seq); |
|
+ max_file_seq = file->hdr.file_seq; |
|
+ max_file_offset = file->hdr.hdr_size; |
|
} else { |
|
i_assert(min_file_seq <= max_file_seq); |
|
} |
|
@@ -126,16 +120,6 @@ int mail_transaction_log_view_set(struct mail_transaction_log_view *view, |
|
return -1; |
|
} |
|
|
|
- if (min_file_offset > 0 && file != NULL && |
|
- min_file_offset < file->hdr.hdr_size) { |
|
- /* log file offset is probably corrupted in the index file. */ |
|
- mail_transaction_log_view_set_corrupted(view, |
|
- "file_seq=%u, min_file_offset (%"PRIuUOFF_T |
|
- ") < hdr_size (%u)", |
|
- min_file_seq, min_file_offset, file->hdr.hdr_size); |
|
- return -1; |
|
- } |
|
- |
|
view->tail = view->head = file = NULL; |
|
for (seq = min_file_seq; seq <= max_file_seq; seq++) { |
|
if (file == NULL || file->hdr.file_seq != seq) { |
|
@@ -200,7 +184,23 @@ int mail_transaction_log_view_set(struct mail_transaction_log_view *view, |
|
max_file_offset = min_file_offset; |
|
} |
|
} |
|
- i_assert(min_file_offset >= view->tail->hdr.hdr_size); |
|
+ |
|
+ if (min_file_offset < view->tail->hdr.hdr_size) { |
|
+ /* log file offset is probably corrupted in the index file. */ |
|
+ mail_transaction_log_view_set_corrupted(view, |
|
+ "file_seq=%u, min_file_offset (%"PRIuUOFF_T |
|
+ ") < hdr_size (%u)", |
|
+ min_file_seq, min_file_offset, view->tail->hdr.hdr_size); |
|
+ return -1; |
|
+ } |
|
+ if (max_file_offset < view->head->hdr.hdr_size) { |
|
+ /* log file offset is probably corrupted in the index file. */ |
|
+ mail_transaction_log_view_set_corrupted(view, |
|
+ "file_seq=%u, min_file_offset (%"PRIuUOFF_T |
|
+ ") < hdr_size (%u)", |
|
+ max_file_seq, max_file_offset, view->head->hdr.hdr_size); |
|
+ return -1; |
|
+ } |
|
|
|
/* we have all of them. update refcounts. */ |
|
mail_transaction_log_view_unref_all(view); |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From cabf0e30e0a51e54566c3229826ae6478744b103 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 6 May 2013 17:27:36 +0300 |
|
Subject: [PATCH] doveadm_mail_iter_init(): Removed unnecessarily returning |
|
transaction. If it's needed in future just add a new |
|
doveadm_mail_iter_get_transaction(). |
|
|
|
|
|
diff --git a/src/doveadm/doveadm-mail-altmove.c b/src/doveadm/doveadm-mail-altmove.c |
|
index f9fc505..a7d9843 100644 |
|
--- a/src/doveadm/doveadm-mail-altmove.c |
|
+++ b/src/doveadm/doveadm-mail-altmove.c |
|
@@ -20,13 +20,12 @@ cmd_altmove_box(struct doveadm_mail_cmd_context *ctx, |
|
struct mail_search_args *search_args, bool reverse) |
|
{ |
|
struct doveadm_mail_iter *iter; |
|
- struct mailbox_transaction_context *trans; |
|
struct mail *mail; |
|
enum modify_type modify_type = |
|
!reverse ? MODIFY_ADD : MODIFY_REMOVE; |
|
|
|
if (doveadm_mail_iter_init(ctx, info, search_args, 0, NULL, |
|
- &trans, &iter) < 0) |
|
+ &iter) < 0) |
|
return -1; |
|
|
|
while (doveadm_mail_iter_next(iter, &mail)) { |
|
diff --git a/src/doveadm/doveadm-mail-copymove.c b/src/doveadm/doveadm-mail-copymove.c |
|
index 3eb16cc..3be9904 100644 |
|
--- a/src/doveadm/doveadm-mail-copymove.c |
|
+++ b/src/doveadm/doveadm-mail-copymove.c |
|
@@ -25,14 +25,13 @@ 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) |
|
+ NULL, &iter) < 0) |
|
return -1; |
|
|
|
/* use a separately committed transaction for each mailbox. |
|
diff --git a/src/doveadm/doveadm-mail-expunge.c b/src/doveadm/doveadm-mail-expunge.c |
|
index 452d3de..8aca907 100644 |
|
--- a/src/doveadm/doveadm-mail-expunge.c |
|
+++ b/src/doveadm/doveadm-mail-expunge.c |
|
@@ -22,13 +22,12 @@ cmd_expunge_box(struct doveadm_mail_cmd_context *_ctx, |
|
struct expunge_cmd_context *ctx = (struct expunge_cmd_context *)_ctx; |
|
struct doveadm_mail_iter *iter; |
|
struct mailbox *box; |
|
- struct mailbox_transaction_context *trans; |
|
struct mail *mail; |
|
enum mail_error error; |
|
int ret = 0; |
|
|
|
if (doveadm_mail_iter_init(_ctx, info, search_args, 0, NULL, |
|
- &trans, &iter) < 0) |
|
+ &iter) < 0) |
|
return -1; |
|
|
|
while (doveadm_mail_iter_next(iter, &mail)) { |
|
diff --git a/src/doveadm/doveadm-mail-fetch.c b/src/doveadm/doveadm-mail-fetch.c |
|
index c918e39..3ade84d 100644 |
|
--- a/src/doveadm/doveadm-mail-fetch.c |
|
+++ b/src/doveadm/doveadm-mail-fetch.c |
|
@@ -507,13 +507,12 @@ static int |
|
cmd_fetch_box(struct fetch_cmd_context *ctx, const struct mailbox_info *info) |
|
{ |
|
struct doveadm_mail_iter *iter; |
|
- struct mailbox_transaction_context *trans; |
|
int ret = 0; |
|
|
|
if (doveadm_mail_iter_init(&ctx->ctx, info, ctx->ctx.search_args, |
|
ctx->wanted_fields, |
|
array_idx(&ctx->header_fields, 0), |
|
- &trans, &iter) < 0) |
|
+ &iter) < 0) |
|
return -1; |
|
|
|
while (doveadm_mail_iter_next(iter, &ctx->mail)) { |
|
diff --git a/src/doveadm/doveadm-mail-import.c b/src/doveadm/doveadm-mail-import.c |
|
index a7727a2..59c79d8 100644 |
|
--- a/src/doveadm/doveadm-mail-import.c |
|
+++ b/src/doveadm/doveadm-mail-import.c |
|
@@ -103,13 +103,12 @@ cmd_import_box(struct import_cmd_context *ctx, struct mail_user *dest_user, |
|
struct mail_search_args *search_args) |
|
{ |
|
struct doveadm_mail_iter *iter; |
|
- struct mailbox_transaction_context *trans; |
|
struct mailbox *box; |
|
struct mail *mail; |
|
int ret = 0; |
|
|
|
if (doveadm_mail_iter_init(&ctx->ctx, info, search_args, 0, NULL, |
|
- &trans, &iter) < 0) |
|
+ &iter) < 0) |
|
return -1; |
|
|
|
if (doveadm_mail_iter_next(iter, &mail)) { |
|
diff --git a/src/doveadm/doveadm-mail-iter.c b/src/doveadm/doveadm-mail-iter.c |
|
index e97c8a8..52470b4 100644 |
|
--- a/src/doveadm/doveadm-mail-iter.c |
|
+++ b/src/doveadm/doveadm-mail-iter.c |
|
@@ -21,7 +21,6 @@ int doveadm_mail_iter_init(struct doveadm_mail_cmd_context *ctx, |
|
struct mail_search_args *search_args, |
|
enum mail_fetch_field wanted_fields, |
|
const char *const *wanted_headers, |
|
- struct mailbox_transaction_context **trans_r, |
|
struct doveadm_mail_iter **iter_r) |
|
{ |
|
struct doveadm_mail_iter *iter; |
|
@@ -49,8 +48,6 @@ int doveadm_mail_iter_init(struct doveadm_mail_cmd_context *ctx, |
|
iter->t = mailbox_transaction_begin(iter->box, 0); |
|
iter->search_ctx = mailbox_search_init(iter->t, search_args, NULL, |
|
wanted_fields, headers_ctx); |
|
- |
|
- *trans_r = iter->t; |
|
*iter_r = iter; |
|
return 0; |
|
} |
|
@@ -128,3 +125,8 @@ bool doveadm_mail_iter_next(struct doveadm_mail_iter *iter, |
|
{ |
|
return mailbox_search_next(iter->search_ctx, mail_r); |
|
} |
|
+ |
|
+struct mailbox *doveadm_mail_iter_get_mailbox(struct doveadm_mail_iter *iter) |
|
+{ |
|
+ return iter->box; |
|
+} |
|
diff --git a/src/doveadm/doveadm-mail-iter.h b/src/doveadm/doveadm-mail-iter.h |
|
index f311fa8..fa33782 100644 |
|
--- a/src/doveadm/doveadm-mail-iter.h |
|
+++ b/src/doveadm/doveadm-mail-iter.h |
|
@@ -11,13 +11,13 @@ int doveadm_mail_iter_init(struct doveadm_mail_cmd_context *ctx, |
|
struct mail_search_args *search_args, |
|
enum mail_fetch_field wanted_fields, |
|
const char *const *wanted_headers, |
|
- struct mailbox_transaction_context **trans_r, |
|
struct doveadm_mail_iter **iter_r) ATTR_NULL(5); |
|
int doveadm_mail_iter_deinit(struct doveadm_mail_iter **iter); |
|
int doveadm_mail_iter_deinit_sync(struct doveadm_mail_iter **iter); |
|
int doveadm_mail_iter_deinit_keep_box(struct doveadm_mail_iter **iter, |
|
struct mailbox **box_r); |
|
void doveadm_mail_iter_deinit_rollback(struct doveadm_mail_iter **iter); |
|
+struct mailbox *doveadm_mail_iter_get_mailbox(struct doveadm_mail_iter *iter); |
|
|
|
bool doveadm_mail_iter_next(struct doveadm_mail_iter *iter, |
|
struct mail **mail_r); |
|
diff --git a/src/doveadm/doveadm-mail-search.c b/src/doveadm/doveadm-mail-search.c |
|
index b6d7331..97a6933 100644 |
|
--- a/src/doveadm/doveadm-mail-search.c |
|
+++ b/src/doveadm/doveadm-mail-search.c |
|
@@ -15,16 +15,15 @@ cmd_search_box(struct doveadm_mail_cmd_context *ctx, |
|
{ |
|
struct doveadm_mail_iter *iter; |
|
struct mailbox *box; |
|
- struct mailbox_transaction_context *trans; |
|
struct mail *mail; |
|
struct mailbox_metadata metadata; |
|
const char *guid_str; |
|
int ret = 0; |
|
|
|
if (doveadm_mail_iter_init(ctx, info, ctx->search_args, 0, NULL, |
|
- &trans, &iter) < 0) |
|
+ &iter) < 0) |
|
return -1; |
|
- box = mailbox_transaction_get_mailbox(trans); |
|
+ box = doveadm_mail_iter_get_mailbox(iter); |
|
|
|
if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) < 0) { |
|
ret = -1; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From f6b7f1619435fc5aec8a689ca67058dff94288fa Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 6 May 2013 17:30:07 +0300 |
|
Subject: [PATCH] doveadm: If search query attempts to access nonexistent |
|
mailbox, just ignore it. Most importantly running a query |
|
for multiple users wouldn't be an error if the mailbox |
|
existed only for some users. It's probably cleaner to then |
|
always just ignore the nonexistent mailboxes. |
|
|
|
|
|
diff --git a/src/doveadm/doveadm-mail-iter.c b/src/doveadm/doveadm-mail-iter.c |
|
index 52470b4..e3fc33f 100644 |
|
--- a/src/doveadm/doveadm-mail-iter.c |
|
+++ b/src/doveadm/doveadm-mail-iter.c |
|
@@ -25,6 +25,8 @@ int doveadm_mail_iter_init(struct doveadm_mail_cmd_context *ctx, |
|
{ |
|
struct doveadm_mail_iter *iter; |
|
struct mailbox_header_lookup_ctx *headers_ctx; |
|
+ const char *errstr; |
|
+ enum mail_error error; |
|
|
|
iter = i_new(struct doveadm_mail_iter, 1); |
|
iter->ctx = ctx; |
|
@@ -33,8 +35,13 @@ int doveadm_mail_iter_init(struct doveadm_mail_cmd_context *ctx, |
|
iter->search_args = search_args; |
|
|
|
if (mailbox_sync(iter->box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) { |
|
- i_error("Syncing mailbox %s failed: %s", info->vname, |
|
- mailbox_get_last_error(iter->box, NULL)); |
|
+ errstr = mailbox_get_last_error(iter->box, &error); |
|
+ if (error == MAIL_ERROR_NOTFOUND) { |
|
+ /* just ignore this mailbox */ |
|
+ *iter_r = iter; |
|
+ return 0; |
|
+ } |
|
+ i_error("Syncing mailbox %s failed: %s", info->vname, errstr); |
|
doveadm_mail_failed_mailbox(ctx, iter->box); |
|
mailbox_free(&iter->box); |
|
i_free(iter); |
|
@@ -58,13 +65,17 @@ doveadm_mail_iter_deinit_transaction(struct doveadm_mail_iter *iter, |
|
{ |
|
int ret = 0; |
|
|
|
- if (mailbox_search_deinit(&iter->search_ctx) < 0) { |
|
- i_error("Searching mailbox %s failed: %s", |
|
- mailbox_get_vname(iter->box), |
|
- mailbox_get_last_error(iter->box, NULL)); |
|
- ret = -1; |
|
+ if (iter->search_ctx != NULL) { |
|
+ if (mailbox_search_deinit(&iter->search_ctx) < 0) { |
|
+ i_error("Searching mailbox %s failed: %s", |
|
+ mailbox_get_vname(iter->box), |
|
+ mailbox_get_last_error(iter->box, NULL)); |
|
+ ret = -1; |
|
+ } |
|
} |
|
- if (commit) { |
|
+ if (iter->t == NULL) |
|
+ ; |
|
+ else if (commit) { |
|
if (mailbox_transaction_commit(&iter->t) < 0) { |
|
i_error("Committing mailbox %s failed: %s", |
|
mailbox_get_vname(iter->box), |
|
@@ -123,6 +134,8 @@ void doveadm_mail_iter_deinit_rollback(struct doveadm_mail_iter **_iter) |
|
bool doveadm_mail_iter_next(struct doveadm_mail_iter *iter, |
|
struct mail **mail_r) |
|
{ |
|
+ if (iter->search_ctx == NULL) |
|
+ return FALSE; |
|
return mailbox_search_next(iter->search_ctx, mail_r); |
|
} |
|
|
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 9943d869c5c9796ec8cbdc05adf14a52ca58d8de Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 6 May 2013 18:35:36 +0300 |
|
Subject: [PATCH] lib-imap-urlauth: Don't try to access garbage memory on |
|
error handling paths. |
|
|
|
|
|
diff --git a/src/lib-imap-urlauth/imap-urlauth-fetch.c b/src/lib-imap-urlauth/imap-urlauth-fetch.c |
|
index 8cee33d..9801822 100644 |
|
--- a/src/lib-imap-urlauth/imap-urlauth-fetch.c |
|
+++ b/src/lib-imap-urlauth/imap-urlauth-fetch.c |
|
@@ -150,7 +150,7 @@ imap_urlauth_fetch_local(struct imap_urlauth_fetch *ufetch, const char *url, |
|
const char *error, *errormsg = NULL, *bpstruct = NULL; |
|
bool debug = ufetch->uctx->user->mail_debug, success; |
|
enum mail_error error_code; |
|
- struct imap_msgpart_url *mpurl; |
|
+ struct imap_msgpart_url *mpurl = NULL; |
|
int ret; |
|
|
|
ufetch->pending_requests--; |
|
diff --git a/src/lib-imap-urlauth/imap-urlauth.c b/src/lib-imap-urlauth/imap-urlauth.c |
|
index 0019f0e..d4ef76c 100644 |
|
--- a/src/lib-imap-urlauth/imap-urlauth.c |
|
+++ b/src/lib-imap-urlauth/imap-urlauth.c |
|
@@ -227,7 +227,7 @@ int imap_urlauth_generate(struct imap_urlauth_context *uctx, |
|
enum imap_url_parse_flags url_flags = |
|
IMAP_URL_PARSE_ALLOW_URLAUTH; |
|
struct imap_url *url; |
|
- struct imap_msgpart_url *mpurl; |
|
+ struct imap_msgpart_url *mpurl = NULL; |
|
struct mailbox *box; |
|
const char *error; |
|
enum mail_error error_code; |
|
@@ -284,7 +284,8 @@ int imap_urlauth_generate(struct imap_urlauth_context *uctx, |
|
if ((ret = imap_msgpart_url_create(user, url, &mpurl, &error)) < 0 || |
|
imap_msgpart_url_verify(mpurl, &error) <= 0) { |
|
*error_r = t_strdup_printf("Invalid URL: %s", error); |
|
- imap_msgpart_url_free(&mpurl); |
|
+ if (mpurl != NULL) |
|
+ imap_msgpart_url_free(&mpurl); |
|
return ret; |
|
} |
|
box = imap_msgpart_url_get_mailbox(mpurl); |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 57fb26d8580d1856a9347425f40a8dda03cb0a79 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 6 May 2013 19:48:32 +0300 |
|
Subject: [PATCH] lib-imap: imap_parser_read_args() shouldn't append multiple |
|
EOLs when calling multiple times. |
|
|
|
|
|
diff --git a/src/lib-imap/imap-parser.c b/src/lib-imap/imap-parser.c |
|
index 33fcf90..0c48da8 100644 |
|
--- a/src/lib-imap/imap-parser.c |
|
+++ b/src/lib-imap/imap-parser.c |
|
@@ -711,11 +711,7 @@ static int finish_line(struct imap_parser *parser, unsigned int count, |
|
|
|
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); |
|
+ parser->args_added_extra_eol = TRUE; |
|
|
|
*args_r = array_get(&parser->root_list, &count); |
|
return ret; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 72f915906b61b0e82624d9f604adc4688db2f640 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 6 May 2013 19:49:18 +0300 |
|
Subject: [PATCH] imap: Don't hang in APPEND when giving it invalid |
|
parameters. |
|
|
|
|
|
diff --git a/src/imap/cmd-append.c b/src/imap/cmd-append.c |
|
index a7e2b31..91376c1 100644 |
|
--- a/src/imap/cmd-append.c |
|
+++ b/src/imap/cmd-append.c |
|
@@ -708,12 +708,13 @@ static bool cmd_append_parse_new_msg(struct client_command_context *cmd) |
|
/* 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; |
|
+ arg_min_count = 0; |
|
do { |
|
- ret = imap_parser_read_args(ctx->save_parser, arg_min_count++, |
|
+ 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(ctx, args)); |
|
+ } while (ret >= (int)arg_min_count && |
|
+ !cmd_append_args_can_stop(ctx, args)); |
|
if (ret == -1) { |
|
if (!ctx->failed) { |
|
msg = imap_parser_get_error(ctx->save_parser, &fatal); |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 40309d92b95e9824170fc51a1160ada8cdec8fdb Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 6 May 2013 19:49:55 +0300 |
|
Subject: [PATCH] imap: Fixed assert-crash on invalid APPEND parameters. |
|
|
|
|
|
diff --git a/src/imap/cmd-append.c b/src/imap/cmd-append.c |
|
index 91376c1..947b959 100644 |
|
--- a/src/imap/cmd-append.c |
|
+++ b/src/imap/cmd-append.c |
|
@@ -501,9 +501,8 @@ cmd_append_handle_args(struct client_command_context *cmd, |
|
ctx->binary_input = args->literal8; |
|
valid = TRUE; |
|
} |
|
- /* we parsed the args only up to here. */ |
|
- i_assert(IMAP_ARG_IS_EOL(&args[1])); |
|
- |
|
+ if (!IMAP_ARG_IS_EOL(&args[1])) |
|
+ valid = FALSE; |
|
if (!valid) { |
|
client->input_skip_line = TRUE; |
|
if (!ctx->failed) |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 14508b41d6ece32d3fa835f368011b97374e7cf7 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 6 May 2013 19:51:07 +0300 |
|
Subject: [PATCH] imap: Don't eat away the next command if CATENATE fails. |
|
|
|
|
|
diff --git a/src/imap/cmd-append.c b/src/imap/cmd-append.c |
|
index 947b959..bc13535 100644 |
|
--- a/src/imap/cmd-append.c |
|
+++ b/src/imap/cmd-append.c |
|
@@ -324,7 +324,6 @@ cmd_append_catenate(struct client_command_context *cmd, |
|
} |
|
if (!ctx->failed) |
|
client_send_command_error(cmd, "Invalid arguments."); |
|
- cmd->client->input_skip_line = TRUE; |
|
return -1; |
|
} |
|
|
|
@@ -431,9 +430,6 @@ static bool cmd_append_continue_catenate(struct client_command_context *cmd) |
|
|
|
/* TEXT <literal> */ |
|
|
|
- /* after literal comes CRLF, if we fail make sure we eat it away */ |
|
- client->input_skip_line = TRUE; |
|
- |
|
if (!nonsync) { |
|
if (ctx->failed) { |
|
/* tagline was already sent, we can abort here */ |
|
@@ -738,8 +734,6 @@ static bool cmd_append_parse_new_msg(struct client_command_context *cmd) |
|
ret = cmd_append_handle_args(cmd, args, &nonsync); |
|
if (ret < 0) { |
|
/* invalid parameters, abort immediately */ |
|
- if (ctx->catenate) |
|
- client->input_skip_line = TRUE; |
|
cmd_append_finish(ctx); |
|
return TRUE; |
|
} |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 9a9ed402e6f5e0110f28cb2dff5db78682826479 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 6 May 2013 20:15:58 +0300 |
|
Subject: [PATCH] imap: Fixed URLFETCH assert-crashes due to output_cmd_lock |
|
not being cleared. |
|
|
|
|
|
diff --git a/src/imap/cmd-urlfetch.c b/src/imap/cmd-urlfetch.c |
|
index 86f1d05..d8c2e7f 100644 |
|
--- a/src/imap/cmd-urlfetch.c |
|
+++ b/src/imap/cmd-urlfetch.c |
|
@@ -43,7 +43,14 @@ static void cmd_urlfetch_finish(struct client_command_context *cmd) |
|
imap_urlauth_fetch_deinit(&ctx->ufetch); |
|
|
|
if (ctx->failed) { |
|
- client_send_internal_error(cmd); |
|
+ if (cmd->client->output_cmd_lock == cmd) { |
|
+ /* failed in the middle of a literal. |
|
+ we need to disconnect. */ |
|
+ cmd->client->output_cmd_lock = NULL; |
|
+ client_disconnect(cmd->client, "URLFETCH failed"); |
|
+ } else { |
|
+ client_send_internal_error(cmd); |
|
+ } |
|
return; |
|
} |
|
|
|
@@ -147,12 +154,12 @@ static bool cmd_urlfetch_continue(struct client_command_context *cmd) |
|
client_send_line(client, ")"); |
|
else |
|
client_send_line(client, ""); |
|
+ client->output_cmd_lock = NULL; |
|
|
|
if (imap_urlauth_fetch_continue(ctx->ufetch)) { |
|
/* waiting for imap urlauth service */ |
|
cmd->state = CLIENT_COMMAND_STATE_WAIT_EXTERNAL; |
|
cmd->func = cmd_urlfetch_cancel; |
|
- client->output_cmd_lock = NULL; |
|
|
|
/* retrieve next url */ |
|
return FALSE; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 9bb3ca1fe8560d8cee51f64097324a9d0935626f Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 6 May 2013 20:20:43 +0300 |
|
Subject: [PATCH] imap: URLFETCH leaked istream on failures. |
|
|
|
|
|
diff --git a/src/imap/cmd-urlfetch.c b/src/imap/cmd-urlfetch.c |
|
index d8c2e7f..92f17b9 100644 |
|
--- a/src/imap/cmd-urlfetch.c |
|
+++ b/src/imap/cmd-urlfetch.c |
|
@@ -39,6 +39,8 @@ static void cmd_urlfetch_finish(struct client_command_context *cmd) |
|
return; |
|
ctx->finished = TRUE; |
|
|
|
+ if (ctx->input != NULL) |
|
+ i_stream_unref(&ctx->input); |
|
if (ctx->ufetch != NULL) |
|
imap_urlauth_fetch_deinit(&ctx->ufetch); |
|
|
|
@@ -225,7 +227,7 @@ static int cmd_urlfetch_url_sucess(struct client_command_context *cmd, |
|
if (reply->input != NULL) { |
|
ctx->input = reply->input; |
|
ctx->size = reply->size; |
|
- i_stream_ref(reply->input); |
|
+ i_stream_ref(ctx->input); |
|
|
|
ret = cmd_urlfetch_transfer_literal(cmd); |
|
if (ret < 0) { |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From e37d7cac7729284fb791b4c0016899f52929e157 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 6 May 2013 20:21:27 +0300 |
|
Subject: [PATCH] imap: URLFETCH sometimes failed thinking it didn't receive |
|
all of the message data. |
|
|
|
|
|
diff --git a/src/imap/cmd-urlfetch.c b/src/imap/cmd-urlfetch.c |
|
index 92f17b9..5ddfb5f 100644 |
|
--- a/src/imap/cmd-urlfetch.c |
|
+++ b/src/imap/cmd-urlfetch.c |
|
@@ -116,7 +116,7 @@ static int cmd_urlfetch_transfer_literal(struct client_command_context *cmd) |
|
client_disconnect(client, "URLFETCH failed"); |
|
return -1; |
|
} |
|
- if (!ctx->input->eof) { |
|
+ if (i_stream_have_bytes_left(ctx->input)) { |
|
o_stream_set_flush_pending(client->output, TRUE); |
|
return 0; |
|
} |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 0c4653587c1d4cfcd212379c154e82af7be8ad00 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 6 May 2013 23:59:41 +0300 |
|
Subject: [PATCH] lib-index: Previous commit sometimes broke scanning |
|
transaction log view. If min_file_seq+offset pointed to the |
|
end of the previous file that no longer existed, we didn't |
|
just skip over it. |
|
|
|
|
|
diff --git a/src/lib-index/mail-transaction-log-view.c b/src/lib-index/mail-transaction-log-view.c |
|
index 707ad6b..ca51aea 100644 |
|
--- a/src/lib-index/mail-transaction-log-view.c |
|
+++ b/src/lib-index/mail-transaction-log-view.c |
|
@@ -95,6 +95,17 @@ int mail_transaction_log_view_set(struct mail_transaction_log_view *view, |
|
} |
|
|
|
for (file = view->log->files; file != NULL; file = file->next) { |
|
+ if (file->hdr.prev_file_seq == min_file_seq) |
|
+ break; |
|
+ } |
|
+ |
|
+ if (file != NULL && min_file_offset == file->hdr.prev_file_offset) { |
|
+ /* we can (and sometimes must) skip to the next file */ |
|
+ min_file_seq = file->hdr.file_seq; |
|
+ min_file_offset = file->hdr.hdr_size; |
|
+ } |
|
+ |
|
+ for (file = view->log->files; file != NULL; file = file->next) { |
|
if (file->hdr.prev_file_seq == max_file_seq) |
|
break; |
|
} |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 67b54367fff8348b1108391baa349a0230c3a839 Mon Sep 17 00:00:00 2001 |
|
From: Dennis Schridde <devurandom@gmx.net> |
|
Date: Mon, 13 May 2013 23:06:31 +0200 |
|
Subject: [PATCH] Fix out of source build of manpages |
|
|
|
|
|
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am |
|
index 4db8cfd..c18e6c3 100644 |
|
--- a/doc/man/Makefile.am |
|
+++ b/doc/man/Makefile.am |
|
@@ -85,4 +85,4 @@ CLEANFILES = $(nodist_man1_MANS) |
|
|
|
.1.in.1: $(man_includefiles) Makefile |
|
$(SHELL) $(srcdir)/sed.sh $(srcdir) $(rundir) $(pkgsysconfdir) \ |
|
- < $(srcdir)/$< > $@ |
|
+ < $< > $@ |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 2c4e0324c5aabbcfab02c3b0589d26c24650c535 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 14 May 2013 14:00:21 +0300 |
|
Subject: [PATCH] login-proxy: Don't crash if connect() succeeds but login |
|
fails with timeout. |
|
|
|
|
|
diff --git a/src/login-common/login-proxy-state.h b/src/login-common/login-proxy-state.h |
|
index 65e8fbb..eb08e6b 100644 |
|
--- a/src/login-common/login-proxy-state.h |
|
+++ b/src/login-common/login-proxy-state.h |
|
@@ -6,8 +6,9 @@ |
|
struct login_proxy_record { |
|
struct ip_addr ip; |
|
unsigned int port; |
|
- unsigned int num_waiting_connections; |
|
|
|
+ /* these are tracking connect()s, not necessarily logins: */ |
|
+ unsigned int num_waiting_connections; |
|
struct timeval last_failure; |
|
struct timeval last_success; |
|
}; |
|
diff --git a/src/login-common/login-proxy.c b/src/login-common/login-proxy.c |
|
index 9290883..1fdb2cf 100644 |
|
--- a/src/login-common/login-proxy.c |
|
+++ b/src/login-common/login-proxy.c |
|
@@ -254,7 +254,8 @@ static void proxy_connect_timeout(struct login_proxy *proxy) |
|
{ |
|
errno = ETIMEDOUT; |
|
proxy_log_connect_error(proxy); |
|
- proxy_fail_connect(proxy); |
|
+ if (!proxy->connected) |
|
+ proxy_fail_connect(proxy); |
|
login_proxy_free(&proxy); |
|
} |
|
|
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 110d79c741c2173cd187cb0e47c1c56fbbb3fe0b Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 14 May 2013 14:02:36 +0300 |
|
Subject: [PATCH] login-proxy: If login fails with timeout, log what the |
|
proxying state was. |
|
|
|
|
|
diff --git a/src/login-common/login-proxy.c b/src/login-common/login-proxy.c |
|
index 1fdb2cf..d2833e2 100644 |
|
--- a/src/login-common/login-proxy.c |
|
+++ b/src/login-common/login-proxy.c |
|
@@ -208,8 +208,9 @@ proxy_log_connect_error(struct login_proxy *proxy) |
|
str_printfa(str, "connect(%s, %u) failed: %m", |
|
proxy->host, proxy->port); |
|
} else { |
|
- str_printfa(str, "Login for %s:%u timed out", |
|
- proxy->host, proxy->port); |
|
+ str_printfa(str, "Login for %s:%u timed out in state=%u", |
|
+ proxy->host, proxy->port, |
|
+ proxy->client->proxy_state); |
|
} |
|
str_printfa(str, " (after %u secs", |
|
(unsigned int)(ioloop_time - proxy->created.tv_sec)); |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 942e14b174ea3e1a7b00e945c918c8ed936336fa Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 14 May 2013 14:14:16 +0300 |
|
Subject: [PATCH] configure: Fixed checking for struct sockpeercred with |
|
OpenBSD <5.3 |
|
|
|
|
|
diff --git a/configure.ac b/configure.ac |
|
index a67d511..b9c1ce5 100644 |
|
--- a/configure.ac |
|
+++ b/configure.ac |
|
@@ -433,7 +433,10 @@ AC_CHECK_FUNCS(fcntl flock lockf inet_aton sigaction getpagesize madvise \ |
|
walkcontext dirfd clearenv malloc_usable_size glob fallocate \ |
|
posix_fadvise getpeereid getpeerucred) |
|
|
|
-AC_CHECK_TYPES([struct sockpeercred],,,[#include <sys/socket.h>]) |
|
+AC_CHECK_TYPES([struct sockpeercred],,,[ |
|
+#include <sys/types.h> |
|
+#include <sys/socket.h> |
|
+]) |
|
|
|
AC_SEARCH_LIBS(clock_gettime, rt, [ |
|
AC_DEFINE(HAVE_CLOCK_GETTIME,, Define if you have the clock_gettime function) |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From eb3938ec8bf9db181964917253eae94477cac2a7 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 14 May 2013 16:32:30 +0300 |
|
Subject: [PATCH] pop3: Added pop3_deleted_flag setting. |
|
|
|
|
|
diff --git a/doc/example-config/conf.d/20-pop3.conf b/doc/example-config/conf.d/20-pop3.conf |
|
index be64c2c..ded9fa9 100644 |
|
--- a/doc/example-config/conf.d/20-pop3.conf |
|
+++ b/doc/example-config/conf.d/20-pop3.conf |
|
@@ -59,6 +59,13 @@ protocol pop3 { |
|
# rename: Append a temporary -2, -3, etc. counter after the UIDL. |
|
#pop3_uidl_duplicates = allow |
|
|
|
+ # This option changes POP3 behavior so that it's not possible to actually |
|
+ # delete mails via POP3, only hide them from future POP3 sessions. The mails |
|
+ # will still be counted towards user's quota until actually deleted via IMAP. |
|
+ # Use e.g. "$POP3Deleted" as the value (it will be visible as IMAP keyword). |
|
+ # Make sure you can legally archive mails before enabling this setting. |
|
+ #pop3_deleted_flag = |
|
+ |
|
# POP3 logout format string: |
|
# %i - total number of bytes read from client |
|
# %o - total number of bytes sent to client |
|
diff --git a/src/pop3/pop3-client.c b/src/pop3/pop3-client.c |
|
index e99f7bd..6de571c 100644 |
|
--- a/src/pop3/pop3-client.c |
|
+++ b/src/pop3/pop3-client.c |
|
@@ -141,6 +141,7 @@ static int read_mailbox(struct client *client, uint32_t *failed_uid_r) |
|
struct mailbox_status status; |
|
struct mailbox_transaction_context *t; |
|
struct mail_search_args *search_args; |
|
+ struct mail_search_arg *sarg; |
|
struct mail_search_context *ctx; |
|
struct mail *mail; |
|
uoff_t size; |
|
@@ -158,7 +159,17 @@ static int read_mailbox(struct client *client, uint32_t *failed_uid_r) |
|
t = mailbox_transaction_begin(client->mailbox, 0); |
|
|
|
search_args = mail_search_build_init(); |
|
- mail_search_build_add_all(search_args); |
|
+ if (client->deleted_kw != NULL) { |
|
+ sarg = mail_search_build_add(search_args, SEARCH_KEYWORDS); |
|
+ sarg->match_not = TRUE; |
|
+ sarg->value.str = p_strdup(search_args->pool, |
|
+ client->set->pop3_deleted_flag); |
|
+ i_array_init(&client->all_seqs, 32); |
|
+ } else { |
|
+ mail_search_build_add_all(search_args); |
|
+ } |
|
+ mail_search_args_init(search_args, client->mailbox, TRUE, NULL); |
|
+ |
|
ctx = mailbox_search_init(t, search_args, pop3_sort_program, |
|
client->set->pop3_fast_size_lookups ? 0 : |
|
MAIL_FETCH_VIRTUAL_SIZE, NULL); |
|
@@ -175,6 +186,8 @@ static int read_mailbox(struct client *client, uint32_t *failed_uid_r) |
|
*failed_uid_r = mail->uid; |
|
break; |
|
} |
|
+ if (array_is_created(&client->all_seqs)) |
|
+ seq_range_array_add(&client->all_seqs, mail->seq); |
|
msgnum_to_seq_map_add(&msgnum_to_seq_map, client, mail, msgnum); |
|
|
|
if ((mail_get_flags(mail) & MAIL_SEEN) != 0) |
|
@@ -197,7 +210,13 @@ static int read_mailbox(struct client *client, uint32_t *failed_uid_r) |
|
array_free(&msgnum_to_seq_map); |
|
return ret; |
|
} |
|
- i_assert(msgnum == client->messages_count); |
|
+ i_assert(msgnum <= client->messages_count); |
|
+ client->messages_count = msgnum; |
|
+ |
|
+ if (!array_is_created(&client->all_seqs)) { |
|
+ i_array_init(&client->all_seqs, 1); |
|
+ seq_range_array_add_range(&client->all_seqs, 1, msgnum); |
|
+ } |
|
|
|
client->trans = t; |
|
client->message_sizes = |
|
@@ -211,6 +230,26 @@ static int read_mailbox(struct client *client, uint32_t *failed_uid_r) |
|
return 1; |
|
} |
|
|
|
+static int init_pop3_deleted_flag(struct client *client, const char **error_r) |
|
+{ |
|
+ const char *deleted_keywords[2]; |
|
+ |
|
+ if (client->set->pop3_deleted_flag[0] == '\0') |
|
+ return 0; |
|
+ |
|
+ deleted_keywords[0] = client->set->pop3_deleted_flag; |
|
+ deleted_keywords[1] = NULL; |
|
+ if (mailbox_keywords_create(client->mailbox, deleted_keywords, |
|
+ &client->deleted_kw) < 0) { |
|
+ *error_r = t_strdup_printf( |
|
+ "pop3_deleted_flags: Invalid keyword '%s': %s", |
|
+ client->set->pop3_deleted_flag, |
|
+ mailbox_get_last_error(client->mailbox, NULL)); |
|
+ return -1; |
|
+ } |
|
+ return 0; |
|
+} |
|
+ |
|
static int init_mailbox(struct client *client, const char **error_r) |
|
{ |
|
uint32_t failed_uid = 0, last_failed_uid = 0; |
|
@@ -392,7 +431,8 @@ int client_create(int fd_in, int fd_out, const char *session_id, |
|
} |
|
client->mail_set = mail_storage_get_settings(storage); |
|
|
|
- if (init_mailbox(client, &errmsg) < 0) { |
|
+ if (init_pop3_deleted_flag(client, &errmsg) < 0 || |
|
+ init_mailbox(client, &errmsg) < 0) { |
|
i_error("Couldn't init INBOX: %s", errmsg); |
|
client_destroy(client, "Mailbox init failed"); |
|
return -1; |
|
@@ -553,6 +593,9 @@ static void client_default_destroy(struct client *client, const char *reason) |
|
message sizes. */ |
|
(void)mailbox_transaction_commit(&client->trans); |
|
} |
|
+ array_free(&client->all_seqs); |
|
+ if (client->deleted_kw != NULL) |
|
+ mailbox_keywords_unref(&client->deleted_kw); |
|
if (client->mailbox != NULL) |
|
mailbox_free(&client->mailbox); |
|
if (client->anvil_sent) { |
|
diff --git a/src/pop3/pop3-client.h b/src/pop3/pop3-client.h |
|
index 5c3bfe5..f8e6c35 100644 |
|
--- a/src/pop3/pop3-client.h |
|
+++ b/src/pop3/pop3-client.h |
|
@@ -1,6 +1,8 @@ |
|
#ifndef POP3_CLIENT_H |
|
#define POP3_CLIENT_H |
|
|
|
+#include "seq-range-array.h" |
|
+ |
|
struct client; |
|
struct mail_storage; |
|
|
|
@@ -48,6 +50,7 @@ struct client { |
|
struct mail_namespace *inbox_ns; |
|
struct mailbox *mailbox; |
|
struct mailbox_transaction_context *trans; |
|
+ struct mail_keywords *deleted_kw; |
|
|
|
struct timeout *to_session_dotlock_refresh; |
|
struct dotlock *session_dotlock; |
|
@@ -63,6 +66,9 @@ struct client { |
|
uoff_t deleted_size; |
|
uint32_t last_seen_pop3_msn, lowest_retr_pop3_msn; |
|
|
|
+ /* All sequences currently visible in the mailbox. */ |
|
+ ARRAY_TYPE(seq_range) all_seqs; |
|
+ |
|
/* [msgnum] contains mail seq. anything after it has seq = msgnum+1 */ |
|
uint32_t *msgnum_to_seq_map; |
|
uint32_t msgnum_to_seq_map_count; |
|
diff --git a/src/pop3/pop3-commands.c b/src/pop3/pop3-commands.c |
|
index a617f94..29e1d44 100644 |
|
--- a/src/pop3/pop3-commands.c |
|
+++ b/src/pop3/pop3-commands.c |
|
@@ -196,11 +196,12 @@ static struct mail_search_args * |
|
pop3_search_build(struct client *client, uint32_t seq) |
|
{ |
|
struct mail_search_args *search_args; |
|
+ struct mail_search_arg *sarg; |
|
|
|
search_args = mail_search_build_init(); |
|
if (seq == 0) { |
|
- mail_search_build_add_seqset(search_args, |
|
- 1, client->messages_count); |
|
+ sarg = mail_search_build_add(search_args, SEARCH_SEQSET); |
|
+ sarg->value.seqset = client->all_seqs; |
|
} else { |
|
mail_search_build_add_seqset(search_args, seq, seq); |
|
} |
|
@@ -222,6 +223,15 @@ static int client_verify_ordering(struct client *client, |
|
return 0; |
|
} |
|
|
|
+static void client_expunge(struct client *client, struct mail *mail) |
|
+{ |
|
+ if (client->deleted_kw != NULL) |
|
+ mail_update_keywords(mail, MODIFY_ADD, client->deleted_kw); |
|
+ else |
|
+ mail_expunge(mail); |
|
+ client->expunged_count++; |
|
+} |
|
+ |
|
bool client_update_mails(struct client *client) |
|
{ |
|
struct mail_search_args *search_args; |
|
@@ -250,8 +260,7 @@ bool client_update_mails(struct client *client) |
|
bit = 1 << (msgnum % CHAR_BIT); |
|
if (client->deleted_bitmask != NULL && |
|
(client->deleted_bitmask[msgnum / CHAR_BIT] & bit) != 0) { |
|
- mail_expunge(mail); |
|
- client->expunged_count++; |
|
+ client_expunge(client, mail); |
|
} else if (client->seen_bitmask != NULL && |
|
(client->seen_bitmask[msgnum / CHAR_BIT] & bit) != 0) { |
|
mail_update_flags(mail, MODIFY_ADD, MAIL_SEEN); |
|
diff --git a/src/pop3/pop3-settings.c b/src/pop3/pop3-settings.c |
|
index 2f3fbff..d9dc69a 100644 |
|
--- a/src/pop3/pop3-settings.c |
|
+++ b/src/pop3/pop3-settings.c |
|
@@ -71,6 +71,7 @@ static const struct setting_define pop3_setting_defines[] = { |
|
DEF(SET_STR, pop3_client_workarounds), |
|
DEF(SET_STR, pop3_logout_format), |
|
DEF(SET_ENUM, pop3_uidl_duplicates), |
|
+ DEF(SET_STR, pop3_deleted_flag), |
|
|
|
SETTING_DEFINE_LIST_END |
|
}; |
|
@@ -86,7 +87,8 @@ static const struct pop3_settings pop3_default_settings = { |
|
.pop3_fast_size_lookups = FALSE, |
|
.pop3_client_workarounds = "", |
|
.pop3_logout_format = "top=%t/%p, retr=%r/%b, del=%d/%m, size=%s", |
|
- .pop3_uidl_duplicates = "allow:rename" |
|
+ .pop3_uidl_duplicates = "allow:rename", |
|
+ .pop3_deleted_flag = "" |
|
}; |
|
|
|
static const struct setting_parser_info *pop3_setting_dependencies[] = { |
|
diff --git a/src/pop3/pop3-settings.h b/src/pop3/pop3-settings.h |
|
index e9bd2ba..90cbf77 100644 |
|
--- a/src/pop3/pop3-settings.h |
|
+++ b/src/pop3/pop3-settings.h |
|
@@ -23,6 +23,7 @@ struct pop3_settings { |
|
const char *pop3_client_workarounds; |
|
const char *pop3_logout_format; |
|
const char *pop3_uidl_duplicates; |
|
+ const char *pop3_deleted_flag; |
|
|
|
enum pop3_client_workarounds parsed_workarounds; |
|
}; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 14aacf975309dc3be388fd067e652a8ec1efc4a3 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 14 May 2013 16:46:08 +0300 |
|
Subject: [PATCH] example-config: Moved imap_* and pop3_* settings outside |
|
protocol section. There's no need to keep them inside |
|
protocol {}, and in case of pop3_uidl_format=%m setting |
|
it's actually harmful. |
|
|
|
|
|
diff --git a/doc/example-config/conf.d/20-imap.conf b/doc/example-config/conf.d/20-imap.conf |
|
index 9de1318..689b0ea 100644 |
|
--- a/doc/example-config/conf.d/20-imap.conf |
|
+++ b/doc/example-config/conf.d/20-imap.conf |
|
@@ -2,60 +2,60 @@ |
|
## IMAP specific settings |
|
## |
|
|
|
-protocol imap { |
|
- # Maximum IMAP command line length. Some clients generate very long command |
|
- # lines with huge mailboxes, so you may need to raise this if you get |
|
- # "Too long argument" or "IMAP command line too large" errors often. |
|
- #imap_max_line_length = 64k |
|
+# Maximum IMAP command line length. Some clients generate very long command |
|
+# lines with huge mailboxes, so you may need to raise this if you get |
|
+# "Too long argument" or "IMAP command line too large" errors often. |
|
+#imap_max_line_length = 64k |
|
+ |
|
+# IMAP logout format string: |
|
+# %i - total number of bytes read from client |
|
+# %o - total number of bytes sent to client |
|
+#imap_logout_format = in=%i out=%o |
|
+ |
|
+# Override the IMAP CAPABILITY response. If the value begins with '+', |
|
+# add the given capabilities on top of the defaults (e.g. +XFOO XBAR). |
|
+#imap_capability = |
|
+ |
|
+# How long to wait between "OK Still here" notifications when client is |
|
+# IDLEing. |
|
+#imap_idle_notify_interval = 2 mins |
|
+ |
|
+# ID field names and values to send to clients. Using * as the value makes |
|
+# Dovecot use the default value. The following fields have default values |
|
+# currently: name, version, os, os-version, support-url, support-email. |
|
+#imap_id_send = |
|
+ |
|
+# ID fields sent by client to log. * means everything. |
|
+#imap_id_log = |
|
+ |
|
+# Workarounds for various client bugs: |
|
+# delay-newmail: |
|
+# Send EXISTS/RECENT new mail notifications only when replying to NOOP |
|
+# and CHECK commands. Some clients ignore them otherwise, for example OSX |
|
+# Mail (<v2.1). Outlook Express breaks more badly though, without this it |
|
+# may show user "Message no longer in server" errors. Note that OE6 still |
|
+# breaks even with this workaround if synchronization is set to |
|
+# "Headers Only". |
|
+# tb-extra-mailbox-sep: |
|
+# Thunderbird gets somehow confused with LAYOUT=fs (mbox and dbox) and |
|
+# adds extra '/' suffixes to mailbox names. This option causes Dovecot to |
|
+# ignore the extra '/' instead of treating it as invalid mailbox name. |
|
+# tb-lsub-flags: |
|
+# Show \Noselect flags for LSUB replies with LAYOUT=fs (e.g. mbox). |
|
+# This makes Thunderbird realize they aren't selectable and show them |
|
+# greyed out, instead of only later giving "not selectable" popup error. |
|
+# |
|
+# The list is space-separated. |
|
+#imap_client_workarounds = |
|
|
|
- # Maximum number of IMAP connections allowed for a user from each IP address. |
|
- # NOTE: The username is compared case-sensitively. |
|
- #mail_max_userip_connections = 10 |
|
+# Host allowed in URLAUTH URLs sent by client. "*" allows all. |
|
+#imap_urlauth_host = |
|
|
|
+protocol imap { |
|
# Space separated list of plugins to load (default is global mail_plugins). |
|
#mail_plugins = $mail_plugins |
|
|
|
- # IMAP logout format string: |
|
- # %i - total number of bytes read from client |
|
- # %o - total number of bytes sent to client |
|
- #imap_logout_format = in=%i out=%o |
|
- |
|
- # Override the IMAP CAPABILITY response. If the value begins with '+', |
|
- # add the given capabilities on top of the defaults (e.g. +XFOO XBAR). |
|
- #imap_capability = |
|
- |
|
- # How long to wait between "OK Still here" notifications when client is |
|
- # IDLEing. |
|
- #imap_idle_notify_interval = 2 mins |
|
- |
|
- # ID field names and values to send to clients. Using * as the value makes |
|
- # Dovecot use the default value. The following fields have default values |
|
- # currently: name, version, os, os-version, support-url, support-email. |
|
- #imap_id_send = |
|
- |
|
- # ID fields sent by client to log. * means everything. |
|
- #imap_id_log = |
|
- |
|
- # Workarounds for various client bugs: |
|
- # delay-newmail: |
|
- # Send EXISTS/RECENT new mail notifications only when replying to NOOP |
|
- # and CHECK commands. Some clients ignore them otherwise, for example OSX |
|
- # Mail (<v2.1). Outlook Express breaks more badly though, without this it |
|
- # may show user "Message no longer in server" errors. Note that OE6 still |
|
- # breaks even with this workaround if synchronization is set to |
|
- # "Headers Only". |
|
- # tb-extra-mailbox-sep: |
|
- # Thunderbird gets somehow confused with LAYOUT=fs (mbox and dbox) and |
|
- # adds extra '/' suffixes to mailbox names. This option causes Dovecot to |
|
- # ignore the extra '/' instead of treating it as invalid mailbox name. |
|
- # tb-lsub-flags: |
|
- # Show \Noselect flags for LSUB replies with LAYOUT=fs (e.g. mbox). |
|
- # This makes Thunderbird realize they aren't selectable and show them |
|
- # greyed out, instead of only later giving "not selectable" popup error. |
|
- # |
|
- # The list is space-separated. |
|
- #imap_client_workarounds = |
|
+ # Maximum number of IMAP connections allowed for a user from each IP address. |
|
+ # NOTE: The username is compared case-sensitively. |
|
+ #mail_max_userip_connections = 10 |
|
} |
|
- |
|
-# Host allowed in URLAUTH URLs sent by client. "*" allows all. |
|
-#imap_urlauth_host = |
|
diff --git a/doc/example-config/conf.d/20-pop3.conf b/doc/example-config/conf.d/20-pop3.conf |
|
index ded9fa9..50470e9 100644 |
|
--- a/doc/example-config/conf.d/20-pop3.conf |
|
+++ b/doc/example-config/conf.d/20-pop3.conf |
|
@@ -2,97 +2,97 @@ |
|
## POP3 specific settings |
|
## |
|
|
|
-protocol pop3 { |
|
- # Don't try to set mails non-recent or seen with POP3 sessions. This is |
|
- # mostly intended to reduce disk I/O. With maildir it doesn't move files |
|
- # from new/ to cur/, with mbox it doesn't write Status-header. |
|
- #pop3_no_flag_updates = no |
|
+# Don't try to set mails non-recent or seen with POP3 sessions. This is |
|
+# mostly intended to reduce disk I/O. With maildir it doesn't move files |
|
+# from new/ to cur/, with mbox it doesn't write Status-header. |
|
+#pop3_no_flag_updates = no |
|
|
|
- # Support LAST command which exists in old POP3 specs, but has been removed |
|
- # from new ones. Some clients still wish to use this though. Enabling this |
|
- # makes RSET command clear all \Seen flags from messages. |
|
- #pop3_enable_last = no |
|
+# Support LAST command which exists in old POP3 specs, but has been removed |
|
+# from new ones. Some clients still wish to use this though. Enabling this |
|
+# makes RSET command clear all \Seen flags from messages. |
|
+#pop3_enable_last = no |
|
|
|
- # If mail has X-UIDL header, use it as the mail's UIDL. |
|
- #pop3_reuse_xuidl = no |
|
+# If mail has X-UIDL header, use it as the mail's UIDL. |
|
+#pop3_reuse_xuidl = no |
|
|
|
- # Allow only one POP3 session to run simultaneously for the same user. |
|
- #pop3_lock_session = no |
|
+# Allow only one POP3 session to run simultaneously for the same user. |
|
+#pop3_lock_session = no |
|
|
|
- # POP3 requires message sizes to be listed as if they had CR+LF linefeeds. |
|
- # Many POP3 servers violate this by returning the sizes with LF linefeeds, |
|
- # because it's faster to get. When this setting is enabled, Dovecot still |
|
- # tries to do the right thing first, but if that requires opening the |
|
- # message, it fallbacks to the easier (but incorrect) size. |
|
- #pop3_fast_size_lookups = no |
|
+# POP3 requires message sizes to be listed as if they had CR+LF linefeeds. |
|
+# Many POP3 servers violate this by returning the sizes with LF linefeeds, |
|
+# because it's faster to get. When this setting is enabled, Dovecot still |
|
+# tries to do the right thing first, but if that requires opening the |
|
+# message, it fallbacks to the easier (but incorrect) size. |
|
+#pop3_fast_size_lookups = no |
|
|
|
- # POP3 UIDL (unique mail identifier) format to use. You can use following |
|
- # variables, along with the variable modifiers described in |
|
- # doc/wiki/Variables.txt (e.g. %Uf for the filename in uppercase) |
|
- # |
|
- # %v - Mailbox's IMAP UIDVALIDITY |
|
- # %u - Mail's IMAP UID |
|
- # %m - MD5 sum of the mailbox headers in hex (mbox only) |
|
- # %f - filename (maildir only) |
|
- # %g - Mail's GUID |
|
- # |
|
- # If you want UIDL compatibility with other POP3 servers, use: |
|
- # UW's ipop3d : %08Xv%08Xu |
|
- # Courier : %f or %v-%u (both might be used simultaneosly) |
|
- # Cyrus (<= 2.1.3) : %u |
|
- # Cyrus (>= 2.1.4) : %v.%u |
|
- # Dovecot v0.99.x : %v.%u |
|
- # tpop3d : %Mf |
|
- # |
|
- # Note that Outlook 2003 seems to have problems with %v.%u format which was |
|
- # Dovecot's default, so if you're building a new server it would be a good |
|
- # idea to change this. %08Xu%08Xv should be pretty fail-safe. |
|
- # |
|
- #pop3_uidl_format = %08Xu%08Xv |
|
+# POP3 UIDL (unique mail identifier) format to use. You can use following |
|
+# variables, along with the variable modifiers described in |
|
+# doc/wiki/Variables.txt (e.g. %Uf for the filename in uppercase) |
|
+# |
|
+# %v - Mailbox's IMAP UIDVALIDITY |
|
+# %u - Mail's IMAP UID |
|
+# %m - MD5 sum of the mailbox headers in hex (mbox only) |
|
+# %f - filename (maildir only) |
|
+# %g - Mail's GUID |
|
+# |
|
+# If you want UIDL compatibility with other POP3 servers, use: |
|
+# UW's ipop3d : %08Xv%08Xu |
|
+# Courier : %f or %v-%u (both might be used simultaneosly) |
|
+# Cyrus (<= 2.1.3) : %u |
|
+# Cyrus (>= 2.1.4) : %v.%u |
|
+# Dovecot v0.99.x : %v.%u |
|
+# tpop3d : %Mf |
|
+# |
|
+# Note that Outlook 2003 seems to have problems with %v.%u format which was |
|
+# Dovecot's default, so if you're building a new server it would be a good |
|
+# idea to change this. %08Xu%08Xv should be pretty fail-safe. |
|
+# |
|
+#pop3_uidl_format = %08Xu%08Xv |
|
|
|
- # Permanently save UIDLs sent to POP3 clients, so pop3_uidl_format changes |
|
- # won't change those UIDLs. Currently this works only with Maildir. |
|
- #pop3_save_uidl = no |
|
+# Permanently save UIDLs sent to POP3 clients, so pop3_uidl_format changes |
|
+# won't change those UIDLs. Currently this works only with Maildir. |
|
+#pop3_save_uidl = no |
|
|
|
- # What to do about duplicate UIDLs if they exist? |
|
- # allow: Show duplicates to clients. |
|
- # rename: Append a temporary -2, -3, etc. counter after the UIDL. |
|
- #pop3_uidl_duplicates = allow |
|
+# What to do about duplicate UIDLs if they exist? |
|
+# allow: Show duplicates to clients. |
|
+# rename: Append a temporary -2, -3, etc. counter after the UIDL. |
|
+#pop3_uidl_duplicates = allow |
|
|
|
- # This option changes POP3 behavior so that it's not possible to actually |
|
- # delete mails via POP3, only hide them from future POP3 sessions. The mails |
|
- # will still be counted towards user's quota until actually deleted via IMAP. |
|
- # Use e.g. "$POP3Deleted" as the value (it will be visible as IMAP keyword). |
|
- # Make sure you can legally archive mails before enabling this setting. |
|
- #pop3_deleted_flag = |
|
+# This option changes POP3 behavior so that it's not possible to actually |
|
+# delete mails via POP3, only hide them from future POP3 sessions. The mails |
|
+# will still be counted towards user's quota until actually deleted via IMAP. |
|
+# Use e.g. "$POP3Deleted" as the value (it will be visible as IMAP keyword). |
|
+# Make sure you can legally archive mails before enabling this setting. |
|
+#pop3_deleted_flag = |
|
|
|
- # POP3 logout format string: |
|
- # %i - total number of bytes read from client |
|
- # %o - total number of bytes sent to client |
|
- # %t - number of TOP commands |
|
- # %p - number of bytes sent to client as a result of TOP command |
|
- # %r - number of RETR commands |
|
- # %b - number of bytes sent to client as a result of RETR command |
|
- # %d - number of deleted messages |
|
- # %m - number of messages (before deletion) |
|
- # %s - mailbox size in bytes (before deletion) |
|
- # %u - old/new UIDL hash. may help finding out if UIDLs changed unexpectedly |
|
- #pop3_logout_format = top=%t/%p, retr=%r/%b, del=%d/%m, size=%s |
|
+# POP3 logout format string: |
|
+# %i - total number of bytes read from client |
|
+# %o - total number of bytes sent to client |
|
+# %t - number of TOP commands |
|
+# %p - number of bytes sent to client as a result of TOP command |
|
+# %r - number of RETR commands |
|
+# %b - number of bytes sent to client as a result of RETR command |
|
+# %d - number of deleted messages |
|
+# %m - number of messages (before deletion) |
|
+# %s - mailbox size in bytes (before deletion) |
|
+# %u - old/new UIDL hash. may help finding out if UIDLs changed unexpectedly |
|
+#pop3_logout_format = top=%t/%p, retr=%r/%b, del=%d/%m, size=%s |
|
|
|
- # Maximum number of POP3 connections allowed for a user from each IP address. |
|
- # NOTE: The username is compared case-sensitively. |
|
- #mail_max_userip_connections = 10 |
|
+# Workarounds for various client bugs: |
|
+# outlook-no-nuls: |
|
+# Outlook and Outlook Express hang if mails contain NUL characters. |
|
+# This setting replaces them with 0x80 character. |
|
+# oe-ns-eoh: |
|
+# Outlook Express and Netscape Mail breaks if end of headers-line is |
|
+# missing. This option simply sends it if it's missing. |
|
+# The list is space-separated. |
|
+#pop3_client_workarounds = |
|
|
|
+protocol pop3 { |
|
# Space separated list of plugins to load (default is global mail_plugins). |
|
#mail_plugins = $mail_plugins |
|
|
|
- # Workarounds for various client bugs: |
|
- # outlook-no-nuls: |
|
- # Outlook and Outlook Express hang if mails contain NUL characters. |
|
- # This setting replaces them with 0x80 character. |
|
- # oe-ns-eoh: |
|
- # Outlook Express and Netscape Mail breaks if end of headers-line is |
|
- # missing. This option simply sends it if it's missing. |
|
- # The list is space-separated. |
|
- #pop3_client_workarounds = |
|
+ # Maximum number of POP3 connections allowed for a user from each IP address. |
|
+ # NOTE: The username is compared case-sensitively. |
|
+ #mail_max_userip_connections = 10 |
|
} |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 2aa4f8006da495916ccea58bf7e2339dd486508b Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 14 May 2013 22:23:27 +0300 |
|
Subject: [PATCH] Avoid strict aliasing warnings. |
|
|
|
|
|
diff --git a/src/lib/hash.h b/src/lib/hash.h |
|
index ead59a1..44c172a 100644 |
|
--- a/src/lib/hash.h |
|
+++ b/src/lib/hash.h |
|
@@ -82,13 +82,20 @@ void *hash_table_lookup(const struct hash_table *table, const void *key) ATTR_PU |
|
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) \ |
|
+#ifndef __cplusplus |
|
+# 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 *)((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) + \ |
|
+ (void *)((value_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._valuep, value_r) + \ |
|
COMPILE_ERROR_IF_TRUE(sizeof(*value_r) != sizeof(void *)))) |
|
+#else |
|
+/* C++ requires (void **) casting, but that's not possible with strict |
|
+ aliasing, so .. we'll just disable the type checks */ |
|
+# define hash_table_lookup_full(table, lookup_key, orig_key_r, value_r) \ |
|
+ hash_table_lookup_full((table)._table, lookup_key, orig_key_r, value_r) |
|
+#endif |
|
|
|
/* 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. */ |
|
@@ -119,12 +126,20 @@ struct hash_iterate_context *hash_table_iterate_init(struct hash_table *table); |
|
hash_table_iterate_init((table)._table) |
|
bool hash_table_iterate(struct hash_iterate_context *ctx, |
|
void **key_r, void **value_r); |
|
-#define hash_table_iterate(ctx, table, key_r, value_r) \ |
|
+#ifndef __cplusplus |
|
+# 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 *)((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)._valuep, value_r))) |
|
+ (void *)((value_r) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE((table)._valuep, value_r))) |
|
+#else |
|
+/* C++ requires (void **) casting, but that's not possible with strict |
|
+ aliasing, so .. we'll just disable the type checks */ |
|
+# define hash_table_iterate(ctx, table, key_r, value_r) \ |
|
+ hash_table_iterate(ctx, key_r, value_r) |
|
+#endif |
|
+ |
|
void hash_table_iterate_deinit(struct hash_iterate_context **ctx); |
|
|
|
/* Hash table isn't resized, and removed nodes aren't removed from |
|
diff --git a/src/plugins/fts-lucene/lucene-wrapper.cc b/src/plugins/fts-lucene/lucene-wrapper.cc |
|
index 1597e03..c57b676 100644 |
|
--- a/src/plugins/fts-lucene/lucene-wrapper.cc |
|
+++ b/src/plugins/fts-lucene/lucene-wrapper.cc |
|
@@ -1322,11 +1322,10 @@ lucene_index_search_multi(struct lucene_index *index, |
|
|
|
BooleanQuery mailbox_query; |
|
struct hash_iterate_context *iter; |
|
- wchar_t *key; |
|
- struct fts_result *value; |
|
+ void *key, *value; |
|
iter = hash_table_iterate_init(guids); |
|
while (hash_table_iterate(iter, guids, &key, &value)) { |
|
- Term *term = _CLNEW Term(_T("box"), key); |
|
+ Term *term = _CLNEW Term(_T("box"), (wchar_t *)key); |
|
TermQuery *q = _CLNEW TermQuery(term); |
|
mailbox_query.add(q, true, BooleanClause::SHOULD); |
|
} |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 13bcdd36670bd342e9f56ae303bcefa0484aff6c Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 14 May 2013 23:34:38 +0300 |
|
Subject: [PATCH] auth passwd-file: If we fail to open passwd-file, log a |
|
request error directly. Instead of one error message and |
|
another info message. |
|
|
|
|
|
diff --git a/src/auth/db-passwd-file.c b/src/auth/db-passwd-file.c |
|
index c43a4e0..eeda7bc 100644 |
|
--- a/src/auth/db-passwd-file.c |
|
+++ b/src/auth/db-passwd-file.c |
|
@@ -164,7 +164,8 @@ passwd_file_new(struct db_passwd_file *db, const char *expanded_path) |
|
return pw; |
|
} |
|
|
|
-static bool passwd_file_open(struct passwd_file *pw, bool startup) |
|
+static int passwd_file_open(struct passwd_file *pw, bool startup, |
|
+ const char **error_r) |
|
{ |
|
const char *no_args = NULL; |
|
struct istream *input; |
|
@@ -176,20 +177,20 @@ static bool passwd_file_open(struct passwd_file *pw, bool startup) |
|
|
|
fd = open(pw->path, O_RDONLY); |
|
if (fd == -1) { |
|
- if (errno == EACCES) { |
|
- i_error("passwd-file %s: %s", pw->path, |
|
- eacces_error_get("open", pw->path)); |
|
- } else { |
|
- i_error("passwd-file %s: Can't open file: %m", |
|
- pw->path); |
|
+ if (errno == EACCES) |
|
+ *error_r = eacces_error_get("open", pw->path); |
|
+ else { |
|
+ *error_r = t_strdup_printf("open(%s) failed: %m", |
|
+ pw->path); |
|
} |
|
- return FALSE; |
|
+ return -1; |
|
} |
|
|
|
if (fstat(fd, &st) != 0) { |
|
- i_error("passwd-file %s: fstat() failed: %m", pw->path); |
|
+ *error_r = t_strdup_printf("fstat(%s) failed: %m", |
|
+ pw->path); |
|
i_close_fd(&fd); |
|
- return FALSE; |
|
+ return -1; |
|
} |
|
|
|
pw->fd = fd; |
|
@@ -229,7 +230,7 @@ static bool passwd_file_open(struct passwd_file *pw, bool startup) |
|
i_debug("passwd-file %s: Read %u users in %u secs", |
|
pw->path, hash_table_count(pw->users), time_secs); |
|
} |
|
- return TRUE; |
|
+ return 0; |
|
} |
|
|
|
static void passwd_file_close(struct passwd_file *pw) |
|
@@ -256,30 +257,37 @@ static void passwd_file_free(struct passwd_file *pw) |
|
i_free(pw); |
|
} |
|
|
|
-static bool passwd_file_sync(struct passwd_file *pw) |
|
+static int passwd_file_sync(struct auth_request *request, |
|
+ struct passwd_file *pw) |
|
{ |
|
struct stat st; |
|
+ const char *error; |
|
|
|
if (stat(pw->path, &st) < 0) { |
|
/* with variables don't give hard errors, or errors about |
|
nonexistent files */ |
|
if (errno == EACCES) { |
|
- i_error("passwd-file %s: %s", pw->path, |
|
- eacces_error_get("stat", pw->path)); |
|
- } else if (errno != ENOENT) { |
|
- i_error("passwd-file %s: stat() failed: %m", pw->path); |
|
+ auth_request_log_error(request, "passwd-file", |
|
+ "%s", eacces_error_get("stat", pw->path)); |
|
+ } else { |
|
+ auth_request_log_error(request, "passwd-file", |
|
+ "stat(%s) failed: %m", pw->path); |
|
} |
|
|
|
if (pw->db->default_file != pw) |
|
passwd_file_free(pw); |
|
- return FALSE; |
|
+ return -1; |
|
} |
|
|
|
if (st.st_mtime != pw->stamp || st.st_size != pw->size) { |
|
passwd_file_close(pw); |
|
- return passwd_file_open(pw, FALSE); |
|
+ if (passwd_file_open(pw, FALSE, &error) < 0) { |
|
+ auth_request_log_error(request, "passwd-file", |
|
+ "%s", error); |
|
+ return -1; |
|
+ } |
|
} |
|
- return TRUE; |
|
+ return 0; |
|
} |
|
|
|
static struct db_passwd_file *db_passwd_file_find(const char *path) |
|
@@ -359,9 +367,12 @@ db_passwd_file_init(const char *path, bool userdb, bool debug) |
|
|
|
void db_passwd_file_parse(struct db_passwd_file *db) |
|
{ |
|
+ const char *error; |
|
+ |
|
if (db->default_file != NULL && db->default_file->stamp == 0) { |
|
/* no variables, open the file immediately */ |
|
- (void)passwd_file_open(db->default_file, TRUE); |
|
+ if (passwd_file_open(db->default_file, TRUE, &error) < 0) |
|
+ i_error("passwd-file: %s", error); |
|
} |
|
} |
|
|
|
@@ -421,7 +432,6 @@ db_passwd_file_lookup(struct db_passwd_file *db, struct auth_request *request, |
|
struct passwd_user *pu; |
|
const struct var_expand_table *table; |
|
string_t *username, *dest; |
|
- const char *path; |
|
|
|
if (!db->vars) |
|
pw = db->default_file; |
|
@@ -437,11 +447,8 @@ db_passwd_file_lookup(struct db_passwd_file *db, struct auth_request *request, |
|
} |
|
} |
|
|
|
- path = t_strdup(pw->path); |
|
- if (!passwd_file_sync(pw)) { |
|
+ if (passwd_file_sync(request, pw) < 0) { |
|
/* pw may be freed now */ |
|
- auth_request_log_info(request, "passwd-file", |
|
- "no passwd file: %s", path); |
|
return NULL; |
|
} |
|
|
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 3098ef40cba6126700c24074a24eaa9dfd8252b2 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Wed, 15 May 2013 12:48:21 +0300 |
|
Subject: [PATCH] example-config: auth-*.conf.ext should say they're included |
|
by 10-auth.conf |
|
|
|
|
|
diff --git a/doc/example-config/conf.d/auth-checkpassword.conf.ext b/doc/example-config/conf.d/auth-checkpassword.conf.ext |
|
index 02efae3..b2fb13a 100644 |
|
--- a/doc/example-config/conf.d/auth-checkpassword.conf.ext |
|
+++ b/doc/example-config/conf.d/auth-checkpassword.conf.ext |
|
@@ -1,4 +1,4 @@ |
|
-# Authentication for checkpassword users. Included from auth.conf. |
|
+# Authentication for checkpassword users. Included from 10-auth.conf. |
|
# |
|
# <doc/wiki/AuthDatabase.CheckPassword.txt> |
|
|
|
diff --git a/doc/example-config/conf.d/auth-deny.conf.ext b/doc/example-config/conf.d/auth-deny.conf.ext |
|
index f2d897d..ce3f1cf 100644 |
|
--- a/doc/example-config/conf.d/auth-deny.conf.ext |
|
+++ b/doc/example-config/conf.d/auth-deny.conf.ext |
|
@@ -1,4 +1,4 @@ |
|
-# Deny access for users. Included from auth.conf. |
|
+# Deny access for users. Included from 10-auth.conf. |
|
|
|
# Users can be (temporarily) disabled by adding a passdb with deny=yes. |
|
# If the user is found from that database, authentication will fail. |
|
diff --git a/doc/example-config/conf.d/auth-ldap.conf.ext b/doc/example-config/conf.d/auth-ldap.conf.ext |
|
index 3e5c51f..5db32fa 100644 |
|
--- a/doc/example-config/conf.d/auth-ldap.conf.ext |
|
+++ b/doc/example-config/conf.d/auth-ldap.conf.ext |
|
@@ -1,4 +1,4 @@ |
|
-# Authentication for LDAP users. Included from auth.conf. |
|
+# Authentication for LDAP users. Included from 10-auth.conf. |
|
# |
|
# <doc/wiki/AuthDatabase.LDAP.txt> |
|
|
|
diff --git a/doc/example-config/conf.d/auth-master.conf.ext b/doc/example-config/conf.d/auth-master.conf.ext |
|
index 8e5107f..2cf128f 100644 |
|
--- a/doc/example-config/conf.d/auth-master.conf.ext |
|
+++ b/doc/example-config/conf.d/auth-master.conf.ext |
|
@@ -1,4 +1,4 @@ |
|
-# Authentication for master users. Included from auth.conf. |
|
+# Authentication for master users. Included from 10-auth.conf. |
|
|
|
# By adding master=yes setting inside a passdb you make the passdb a list |
|
# of "master users", who can log in as anyone else. |
|
diff --git a/doc/example-config/conf.d/auth-passwdfile.conf.ext b/doc/example-config/conf.d/auth-passwdfile.conf.ext |
|
index 5554957..c89d28c 100644 |
|
--- a/doc/example-config/conf.d/auth-passwdfile.conf.ext |
|
+++ b/doc/example-config/conf.d/auth-passwdfile.conf.ext |
|
@@ -1,4 +1,4 @@ |
|
-# Authentication for passwd-file users. Included from auth.conf. |
|
+# Authentication for passwd-file users. Included from 10-auth.conf. |
|
# |
|
# passwd-like file with specified location. |
|
# <doc/wiki/AuthDatabase.PasswdFile.txt> |
|
diff --git a/doc/example-config/conf.d/auth-sql.conf.ext b/doc/example-config/conf.d/auth-sql.conf.ext |
|
index 9ba585b..ccbea86 100644 |
|
--- a/doc/example-config/conf.d/auth-sql.conf.ext |
|
+++ b/doc/example-config/conf.d/auth-sql.conf.ext |
|
@@ -1,4 +1,4 @@ |
|
-# Authentication for SQL users. Included from auth.conf. |
|
+# Authentication for SQL users. Included from 10-auth.conf. |
|
# |
|
# <doc/wiki/AuthDatabase.SQL.txt> |
|
|
|
diff --git a/doc/example-config/conf.d/auth-static.conf.ext b/doc/example-config/conf.d/auth-static.conf.ext |
|
index 238d517..90890c5 100644 |
|
--- a/doc/example-config/conf.d/auth-static.conf.ext |
|
+++ b/doc/example-config/conf.d/auth-static.conf.ext |
|
@@ -1,4 +1,4 @@ |
|
-# Static passdb. Included from auth.conf. |
|
+# Static passdb. Included from 10-auth.conf. |
|
|
|
# This can be used for situations where Dovecot doesn't need to verify the |
|
# username or the password, or if there is a single password for all users: |
|
diff --git a/doc/example-config/conf.d/auth-system.conf.ext b/doc/example-config/conf.d/auth-system.conf.ext |
|
index 260c080..23f943c 100644 |
|
--- a/doc/example-config/conf.d/auth-system.conf.ext |
|
+++ b/doc/example-config/conf.d/auth-system.conf.ext |
|
@@ -1,4 +1,4 @@ |
|
-# Authentication for system users. Included from auth.conf. |
|
+# Authentication for system users. Included from 10-auth.conf. |
|
# |
|
# <doc/wiki/PasswordDatabase.txt> |
|
# <doc/wiki/UserDatabase.txt> |
|
diff --git a/doc/example-config/conf.d/auth-vpopmail.conf.ext b/doc/example-config/conf.d/auth-vpopmail.conf.ext |
|
index 355237d..f2da976 100644 |
|
--- a/doc/example-config/conf.d/auth-vpopmail.conf.ext |
|
+++ b/doc/example-config/conf.d/auth-vpopmail.conf.ext |
|
@@ -1,4 +1,4 @@ |
|
-# Authentication for vpopmail users. Included from auth.conf. |
|
+# Authentication for vpopmail users. Included from 10-auth.conf. |
|
# |
|
# <doc/wiki/AuthDatabase.VPopMail.txt> |
|
|
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 68f86f89ba6ade74b215a65cc35dc0877241ccd8 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Wed, 15 May 2013 12:50:03 +0300 |
|
Subject: [PATCH] example-config: Removed dovecot-db.conf.ext since Berkeley |
|
DB support is never built in. |
|
|
|
|
|
diff --git a/doc/example-config/dovecot-db.conf.ext b/doc/example-config/dovecot-db.conf.ext |
|
deleted file mode 100644 |
|
index 165dc13..0000000 |
|
--- a/doc/example-config/dovecot-db.conf.ext |
|
+++ /dev/null |
|
@@ -1,11 +0,0 @@ |
|
-# Example DB_CONFIG for Berkeley DB. Typically dict_db_config setting is used |
|
-# to point to this file. |
|
-# http://www.oracle.com/technology/documentation/berkeley-db/db/ref/env/db_config.html |
|
- |
|
-# Maximum number of simultaneous transactions. |
|
-set_tx_max 1000 |
|
- |
|
-# http://www.oracle.com/technology/documentation/berkeley-db/db/ref/lock/max.html |
|
-#set_lk_max_locks 1000 |
|
-#set_lk_max_lockers 1000 |
|
-#set_lk_max_objects 1000 |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 43e1226ce6ef93aaaf1fb51789949ec6464eee13 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Wed, 15 May 2013 12:50:29 +0300 |
|
Subject: [PATCH] Makefile: Removed dovecot-db.conf.ext |
|
|
|
|
|
diff --git a/doc/example-config/Makefile.am b/doc/example-config/Makefile.am |
|
index d609f06..5a2dd8b 100644 |
|
--- a/doc/example-config/Makefile.am |
|
+++ b/doc/example-config/Makefile.am |
|
@@ -12,7 +12,6 @@ README: README.in Makefile |
|
exampledir = $(docdir)/example-config |
|
example_DATA = \ |
|
dovecot.conf \ |
|
- dovecot-db.conf.ext \ |
|
dovecot-dict-auth.conf.ext \ |
|
dovecot-dict-sql.conf.ext \ |
|
dovecot-ldap.conf.ext \ |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 2dcba78690d3e7282afdf0012c98ea08924c49da Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Wed, 15 May 2013 12:52:29 +0300 |
|
Subject: [PATCH] example-config: Added comment how all *.conf.ext files are |
|
accessed typically. |
|
|
|
|
|
diff --git a/doc/example-config/dovecot-dict-auth.conf.ext b/doc/example-config/dovecot-dict-auth.conf.ext |
|
index 7e79d3c..50617bb 100644 |
|
--- a/doc/example-config/dovecot-dict-auth.conf.ext |
|
+++ b/doc/example-config/dovecot-dict-auth.conf.ext |
|
@@ -1,3 +1,5 @@ |
|
+# This file is commonly accessed via dict {} section in dovecot.conf |
|
+ |
|
# Dictionary URI |
|
#uri = |
|
|
|
diff --git a/doc/example-config/dovecot-dict-sql.conf.ext b/doc/example-config/dovecot-dict-sql.conf.ext |
|
index 674a25f..a9a903f 100644 |
|
--- a/doc/example-config/dovecot-dict-sql.conf.ext |
|
+++ b/doc/example-config/dovecot-dict-sql.conf.ext |
|
@@ -1,3 +1,5 @@ |
|
+# This file is commonly accessed via dict {} section in dovecot.conf |
|
+ |
|
#connect = host=localhost dbname=mails user=testuser password=pass |
|
|
|
# CREATE TABLE quota ( |
|
diff --git a/doc/example-config/dovecot-ldap.conf.ext b/doc/example-config/dovecot-ldap.conf.ext |
|
index 7dcc748..1ca6733 100644 |
|
--- a/doc/example-config/dovecot-ldap.conf.ext |
|
+++ b/doc/example-config/dovecot-ldap.conf.ext |
|
@@ -1,3 +1,6 @@ |
|
+# This file is commonly accessed via passdb {} or userdb {} section in |
|
+# conf.d/auth-ldap.conf.ext |
|
+ |
|
# This file is opened as root, so it should be owned by root and mode 0600. |
|
# |
|
# http://wiki2.dovecot.org/AuthDatabase/LDAP |
|
diff --git a/doc/example-config/dovecot-sql.conf.ext b/doc/example-config/dovecot-sql.conf.ext |
|
index b650c57..77e8187 100644 |
|
--- a/doc/example-config/dovecot-sql.conf.ext |
|
+++ b/doc/example-config/dovecot-sql.conf.ext |
|
@@ -1,3 +1,6 @@ |
|
+# This file is commonly accessed via passdb {} or userdb {} section in |
|
+# conf.d/auth-sql.conf.ext |
|
+ |
|
# This file is opened as root, so it should be owned by root and mode 0600. |
|
# |
|
# http://wiki2.dovecot.org/AuthDatabase/SQL |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 36faafec8112b7f76ec89597510925ca85873acd Mon Sep 17 00:00:00 2001 |
|
From: Florian Zeitz <florob@babelmonkeys.de> |
|
Date: Sat, 11 May 2013 17:08:12 +0200 |
|
Subject: [PATCH] liblib: Fix Unicode decomposition |
|
|
|
|
|
diff --git a/src/lib/test-unichar.c b/src/lib/test-unichar.c |
|
index abb6357..b7bb258 100644 |
|
--- a/src/lib/test-unichar.c |
|
+++ b/src/lib/test-unichar.c |
|
@@ -2,11 +2,15 @@ |
|
|
|
#include "test-lib.h" |
|
#include "str.h" |
|
+#include "buffer.h" |
|
#include "unichar.h" |
|
|
|
void test_unichar(void) |
|
{ |
|
- static const char *overlong_utf8 = "\xf8\x80\x95\x81\xa1"; |
|
+ static const char overlong_utf8[] = "\xf8\x80\x95\x81\xa1"; |
|
+ static const char collate_in[] = "\xc3\xbc \xc2\xb3"; |
|
+ static const char collate_exp[] = "U\xcc\x88 3"; |
|
+ buffer_t *collate_out; |
|
unichar_t chr, chr2; |
|
string_t *str = t_str_new(16); |
|
|
|
@@ -18,6 +22,13 @@ void test_unichar(void) |
|
test_assert(uni_utf8_get_char(str_c(str), &chr2) > 0); |
|
test_assert(chr2 == chr); |
|
} |
|
+ |
|
+ collate_out = buffer_create_dynamic(default_pool, 32); |
|
+ uni_utf8_to_decomposed_titlecase(collate_in, sizeof(collate_in), |
|
+ collate_out); |
|
+ test_assert(!strcmp(collate_out->data, collate_exp)); |
|
+ buffer_free(&collate_out); |
|
+ |
|
test_assert(!uni_utf8_str_is_valid(overlong_utf8)); |
|
test_assert(uni_utf8_get_char(overlong_utf8, &chr2) < 0); |
|
test_end(); |
|
diff --git a/src/lib/unichar.c b/src/lib/unichar.c |
|
index b0c50f5..97b0aaf 100644 |
|
--- a/src/lib/unichar.c |
|
+++ b/src/lib/unichar.c |
|
@@ -287,7 +287,7 @@ static void uni_ucs4_decompose_hangul_utf8(unichar_t chr, buffer_t *output) |
|
|
|
static bool uni_ucs4_decompose_multi_utf8(unichar_t chr, buffer_t *output) |
|
{ |
|
- const uint16_t *value; |
|
+ const uint32_t *value; |
|
unsigned int idx; |
|
|
|
if (chr < multidecomp_keys[0] || chr > 0xffff) |
|
diff --git a/src/lib/unicodemap.pl b/src/lib/unicodemap.pl |
|
index c18c273..2c1bf7a 100755 |
|
--- a/src/lib/unicodemap.pl |
|
+++ b/src/lib/unicodemap.pl |
|
@@ -30,14 +30,14 @@ while (<>) { |
|
push @titlecase32_keys, $code; |
|
push @titlecase32_values, $value; |
|
} |
|
- } elsif ($decomp =~ /\<[^>]*> (.+)/) { |
|
+ } elsif ($decomp =~ /(?:\<[^>]*> )?(.+)/) { |
|
# decompositions |
|
my $decomp_codes = $1; |
|
if ($decomp_codes =~ /^([0-9A-Z]*)$/i) { |
|
# unicharacter decomposition. use separate lists for this |
|
my $value = eval("0x$1"); |
|
- if ($value > 0xffff) { |
|
- print STDERR "Error: We've assumed decomposition codes are max. 16bit\n"; |
|
+ if ($value > 0xffffffff) { |
|
+ print STDERR "Error: We've assumed decomposition codes are max. 32bit\n"; |
|
exit 1; |
|
} |
|
if ($code <= 0xff) { |
|
@@ -61,8 +61,8 @@ while (<>) { |
|
|
|
foreach my $dcode (split(" ", $decomp_codes)) { |
|
my $value = eval("0x$dcode"); |
|
- if ($value > 0xffff) { |
|
- print STDERR "Error: We've assumed decomposition codes are max. 16bit\n"; |
|
+ if ($value > 0xffffffff) { |
|
+ print STDERR "Error: We've assumed decomposition codes are max. 32bit\n"; |
|
exit 1; |
|
} |
|
push @multidecomp_values, $value; |
|
@@ -78,7 +78,7 @@ sub print_list { |
|
my $last = $#list; |
|
my $n = 0; |
|
foreach my $key (@list) { |
|
- printf("0x%04x", $key); |
|
+ printf("0x%05x", $key); |
|
last if ($n == $last); |
|
print ","; |
|
|
|
@@ -137,7 +137,7 @@ print "static const uint16_t uni16_decomp_keys[] = {\n\t"; |
|
print_list(\@uni16_decomp_keys); |
|
print "\n};\n"; |
|
|
|
-print "static const uint16_t uni16_decomp_values[] = {\n\t"; |
|
+print "static const uint32_t uni16_decomp_values[] = {\n\t"; |
|
print_list(\@uni16_decomp_values); |
|
print "\n};\n"; |
|
|
|
@@ -145,7 +145,7 @@ print "static const uint32_t uni32_decomp_keys[] = {\n\t"; |
|
print_list(\@uni32_decomp_keys); |
|
print "\n};\n"; |
|
|
|
-print "static const uint16_t uni32_decomp_values[] = {\n\t"; |
|
+print "static const uint32_t uni32_decomp_values[] = {\n\t"; |
|
print_list(\@uni32_decomp_values); |
|
print "\n};\n"; |
|
|
|
@@ -157,6 +157,6 @@ print "static const uint16_t multidecomp_offsets[] = {\n\t"; |
|
print_list(\@multidecomp_offsets); |
|
print "\n};\n"; |
|
|
|
-print "static const uint16_t multidecomp_values[] = {\n\t"; |
|
+print "static const uint32_t multidecomp_values[] = {\n\t"; |
|
print_list(\@multidecomp_values); |
|
print "\n};\n"; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From b92f8fd079ad5aae050cc1e560d1f3bf0a4fd14f Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Wed, 15 May 2013 13:20:43 +0300 |
|
Subject: [PATCH] lib-storage: Added mail_always_cache_fields setting. |
|
|
|
|
|
diff --git a/src/lib-storage/index/index-storage.c b/src/lib-storage/index/index-storage.c |
|
index a4c1061..c5c1380 100644 |
|
--- a/src/lib-storage/index/index-storage.c |
|
+++ b/src/lib-storage/index/index-storage.c |
|
@@ -65,6 +65,10 @@ static void index_cache_register_defaults(struct mailbox *box) |
|
set_cache_decisions("mail_cache_fields", |
|
set->mail_cache_fields, |
|
MAIL_CACHE_DECISION_TEMP); |
|
+ set_cache_decisions("mail_always_cache_fields", |
|
+ set->mail_always_cache_fields, |
|
+ MAIL_CACHE_DECISION_YES | |
|
+ MAIL_CACHE_DECISION_FORCED); |
|
set_cache_decisions("mail_never_cache_fields", |
|
set->mail_never_cache_fields, |
|
MAIL_CACHE_DECISION_NO | |
|
diff --git a/src/lib-storage/mail-storage-settings.c b/src/lib-storage/mail-storage-settings.c |
|
index 3eb3aa5..67f724d 100644 |
|
--- a/src/lib-storage/mail-storage-settings.c |
|
+++ b/src/lib-storage/mail-storage-settings.c |
|
@@ -33,6 +33,7 @@ static const struct setting_define mail_storage_setting_defines[] = { |
|
DEF(SET_STR_VARS, mail_attribute_dict), |
|
DEF(SET_UINT, mail_prefetch_count), |
|
DEF(SET_STR, mail_cache_fields), |
|
+ DEF(SET_STR, mail_always_cache_fields), |
|
DEF(SET_STR, mail_never_cache_fields), |
|
DEF(SET_UINT, mail_cache_min_mail_count), |
|
DEF(SET_TIME, mailbox_idle_check_interval), |
|
@@ -69,6 +70,7 @@ const struct mail_storage_settings mail_storage_default_settings = { |
|
.mail_attribute_dict = "", |
|
.mail_prefetch_count = 0, |
|
.mail_cache_fields = "flags", |
|
+ .mail_always_cache_fields = "", |
|
.mail_never_cache_fields = "imap.envelope", |
|
.mail_cache_min_mail_count = 0, |
|
.mailbox_idle_check_interval = 30, |
|
diff --git a/src/lib-storage/mail-storage-settings.h b/src/lib-storage/mail-storage-settings.h |
|
index aa599f6..aeeadc8 100644 |
|
--- a/src/lib-storage/mail-storage-settings.h |
|
+++ b/src/lib-storage/mail-storage-settings.h |
|
@@ -18,6 +18,7 @@ struct mail_storage_settings { |
|
const char *mail_attribute_dict; |
|
unsigned int mail_prefetch_count; |
|
const char *mail_cache_fields; |
|
+ const char *mail_always_cache_fields; |
|
const char *mail_never_cache_fields; |
|
unsigned int mail_cache_min_mail_count; |
|
unsigned int mailbox_idle_check_interval; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 20bd7d25419ab4e4bca7d7eef0ba11f50110cb71 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Wed, 15 May 2013 13:34:59 +0300 |
|
Subject: [PATCH] lib-index: Fixed mail_cache_register_fields() decision |
|
updates. Normally this shouldn't matter, except when |
|
mail_*cache_fields settings have been used. |
|
|
|
|
|
diff --git a/src/lib-index/mail-cache-fields.c b/src/lib-index/mail-cache-fields.c |
|
index 347486e..3cbfc4a 100644 |
|
--- a/src/lib-index/mail-cache-fields.c |
|
+++ b/src/lib-index/mail-cache-fields.c |
|
@@ -74,8 +74,8 @@ mail_cache_field_update(struct mail_cache *cache, |
|
i_assert(newfield->type < MAIL_CACHE_FIELD_COUNT); |
|
|
|
orig = &cache->fields[newfield->idx]; |
|
- if (newfield->decision != MAIL_CACHE_DECISION_NO && |
|
- orig->field.decision != newfield->decision) { |
|
+ if ((newfield->decision & MAIL_CACHE_DECISION_FORCED) != 0 || |
|
+ newfield->decision > orig->field.decision) { |
|
orig->field.decision = newfield->decision; |
|
orig->decision_dirty = TRUE; |
|
} |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 22531ca1ad97537cf96085fe9aac0ba19d7e55aa Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Wed, 15 May 2013 13:36:43 +0300 |
|
Subject: [PATCH] lib-index: Don't mark field decisions dirty when registering |
|
initial cache fields. |
|
|
|
|
|
diff --git a/src/lib-index/mail-cache-fields.c b/src/lib-index/mail-cache-fields.c |
|
index 3cbfc4a..084331e 100644 |
|
--- a/src/lib-index/mail-cache-fields.c |
|
+++ b/src/lib-index/mail-cache-fields.c |
|
@@ -70,18 +70,26 @@ mail_cache_field_update(struct mail_cache *cache, |
|
const struct mail_cache_field *newfield) |
|
{ |
|
struct mail_cache_field_private *orig; |
|
+ bool initial_registering; |
|
|
|
i_assert(newfield->type < MAIL_CACHE_FIELD_COUNT); |
|
|
|
+ /* are we still doing the initial cache field registering for |
|
+ internal fields and for mail_*cache_fields settings? */ |
|
+ initial_registering = cache->file_fields_count == 0; |
|
+ |
|
orig = &cache->fields[newfield->idx]; |
|
if ((newfield->decision & MAIL_CACHE_DECISION_FORCED) != 0 || |
|
- newfield->decision > orig->field.decision) { |
|
+ ((orig->field.decision & MAIL_CACHE_DECISION_FORCED) == 0 && |
|
+ newfield->decision > orig->field.decision)) { |
|
orig->field.decision = newfield->decision; |
|
- orig->decision_dirty = TRUE; |
|
+ if (!initial_registering) |
|
+ orig->decision_dirty = TRUE; |
|
} |
|
if (orig->field.last_used < newfield->last_used) { |
|
orig->field.last_used = newfield->last_used; |
|
- orig->decision_dirty = TRUE; |
|
+ if (!initial_registering) |
|
+ orig->decision_dirty = TRUE; |
|
} |
|
if (orig->decision_dirty) |
|
cache->field_header_write_pending = TRUE; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 8449d1499abda0d5e0667a2a95298d4863a45265 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Wed, 15 May 2013 13:44:01 +0300 |
|
Subject: [PATCH] lib-storage: Allow mail_*cache_fields settings to specify |
|
any hdr.* fields. Also the fields were previously set only |
|
once globally, so if the process served multiple users, it |
|
wouldn't have been possible to use per-user values for |
|
these fields. |
|
|
|
|
|
diff --git a/src/lib-storage/index/index-storage.c b/src/lib-storage/index/index-storage.c |
|
index c5c1380..727767f 100644 |
|
--- a/src/lib-storage/index/index-storage.c |
|
+++ b/src/lib-storage/index/index-storage.c |
|
@@ -28,27 +28,35 @@ |
|
struct index_storage_module index_storage_module = |
|
MODULE_CONTEXT_INIT(&mail_storage_module_register); |
|
|
|
-static void set_cache_decisions(const char *set, const char *fields, |
|
+static void set_cache_decisions(struct mail_cache *cache, |
|
+ const char *set, const char *fields, |
|
enum mail_cache_decision_type dec) |
|
{ |
|
+ struct mail_cache_field field; |
|
const char *const *arr; |
|
- int i; |
|
+ unsigned int idx; |
|
|
|
if (fields == NULL || *fields == '\0') |
|
return; |
|
|
|
for (arr = t_strsplit_spaces(fields, " ,"); *arr != NULL; arr++) { |
|
- for (i = 0; i < MAIL_INDEX_CACHE_FIELD_COUNT; i++) { |
|
- if (strcasecmp(global_cache_fields[i].name, |
|
- *arr) == 0) { |
|
- global_cache_fields[i].decision = dec; |
|
- break; |
|
- } |
|
- } |
|
- if (i == MAIL_INDEX_CACHE_FIELD_COUNT) { |
|
- i_error("%s: Invalid cache field name '%s', ignoring ", |
|
+ const char *name = *arr; |
|
+ |
|
+ idx = mail_cache_register_lookup(cache, name); |
|
+ if (idx != UINT_MAX) { |
|
+ field = *mail_cache_register_get_field(cache, idx); |
|
+ } else if (strncasecmp(name, "hdr.", 4) == 0) { |
|
+ memset(&field, 0, sizeof(field)); |
|
+ field.name = name; |
|
+ field.type = MAIL_CACHE_FIELD_HEADER; |
|
+ } else { |
|
+ i_error("%s: Unknown cache field name '%s', ignoring", |
|
set, *arr); |
|
+ continue; |
|
} |
|
+ |
|
+ field.decision = dec; |
|
+ mail_cache_register_fields(cache, &field, 1); |
|
} |
|
} |
|
|
|
@@ -56,30 +64,24 @@ static void index_cache_register_defaults(struct mailbox *box) |
|
{ |
|
struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box); |
|
const struct mail_storage_settings *set = box->storage->set; |
|
- static bool initialized = FALSE; |
|
struct mail_cache *cache = box->cache; |
|
|
|
- if (!initialized) { |
|
- initialized = TRUE; |
|
- |
|
- set_cache_decisions("mail_cache_fields", |
|
- set->mail_cache_fields, |
|
- MAIL_CACHE_DECISION_TEMP); |
|
- set_cache_decisions("mail_always_cache_fields", |
|
- set->mail_always_cache_fields, |
|
- MAIL_CACHE_DECISION_YES | |
|
- MAIL_CACHE_DECISION_FORCED); |
|
- set_cache_decisions("mail_never_cache_fields", |
|
- set->mail_never_cache_fields, |
|
- MAIL_CACHE_DECISION_NO | |
|
- MAIL_CACHE_DECISION_FORCED); |
|
- } |
|
- |
|
ibox->cache_fields = i_malloc(sizeof(global_cache_fields)); |
|
memcpy(ibox->cache_fields, global_cache_fields, |
|
sizeof(global_cache_fields)); |
|
mail_cache_register_fields(cache, ibox->cache_fields, |
|
MAIL_INDEX_CACHE_FIELD_COUNT); |
|
+ set_cache_decisions(cache, "mail_cache_fields", |
|
+ set->mail_cache_fields, |
|
+ MAIL_CACHE_DECISION_TEMP); |
|
+ set_cache_decisions(cache, "mail_always_cache_fields", |
|
+ set->mail_always_cache_fields, |
|
+ MAIL_CACHE_DECISION_YES | |
|
+ MAIL_CACHE_DECISION_FORCED); |
|
+ set_cache_decisions(cache, "mail_never_cache_fields", |
|
+ set->mail_never_cache_fields, |
|
+ MAIL_CACHE_DECISION_NO | |
|
+ MAIL_CACHE_DECISION_FORCED); |
|
} |
|
|
|
void index_storage_lock_notify(struct mailbox *box, |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From e73e2223cf1a42d87c1fcd8ede02998a69036415 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Wed, 15 May 2013 14:28:04 +0300 |
|
Subject: [PATCH] quota-status: If quota_status_* settings are set, don't free |
|
them before using. |
|
|
|
|
|
diff --git a/src/plugins/quota/quota-status.c b/src/plugins/quota/quota-status.c |
|
index bfac5e7..bff7540 100644 |
|
--- a/src/plugins/quota/quota-status.c |
|
+++ b/src/plugins/quota/quota-status.c |
|
@@ -109,6 +109,7 @@ static void client_handle_request(struct quota_client *client) |
|
if (value == NULL) |
|
value = t_strdup_printf("554 5.2.2 %s\n\n", error); |
|
} |
|
+ value = t_strdup(value); /* user's pool is being freed */ |
|
mail_user_unref(&user); |
|
mail_storage_service_user_free(&service_user); |
|
} |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From eee84842f41ed4e0753fb49199ea930f9e2b613a Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Wed, 15 May 2013 15:06:24 +0300 |
|
Subject: [PATCH] Added asserts to binary searches to make sure we don't go to |
|
infinite loop. Using idx=left+(right-left)/2 would have |
|
worked also to allow 4GB sizes, but since none of the |
|
places in the code are likely to reach 2GB we might as well |
|
just add an assert. (Also if they do reach 2GB, it could be |
|
possible that they could reach also above 4GB and cause |
|
problems. Better to see an early error.) |
|
|
|
|
|
diff --git a/src/lib-index/mail-index-map.c b/src/lib-index/mail-index-map.c |
|
index e1275dc..a735c3c 100644 |
|
--- a/src/lib-index/mail-index-map.c |
|
+++ b/src/lib-index/mail-index-map.c |
|
@@ -514,6 +514,7 @@ static uint32_t mail_index_bsearch_uid(struct mail_index_map *map, |
|
idx = left_idx; |
|
right_idx = I_MIN(map->hdr.messages_count, uid); |
|
|
|
+ i_assert(right_idx < INT_MAX); |
|
while (left_idx < right_idx) { |
|
idx = (left_idx + right_idx) / 2; |
|
|
|
diff --git a/src/lib-index/mail-index-transaction-update.c b/src/lib-index/mail-index-transaction-update.c |
|
index f7887bf..aae27e2 100644 |
|
--- a/src/lib-index/mail-index-transaction-update.c |
|
+++ b/src/lib-index/mail-index-transaction-update.c |
|
@@ -402,6 +402,7 @@ mail_index_transaction_get_flag_update_pos(struct mail_index_transaction *t, |
|
|
|
updates = array_get(&t->updates, &count); |
|
i_assert(left_idx <= right_idx && right_idx <= count); |
|
+ i_assert(count < INT_MAX); |
|
|
|
/* find the first update with either overlapping range, |
|
or the update which will come after our insert */ |
|
diff --git a/src/lib-storage/index/index-sort-string.c b/src/lib-storage/index/index-sort-string.c |
|
index 0f1f486..17270d3 100644 |
|
--- a/src/lib-storage/index/index-sort-string.c |
|
+++ b/src/lib-storage/index/index-sort-string.c |
|
@@ -382,6 +382,7 @@ index_sort_bsearch(struct sort_string_context *ctx, const char *key, |
|
int ret; |
|
|
|
nodes = array_get_modifiable(&ctx->nonzero_nodes, &right_idx); |
|
+ i_assert(right_idx < INT_MAX); |
|
idx = left_idx = start_idx; |
|
while (left_idx < right_idx) { |
|
idx = (left_idx + right_idx) / 2; |
|
diff --git a/src/lib/bsearch-insert-pos.c b/src/lib/bsearch-insert-pos.c |
|
index 7bb9e53..d9feebf 100644 |
|
--- a/src/lib/bsearch-insert-pos.c |
|
+++ b/src/lib/bsearch-insert-pos.c |
|
@@ -13,6 +13,8 @@ bool bsearch_insert_pos(const void *key, const void *base, unsigned int nmemb, |
|
unsigned int idx, left_idx, right_idx; |
|
int ret; |
|
|
|
+ i_assert(nmemb < INT_MAX); |
|
+ |
|
idx = 0; left_idx = 0; right_idx = nmemb; |
|
while (left_idx < right_idx) { |
|
idx = (left_idx + right_idx) / 2; |
|
diff --git a/src/lib/bsearch-insert-pos.h b/src/lib/bsearch-insert-pos.h |
|
index 64b547b..52552d0 100644 |
|
--- a/src/lib/bsearch-insert-pos.h |
|
+++ b/src/lib/bsearch-insert-pos.h |
|
@@ -5,6 +5,7 @@ |
|
#define BINARY_NUMBER_SEARCH(data, count, value, idx_r) \ |
|
unsigned int idx, left_idx, right_idx; \ |
|
\ |
|
+ i_assert((count) < INT_MAX); \ |
|
idx = 0; left_idx = 0; right_idx = (count); \ |
|
while (left_idx < right_idx) { \ |
|
idx = (left_idx + right_idx) / 2; \ |
|
diff --git a/src/lib/seq-range-array.c b/src/lib/seq-range-array.c |
|
index 132fc22..c1a1af9 100644 |
|
--- a/src/lib/seq-range-array.c |
|
+++ b/src/lib/seq-range-array.c |
|
@@ -12,6 +12,7 @@ seq_range_lookup(const ARRAY_TYPE(seq_range) *array, |
|
unsigned int idx, left_idx, right_idx, count; |
|
|
|
data = array_get(array, &count); |
|
+ i_assert(count < INT_MAX); |
|
|
|
idx = 0; left_idx = 0; right_idx = count; |
|
while (left_idx < right_idx) { |
|
@@ -198,6 +199,7 @@ bool seq_range_array_remove(ARRAY_TYPE(seq_range) *array, uint32_t seq) |
|
|
|
/* somewhere in the middle, array is sorted so find it with |
|
binary search */ |
|
+ i_assert(count < INT_MAX); |
|
left_idx = 0; right_idx = count; |
|
while (left_idx < right_idx) { |
|
idx = (left_idx + right_idx) / 2; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From f8034a3a01bb4ad01255fa9f059422dc9381b2d1 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Wed, 15 May 2013 15:26:47 +0300 |
|
Subject: [PATCH] maildir: Fixed handling over 26 keywords in a mailbox. |
|
|
|
|
|
diff --git a/src/lib-storage/index/maildir/maildir-sync-index.c b/src/lib-storage/index/maildir/maildir-sync-index.c |
|
index 6869489..299da72 100644 |
|
--- a/src/lib-storage/index/maildir/maildir-sync-index.c |
|
+++ b/src/lib-storage/index/maildir/maildir-sync-index.c |
|
@@ -390,10 +390,11 @@ maildir_sync_mail_keywords(struct maildir_index_sync_context *ctx, uint32_t seq) |
|
old_indexes = array_get(&ctx->idx_keywords, &old_count); |
|
have_indexonly_keywords = FALSE; |
|
for (i = old_count; i > 0; i--) { |
|
- if (old_indexes[i-1] < MAILDIR_MAX_KEYWORDS) |
|
- break; |
|
- have_indexonly_keywords = TRUE; |
|
- array_delete(&ctx->idx_keywords, i-1, 1); |
|
+ if (maildir_keywords_idx_char(ctx->keywords_sync_ctx, |
|
+ old_indexes[i-1]) == '\0') { |
|
+ have_indexonly_keywords = TRUE; |
|
+ array_delete(&ctx->idx_keywords, i-1, 1); |
|
+ } |
|
} |
|
|
|
if (!have_indexonly_keywords) { |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 8db81610a50c448d483fb4bf6f4d1ee25ebeb797 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Wed, 15 May 2013 15:35:10 +0300 |
|
Subject: [PATCH] imap: Return how long SELECT or EXAMINE command took to |
|
answer. Could be useful to know sometimes if there's a |
|
large maildir where a lot files need to be rename()d. |
|
|
|
|
|
diff --git a/src/imap/cmd-select.c b/src/imap/cmd-select.c |
|
index 46d07b9..966ed2f 100644 |
|
--- a/src/imap/cmd-select.c |
|
+++ b/src/imap/cmd-select.c |
|
@@ -2,6 +2,7 @@ |
|
|
|
#include "imap-common.h" |
|
#include "seq-range-array.h" |
|
+#include "time-util.h" |
|
#include "imap-commands.h" |
|
#include "mail-search-build.h" |
|
#include "imap-search-args.h" |
|
@@ -16,6 +17,7 @@ struct imap_select_context { |
|
struct mail_namespace *ns; |
|
struct mailbox *box; |
|
|
|
+ struct timeval start_time; |
|
struct imap_fetch_context *fetch_ctx; |
|
|
|
uint32_t qresync_uid_validity; |
|
@@ -198,14 +200,24 @@ static void select_context_free(struct imap_select_context *ctx) |
|
|
|
static void cmd_select_finish(struct imap_select_context *ctx, int ret) |
|
{ |
|
+ const char *resp_code; |
|
+ struct timeval end_time; |
|
+ int time_msecs; |
|
+ |
|
if (ret < 0) { |
|
if (ctx->box != NULL) |
|
mailbox_free(&ctx->box); |
|
ctx->cmd->client->mailbox = NULL; |
|
} else { |
|
- client_send_tagline(ctx->cmd, mailbox_is_readonly(ctx->box) ? |
|
- "OK [READ-ONLY] Select completed." : |
|
- "OK [READ-WRITE] Select completed."); |
|
+ resp_code = mailbox_is_readonly(ctx->box) ? |
|
+ "READ-ONLY" : "READ-WRITE"; |
|
+ if (gettimeofday(&end_time, NULL) < 0) |
|
+ memset(&end_time, 0, sizeof(end_time)); |
|
+ time_msecs = timeval_diff_msecs(&end_time, &ctx->start_time); |
|
+ client_send_tagline(ctx->cmd, t_strdup_printf( |
|
+ "OK [%s] %s completed (%d.%03d secs).", resp_code, |
|
+ ctx->cmd->client->mailbox_examined ? "Examine" : "Select", |
|
+ time_msecs/1000, time_msecs%1000)); |
|
} |
|
select_context_free(ctx); |
|
} |
|
@@ -398,6 +410,7 @@ bool cmd_select_full(struct client_command_context *cmd, bool readonly) |
|
ctx = p_new(cmd->pool, struct imap_select_context, 1); |
|
ctx->cmd = cmd; |
|
ctx->ns = client_find_namespace(cmd, &mailbox); |
|
+ (void)gettimeofday(&ctx->start_time, NULL); |
|
if (ctx->ns == NULL) { |
|
close_selected_mailbox(client); |
|
return TRUE; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 62c9b86b3a5eef87c553cbbee4769fda183f730f Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Wed, 15 May 2013 16:10:48 +0300 |
|
Subject: [PATCH] lib-storage: Don't lose INBOX's \Subscribed flag when |
|
returning it is delayed. |
|
|
|
|
|
diff --git a/src/lib-storage/list/mailbox-list-iter.c b/src/lib-storage/list/mailbox-list-iter.c |
|
index da95178..9d2b8a9 100644 |
|
--- a/src/lib-storage/list/mailbox-list-iter.c |
|
+++ b/src/lib-storage/list/mailbox-list-iter.c |
|
@@ -597,9 +597,12 @@ mailbox_list_ns_iter_try_next(struct mailbox_list_iterate_context *_ctx, |
|
if (info != NULL) { |
|
if (strcasecmp(info->vname, "INBOX") == 0 && ctx->inbox_list) { |
|
/* delay sending INBOX reply. we already saved its |
|
- flags at init stage, except for \Noinferiors */ |
|
+ flags at init stage, except for \Noinferiors |
|
+ and subscription states */ |
|
ctx->inbox_info.flags |= |
|
- (info->flags & MAILBOX_NOINFERIORS); |
|
+ (info->flags & (MAILBOX_NOINFERIORS | |
|
+ MAILBOX_SUBSCRIBED | |
|
+ MAILBOX_CHILD_SUBSCRIBED)); |
|
return FALSE; |
|
} |
|
if (strncasecmp(info->vname, "INBOX", 5) == 0 && |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From efef70a8310a915cdc7e896106159f1923574055 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Wed, 15 May 2013 17:09:36 +0300 |
|
Subject: [PATCH] layout=fs: Always return INBOX uppercased when listing |
|
mailboxes. |
|
|
|
|
|
diff --git a/src/lib-storage/list/mailbox-list-fs-iter.c b/src/lib-storage/list/mailbox-list-fs-iter.c |
|
index 9aabf0a..1688264 100644 |
|
--- a/src/lib-storage/list/mailbox-list-fs-iter.c |
|
+++ b/src/lib-storage/list/mailbox-list-fs-iter.c |
|
@@ -682,6 +682,7 @@ fs_list_entry(struct fs_list_iterate_context *ctx, |
|
return 0; |
|
} |
|
inbox_flags_set(ctx, child_dir_match); |
|
+ ctx->info.vname = "INBOX"; /* always return uppercased */ |
|
ctx->inbox_found = TRUE; |
|
} else if (strcmp(storage_name, "INBOX") == 0 && |
|
(ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) { |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 8a37bc920230ceac1f72d0628e7aa05e5ae0431a Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Wed, 15 May 2013 17:10:28 +0300 |
|
Subject: [PATCH] mbox: If save's input stream fails, fail saving instead of |
|
ignoring the error. |
|
|
|
|
|
diff --git a/src/lib-storage/index/mbox/mbox-save.c b/src/lib-storage/index/mbox/mbox-save.c |
|
index 9880083..ff84725 100644 |
|
--- a/src/lib-storage/index/mbox/mbox-save.c |
|
+++ b/src/lib-storage/index/mbox/mbox-save.c |
|
@@ -635,6 +635,11 @@ int mbox_save_continue(struct mail_save_context *_ctx) |
|
} |
|
if (ret == 0) |
|
return 0; |
|
+ if (ctx->input->stream_errno != 0) { |
|
+ i_error("read(%s) failed: %m", i_stream_get_name(ctx->input)); |
|
+ ctx->failed = TRUE; |
|
+ return -1; |
|
+ } |
|
|
|
i_assert(ctx->last_char == '\n'); |
|
|
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From e6237e5511e0dc0a5ab2c3aaaa4ec43968a9c345 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Wed, 15 May 2013 17:18:29 +0300 |
|
Subject: [PATCH] mbox: Fixed committing transaction after a previous save had |
|
failed. |
|
|
|
|
|
diff --git a/src/lib-storage/index/mbox/mbox-save.c b/src/lib-storage/index/mbox/mbox-save.c |
|
index ff84725..218f290 100644 |
|
--- a/src/lib-storage/index/mbox/mbox-save.c |
|
+++ b/src/lib-storage/index/mbox/mbox-save.c |
|
@@ -715,6 +715,13 @@ int mbox_save_finish(struct mail_save_context *_ctx) |
|
ctx->mail_offset = (uoff_t)-1; |
|
} |
|
|
|
+ if (ctx->seq != 0) { |
|
+ mail_index_expunge(ctx->trans, ctx->seq); |
|
+ /* currently we can't just drop pending cache updates for this |
|
+ one specific record, so we'll reset the whole cache |
|
+ transaction. */ |
|
+ mail_cache_transaction_reset(ctx->ctx.transaction->cache_trans); |
|
+ } |
|
index_save_context_free(_ctx); |
|
return ctx->failed ? -1 : 0; |
|
} |
|
-- |
|
1.7.10.2 |
|
|
|
|