dovecot-2.1: imapc: Added support for fetching GUID from remote ...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Dec 12 08:45:44 EET 2011
details: http://hg.dovecot.org/dovecot-2.1/rev/0bdbb8d99492
changeset: 13855:0bdbb8d99492
user: Timo Sirainen <tss at iki.fi>
date: Mon Dec 12 08:45:32 2011 +0200
description:
imapc: Added support for fetching GUID from remote server, if supported.
Currently this is only done for GMail.
diffstat:
src/lib-storage/index/imapc/imapc-mail-fetch.c | 34 +++++++++++++++-
src/lib-storage/index/imapc/imapc-mail.c | 51 +++++++++++++++++++++++++-
src/lib-storage/index/imapc/imapc-storage.c | 16 ++++++++
src/lib-storage/index/imapc/imapc-storage.h | 2 +
4 files changed, 99 insertions(+), 4 deletions(-)
diffs (194 lines):
diff -r 31810fed489d -r 0bdbb8d99492 src/lib-storage/index/imapc/imapc-mail-fetch.c
--- a/src/lib-storage/index/imapc/imapc-mail-fetch.c Mon Dec 12 08:41:50 2011 +0200
+++ b/src/lib-storage/index/imapc/imapc-mail-fetch.c Mon Dec 12 08:45:32 2011 +0200
@@ -95,6 +95,11 @@
str_printfa(str, "UID FETCH %u (", _mail->uid);
if ((fields & MAIL_FETCH_RECEIVED_DATE) != 0)
str_append(str, "INTERNALDATE ");
+ if ((fields & MAIL_FETCH_GUID) != 0) {
+ str_append(str, mbox->guid_fetch_field_name);
+ str_append_c(str, ' ');
+ }
+
if ((fields & MAIL_FETCH_STREAM_BODY) != 0)
str_append(str, "BODY.PEEK[] ");
else if ((fields & MAIL_FETCH_STREAM_HEADER) != 0)
@@ -152,6 +157,9 @@
if ((data->wanted_fields & MAIL_FETCH_RECEIVED_DATE) != 0 &&
data->received_date == (time_t)-1)
fields |= MAIL_FETCH_RECEIVED_DATE;
+ if ((data->wanted_fields & MAIL_FETCH_GUID) != 0 &&
+ data->guid == NULL && mbox->guid_fetch_field_name != NULL)
+ fields |= MAIL_FETCH_GUID;
if (data->stream == NULL && data->access_part != 0) {
if ((data->access_part & (READ_BODY | PARSE_BODY)) != 0)
@@ -173,6 +181,11 @@
return FALSE;
fields &= ~MAIL_FETCH_RECEIVED_DATE;
}
+ if ((fields & MAIL_FETCH_GUID) != 0) {
+ if (imail->imail.data.guid == NULL)
+ return FALSE;
+ fields &= ~MAIL_FETCH_GUID;
+ }
if ((fields & (MAIL_FETCH_STREAM_HEADER |
MAIL_FETCH_STREAM_BODY)) != 0) {
if (imail->imail.data.stream == NULL)
@@ -186,10 +199,18 @@
int imapc_mail_fetch(struct mail *_mail, enum mail_fetch_field fields)
{
struct imapc_mail *imail = (struct imapc_mail *)_mail;
- struct imapc_storage *storage =
- (struct imapc_storage *)_mail->box->storage;
+ struct imapc_mailbox *mbox =
+ (struct imapc_mailbox *)_mail->box;
int ret;
+ if ((fields & MAIL_FETCH_GUID) != 0 &&
+ mbox->guid_fetch_field_name == NULL) {
+ mail_storage_set_error(_mail->box->storage,
+ MAIL_ERROR_NOTPOSSIBLE,
+ "Message GUID not available in this server");
+ return -1;
+ }
+
T_BEGIN {
ret = imapc_mail_send_fetch(_mail, fields);
} T_END;
@@ -200,7 +221,7 @@
or until all FETCH replies have been received (i.e. some FETCHes
failed) */
while (!imapc_mail_have_fields(imail, fields) && imail->fetch_count > 0)
- imapc_storage_run(storage);
+ imapc_storage_run(mbox->storage);
return 0;
}
@@ -356,6 +377,13 @@
imap_parse_datetime(value, &t, &tz))
mail->imail.data.received_date = t;
match = TRUE;
+ } else if (strcasecmp(key, "X-GM-MSGID") == 0 ||
+ strcasecmp(key, "X-GUID") == 0) {
+ if (imap_arg_get_astring(&args[i+1], &value)) {
+ mail->imail.data.guid =
+ p_strdup(mail->imail.mail.pool, value);
+ }
+ match = TRUE;
}
}
if (!match) {
diff -r 31810fed489d -r 0bdbb8d99492 src/lib-storage/index/imapc/imapc-mail.c
--- a/src/lib-storage/index/imapc/imapc-mail.c Mon Dec 12 08:41:50 2011 +0200
+++ b/src/lib-storage/index/imapc/imapc-mail.c Mon Dec 12 08:45:32 2011 +0200
@@ -267,6 +267,55 @@
buffer_free(&mail->body);
}
+static int imapc_mail_get_guid(struct mail *_mail, const char **value_r)
+{
+ struct index_mail *imail = (struct index_mail *)_mail;
+ struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box;
+ const enum index_cache_field cache_idx =
+ imail->ibox->cache_fields[MAIL_CACHE_GUID].idx;
+ string_t *str;
+
+ if (imail->data.guid != NULL) {
+ *value_r = imail->data.guid;
+ return 0;
+ }
+
+ str = str_new(imail->data_pool, 64);
+ if (mail_cache_lookup_field(_mail->transaction->cache_view,
+ str, imail->mail.mail.seq, cache_idx) > 0) {
+ *value_r = str_c(str);
+ return 0;
+ }
+
+ /* GUID not in cache, fetch it */
+ if (imapc_mail_fetch(_mail, MAIL_FETCH_GUID) < 0)
+ return -1;
+ if (imail->data.guid == NULL) {
+ imapc_mail_failed(_mail, mbox->guid_fetch_field_name);
+ return -1;
+ }
+
+ index_mail_cache_add_idx(imail, cache_idx,
+ imail->data.guid, strlen(imail->data.guid)+1);
+ *value_r = imail->data.guid;
+ return 0;
+}
+
+static int
+imapc_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
+ const char **value_r)
+{
+ switch (field) {
+ case MAIL_FETCH_GUID:
+ *value_r = "";
+ return imapc_mail_get_guid(_mail, value_r);
+ default:
+ break;
+ }
+
+ return index_mail_get_special(_mail, field, value_r);
+}
+
struct mail_vfuncs imapc_mail_vfuncs = {
imapc_mail_close,
index_mail_free,
@@ -291,7 +340,7 @@
index_mail_get_headers,
index_mail_get_header_stream,
imapc_mail_get_stream,
- index_mail_get_special,
+ imapc_mail_get_special,
index_mail_get_real_mail,
index_mail_update_flags,
index_mail_update_keywords,
diff -r 31810fed489d -r 0bdbb8d99492 src/lib-storage/index/imapc/imapc-storage.c
--- a/src/lib-storage/index/imapc/imapc-storage.c Mon Dec 12 08:41:50 2011 +0200
+++ b/src/lib-storage/index/imapc/imapc-storage.c Mon Dec 12 08:45:32 2011 +0200
@@ -410,6 +410,20 @@
imapc_client_stop(ctx->mbox->storage->client);
}
+static void imapc_mailbox_get_extensions(struct imapc_mailbox *mbox)
+{
+ enum imapc_capability capa =
+ imapc_client_get_capabilities(mbox->storage->client);
+
+ if (mbox->guid_fetch_field_name == NULL) {
+ /* see if we can get message GUIDs somehow */
+ if ((capa & IMAPC_CAPABILITY_X_GM_EXT_1) != 0) {
+ /* GMail */
+ mbox->guid_fetch_field_name = "X-GM-MSGID";
+ }
+ }
+}
+
int imapc_mailbox_select(struct imapc_mailbox *mbox)
{
struct imapc_command *cmd;
@@ -422,6 +436,8 @@
imapc_client_mailbox_set_reopen_cb(mbox->client_box,
imapc_mailbox_reopen, mbox);
+ imapc_mailbox_get_extensions(mbox);
+
mbox->selecting = TRUE;
ctx.mbox = mbox;
ctx.ret = -2;
diff -r 31810fed489d -r 0bdbb8d99492 src/lib-storage/index/imapc/imapc-storage.h
--- a/src/lib-storage/index/imapc/imapc-storage.h Mon Dec 12 08:41:50 2011 +0200
+++ b/src/lib-storage/index/imapc/imapc-storage.h Mon Dec 12 08:45:32 2011 +0200
@@ -83,6 +83,8 @@
uint32_t prev_skipped_rseq, prev_skipped_uid;
struct imapc_sync_context *sync_ctx;
+ const char *guid_fetch_field_name;
+
unsigned int selecting:1;
unsigned int syncing:1;
unsigned int initial_sync_done:1;
More information about the dovecot-cvs
mailing list