From 0eb66d27de33c5afd1415b7bebd56dbcb9c3a13e Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Tue, 2 Dec 2025 23:39:40 +0200 Subject: [PATCH] imapc: Use ESORT extension if it exists --- src/lib-imap-client/imapc-settings.c | 1 + src/lib-imap-client/imapc-settings.h | 1 + src/lib-storage/index/imapc/imapc-search.c | 24 +++++++++++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/lib-imap-client/imapc-settings.c b/src/lib-imap-client/imapc-settings.c index 851b883f0d..884aeece4e 100644 --- a/src/lib-imap-client/imapc-settings.c +++ b/src/lib-imap-client/imapc-settings.c @@ -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 }, diff --git a/src/lib-imap-client/imapc-settings.h b/src/lib-imap-client/imapc-settings.h index da4db8887c..3ba6b85781 100644 --- a/src/lib-imap-client/imapc-settings.h +++ b/src/lib-imap-client/imapc-settings.h @@ -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, diff --git a/src/lib-storage/index/imapc/imapc-search.c b/src/lib-storage/index/imapc/imapc-search.c index 21b0e366bf..3f0192afdc 100644 --- a/src/lib-storage/index/imapc/imapc-search.c +++ b/src/lib-storage/index/imapc/imapc-search.c @@ -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 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 or nonexistent if nothing matched */ if (args[0].type != IMAP_ARG_EOL && (!imap_arg_atom_equals(&args[0], "ALL") || -- 2.47.3