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.
1011 lines
32 KiB
1011 lines
32 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 |
|
|
|
|