changeset 7910:c1bbdc2b262e HEAD

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.
author Timo Sirainen <tss@iki.fi>
date Fri, 20 Jun 2008 06:26:21 +0300
parents bf9c51edbc66
children 3d65aeed7ea0
files src/imap/imap-fetch.c src/lib-storage/index/index-mail.c src/lib-storage/index/index-search.c src/lib-storage/mail-search-build.c src/lib-storage/mail-search.h src/lib-storage/mail-storage.h src/plugins/virtual/virtual-mail.c
diffstat 7 files changed, 52 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/imap/imap-fetch.c	Fri Jun 20 05:37:30 2008 +0300
+++ b/src/imap/imap-fetch.c	Fri Jun 20 06:26:21 2008 +0300
@@ -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 @@
 	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 @@
 	{ "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 }
 };
--- a/src/lib-storage/index/index-mail.c	Fri Jun 20 05:37:30 2008 +0300
+++ b/src/lib-storage/index/index-mail.c	Fri Jun 20 06:26:21 2008 +0300
@@ -1019,6 +1019,9 @@
 		}
 		*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;
--- a/src/lib-storage/index/index-search.c	Fri Jun 20 05:37:30 2008 +0300
+++ b/src/lib-storage/index/index-search.c	Fri Jun 20 06:26:21 2008 +0300
@@ -198,6 +198,7 @@
 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 @@
 		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 @@
 	case SEARCH_TEXT:
 	case SEARCH_BODY_FAST:
 	case SEARCH_TEXT_FAST:
+	case SEARCH_MAILBOX:
 		return TRUE;
 	}
 	return FALSE;
--- a/src/lib-storage/mail-search-build.c	Fri Jun 20 05:37:30 2008 +0300
+++ b/src/lib-storage/mail-search-build.c	Fri Jun 20 06:26:21 2008 +0300
@@ -599,6 +599,9 @@
 				return ARG_NEW_SINGLE(SEARCH_ALL);
 			}
 			return ARG_NEW_STR(SEARCH_TEXT_FAST);
+		} else if (strcmp(str, "X-MAILBOX") == 0) {
+			/* <string> */
+			return ARG_NEW_STR(SEARCH_MAILBOX);
 		}
 		break;
 	default:
--- a/src/lib-storage/mail-search.h	Fri Jun 20 05:37:30 2008 +0300
+++ b/src/lib-storage/mail-search.h	Fri Jun 20 06:26:21 2008 +0300
@@ -43,7 +43,8 @@
 
 	/* extensions */
 	SEARCH_MODSEQ,
-	SEARCH_INTHREAD
+	SEARCH_INTHREAD,
+	SEARCH_MAILBOX
 };
 
 enum mail_search_arg_flag {
--- a/src/lib-storage/mail-storage.h	Fri Jun 20 05:37:30 2008 +0300
+++ b/src/lib-storage/mail-storage.h	Fri Jun 20 06:26:21 2008 +0300
@@ -125,7 +125,8 @@
 	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 {
--- a/src/plugins/virtual/virtual-mail.c	Fri Jun 20 05:37:30 2008 +0300
+++ b/src/plugins/virtual/virtual-mail.c	Fri Jun 20 06:26:21 2008 +0300
@@ -225,6 +225,10 @@
 {
 	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);
 }