]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imap: Implement the standard SAVEDATE capability.
authorStephan Bosch <stephan.bosch@open-xchange.com>
Thu, 19 Mar 2020 00:19:40 +0000 (01:19 +0100)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Sun, 5 Apr 2020 21:31:34 +0000 (21:31 +0000)
configure.ac
src/imap/imap-fetch.c
src/lib-storage/mail-search-args-imap.c
src/lib-storage/mail-search-register-human.c
src/lib-storage/mail-search-register-imap.c
src/lib-storage/test-mail-search-args-imap.c

index 0185039feb14019fcb4d9ef511cba8f0dae897c5..dfb59021d79f61ffec8c813e89cfb413b2d1bd72 100644 (file)
@@ -787,7 +787,7 @@ dnl **
 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 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE"
-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 BINARY MOVE SNIPPET=FUZZY PREVIEW=FUZZY STATUS=SIZE"
+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 BINARY MOVE SNIPPET=FUZZY PREVIEW=FUZZY STATUS=SIZE SAVEDATE"
 AC_DEFINE_UNQUOTED(CAPABILITY_STRING, "$capability", [IMAP capabilities])
 AC_DEFINE_UNQUOTED(CAPABILITY_BANNER_STRING, "$capability_banner", [IMAP capabilities advertised in banner])
 
index e9b3b9f84ae323da64010917f693f6665242190f..4f5a231118c689b51c15e736ebac25e77888afe2 100644 (file)
@@ -889,6 +889,33 @@ bool imap_fetch_uid_init(struct imap_fetch_init_context *ctx)
        return TRUE;
 }
 
