]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Added mail_log_update_wanted_fields()
authorTimo Sirainen <tss@iki.fi>
Wed, 12 Oct 2011 16:08:31 +0000 (19:08 +0300)
committerTimo Sirainen <tss@iki.fi>
Wed, 12 Oct 2011 16:08:31 +0000 (19:08 +0300)
16 files changed:
src/lib-storage/index/cydir/cydir-mail.c
src/lib-storage/index/dbox-multi/mdbox-mail.c
src/lib-storage/index/dbox-single/sdbox-mail.c
src/lib-storage/index/imapc/imapc-mail-fetch.c
src/lib-storage/index/imapc/imapc-mail.c
src/lib-storage/index/index-mail-headers.c
src/lib-storage/index/index-mail.c
src/lib-storage/index/index-mail.h
src/lib-storage/index/maildir/maildir-mail.c
src/lib-storage/index/mbox/mbox-mail.c
src/lib-storage/index/raw/raw-mail.c
src/lib-storage/mail-storage-private.h
src/lib-storage/mail-storage.h
src/lib-storage/mail.c
src/lib-storage/test-mail.c
src/plugins/virtual/virtual-mail.c

index e1ccabae7437466c15dab44bac0b6e0bf9a230c4..6c3c0414bbf301ccd1ccbb0d22a5aa8740954a02 100644 (file)
@@ -133,6 +133,7 @@ struct mail_vfuncs cydir_mail_vfuncs = {
        index_mail_set_uid_cache_updates,
        index_mail_prefetch,
        index_mail_precache,
+       index_mail_add_temp_wanted_fields,
 
        index_mail_get_flags,
        index_mail_get_keywords,
index 8d5afebabc30af9dbf345677678ab703ade4ecde..0b173e6259bf4afa13c1528e5223efe0fe855120 100644 (file)
@@ -192,6 +192,7 @@ struct mail_vfuncs mdbox_mail_vfuncs = {
        index_mail_set_uid_cache_updates,
        index_mail_prefetch,
        index_mail_precache,
+       index_mail_add_temp_wanted_fields,
 
        index_mail_get_flags,
        index_mail_get_keywords,
index 73a3f356cbbb84c4d22c2b64ad3d66b985acea75..0435c2bc77d9f6e5db9803956611da8b127d9993 100644 (file)
@@ -100,6 +100,7 @@ struct mail_vfuncs sdbox_mail_vfuncs = {
        index_mail_set_uid_cache_updates,
        index_mail_prefetch,
        index_mail_precache,
+       index_mail_add_temp_wanted_fields,
 
        index_mail_get_flags,
        index_mail_get_keywords,
index c9adbd4a6a62dca35fa1251935735a641293a22a..6852c28bc179e551efa0c32fc6f941bbe821b89d 100644 (file)
@@ -149,7 +149,7 @@ bool imapc_mail_prefetch(struct mail *_mail)
        if (mbox->prev_mail_cache.uid == _mail->uid)
                imapc_mail_cache_get(mail, &mbox->prev_mail_cache);
 
-       if ((mail->imail.wanted_fields & MAIL_FETCH_RECEIVED_DATE) != 0 &&
+       if ((data->wanted_fields & MAIL_FETCH_RECEIVED_DATE) != 0 &&
            data->received_date == (time_t)-1)
                fields |= MAIL_FETCH_RECEIVED_DATE;
 
index 6a129d5aee746b1cc07adde851b56acaffe933f7..d4be94dc117361e9fe445a56ffe72a12ad43a33a 100644 (file)
@@ -180,44 +180,62 @@ imapc_mail_has_headers_in_cache(struct index_mail *mail,
        return TRUE;
 }
 
-static void imapc_mail_set_seq(struct mail *_mail, uint32_t seq, bool saving)
+static void index_mail_update_access_parts(struct index_mail *mail)
 {
-       struct imapc_mail *imail = (struct imapc_mail *)_mail;
-       struct index_mail *mail = &imail->imail;
+       struct mail *_mail = &mail->mail.mail;
+       struct index_mail_data *data = &mail->data;
        struct mailbox_header_lookup_ctx *header_ctx;
        time_t date;
        uoff_t size;
 
-       index_mail_set_seq(_mail, seq, saving);
-
-       if ((mail->wanted_fields & MAIL_FETCH_RECEIVED_DATE) != 0)
+       if ((data->wanted_fields & MAIL_FETCH_RECEIVED_DATE) != 0)
                (void)index_mail_get_received_date(_mail, &date);
-       if ((mail->wanted_fields & MAIL_FETCH_PHYSICAL_SIZE) != 0) {
+       if ((data->wanted_fields & MAIL_FETCH_PHYSICAL_SIZE) != 0) {
                if (index_mail_get_physical_size(_mail, &size) < 0)
-                       mail->data.access_part |= READ_HDR | READ_BODY;
+                       data->access_part |= READ_HDR | READ_BODY;
        }
 
-       if (mail->data.access_part == 0 && mail->wanted_headers != NULL) {
+       if (data->access_part == 0 && data->wanted_headers != NULL) {
                /* see if all wanted headers exist in cache */
-               if (!imapc_mail_has_headers_in_cache(mail, mail->wanted_headers))
-                       mail->data.access_part |= PARSE_HDR;
+               if (!imapc_mail_has_headers_in_cache(mail, data->wanted_headers))
+                       data->access_part |= PARSE_HDR;
        }
-       if (mail->data.access_part == 0 &&
-           (mail->wanted_fields & MAIL_FETCH_IMAP_ENVELOPE) != 0) {
+       if (data->access_part == 0 &&
+           (data->wanted_fields & MAIL_FETCH_IMAP_ENVELOPE) != 0) {
                /* the common code already checked this partially,
                   but we need a guaranteed correct answer */
                header_ctx = mailbox_header_lookup_init(_mail->box,
                                                        imap_envelope_headers);
                if (!imapc_mail_has_headers_in_cache(mail, header_ctx))
-                       mail->data.access_part |= PARSE_HDR;
+                       data->access_part |= PARSE_HDR;
                mailbox_header_lookup_unref(&header_ctx);
        }
+}
+
+static void imapc_mail_set_seq(struct mail *_mail, uint32_t seq, bool saving)
+{
+       struct imapc_mail *imail = (struct imapc_mail *)_mail;
+       struct index_mail *mail = &imail->imail;
+
+       index_mail_set_seq(_mail, seq, saving);
+
        /* searching code handles prefetching internally,
           elsewhere we want to do it immediately */
        if (!mail->search_mail && !_mail->saving)
                (void)imapc_mail_prefetch(_mail);
 }
 
+static void
+imapc_mail_add_temp_wanted_fields(struct mail *_mail,
+                                 enum mail_fetch_field fields,
+                                 struct mailbox_header_lookup_ctx *headers)
+{
+       struct index_mail *mail = (struct index_mail *)_mail;
+
+       index_mail_add_temp_wanted_fields(_mail, fields, headers);
+       index_mail_update_access_parts(mail);
+}
+
 static void imapc_mail_close(struct mail *_mail)
 {
        struct imapc_mail *mail = (struct imapc_mail *)_mail;
@@ -257,6 +275,7 @@ struct mail_vfuncs imapc_mail_vfuncs = {
        index_mail_set_uid_cache_updates,
        imapc_mail_prefetch,
        index_mail_precache,
+       imapc_mail_add_temp_wanted_fields,
 
        index_mail_get_flags,
        index_mail_get_keywords,
index 53bb95dfb0b1429fb777329d4943625c7aa49cbe..7490e30289709fdeaac7d77a7b04e1c3c40deb67 100644 (file)
@@ -151,7 +151,7 @@ get_header_field_idx(struct mailbox *box, const char *field,
 
 bool index_mail_want_parse_headers(struct index_mail *mail)
 {
-       if (mail->wanted_headers != NULL ||
+       if (mail->data.wanted_headers != NULL ||
            mail->data.save_bodystructure_header)
                return TRUE;
 
@@ -185,10 +185,11 @@ static void index_mail_parse_header_register_all_wanted(struct index_mail *mail)
 void index_mail_parse_header_init(struct index_mail *mail,
                                  struct mailbox_header_lookup_ctx *headers)
 {
+       struct index_mail_data *data = &mail->data;
        const uint8_t *match;
        unsigned int i, field_idx, match_count;
 
-       mail->header_seq = mail->data.seq;
+       mail->header_seq = data->seq;
        if (mail->header_data == NULL) {
                mail->header_data = buffer_create_dynamic(default_pool, 4096);
                i_array_init(&mail->header_lines, 32);
@@ -217,8 +218,8 @@ void index_mail_parse_header_init(struct index_mail *mail,
                }
        }
 
-       if (mail->wanted_headers != NULL && mail->wanted_headers != headers) {
-               headers = mail->wanted_headers;
+       if (data->wanted_headers != NULL && data->wanted_headers != headers) {
+               headers = data->wanted_headers;
                for (i = 0; i < headers->count; i++) {
                        array_idx_set(&mail->header_match, headers->idx[i],
                                      &mail->header_match_value);
@@ -240,10 +241,10 @@ void index_mail_parse_header_init(struct index_mail *mail,
        if (field_idx < match_count &&
            match[field_idx] == mail->header_match_value) {
                /* cache Date: header */
-       } else if ((mail->data.cache_fetch_fields & MAIL_FETCH_DATE) != 0 ||
-                  mail->data.save_sent_date) {
+       } else if ((data->cache_fetch_fields & MAIL_FETCH_DATE) != 0 ||
+                  data->save_sent_date) {
                /* parse Date: header, but don't cache it. */
-               mail->data.dont_cache_field_idx = field_idx;
+               data->dont_cache_field_idx = field_idx;
                array_idx_set(&mail->header_match, field_idx,
                              &mail->header_match_value);
        }
index 6620506993c27912c6708f2e358d50f9fa84cc15..a4affe21d410e0ee322f4e97d5a0cac2be6d2567 100644 (file)
@@ -457,8 +457,8 @@ static bool want_plain_bodystructure_cached(struct index_mail *mail)
                mail->ibox->cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
        struct mail *_mail = &mail->mail.mail;
 
-       if ((mail->wanted_fields & (MAIL_FETCH_IMAP_BODY |
-                                   MAIL_FETCH_IMAP_BODYSTRUCTURE)) != 0)
+       if ((mail->data.wanted_fields & (MAIL_FETCH_IMAP_BODY |
+                                        MAIL_FETCH_IMAP_BODYSTRUCTURE)) != 0)
                return TRUE;
 
        if (mail_cache_field_want_add(_mail->transaction->cache_trans,
@@ -544,7 +544,7 @@ static void index_mail_body_parsed_cache_message_parts(struct index_mail *mail)
        }
        if (decision == MAIL_CACHE_DECISION_NO &&
            !data->save_message_parts &&
-           (mail->wanted_fields & MAIL_FETCH_MESSAGE_PARTS) == 0) {
+           (data->wanted_fields & MAIL_FETCH_MESSAGE_PARTS) == 0) {
                /* we didn't really care about the message parts themselves,
                   just wanted to use something that depended on it */
                return;
@@ -596,7 +596,7 @@ index_mail_body_parsed_cache_bodystructure(struct index_mail *mail,
        if (plain_bodystructure)
                cache_bodystructure = FALSE;
        else if (field == MAIL_CACHE_IMAP_BODYSTRUCTURE ||
-                (mail->wanted_fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) != 0) {
+                (data->wanted_fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) != 0) {
                cache_bodystructure =
                        mail_cache_field_can_add(_mail->transaction->cache_trans,
                                _mail->seq, cache_field_bodystructure);
@@ -1113,15 +1113,13 @@ void index_mail_init(struct index_mail *mail,
        mail->mail.v = *t->box->mail_vfuncs;
        mail->mail.mail.box = t->box;
        mail->mail.mail.transaction = t;
-       mail->mail.wanted_fields = wanted_fields;
-       mail->mail.wanted_headers = wanted_headers;
 
        t->mail_ref_count++;
        mail->data_pool = pool_alloconly_create("index_mail", 16384);
        mail->ibox = INDEX_STORAGE_CONTEXT(t->box);
-       mail->wanted_fields = wanted_fields;
+       mail->mail.wanted_fields = wanted_fields;
        if (wanted_headers != NULL) {
-               mail->wanted_headers = wanted_headers;
+               mail->mail.wanted_headers = wanted_headers;
                mailbox_header_lookup_ref(wanted_headers);
        }
 }
@@ -1164,6 +1162,8 @@ void index_mail_close(struct mail *_mail)
        }
 
        index_mail_close_streams(mail);
+       if (mail->data.wanted_headers != NULL)
+               mailbox_header_lookup_unref(&mail->data.wanted_headers);
 }
 
 static void index_mail_reset(struct index_mail *mail)
@@ -1182,6 +1182,12 @@ static void index_mail_reset(struct index_mail *mail)
        data->sent_date.time = (uint32_t)-1;
        data->dont_cache_field_idx = -1U;
 
+       data->wanted_fields = mail->mail.wanted_fields;
+       if (mail->mail.wanted_headers != NULL) {
+               data->wanted_headers = mail->mail.wanted_headers;
+               mailbox_header_lookup_ref(data->wanted_headers);
+       }
+
        mail->mail.mail.seq = 0;
        mail->mail.mail.uid = 0;
        mail->mail.mail.expunged = FALSE;
@@ -1219,35 +1225,19 @@ static void check_envelope(struct index_mail *mail)
        mail->data.save_envelope = TRUE;
 }
 
-void index_mail_set_seq(struct mail *_mail, uint32_t seq, bool saving)
+static void index_mail_update_access_parts(struct index_mail *mail)
 {
-       struct index_mail *mail = (struct index_mail *)_mail;
+       struct mail *_mail = &mail->mail.mail;
        struct index_mail_data *data = &mail->data;
        const struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
        struct mail_cache_view *cache_view = _mail->transaction->cache_view;
        const struct mail_index_header *hdr;
        struct istream *input;
 
-       if (data->seq == seq)
-               return;
-
-       index_mail_reset(mail);
-
-       data->seq = seq;
-
-       mail->mail.mail.seq = seq;
-       mail->mail.mail.saving = saving;
-       mail_index_lookup_uid(_mail->transaction->view, seq,
-                             &mail->mail.mail.uid);
-
-       if (mail_index_view_is_inconsistent(_mail->transaction->view)) {
-               mail_set_expunged(&mail->mail.mail);
-               return;
-       }
-
-       if ((mail->wanted_fields & (MAIL_FETCH_NUL_STATE |
+       if ((data->wanted_fields & (MAIL_FETCH_NUL_STATE |
                                    MAIL_FETCH_IMAP_BODY |
-                                   MAIL_FETCH_IMAP_BODYSTRUCTURE)) != 0) {
+                                   MAIL_FETCH_IMAP_BODYSTRUCTURE)) != 0 &&
+           !_mail->has_nuls && !_mail->has_no_nuls) {
                (void)index_mail_get_fixed_field(mail, MAIL_CACHE_FLAGS,
                                                 &data->cache_flags,
                                                 sizeof(data->cache_flags));
@@ -1262,44 +1252,48 @@ void index_mail_set_seq(struct mail *_mail, uint32_t seq, bool saving)
 
        /* see if wanted_fields can tell us if we need to read/parse
           header/body */
-       if ((mail->wanted_fields & MAIL_FETCH_MESSAGE_PARTS) != 0) {
+       if ((data->wanted_fields & MAIL_FETCH_MESSAGE_PARTS) != 0 &&
+           data->parts == NULL) {
                const unsigned int cache_field =
                        cache_fields[MAIL_CACHE_MESSAGE_PARTS].idx;
 
-               if (mail_cache_field_exists(cache_view, seq,
+               if (mail_cache_field_exists(cache_view, _mail->seq,
                                            cache_field) <= 0) {
                        data->access_part |= PARSE_HDR | PARSE_BODY;
                        data->save_message_parts = TRUE;
                }
        }
 
-       if ((mail->wanted_fields & MAIL_FETCH_IMAP_ENVELOPE) != 0)
+       if ((data->wanted_fields & MAIL_FETCH_IMAP_ENVELOPE) != 0 &&
+           data->envelope == NULL)
                check_envelope(mail);
 
-       if ((mail->wanted_fields & MAIL_FETCH_IMAP_BODY) != 0 &&
-           (data->cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) == 0) {
+       if ((data->wanted_fields & MAIL_FETCH_IMAP_BODY) != 0 &&
+           (data->cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) == 0 &&
+           data->body == NULL) {
                /* we need either imap.body or imap.bodystructure */
                const unsigned int cache_field1 =
                        cache_fields[MAIL_CACHE_IMAP_BODY].idx;
                const unsigned int cache_field2 =
                        cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
 
-               if (mail_cache_field_exists(cache_view,
-                                           seq, cache_field1) <= 0 &&
-                   mail_cache_field_exists(cache_view,
-                                            seq, cache_field2) <= 0) {
+               if (mail_cache_field_exists(cache_view, _mail->seq,
+                                           cache_field1) <= 0 &&
+                   mail_cache_field_exists(cache_view, _mail->seq,
+                                           cache_field2) <= 0) {
                        data->access_part |= PARSE_HDR | PARSE_BODY;
                        data->save_bodystructure_header = TRUE;
                        data->save_bodystructure_body = TRUE;
                }
        }
 
-       if ((mail->wanted_fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) != 0 &&
-           (data->cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) == 0) {
+       if ((data->wanted_fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) != 0 &&
+           (data->cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) == 0 &&
+           data->bodystructure == NULL) {
                const unsigned int cache_field =
                        cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
 
-                if (mail_cache_field_exists(cache_view, seq,
+                if (mail_cache_field_exists(cache_view, _mail->seq,
                                             cache_field) <= 0) {
                        data->access_part |= PARSE_HDR | PARSE_BODY;
                        data->save_bodystructure_header = TRUE;
@@ -1307,24 +1301,25 @@ void index_mail_set_seq(struct mail *_mail, uint32_t seq, bool saving)
                }
        }
 
-       if ((mail->wanted_fields & MAIL_FETCH_DATE) != 0) {
+       if ((data->wanted_fields & MAIL_FETCH_DATE) != 0 &&
+           data->sent_date.time == (uint32_t)-1) {
                const unsigned int cache_field =
                        cache_fields[MAIL_CACHE_SENT_DATE].idx;
 
-               if (mail_cache_field_exists(cache_view, seq,
+               if (mail_cache_field_exists(cache_view, _mail->seq,
                                            cache_field) <= 0) {
                        data->access_part |= PARSE_HDR;
                        data->save_sent_date = TRUE;
                }
        }
 
-       if ((mail->wanted_fields & (MAIL_FETCH_STREAM_HEADER |
+       if ((data->wanted_fields & (MAIL_FETCH_STREAM_HEADER |
                                    MAIL_FETCH_STREAM_BODY)) != 0) {
                /* open stream immediately to set expunged flag if
                   it's already lost */
-               if ((mail->wanted_fields & MAIL_FETCH_STREAM_HEADER) != 0)
+               if ((data->wanted_fields & MAIL_FETCH_STREAM_HEADER) != 0)
                        data->access_part |= READ_HDR;
-               if ((mail->wanted_fields & MAIL_FETCH_STREAM_BODY) != 0)
+               if ((data->wanted_fields & MAIL_FETCH_STREAM_BODY) != 0)
                        data->access_part |= READ_BODY;
 
                /* open the stream only if we didn't get here from
@@ -1338,7 +1333,8 @@ void index_mail_set_seq(struct mail *_mail, uint32_t seq, bool saving)
                }
        }
 
-       if ((mail->wanted_fields & MAIL_FETCH_VIRTUAL_SIZE) != 0 &&
+       if ((data->wanted_fields & MAIL_FETCH_VIRTUAL_SIZE) != 0 &&
+           data->virtual_size == (uoff_t)-1 &&
            _mail->lookup_abort == MAIL_LOOKUP_ABORT_NEVER &&
            ((data->access_part & (READ_HDR | PARSE_HDR)) == 0 ||
              (data->access_part & (READ_BODY | PARSE_BODY)) == 0)) {
@@ -1351,7 +1347,29 @@ void index_mail_set_seq(struct mail *_mail, uint32_t seq, bool saving)
                        mail->data.access_part |= READ_HDR | READ_BODY;
                _mail->lookup_abort = MAIL_LOOKUP_ABORT_NEVER;
        }
+}
 
+void index_mail_set_seq(struct mail *_mail, uint32_t seq, bool saving)
+{
+       struct index_mail *mail = (struct index_mail *)_mail;
+
+       if (mail->data.seq == seq)
+               return;
+
+       index_mail_reset(mail);
+
+       mail->data.seq = seq;
+       mail->mail.mail.seq = seq;
+       mail->mail.mail.saving = saving;
+       mail_index_lookup_uid(_mail->transaction->view, seq,
+                             &mail->mail.mail.uid);
+
+       if (mail_index_view_is_inconsistent(_mail->transaction->view)) {
+               mail_set_expunged(&mail->mail.mail);
+               return;
+       }
+
+       index_mail_update_access_parts(mail);
        mail->data.initialized = TRUE;
 }
 
@@ -1413,6 +1431,36 @@ bool index_mail_set_uid(struct mail *_mail, uint32_t uid)
        }
 }
 
+void index_mail_add_temp_wanted_fields(struct mail *_mail,
+                                      enum mail_fetch_field fields,
+                                      struct mailbox_header_lookup_ctx *headers)
+{
+       struct index_mail *mail = (struct index_mail *)_mail;
+       struct index_mail_data *data = &mail->data;
+       ARRAY_TYPE(const_string) names;
+       unsigned int i;
+
+       data->wanted_fields |= fields;
+       if (headers == NULL) {
+               /* keep old ones */
+       } else if (data->wanted_headers == NULL) {
+               data->wanted_headers = headers;
+               mailbox_header_lookup_ref(headers);
+       } else {
+               /* merge headers */
+               t_array_init(&names, 32);
+               for (i = 0; i < data->wanted_headers->count; i++)
+                       array_append(&names, &data->wanted_headers->name[i], 1);
+               for (i = 0; i < headers->count; i++)
+                       array_append(&names, &headers->name[i], 1);
+               (void)array_append_space(&names);
+               data->wanted_headers =
+                       mailbox_header_lookup_init(_mail->box,
+                                                  array_idx(&names, 0));
+       }
+       index_mail_update_access_parts(mail);
+}
+
 void index_mail_set_uid_cache_updates(struct mail *_mail, bool set)
 {
        struct index_mail *mail = (struct index_mail *)_mail;
@@ -1424,7 +1472,7 @@ void index_mail_free(struct mail *_mail)
 {
        struct index_mail *mail = (struct index_mail *)_mail;
        struct mailbox_header_lookup_ctx *headers_ctx =
-               (struct mailbox_header_lookup_ctx *)mail->wanted_headers;
+               (struct mailbox_header_lookup_ctx *)mail->mail.wanted_headers;
 
        /* make sure mailbox_search_*() users don't try to free the mail
           directly */
@@ -1599,7 +1647,7 @@ void index_mail_precache(struct mail *mail)
                return;
        }
 
-       cache = imail->wanted_fields;
+       cache = imail->data.wanted_fields;
        if ((cache & (MAIL_FETCH_STREAM_HEADER | MAIL_FETCH_STREAM_BODY)) != 0)
                index_mail_parse(mail, (cache & MAIL_FETCH_STREAM_BODY) != 0);
        if ((cache & MAIL_FETCH_RECEIVED_DATE) != 0)
index 8534e42d0c461119c04662f3998f3fe5e5aee2f3..30bbcefe0a18148d7640a4af5b250d4b43d83685 100644 (file)
@@ -87,6 +87,8 @@ struct index_mail_data {
        /* dont_cache_fields overrides cache_fields */
        enum mail_fetch_field cache_fetch_fields, dont_cache_fetch_fields;
        unsigned int dont_cache_field_idx;
+       enum mail_fetch_field wanted_fields;
+       struct mailbox_header_lookup_ctx *wanted_headers;
 
        buffer_t *search_results;
 
@@ -126,9 +128,6 @@ struct index_mail {
 
        pool_t data_pool;
 
-       enum mail_fetch_field wanted_fields;
-       struct mailbox_header_lookup_ctx *wanted_headers;
-
        int pop3_state;
 
        /* per-mail variables, here for performance reasons: */
@@ -161,6 +160,9 @@ void index_mail_set_seq(struct mail *mail, uint32_t seq, bool saving);
 bool index_mail_set_uid(struct mail *mail, uint32_t uid);
 void index_mail_set_uid_cache_updates(struct mail *mail, bool set);
 bool index_mail_prefetch(struct mail *mail);
+void index_mail_add_temp_wanted_fields(struct mail *mail,
+                                      enum mail_fetch_field fields,
+                                      struct mailbox_header_lookup_ctx *headers);
 void index_mail_close(struct mail *mail);
 void index_mail_close_streams(struct index_mail *mail);
 void index_mail_free(struct mail *mail);
index 933e4d9eb7e3a18435279d6d043711c1422e8ab8..9362ab22b1df9f6ab1a3b086e3f3e9e85254a702 100644 (file)
@@ -231,8 +231,8 @@ static int maildir_get_pop3_state(struct index_mail *mail)
                MAIL_FETCH_STREAM_BODY | MAIL_FETCH_UIDL_FILE_NAME |
                MAIL_FETCH_VIRTUAL_SIZE;
 
-       if (mail->wanted_headers != NULL ||
-           (mail->wanted_fields & ~allowed_pop3_fields) != 0)
+       if (mail->data.wanted_headers != NULL ||
+           (mail->data.wanted_fields & ~allowed_pop3_fields) != 0)
                not_pop3_only = TRUE;
 
        /* get vsize decisions */
@@ -636,6 +636,7 @@ struct mail_vfuncs maildir_mail_vfuncs = {
        index_mail_set_uid_cache_updates,
        index_mail_prefetch,
        index_mail_precache,
+       index_mail_add_temp_wanted_fields,
 
        index_mail_get_flags,
        index_mail_get_keywords,
index fea3337b324365ef3f7daf6487e282ab13079f2e..9c1ae4c2b6321ebf86dd1f66820952db730bf290 100644 (file)
@@ -402,6 +402,7 @@ struct mail_vfuncs mbox_mail_vfuncs = {
        index_mail_set_uid_cache_updates,
        index_mail_prefetch,
        index_mail_precache,
+       index_mail_add_temp_wanted_fields,
 
        index_mail_get_flags,
        index_mail_get_keywords,
index 9e74bfdef5cde1a0168a1b175ace7ea323afd74f..9b142b91fdb5c27b31a13d9302421144541cd57c 100644 (file)
@@ -120,6 +120,7 @@ struct mail_vfuncs raw_mail_vfuncs = {
        index_mail_set_uid_cache_updates,
        index_mail_prefetch,
        index_mail_precache,
+       index_mail_add_temp_wanted_fields,
 
        index_mail_get_flags,
        index_mail_get_keywords,
index 528d47cbe598a2deea6d7115171c0e14e782d1f9..b1a44cb30083d13bb1fb527ca0e7d6ce0ed960e0 100644 (file)
@@ -278,6 +278,9 @@ struct mail_vfuncs {
        void (*set_uid_cache_updates)(struct mail *mail, bool set);
        bool (*prefetch)(struct mail *mail);
        void (*precache)(struct mail *mail);
+       void (*add_temp_wanted_fields)(struct mail *mail,
+                                      enum mail_fetch_field fields,
+                                      struct mailbox_header_lookup_ctx *headers);
 
        enum mail_flags (*get_flags)(struct mail *mail);
        const char *const *(*get_keywords)(struct mail *mail);
@@ -330,6 +333,7 @@ struct mail_private {
        struct mail mail;
        struct mail_vfuncs v, *vlast;
 
+       /* initial wanted fields/headers, set by mail_alloc(): */
        enum mail_fetch_field wanted_fields;
        struct mailbox_header_lookup_ctx *wanted_headers;
 
index 18b0bfb8e4ac3ecd02e03891efbc912a493e84c7..2f802bba9464ead1032da1fe647c34e3e54d3026 100644 (file)
@@ -665,6 +665,12 @@ void mail_set_seq(struct mail *mail, uint32_t seq);
    mail_*() functions shouldn't be called if FALSE is returned. */
 bool mail_set_uid(struct mail *mail, uint32_t uid);
 
+/* Add wanted fields/headers on top of existing ones. These will be forgotten
+   after the next mail_set_seq/uid(). */
+void mail_add_temp_wanted_fields(struct mail *mail,
+                                enum mail_fetch_field fields,
+                                struct mailbox_header_lookup_ctx *headers);
+
 /* Returns message's flags */
 enum mail_flags mail_get_flags(struct mail *mail);
 /* Returns message's keywords */
index fb7efb525db31ebf9211a663b792c264db1bff4f..f8852b46d8b2d53b7bf56af7c47c3b1575062b03 100644 (file)
@@ -63,6 +63,15 @@ bool mail_prefetch(struct mail *mail)
        return p->v.prefetch(mail);
 }
 
+void mail_add_temp_wanted_fields(struct mail *mail,
+                                enum mail_fetch_field fields,
+                                struct mailbox_header_lookup_ctx *headers)
+{
+       struct mail_private *p = (struct mail_private *)mail;
+
+       p->v.add_temp_wanted_fields(mail, fields, headers);
+}
+
 enum mail_flags mail_get_flags(struct mail *mail)
 {
        struct mail_private *p = (struct mail_private *)mail;
index 8e3f8507e1514f0a31cccd2ca2572d6a0d818598..9e8f7cd8c34f051237b2e1f35868f0562ece58cf 100644 (file)
@@ -63,6 +63,13 @@ static void test_mail_precache(struct mail *mail ATTR_UNUSED)
 {
 }
 
+static void
+test_mail_add_temp_wanted_fields(struct mail *mail ATTR_UNUSED,
+                                enum mail_fetch_field fields ATTR_UNUSED,
+                                struct mailbox_header_lookup_ctx *headers ATTR_UNUSED)
+{
+}
+
 static enum mail_flags test_mail_get_flags(struct mail *mail ATTR_UNUSED)
 {
        return 0;
@@ -219,6 +226,7 @@ struct mail_vfuncs test_mail_vfuncs = {
        test_mail_set_uid_cache_updates,
        test_mail_prefetch,
        test_mail_precache,
+       test_mail_add_temp_wanted_fields,
 
        test_mail_get_flags,
        test_mail_get_keywords,
index f1330114b5c8bbdaab052d3a376a7b4f74f2fb32..f69c69a9aeae5e030577a31ee3898c85e31028d4 100644 (file)
@@ -179,6 +179,17 @@ static void virtual_mail_precache(struct mail *mail)
        p->v.precache(vmail->backend_mail);
 }
 
+static void
+virtual_mail_add_temp_wanted_fields(struct mail *mail,
+                                   enum mail_fetch_field fields,
+                                   struct mailbox_header_lookup_ctx *headers)
+{
+       struct virtual_mail *vmail = (struct virtual_mail *)mail;
+       struct mail_private *p = (struct mail_private *)vmail->backend_mail;
+
+       p->v.add_temp_wanted_fields(vmail->backend_mail, fields, headers);
+}
+
 static int virtual_mail_handle_lost(struct virtual_mail *vmail)
 {
        if (!vmail->lost)
@@ -412,6 +423,7 @@ struct mail_vfuncs virtual_mail_vfuncs = {
        virtual_mail_set_uid_cache_updates,
        virtual_mail_prefetch,
        virtual_mail_precache,
+       virtual_mail_add_temp_wanted_fields,
 
        index_mail_get_flags,
        index_mail_get_keywords,