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

# --- 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