+static int imap_fetch_savedate(struct imap_fetch_context *ctx, struct mail *mail,
+                              void *context ATTR_UNUSED)
+{
+       time_t date;
+       int ret;
+
+       ret = mail_get_save_date(mail, &date);
+       if (ret < 0)
+               return -1;
+
+       if (ret == 0)
+               str_append(ctx->state.cur_str, "SAVEDATE NIL ");
+       else {
+               str_printfa(ctx->state.cur_str, "SAVEDATE \"%s\" ",
+                           imap_to_datetime(date));
+       }
+       return 1;
+}
+
+static bool imap_fetch_savedate_init(struct imap_fetch_init_context *ctx)
+{
+       ctx->fetch_ctx->fetch_data |= MAIL_FETCH_SAVE_DATE;
+       imap_fetch_add_handler(ctx, IMAP_FETCH_HANDLER_FLAG_BUFFERED,
+                              "NIL", imap_fetch_savedate, NULL);
+       return TRUE;
+}
+
 static int fetch_guid(struct imap_fetch_context *ctx, struct mail *mail,
                      void *context ATTR_UNUSED)
 {
@@ -993,6 +1020,7 @@ imap_fetch_default_handlers[] = {
        { "RFC822", imap_fetch_rfc822_init },
        { "SNIPPET", imap_fetch_snippet_init },
        { "UID", imap_fetch_uid_init },
+       { "SAVEDATE", imap_fetch_savedate_init },
        { "X-GUID", fetch_guid_init },
        { "X-MAILBOX", fetch_x_mailbox_init },
        { "X-REAL-UID", fetch_x_real_uid_init },
index da5d45325df7c57e496d2ab0d216cb49908d1723..73aab6c82f09daf3145149c0e4f9105502551cbb 100644 (file)
@@ -144,7 +144,7 @@ bool mail_search_arg_to_imap(string_t *dest, const struct mail_search_arg *arg,
                        str_append(dest, "BEFORE");
                        break;
                case MAIL_SEARCH_DATE_TYPE_SAVED:
-                       str_append(dest, "X-SAVEDBEFORE");
+                       str_append(dest, "SAVEDBEFORE");
                        break;
                }
                if (mail_search_arg_to_imap_date(dest, arg))
@@ -171,7 +171,7 @@ bool mail_search_arg_to_imap(string_t *dest, const struct mail_search_arg *arg,
                        str_append(dest, "ON");
                        break;
                case MAIL_SEARCH_DATE_TYPE_SAVED:
-                       str_append(dest, "X-SAVEDON");
+                       str_append(dest, "SAVEDON");
                        break;
                }
                if (!mail_search_arg_to_imap_date(dest, arg)) {
@@ -191,7 +191,7 @@ bool mail_search_arg_to_imap(string_t *dest, const struct mail_search_arg *arg,
                        str_append(dest, "SINCE");
                        break;
                case MAIL_SEARCH_DATE_TYPE_SAVED:
-                       str_append(dest, "X-SAVEDSINCE");
+                       str_append(dest, "SAVEDSINCE");
                        break;
                }
                if (mail_search_arg_to_imap_date(dest, arg))
index 2ff0a6ae03f2dd7b2f9f0ffb729459411b7ff49b..8e82bdc263f4ffd46e659b4576127d74f6ba2c6f 100644 (file)
@@ -73,6 +73,12 @@ CALLBACK_DATE(savedbefore, SEARCH_BEFORE, MAIL_SEARCH_DATE_TYPE_SAVED)
 CALLBACK_DATE(savedon, SEARCH_ON, MAIL_SEARCH_DATE_TYPE_SAVED)
 CALLBACK_DATE(savedsince, SEARCH_SINCE, MAIL_SEARCH_DATE_TYPE_SAVED)
 
+static struct mail_search_arg *
+human_search_savedatesupported(struct mail_search_build_context *ctx)
+{
+       return mail_search_build_new(ctx, SEARCH_SAVEDATESUPPORTED);
+}
+
 static struct mail_search_arg *
 arg_new_human_size(struct mail_search_build_context *ctx,
                   enum mail_search_arg_type type)
@@ -157,6 +163,7 @@ static const struct mail_search_register_arg human_register_args[] = {
        { "SAVEDBEFORE", human_search_savedbefore },
        { "SAVEDON", human_search_savedon },
        { "SAVEDSINCE", human_search_savedsince },
+       { "SAVEDATESUPPORTED", human_search_savedatesupported },
        { "X-SAVEDBEFORE", human_search_savedbefore },
        { "X-SAVEDON", human_search_savedon },
        { "X-SAVEDSINCE", human_search_savedsince },
index b64fb5f1356214857534bf2cfcc0803c201d3b10..c888b9e19513bb80aa34d83b4af59a2b4f98959e 100644 (file)
@@ -11,6 +11,7 @@
 #include "mail-search-register.h"
 #include "mail-search-parser.h"
 #include "mail-search-build.h"
+#include "mail-search-build.h"
 #include "mail-search-mime-build.h"
 
 struct mail_search_register *mail_search_register_imap;
@@ -186,10 +187,20 @@ CALLBACK_DATE(sentbefore, SEARCH_BEFORE, MAIL_SEARCH_DATE_TYPE_SENT)
 CALLBACK_DATE(senton, SEARCH_ON, MAIL_SEARCH_DATE_TYPE_SENT)
 CALLBACK_DATE(sentsince, SEARCH_SINCE, MAIL_SEARCH_DATE_TYPE_SENT)
 
+CALLBACK_DATE(savedbefore, SEARCH_BEFORE, MAIL_SEARCH_DATE_TYPE_SAVED)
+CALLBACK_DATE(savedon, SEARCH_ON, MAIL_SEARCH_DATE_TYPE_SAVED)
+CALLBACK_DATE(savedsince, SEARCH_SINCE, MAIL_SEARCH_DATE_TYPE_SAVED)
+
 CALLBACK_DATE(x_savedbefore, SEARCH_BEFORE, MAIL_SEARCH_DATE_TYPE_SAVED)
 CALLBACK_DATE(x_savedon, SEARCH_ON, MAIL_SEARCH_DATE_TYPE_SAVED)
 CALLBACK_DATE(x_savedsince, SEARCH_SINCE, MAIL_SEARCH_DATE_TYPE_SAVED)
 
+static struct mail_search_arg *
+imap_search_savedatesupported(struct mail_search_build_context *ctx)
+{
+       return mail_search_build_new(ctx, SEARCH_SAVEDATESUPPORTED);
+}
+
 static struct mail_search_arg *
 arg_new_size(struct mail_search_build_context *ctx,
             enum mail_search_arg_type type)
@@ -559,6 +570,11 @@ static const struct mail_search_register_arg imap_register_args[] = {
        { "SENTBEFORE", imap_search_sentbefore },
        { "SENTON", imap_search_senton },
        { "SENTSINCE", imap_search_sentsince },
+       { "SAVEDBEFORE", imap_search_savedbefore },
+       { "SAVEDON", imap_search_savedon },
+       { "SAVEDSINCE", imap_search_savedsince },
+       { "SAVEDATESUPPORTED", imap_search_savedatesupported },
+       /* FIXME: remove these in v2.4: */
        { "X-SAVEDBEFORE", imap_search_x_savedbefore },
        { "X-SAVEDON", imap_search_x_savedon },
        { "X-SAVEDSINCE", imap_search_x_savedsince },
index 698ff53fa8d848e061ea48975511e100797ef000..c6cda9c41ca599238cae800230d63a10cb0411fa 100644 (file)
@@ -25,9 +25,12 @@ static const struct {
        { "SENTBEFORE 20-May-2015", "SENTBEFORE \"20-May-2015\"" },
        { "SENTON 20-May-2015", "SENTON \"20-May-2015\"" },
        { "SENTSINCE 20-May-2015", "SENTSINCE \"20-May-2015\"" },
-       { "X-SAVEDBEFORE 20-May-2015", "X-SAVEDBEFORE \"20-May-2015\"" },
-       { "X-SAVEDON 20-May-2015", "X-SAVEDON \"20-May-2015\"" },
-       { "X-SAVEDSINCE 20-May-2015", "X-SAVEDSINCE \"20-May-2015\"" },
+       { "SAVEDBEFORE 20-May-2015", "SAVEDBEFORE \"20-May-2015\"" },
+       { "SAVEDON 20-May-2015", "SAVEDON \"20-May-2015\"" },
+       { "SAVEDSINCE 20-May-2015", "SAVEDSINCE \"20-May-2015\"" },
+       { "X-SAVEDBEFORE 20-May-2015", "SAVEDBEFORE \"20-May-2015\"" },
+       { "X-SAVEDON 20-May-2015", "SAVEDON \"20-May-2015\"" },
+       { "X-SAVEDSINCE 20-May-2015", "SAVEDSINCE \"20-May-2015\"" },
        { "OLDER 1", NULL },
        { "OLDER 1000", NULL },
        { "YOUNGER 1", NULL },