]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imapc: Use ESORT extension if it exists
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 2 Dec 2025 21:39:40 +0000 (23:39 +0200)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 3 Dec 2025 21:13:15 +0000 (23:13 +0200)
src/lib-imap-client/imapc-settings.c
src/lib-imap-client/imapc-settings.h
src/lib-storage/index/imapc/imapc-search.c

index 851b883f0d4393bfadd0585486258c60d2d9ff43..884aeece4ef2f1809cd59d15421f5373bc2b7a56 100644 (file)
@@ -112,6 +112,7 @@ const struct imapc_capability_name imapc_capability_names[] = {
        { "SAVEDATE", IMAPC_CAPABILITY_SAVEDATE },
        { "METADATA", IMAPC_CAPABILITY_METADATA },
        { "SORT", IMAPC_CAPABILITY_SORT },
+       { "ESORT", IMAPC_CAPABILITY_ESORT },
 
        { "IMAP4REV1", IMAPC_CAPABILITY_IMAP4REV1 },
        { "IMAP4REV2", IMAPC_CAPABILITY_IMAP4REV2 },
index da4db8887cbaf99610610cfa4ae6fc7b7a3a059b..3ba6b85781ad55dee8abd6158866137bdc145a53 100644 (file)
@@ -46,6 +46,7 @@ enum imapc_capability {
        IMAPC_CAPABILITY_SAVEDATE       = 0x8000,
        IMAPC_CAPABILITY_METADATA       = 0x10000,
        IMAPC_CAPABILITY_SORT           = 0x20000,
+       IMAPC_CAPABILITY_ESORT          = 0x40000,
 
        IMAPC_CAPABILITY_IMAP4REV2      = 0x20000000,
        IMAPC_CAPABILITY_IMAP4REV1      = 0x40000000,
index 21b0e366bf048d63021ff0b4c55c91b093b025ad..3f0192afdc0fd5f5a531d12a5a2ccb6987104368 100644 (file)
@@ -35,7 +35,10 @@ imapc_build_sort_query(struct imapc_mailbox *mbox,
                return FALSE;
        }
 
-       str_append(str, "UID SORT (");
+       str_append(str, "UID SORT ");
+       if ((mbox->capabilities & IMAPC_CAPABILITY_ESORT) != 0)
+               str_append(str, "RETURN (ALL) ");
+       str_append_c(str, '(');
        for (i = 0; sort_program[i] != MAIL_SORT_END; i++) {
                if ((sort_program[i] & MAIL_SORT_FLAG_REVERSE) != 0)
                        str_append(str, "REVERSE ");
@@ -407,6 +410,20 @@ void imapc_search_reply_search(const struct imap_arg *args,
        }
 }
 
+static void imapc_search_reply_esort(const struct imap_arg *args,
+                                    struct imapc_mailbox *mbox)
+{
+       const char *atom;
+
+       /* It should contain UID ALL <uidset> or just UID if nothing matched */
+       if (!imap_arg_atom_equals(&args[0], "UID") ||
+           (args[1].type != IMAP_ARG_EOL &&
+            (!imap_arg_atom_equals(&args[1], "ALL") ||
+             !imap_arg_get_atom(&args[2], &atom) ||
+             imap_seq_set_ordered_parse(atom, &mbox->search_ctx->sorted_uids) < 0)))
+               e_error(mbox->box.event, "Invalid ESEARCH reply for SORT");
+}
+
 void imapc_search_reply_esearch(const struct imap_arg *args,
                                struct imapc_mailbox *mbox)
 {
@@ -418,6 +435,11 @@ void imapc_search_reply_esearch(const struct imap_arg *args,
                return;
        }
 
+       if (mbox->search_ctx->sorted) {
+               imapc_search_reply_esort(args, mbox);
+               return;
+       }
+
        /* It should contain ALL <seqset> or nonexistent if nothing matched */
        if (args[0].type != IMAP_ARG_EOL &&
            (!imap_arg_atom_equals(&args[0], "ALL") ||