dovecot-2.2: Merged changes from v2.1 tree.
dovecot at dovecot.org
dovecot at dovecot.org
Mon Aug 20 11:09:53 EEST 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/2fc74b72817b
changeset: 14939:2fc74b72817b
user: Timo Sirainen <tss at iki.fi>
date: Mon Aug 20 11:09:42 2012 +0300
description:
Merged changes from v2.1 tree.
diffstat:
configure.in | 2 +-
src/doveadm/doveadm-mail-server.c | 3 +
src/imap/cmd-list.c | 6 +-
src/imap/cmd-thread.c | 148 ++++++++++++++++++++++++++-
src/lib-imap-client/imapc-client.h | 1 +
src/lib-imap-client/imapc-connection.c | 4 +-
src/lib-storage/index/imapc/imapc-settings.c | 4 +
src/lib-storage/index/imapc/imapc-settings.h | 2 +
src/lib-storage/index/imapc/imapc-storage.c | 1 +
src/lib-storage/list/mailbox-list-fs-iter.c | 32 ++++-
src/lib-storage/mail-namespace.c | 11 +-
src/lib-storage/mail-namespace.h | 5 +-
src/lib-storage/mail-storage.h | 5 +-
src/lib-storage/mail-thread.c | 2 +
src/lib-storage/mailbox-list.c | 6 +-
src/lib/ioloop.c | 4 +-
16 files changed, 214 insertions(+), 22 deletions(-)
diffs (truncated from 495 to 300 lines):
diff -r 9c69df65af7b -r 2fc74b72817b configure.in
--- a/configure.in Mon Aug 20 10:54:04 2012 +0300
+++ b/configure.in Mon Aug 20 11:09:42 2012 +0300
@@ -2718,7 +2718,7 @@
dnl IDLE doesn't really belong to banner. It's there just to make Blackberries
dnl happy, because otherwise BIS server disables push email.
capability_banner="IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE"
-capability="$capability_banner SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE BINARY MOVE"
+capability="$capability_banner SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE BINARY MOVE"
AC_DEFINE_UNQUOTED(CAPABILITY_STRING, "$capability", IMAP capabilities)
AC_DEFINE_UNQUOTED(CAPABILITY_BANNER_STRING, "$capability_banner", IMAP capabilities advertised in banner)
diff -r 9c69df65af7b -r 2fc74b72817b src/doveadm/doveadm-mail-server.c
--- a/src/doveadm/doveadm-mail-server.c Mon Aug 20 10:54:04 2012 +0300
+++ b/src/doveadm/doveadm-mail-server.c Mon Aug 20 11:09:42 2012 +0300
@@ -181,6 +181,9 @@
if (ret < 0) {
*error_r = fields[0] != NULL ?
t_strdup(fields[0]) : "passdb lookup failed";
+ *error_r = t_strdup_printf("%s (to see if user is proxied, "
+ "because doveadm_proxy_port is set)",
+ *error_r);
} else if (ret == 0) {
/* user not found from passdb. it could be in userdb though,
so just continue with the default host */
diff -r 9c69df65af7b -r 2fc74b72817b src/imap/cmd-list.c
--- a/src/imap/cmd-list.c Mon Aug 20 10:54:04 2012 +0300
+++ b/src/imap/cmd-list.c Mon Aug 20 11:09:42 2012 +0300
@@ -438,10 +438,12 @@
if (ctx->cur_ns_send_prefix)
list_namespace_send_prefix(ctx, TRUE);
- /* if there's a namespace with this name, list it as
+ /* if there's a list=yes namespace with this name, list it as
having children */
ns = mail_namespace_find_prefix_nosep(ctx->ns, name);
- if (ns != NULL) {
+ if (ns != NULL &&
+ (ns->flags & (NAMESPACE_FLAG_LIST_PREFIX |
+ NAMESPACE_FLAG_LIST_CHILDREN)) != 0) {
flags |= MAILBOX_CHILDREN;
flags &= ~MAILBOX_NOCHILDREN;
array_append(&ctx->ns_prefixes_listed, &ns, 1);
diff -r 9c69df65af7b -r 2fc74b72817b src/imap/cmd-thread.c
--- a/src/imap/cmd-thread.c Mon Aug 20 10:54:04 2012 +0300
+++ b/src/imap/cmd-thread.c Mon Aug 20 11:09:42 2012 +0300
@@ -3,6 +3,7 @@
#include "imap-common.h"
#include "str.h"
#include "ostream.h"
+#include "imap-base-subject.h"
#include "imap-commands.h"
#include "imap-search-args.h"
#include "mail-thread.h"
@@ -100,6 +101,148 @@
return ret;
}
+struct orderedsubject_thread {
+ time_t timestamp;
+ ARRAY_TYPE(uint32_t) msgs;
+};
+
+static int orderedsubject_thread_cmp(const struct orderedsubject_thread *t1,
+ const struct orderedsubject_thread *t2)
+{
+ const uint32_t *m1, *m2;
+
+ if (t1->timestamp < t2->timestamp)
+ return -1;
+ if (t1->timestamp > t2->timestamp)
+ return 1;
+
+ m1 = array_idx(&t1->msgs, 0);
+ m2 = array_idx(&t2->msgs, 0);
+ if (*m1 < *m2)
+ return -1;
+ if (*m1 > *m2)
+ return 1;
+ i_unreached();
+}
+
+static void
+imap_orderedsubject_thread_write(struct ostream *output, string_t *reply,
+ const struct orderedsubject_thread *thread)
+{
+ const uint32_t *msgs;
+ unsigned int i, count;
+
+ if (str_len(reply) > 128-10) {
+ o_stream_send(output, str_data(reply), str_len(reply));
+ str_truncate(reply, 0);
+ }
+
+ msgs = array_get(&thread->msgs, &count);
+ switch (count) {
+ case 1:
+ str_printfa(reply, "(%u)", msgs[0]);
+ break;
+ case 2:
+ str_printfa(reply, "(%u %u)", msgs[0], msgs[1]);
+ break;
+ default:
+ /* (1 (2)(3)) */
+ str_printfa(reply, "(%u ", msgs[0]);
+ for (i = 1; i < count; i++) {
+ if (str_len(reply) > 128-10) {
+ o_stream_send(output, str_data(reply),
+ str_len(reply));
+ str_truncate(reply, 0);
+ }
+ str_printfa(reply, "(%u)", msgs[i]);
+ }
+ str_append_c(reply, ')');
+ }
+}
+
+static int imap_thread_orderedsubject(struct client_command_context *cmd,
+ struct mail_search_args *search_args)
+{
+ static const enum mail_sort_type sort_program[] = {
+ MAIL_SORT_SUBJECT,
+ MAIL_SORT_DATE,
+ 0
+ };
+ struct mailbox_transaction_context *trans;
+ struct mail_search_context *search_ctx;
+ struct mail *mail;
+ string_t *prev_subject, *reply;
+ const char *subject, *base_subject;
+ pool_t pool;
+ ARRAY(struct orderedsubject_thread) threads;
+ const struct orderedsubject_thread *thread;
+ struct orderedsubject_thread *cur_thread = NULL;
+ uint32_t num;
+ int ret;
+
+ prev_subject = str_new(default_pool, 128);
+
+ /* first read all of the threads into memory */
+ pool = pool_alloconly_create("orderedsubject thread", 1024);
+ i_array_init(&threads, 128);
+ trans = mailbox_transaction_begin(cmd->client->mailbox, 0);
+ search_ctx = mailbox_search_init(trans, search_args, sort_program,
+ 0, NULL);
+ while (mailbox_search_next(search_ctx, &mail)) {
+ if (mail_get_first_header(mail, "Subject", &subject) <= 0)
+ subject = "";
+ T_BEGIN {
+ base_subject = imap_get_base_subject_cased(
+ pool_datastack_create(), subject, NULL);
+ if (strcmp(str_c(prev_subject), base_subject) != 0) {
+ /* thread changed */
+ cur_thread = NULL;
+ }
+ str_truncate(prev_subject, 0);
+ str_append(prev_subject, base_subject);
+ } T_END;
+
+ if (cur_thread == NULL) {
+ /* starting a new thread. get the first message's
+ date */
+ cur_thread = array_append_space(&threads);
+ if (mail_get_date(mail, &cur_thread->timestamp, NULL) == 0 &&
+ cur_thread->timestamp == 0) {
+ (void)mail_get_received_date(mail,
+ &cur_thread->timestamp);
+ }
+ p_array_init(&cur_thread->msgs, pool, 4);
+ }
+ num = cmd->uid ? mail->uid : mail->seq;
+ array_append(&cur_thread->msgs, &num, 1);
+ }
+ str_free(&prev_subject);
+ ret = mailbox_search_deinit(&search_ctx);
+ (void)mailbox_transaction_commit(&trans);
+ if (ret < 0) {
+ array_free(&threads);
+ pool_unref(&pool);
+ return -1;
+ }
+
+ /* sort the threads by their first message's timestamp */
+ array_sort(&threads, orderedsubject_thread_cmp);
+
+ /* write the threads to client */
+ reply = t_str_new(128);
+ str_append(reply, "* THREAD ");
+ array_foreach(&threads, thread) {
+ imap_orderedsubject_thread_write(cmd->client->output,
+ reply, thread);
+ }
+ str_append(reply, "\r\n");
+ o_stream_send(cmd->client->output, str_data(reply), str_len(reply));
+
+ array_free(&threads);
+ pool_unref(&pool);
+ return 0;
+}
+
bool cmd_thread(struct client_command_context *cmd)
{
struct client *client = cmd->client;
@@ -131,7 +274,10 @@
if (ret <= 0)
return ret < 0;
- ret = imap_thread(cmd, sargs, thread_type);
+ if (thread_type != MAIL_THREAD_ORDEREDSUBJECT)
+ ret = imap_thread(cmd, sargs, thread_type);
+ else
+ ret = imap_thread_orderedsubject(cmd, sargs);
mail_search_args_unref(&sargs);
if (ret < 0) {
client_send_storage_error(cmd,
diff -r 9c69df65af7b -r 2fc74b72817b src/lib-imap-client/imapc-client.h
--- a/src/lib-imap-client/imapc-client.h Mon Aug 20 10:54:04 2012 +0300
+++ b/src/lib-imap-client/imapc-client.h Mon Aug 20 11:09:42 2012 +0300
@@ -52,6 +52,7 @@
const char *master_user;
const char *username;
const char *password;
+ unsigned int max_idle_time;
const char *dns_client_socket_path;
const char *temp_path_prefix;
diff -r 9c69df65af7b -r 2fc74b72817b src/lib-imap-client/imapc-connection.c
--- a/src/lib-imap-client/imapc-connection.c Mon Aug 20 10:54:04 2012 +0300
+++ b/src/lib-imap-client/imapc-connection.c Mon Aug 20 11:09:42 2012 +0300
@@ -24,8 +24,6 @@
#define IMAPC_CONNECT_TIMEOUT_MSECS (1000*30)
#define IMAPC_COMMAND_TIMEOUT_MSECS (1000*60*5)
#define IMAPC_MAX_INLINE_LITERAL_SIZE (1024*32)
-/* IMAP protocol requires activity at least every 30 minutes */
-#define IMAPC_MAX_IDLE_MSECS (1000*60*29)
enum imapc_input_state {
IMAPC_INPUT_STATE_NONE = 0,
@@ -1310,7 +1308,7 @@
conn->parser = imap_parser_create(conn->input, NULL, (size_t)-1);
conn->to = timeout_add(IMAPC_CONNECT_TIMEOUT_MSECS,
imapc_connection_timeout, conn);
- conn->to_output = timeout_add(IMAPC_MAX_IDLE_MSECS,
+ conn->to_output = timeout_add(conn->client->set.max_idle_time*1000,
imapc_connection_reset_idle, conn);
if (conn->client->set.debug) {
i_debug("imapc(%s): Connecting to %s:%u", conn->name,
diff -r 9c69df65af7b -r 2fc74b72817b src/lib-storage/index/imapc/imapc-settings.c
--- a/src/lib-storage/index/imapc/imapc-settings.c Mon Aug 20 10:54:04 2012 +0300
+++ b/src/lib-storage/index/imapc/imapc-settings.c Mon Aug 20 11:09:42 2012 +0300
@@ -28,6 +28,8 @@
DEF(SET_STR, imapc_features),
DEF(SET_STR, imapc_rawlog_dir),
DEF(SET_STR, imapc_list_prefix),
+ DEF(SET_TIME, imapc_max_idle_time),
+
DEF(SET_STR, ssl_crypto_device),
SETTING_DEFINE_LIST_END
@@ -48,6 +50,8 @@
.imapc_features = "",
.imapc_rawlog_dir = "",
.imapc_list_prefix = "",
+ .imapc_max_idle_time = 60*29,
+
.ssl_crypto_device = ""
};
diff -r 9c69df65af7b -r 2fc74b72817b src/lib-storage/index/imapc/imapc-settings.h
--- a/src/lib-storage/index/imapc/imapc-settings.h Mon Aug 20 10:54:04 2012 +0300
+++ b/src/lib-storage/index/imapc/imapc-settings.h Mon Aug 20 11:09:42 2012 +0300
@@ -23,6 +23,8 @@
const char *imapc_features;
const char *imapc_rawlog_dir;
const char *imapc_list_prefix;
+ unsigned int imapc_max_idle_time;
+
const char *ssl_crypto_device;
enum imapc_features parsed_features;
diff -r 9c69df65af7b -r 2fc74b72817b src/lib-storage/index/imapc/imapc-storage.c
--- a/src/lib-storage/index/imapc/imapc-storage.c Mon Aug 20 10:54:04 2012 +0300
+++ b/src/lib-storage/index/imapc/imapc-storage.c Mon Aug 20 11:09:42 2012 +0300
@@ -228,6 +228,7 @@
*error_r = "missing imapc_password";
return -1;
}
+ set.max_idle_time = storage->set->imapc_max_idle_time;
set.dns_client_socket_path =
*_storage->user->set->base_dir == '\0' ? "" :
t_strconcat(_storage->user->set->base_dir, "/",
diff -r 9c69df65af7b -r 2fc74b72817b src/lib-storage/list/mailbox-list-fs-iter.c
--- a/src/lib-storage/list/mailbox-list-fs-iter.c Mon Aug 20 10:54:04 2012 +0300
+++ b/src/lib-storage/list/mailbox-list-fs-iter.c Mon Aug 20 11:09:42 2012 +0300
@@ -49,6 +49,7 @@
struct list_dir_context *dir;
unsigned int inbox_found:1;
+ unsigned int list_inbox_inbox:1;
};
More information about the dovecot-cvs
mailing list