dovecot-2.2: imapc: Implemented imapc_features=gmail-pop3 that a...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Jan 20 19:56:19 UTC 2015
details: http://hg.dovecot.org/dovecot-2.2/rev/df92d09acc63
changeset: 18187:df92d09acc63
user: Timo Sirainen <tss at iki.fi>
date: Tue Jan 20 21:54:58 2015 +0200
description:
imapc: Implemented imapc_features=gmail-pop3 that also migrates pop3_deleted_flag.
This also caused gmail-pop3-uidl feature to be renamed to simply gmail-pop3,
which includes both the features.
diffstat:
src/lib-storage/index/imapc/imapc-mail.c | 2 +-
src/lib-storage/index/imapc/imapc-mailbox.c | 76 ++++++++++++++++++++++++++++
src/lib-storage/index/imapc/imapc-settings.c | 8 ++-
src/lib-storage/index/imapc/imapc-settings.h | 4 +-
src/lib-storage/index/imapc/imapc-storage.h | 1 +
src/lib-storage/index/imapc/imapc-sync.c | 45 ++++++++++++----
6 files changed, 120 insertions(+), 16 deletions(-)
diffs (266 lines):
diff -r 034cb24bc590 -r df92d09acc63 src/lib-storage/index/imapc/imapc-mail.c
--- a/src/lib-storage/index/imapc/imapc-mail.c Tue Jan 20 21:49:04 2015 +0200
+++ b/src/lib-storage/index/imapc/imapc-mail.c Tue Jan 20 21:54:58 2015 +0200
@@ -476,7 +476,7 @@
*value_r = "";
return imapc_mail_get_guid(_mail, value_r);
case MAIL_FETCH_UIDL_BACKEND:
- if (!IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_GMAIL_POP3_UIDL))
+ if (!IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_GMAIL_POP3))
break;
if (imapc_mail_get_guid(_mail, value_r) < 0)
return -1;
diff -r 034cb24bc590 -r df92d09acc63 src/lib-storage/index/imapc/imapc-mailbox.c
--- a/src/lib-storage/index/imapc/imapc-mailbox.c Tue Jan 20 21:49:04 2015 +0200
+++ b/src/lib-storage/index/imapc/imapc-mailbox.c Tue Jan 20 21:54:58 2015 +0200
@@ -3,6 +3,7 @@
#include "lib.h"
#include "ioloop.h"
#include "imap-arg.h"
+#include "imap-seqset.h"
#include "imap-util.h"
#include "imapc-client.h"
#include "imapc-mail.h"
@@ -422,6 +423,79 @@
}
static void
+imapc_untagged_esearch_gmail_pop3(const struct imap_arg *args,
+ struct imapc_mailbox *mbox)
+{
+ struct imapc_msgmap *msgmap;
+ const char *atom;
+ struct seq_range_iter iter;
+ ARRAY_TYPE(seq_range) rseqs;
+ unsigned int n;
+ uint32_t rseq, lseq, uid;
+ ARRAY_TYPE(keyword_indexes) keywords;
+ struct mail_keywords *kw;
+ unsigned int pop3_deleted_kw_idx;
+
+ i_free_and_null(mbox->sync_gmail_pop3_search_tag);
+
+ /* It should contain ALL <seqset> */
+ t_array_init(&rseqs, 64);
+ if (!imap_arg_atom_equals(&args[0], "ALL") ||
+ !imap_arg_get_atom(&args[1], &atom) ||
+ imap_seq_set_parse(atom, &rseqs) < 0) {
+ i_error("Invalid gmail-pop3 ESEARCH reply");
+ return;
+ }
+
+ mail_index_keyword_lookup_or_create(mbox->box.index,
+ mbox->storage->set->pop3_deleted_flag, &pop3_deleted_kw_idx);
+
+ t_array_init(&keywords, 1);
+ array_append(&keywords, &pop3_deleted_kw_idx, 1);
+ kw = mail_index_keywords_create_from_indexes(mbox->box.index, &keywords);
+
+ msgmap = imapc_client_mailbox_get_msgmap(mbox->client_box);
+ seq_range_array_iter_init(&iter, &rseqs); n = 0;
+ while (seq_range_array_iter_nth(&iter, n++, &rseq)) {
+ if (rseq > imapc_msgmap_count(msgmap)) {
+ /* we haven't even seen this message yet */
+ break;
+ }
+ uid = imapc_msgmap_rseq_to_uid(msgmap, rseq);
+ if (!mail_index_lookup_seq(mbox->delayed_sync_view,
+ uid, &lseq))
+ continue;
+
+ /* add the pop3_deleted_flag */
+ mail_index_update_keywords(mbox->delayed_sync_trans,
+ lseq, MODIFY_ADD, kw);
+ }
+ mail_index_keywords_unref(&kw);
+}
+
+static void imapc_untagged_esearch(const struct imapc_untagged_reply *reply,
+ struct imapc_mailbox *mbox)
+{
+ const struct imap_arg *tag_list;
+ const char *str;
+
+ if (mbox == NULL || !imap_arg_get_list(reply->args, &tag_list))
+ return;
+
+ /* ESEARCH begins with (TAG <tag>) */
+ if (!imap_arg_atom_equals(&tag_list[0], "TAG") ||
+ !imap_arg_get_string(&tag_list[1], &str) ||
+ tag_list[2].type != IMAP_ARG_EOL)
+ return;
+
+ /* for now the only ESEARCH reply that we have is for getting GMail's
+ list of hidden POP3 messages. */
+ if (mbox->sync_gmail_pop3_search_tag != NULL &&
+ strcmp(mbox->sync_gmail_pop3_search_tag, str) == 0)
+ imapc_untagged_esearch_gmail_pop3(reply->args+1, mbox);
+}
+
+static void
imapc_resp_text_uidvalidity(const struct imapc_untagged_reply *reply,
struct imapc_mailbox *mbox)
{
@@ -512,6 +586,8 @@
imapc_untagged_fetch);
imapc_mailbox_register_untagged(mbox, "EXPUNGE",
imapc_untagged_expunge);
+ imapc_mailbox_register_untagged(mbox, "ESEARCH",
+ imapc_untagged_esearch);
imapc_mailbox_register_resp_text(mbox, "UIDVALIDITY",
imapc_resp_text_uidvalidity);
imapc_mailbox_register_resp_text(mbox, "UIDNEXT",
diff -r 034cb24bc590 -r df92d09acc63 src/lib-storage/index/imapc/imapc-settings.c
--- a/src/lib-storage/index/imapc/imapc-settings.c Tue Jan 20 21:49:04 2015 +0200
+++ b/src/lib-storage/index/imapc/imapc-settings.c Tue Jan 20 21:54:58 2015 +0200
@@ -30,6 +30,8 @@
DEF(SET_STR, imapc_list_prefix),
DEF(SET_TIME, imapc_max_idle_time),
+ DEF(SET_STR, pop3_deleted_flag),
+
SETTING_DEFINE_LIST_END
};
@@ -48,7 +50,9 @@
.imapc_features = "",
.imapc_rawlog_dir = "",
.imapc_list_prefix = "",
- .imapc_max_idle_time = 60*29
+ .imapc_max_idle_time = 60*29,
+
+ .pop3_deleted_flag = ""
};
static const struct setting_parser_info imapc_setting_parser_info = {
@@ -81,7 +85,7 @@
{ "guid-forced", IMAPC_FEATURE_GUID_FORCED },
{ "fetch-headers", IMAPC_FEATURE_FETCH_HEADERS },
{ "gmail-labels-keyword", IMAPC_FEATURE_GMAIL_LABELS_KEYWORD },
- { "gmail-pop3-uidl", IMAPC_FEATURE_GMAIL_POP3_UIDL },
+ { "gmail-pop3", IMAPC_FEATURE_GMAIL_POP3 },
{ NULL, 0 }
};
diff -r 034cb24bc590 -r df92d09acc63 src/lib-storage/index/imapc/imapc-settings.h
--- a/src/lib-storage/index/imapc/imapc-settings.h Tue Jan 20 21:49:04 2015 +0200
+++ b/src/lib-storage/index/imapc/imapc-settings.h Tue Jan 20 21:54:58 2015 +0200
@@ -7,7 +7,7 @@
IMAPC_FEATURE_GUID_FORCED = 0x02,
IMAPC_FEATURE_FETCH_HEADERS = 0x04,
IMAPC_FEATURE_GMAIL_LABELS_KEYWORD = 0x08,
- IMAPC_FEATURE_GMAIL_POP3_UIDL = 0x10
+ IMAPC_FEATURE_GMAIL_POP3 = 0x10
};
/* </settings checks> */
@@ -28,6 +28,8 @@
const char *imapc_list_prefix;
unsigned int imapc_max_idle_time;
+ const char *pop3_deleted_flag;
+
enum imapc_features parsed_features;
};
diff -r 034cb24bc590 -r df92d09acc63 src/lib-storage/index/imapc/imapc-storage.h
--- a/src/lib-storage/index/imapc/imapc-storage.h Tue Jan 20 21:49:04 2015 +0200
+++ b/src/lib-storage/index/imapc/imapc-storage.h Tue Jan 20 21:54:58 2015 +0200
@@ -110,6 +110,7 @@
uint32_t sync_next_rseq;
uint32_t exists_count;
uint32_t min_append_uid;
+ char *sync_gmail_pop3_search_tag;
/* keep the previous fetched message body cached,
mainly for partial IMAP fetches */
diff -r 034cb24bc590 -r df92d09acc63 src/lib-storage/index/imapc/imapc-sync.c
--- a/src/lib-storage/index/imapc/imapc-sync.c Tue Jan 20 21:49:04 2015 +0200
+++ b/src/lib-storage/index/imapc/imapc-sync.c Tue Jan 20 21:54:58 2015 +0200
@@ -38,7 +38,8 @@
imapc_client_stop(ctx->mbox->storage->client->client);
}
-static void imapc_sync_cmd(struct imapc_sync_context *ctx, const char *cmd_str)
+static struct imapc_command *
+imapc_sync_cmd(struct imapc_sync_context *ctx, const char *cmd_str)
{
struct imapc_command *cmd;
@@ -47,6 +48,7 @@
imapc_sync_callback, ctx);
imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE);
imapc_command_send(cmd, cmd_str);
+ return cmd;
}
static void
@@ -273,6 +275,28 @@
}
}
+static void
+imapc_sync_send_commands(struct imapc_sync_context *ctx, uint32_t first_uid)
+{
+ string_t *cmd = t_str_new(64);
+
+ str_printfa(cmd, "UID FETCH %u:* (FLAGS", first_uid);
+ if (IMAPC_BOX_HAS_FEATURE(ctx->mbox, IMAPC_FEATURE_GMAIL_LABELS_KEYWORD))
+ str_append(cmd, " X-GM-LABELS");
+ str_append_c(cmd, ')');
+ imapc_sync_cmd(ctx, str_c(cmd));
+
+ if (IMAPC_BOX_HAS_FEATURE(ctx->mbox, IMAPC_FEATURE_GMAIL_POP3) &&
+ ctx->mbox->storage->set->pop3_deleted_flag[0] != '\0') {
+ struct imapc_command *cmd;
+
+ cmd = imapc_sync_cmd(ctx, "SEARCH RETURN (ALL) X-GM-RAW \"in:^pop\"");
+ i_free(ctx->mbox->sync_gmail_pop3_search_tag);
+ ctx->mbox->sync_gmail_pop3_search_tag =
+ i_strdup(imapc_command_get_tag(cmd));
+ }
+}
+
static void imapc_sync_index(struct imapc_sync_context *ctx)
{
struct imapc_mailbox *mbox = ctx->mbox;
@@ -316,13 +340,7 @@
/* we'll resync existing messages' flags and add new messages.
adding new messages requires sync locking to avoid
duplicates. */
- string_t *cmd = t_str_new(64);
-
- str_printfa(cmd, "UID FETCH %u:* (FLAGS", mbox->sync_fetch_first_uid);
- if (IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_GMAIL_LABELS_KEYWORD))
- str_append(cmd, " X-GM-LABELS");
- str_append_c(cmd, ')');
- imapc_sync_cmd(ctx, str_c(cmd));
+ imapc_sync_send_commands(ctx, mbox->sync_fetch_first_uid);
mbox->sync_fetch_first_uid = 0;
}
@@ -357,10 +375,7 @@
mbox->sync_next_lseq = 1;
mbox->sync_next_rseq = 1;
- if (!IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_GMAIL_LABELS_KEYWORD))
- imapc_sync_cmd(ctx, "UID FETCH 1:* FLAGS");
- else
- imapc_sync_cmd(ctx, "UID FETCH 1:* (FLAGS X-GM-LABELS)");
+ imapc_sync_send_commands(ctx, 1);
}
static int
@@ -427,6 +442,12 @@
} else {
mail_index_sync_rollback(&ctx->index_sync_ctx);
}
+ if (ctx->mbox->sync_gmail_pop3_search_tag != NULL) {
+ mail_storage_set_critical(&ctx->mbox->storage->storage,
+ "gmail-pop3 search not successful");
+ i_free_and_null(ctx->mbox->sync_gmail_pop3_search_tag);
+ ret = -1;
+ }
ctx->mbox->syncing = FALSE;
ctx->mbox->sync_ctx = NULL;
More information about the dovecot-cvs
mailing list