From: Timo Sirainen Date: Fri, 20 Jun 2008 03:26:21 +0000 (+0300) Subject: FETCH X-MAILBOX and SEARCH X-MAILBOX can be used with virtual mailboxes to X-Git-Tag: 1.2.alpha1~251 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=06ff2a72c39cb34cc6425f17fc82c5e93fef2018;p=thirdparty%2Fdovecot%2Fcore.git FETCH X-MAILBOX and SEARCH X-MAILBOX can be used with virtual mailboxes to find out the original mailbox. In non-virtual mailboxes they always just use the current mailbox name. --HG-- branch : HEAD --- diff --git a/src/imap/imap-fetch.c b/src/imap/imap-fetch.c index 7a6ec213d3..cb095ea905 100644 --- a/src/imap/imap-fetch.c +++ b/src/imap/imap-fetch.c @@ -11,6 +11,7 @@ #include "imap-date.h" #include "mail-search-build.h" #include "commands.h" +#include "imap-quote.h" #include "imap-fetch.h" #include "imap-util.h" @@ -21,7 +22,8 @@ #define ENVELOPE_NIL_REPLY \ "(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL)" -const struct imap_fetch_handler default_handlers[8]; +#define IMAP_FETCH_HANDLER_COUNT 9 +const struct imap_fetch_handler default_handlers[IMAP_FETCH_HANDLER_COUNT]; static buffer_t *fetch_handlers = NULL; static int imap_fetch_handler_cmp(const void *p1, const void *p2) @@ -775,7 +777,29 @@ fetch_uid_init(struct imap_fetch_context *ctx ATTR_UNUSED, const char *name, return TRUE; } -const struct imap_fetch_handler default_handlers[8] = { +static int fetch_x_mailbox(struct imap_fetch_context *ctx, struct mail *mail, + void *context ATTR_UNUSED) +{ + const char *str; + + if (mail_get_special(mail, MAIL_FETCH_MAILBOX_NAME, &str) < 0) + i_panic("mailbox name not returned"); + str_append(ctx->cur_str, "X-MAILBOX "); + imap_quote_append_string(ctx->cur_str, str, FALSE); + return 1; +} + +static bool +fetch_x_mailbox_init(struct imap_fetch_context *ctx ATTR_UNUSED, + const char *name, + const struct imap_arg **args ATTR_UNUSED) +{ + imap_fetch_add_handler(ctx, TRUE, FALSE, name, NULL, + fetch_x_mailbox, NULL); + return TRUE; +} + +const struct imap_fetch_handler default_handlers[IMAP_FETCH_HANDLER_COUNT] = { { "BODY", fetch_body_init }, { "BODYSTRUCTURE", fetch_bodystructure_init }, { "ENVELOPE", fetch_envelope_init }, @@ -783,5 +807,6 @@ const struct imap_fetch_handler default_handlers[8] = { { "INTERNALDATE", fetch_internaldate_init }, { "MODSEQ", fetch_modseq_init }, { "RFC822", fetch_rfc822_init }, - { "UID", fetch_uid_init } + { "UID", fetch_uid_init }, + { "X-MAILBOX", fetch_x_mailbox_init } }; diff --git a/src/lib-storage/index/index-mail.c b/src/lib-storage/index/index-mail.c index 4fbb648104..39309d3f53 100644 --- a/src/lib-storage/index/index-mail.c +++ b/src/lib-storage/index/index-mail.c @@ -1019,6 +1019,9 @@ int index_mail_get_special(struct mail *_mail, } *value_r = binary_to_hex(ext_data, 16); return 0; + case MAIL_FETCH_MAILBOX_NAME: + *value_r = _mail->box->name; + return 0; default: i_unreached(); return -1; diff --git a/src/lib-storage/index/index-search.c b/src/lib-storage/index/index-search.c index 03e34f8793..02785a6711 100644 --- a/src/lib-storage/index/index-search.c +++ b/src/lib-storage/index/index-search.c @@ -198,6 +198,7 @@ static void search_index_arg(struct mail_search_arg *arg, static int search_arg_match_cached(struct index_search_context *ctx, struct mail_search_arg *arg) { + const char *str; struct tm *tm; uoff_t virtual_size; time_t date; @@ -266,6 +267,14 @@ static int search_arg_match_cached(struct index_search_context *ctx, else return virtual_size > arg->value.size; + case SEARCH_MAILBOX: + if (mail_get_special(ctx->mail, MAIL_FETCH_MAILBOX_NAME, + &str) < 0) + return -1; + + if (strcasecmp(str, "INBOX") == 0) + return strcasecmp(arg->value.str, "INBOX") == 0; + return strcmp(str, arg->value.str) == 0; default: return -1; } @@ -1122,6 +1131,7 @@ static bool search_arg_is_static(struct mail_search_arg *arg) case SEARCH_TEXT: case SEARCH_BODY_FAST: case SEARCH_TEXT_FAST: + case SEARCH_MAILBOX: return TRUE; } return FALSE; diff --git a/src/lib-storage/mail-search-build.c b/src/lib-storage/mail-search-build.c index bf10d44fd4..6c59b53204 100644 --- a/src/lib-storage/mail-search-build.c +++ b/src/lib-storage/mail-search-build.c @@ -599,6 +599,9 @@ static bool search_arg_build(struct search_build_data *data, return ARG_NEW_SINGLE(SEARCH_ALL); } return ARG_NEW_STR(SEARCH_TEXT_FAST); + } else if (strcmp(str, "X-MAILBOX") == 0) { + /* */ + return ARG_NEW_STR(SEARCH_MAILBOX); } break; default: diff --git a/src/lib-storage/mail-search.h b/src/lib-storage/mail-search.h index 6cc1c1a171..c0934b020d 100644 --- a/src/lib-storage/mail-search.h +++ b/src/lib-storage/mail-search.h @@ -43,7 +43,8 @@ enum mail_search_arg_type { /* extensions */ SEARCH_MODSEQ, - SEARCH_INTHREAD + SEARCH_INTHREAD, + SEARCH_MAILBOX }; enum mail_search_arg_flag { diff --git a/src/lib-storage/mail-storage.h b/src/lib-storage/mail-storage.h index 829819be93..de5386997d 100644 --- a/src/lib-storage/mail-storage.h +++ b/src/lib-storage/mail-storage.h @@ -125,7 +125,8 @@ enum mail_fetch_field { MAIL_FETCH_FROM_ENVELOPE = 0x00008000, MAIL_FETCH_HEADER_MD5 = 0x00010000, MAIL_FETCH_UIDL_FILE_NAME = 0x00020000, - MAIL_FETCH_UIDL_BACKEND = 0x00040000 + MAIL_FETCH_UIDL_BACKEND = 0x00040000, + MAIL_FETCH_MAILBOX_NAME = 0x00080000 }; enum mailbox_transaction_flags { diff --git a/src/plugins/virtual/virtual-mail.c b/src/plugins/virtual/virtual-mail.c index 8d1361dbf8..551c82a094 100644 --- a/src/plugins/virtual/virtual-mail.c +++ b/src/plugins/virtual/virtual-mail.c @@ -225,6 +225,10 @@ virtual_mail_get_special(struct mail *mail, enum mail_fetch_field field, { struct virtual_mail *vmail = (struct virtual_mail *)mail; + if (field == MAIL_FETCH_MAILBOX_NAME) { + *value_r = vmail->backend_mail->box->name; + return 0; + } return mail_get_special(vmail->backend_mail, field, value_r); }