]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imapc: Decouple imapc_untagged_fetch parsing and handling
authorMarkus Valentin <markus.valentin@open-xchange.com>
Mon, 17 Jan 2022 12:57:56 +0000 (13:57 +0100)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Mon, 14 Mar 2022 11:38:19 +0000 (11:38 +0000)
src/lib-storage/index/imapc/imapc-mailbox.c

index 370e308be5310735ff45566f616663c782c326fc..9a1a07341318bdd6055c71c98ccf52ab0c4f27bf 100644 (file)
@@ -474,6 +474,106 @@ bool imapc_mailbox_name_equals(struct imapc_mailbox *mbox,
        return FALSE;
 }
 
+static void imapc_untagged_fetch_handle(struct imapc_mailbox *mbox,
+                                       ARRAY_TYPE(const_string) keywords,
+                                       const char *guid,
+                                       enum mail_flags flags,
+                                       uint32_t rseq,
+                                       uint64_t modseq,
+                                       uint32_t fetch_uid,
+                                       uint32_t *lseq_r,
+                                       uint32_t *uid_r,
+                                       bool have_labels,
+                                       bool seen_flags)
+{
+       const struct mail_index_record *rec = NULL;
+       const char *atom;
+
+       imapc_mailbox_init_delayed_trans(mbox);
+       if (imapc_mailbox_msgmap_update(mbox, rseq, fetch_uid,
+                                       lseq_r, uid_r) < 0 || *uid_r == 0)
+               return;
+
+       if ((flags & MAIL_RECENT) == 0 && mbox->highest_nonrecent_uid < *uid_r) {
+               /* remember for STATUS_FIRST_RECENT_UID */
+               mbox->highest_nonrecent_uid = *uid_r;
+       }
+       /* FIXME: we should ideally also pass these through so they show up
+          to clients. */
+       flags &= ENUM_NEGATE(MAIL_RECENT);
+
+       if (*lseq_r == 0) {
+               if (!mail_index_lookup_seq(mbox->delayed_sync_view,
+                                          *uid_r, lseq_r)) {
+                       /* already expunged by another session */
+                       if (rseq == mbox->sync_next_rseq)
+                               mbox->sync_next_rseq++;
+                       return;
+               }
+       }
+
+       if (rseq == mbox->sync_next_rseq) {
+               /* we're doing the initial full sync of mails. expunge any
+                  mails that no longer exist. */
+               while (mbox->sync_next_lseq < *lseq_r) {
+                       mail_index_lookup_uid(mbox->delayed_sync_view,
+                                             mbox->sync_next_lseq, uid_r);
+                       imapc_mailbox_index_expunge(mbox, *uid_r);
+                       mbox->sync_next_lseq++;
+               }
+               i_assert(*lseq_r == mbox->sync_next_lseq);
+               mbox->sync_next_rseq++;
+               mbox->sync_next_lseq++;
+       }
+
+       rec = mail_index_lookup(mbox->delayed_sync_view, *lseq_r);
+       if (seen_flags && rec->flags != flags) {
+               mail_index_update_flags(mbox->delayed_sync_trans, *lseq_r,
+                                       MODIFY_REPLACE, flags);
+       }
+       if (seen_flags) {
+               ARRAY_TYPE(keyword_indexes) old_kws;
+               struct mail_keywords *kw;
+
+               t_array_init(&old_kws, 8);
+               mail_index_lookup_keywords(mbox->delayed_sync_view, *lseq_r,
+                                          &old_kws);
+
+               if (have_labels) {
+                       /* add keyword for mails that have GMail labels.
+                          this can be used for "All Mail" mailbox migrations
+                          with dsync */
+                       atom = "$GMailHaveLabels";
+                       array_push_back(&keywords, &atom);
+               }
+
+               array_append_zero(&keywords);
+               kw = mail_index_keywords_create(mbox->box.index,
+                                               array_front(&keywords));
+               if (!keywords_are_equal(kw, &old_kws)) {
+                       mail_index_update_keywords(mbox->delayed_sync_trans,
+                                                  *lseq_r, MODIFY_REPLACE, kw);
+               }
+               mail_index_keywords_unref(&kw);
+       }
+       if (modseq != 0) {
+               if (mail_index_modseq_lookup(mbox->delayed_sync_view, *lseq_r) < modseq)
+                       mail_index_update_modseq(mbox->delayed_sync_trans, *lseq_r, modseq);
+               array_idx_set(&mbox->rseq_modseqs, rseq-1, &modseq);
+       }
+       if (guid != NULL) {
+               struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(&mbox->box);
+               const enum index_cache_field guid_cache_idx =
+                       ibox->cache_fields[MAIL_CACHE_GUID].idx;
+
+               if (mail_cache_field_can_add(mbox->delayed_sync_cache_trans,
+                                            *lseq_r, guid_cache_idx)) {
+                       mail_cache_add(mbox->delayed_sync_cache_trans, *lseq_r,
+                                      guid_cache_idx, guid, strlen(guid));
+               }
+       }
+}
+
 static void imapc_untagged_fetch(const struct imapc_untagged_reply *reply,
                                 struct imapc_mailbox *mbox)
 {
@@ -482,7 +582,6 @@ static void imapc_untagged_fetch(const struct imapc_untagged_reply *reply,
        struct imapc_mail *mail;
        const struct imap_arg *list, *flags_list, *modseq_list;
        const char *atom, *guid = NULL;
-       const struct mail_index_record *rec = NULL;
        enum mail_flags flags;
        uint32_t fetch_uid, uid;
        uint64_t modseq = 0;
@@ -549,19 +648,9 @@ static void imapc_untagged_fetch(const struct imapc_untagged_reply *reply,
                /* UID missing and we're not tracking MSNs */
                return;
        }
-
-       imapc_mailbox_init_delayed_trans(mbox);
-       if (imapc_mailbox_msgmap_update(mbox, rseq, fetch_uid,
-                                       &lseq, &uid) < 0 || uid == 0)
-               return;
-
-       if ((flags & MAIL_RECENT) == 0 && mbox->highest_nonrecent_uid < uid) {
-               /* remember for STATUS_FIRST_RECENT_UID */
-               mbox->highest_nonrecent_uid = uid;
-       }
-       /* FIXME: we should ideally also pass these through so they show up
-          to clients. */
-       flags &= ENUM_NEGATE(MAIL_RECENT);
+       imapc_untagged_fetch_handle(mbox, keywords, guid, flags, rseq, modseq,
+                                   fetch_uid, &lseq, &uid, have_labels,
+                                   seen_flags);
 
        /* if this is a reply to some FETCH request, update the mail's fields */
        array_foreach_elem(&mbox->fetch_requests, fetch_request) {
@@ -570,77 +659,6 @@ static void imapc_untagged_fetch(const struct imapc_untagged_reply *reply,
                                imapc_mail_fetch_update(mail, reply, list);
                }
        }
-
-       if (lseq == 0) {
-               if (!mail_index_lookup_seq(mbox->delayed_sync_view,
-                                          uid, &lseq)) {
-                       /* already expunged by another session */
-                       if (rseq == mbox->sync_next_rseq)
-                               mbox->sync_next_rseq++;
-                       return;
-               }
-       }
-
-       if (rseq == mbox->sync_next_rseq) {
-               /* we're doing the initial full sync of mails. expunge any
-                  mails that no longer exist. */
-               while (mbox->sync_next_lseq < lseq) {
-                       mail_index_lookup_uid(mbox->delayed_sync_view,
-                                             mbox->sync_next_lseq, &uid);
-                       imapc_mailbox_index_expunge(mbox, uid);
-                       mbox->sync_next_lseq++;
-               }
-               i_assert(lseq == mbox->sync_next_lseq);
-               mbox->sync_next_rseq++;
-               mbox->sync_next_lseq++;
-       }
-
-       rec = mail_index_lookup(mbox->delayed_sync_view, lseq);
-       if (seen_flags && rec->flags != flags) {
-               mail_index_update_flags(mbox->delayed_sync_trans, lseq,
-                                       MODIFY_REPLACE, flags);
-       }
-       if (seen_flags) {
-               ARRAY_TYPE(keyword_indexes) old_kws;
-               struct mail_keywords *kw;
-
-               t_array_init(&old_kws, 8);
-               mail_index_lookup_keywords(mbox->delayed_sync_view, lseq,
-                                          &old_kws);
-
-               if (have_labels) {
-                       /* add keyword for mails that have GMail labels.
-                          this can be used for "All Mail" mailbox migrations
-                          with dsync */
-                       atom = "$GMailHaveLabels";
-                       array_push_back(&keywords, &atom);
-               }
-
-               array_append_zero(&keywords);
-               kw = mail_index_keywords_create(mbox->box.index,
-                                               array_front(&keywords));
-               if (!keywords_are_equal(kw, &old_kws)) {
-                       mail_index_update_keywords(mbox->delayed_sync_trans,
-                                                  lseq, MODIFY_REPLACE, kw);
-               }
-               mail_index_keywords_unref(&kw);
-       }
-       if (modseq != 0) {
-               if (mail_index_modseq_lookup(mbox->delayed_sync_view, lseq) < modseq)
-                       mail_index_update_modseq(mbox->delayed_sync_trans, lseq, modseq);
-               array_idx_set(&mbox->rseq_modseqs, rseq-1, &modseq);
-       }
-       if (guid != NULL) {
-               struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(&mbox->box);
-               const enum index_cache_field guid_cache_idx =
-                       ibox->cache_fields[MAIL_CACHE_GUID].idx;
-
-               if (mail_cache_field_can_add(mbox->delayed_sync_cache_trans,
-                                            lseq, guid_cache_idx)) {
-                       mail_cache_add(mbox->delayed_sync_cache_trans, lseq,
-                                      guid_cache_idx, guid, strlen(guid));
-               }
-       }
        imapc_mailbox_idle_notify(mbox);
 }