From: Timo Sirainen Date: Wed, 12 Oct 2011 16:08:31 +0000 (+0300) Subject: lib-storage: Added mail_log_update_wanted_fields() X-Git-Tag: 2.1.beta1~46 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ecd69c4e8371853667e01b0c16d436ef7f7393e2;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Added mail_log_update_wanted_fields() --- diff --git a/src/lib-storage/index/cydir/cydir-mail.c b/src/lib-storage/index/cydir/cydir-mail.c index e1ccabae74..6c3c0414bb 100644 --- a/src/lib-storage/index/cydir/cydir-mail.c +++ b/src/lib-storage/index/cydir/cydir-mail.c @@ -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, diff --git a/src/lib-storage/index/dbox-multi/mdbox-mail.c b/src/lib-storage/index/dbox-multi/mdbox-mail.c index 8d5afebabc..0b173e6259 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-mail.c +++ b/src/lib-storage/index/dbox-multi/mdbox-mail.c @@ -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, diff --git a/src/lib-storage/index/dbox-single/sdbox-mail.c b/src/lib-storage/index/dbox-single/sdbox-mail.c index 73a3f356cb..0435c2bc77 100644 --- a/src/lib-storage/index/dbox-single/sdbox-mail.c +++ b/src/lib-storage/index/dbox-single/sdbox-mail.c @@ -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, diff --git a/src/lib-storage/index/imapc/imapc-mail-fetch.c b/src/lib-storage/index/imapc/imapc-mail-fetch.c index c9adbd4a6a..6852c28bc1 100644 --- a/src/lib-storage/index/imapc/imapc-mail-fetch.c +++ b/src/lib-storage/index/imapc/imapc-mail-fetch.c @@ -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; diff --git a/src/lib-storage/index/imapc/imapc-mail.c b/src/lib-storage/index/imapc/imapc-mail.c index 6a129d5aee..d4be94dc11 100644 --- a/src/lib-storage/index/imapc/imapc-mail.c +++ b/src/lib-storage/index/imapc/imapc-mail.c @@ -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, diff --git a/src/lib-storage/index/index-mail-headers.c b/src/lib-storage/index/index-mail-headers.c index 53bb95dfb0..7490e30289 100644 --- a/src/lib-storage/index/index-mail-headers.c +++ b/src/lib-storage/index/index-mail-headers.c @@ -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); } diff --git a/src/lib-storage/index/index-mail.c b/src/lib-storage/index/index-mail.c index 6620506993..a4affe21d4 100644 --- a/src/lib-storage/index/index-mail.c +++ b/src/lib-storage/index/index-mail.c @@ -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) diff --git a/src/lib-storage/index/index-mail.h b/src/lib-storage/index/index-mail.h index 8534e42d0c..30bbcefe0a 100644 --- a/src/lib-storage/index/index-mail.h +++ b/src/lib-storage/index/index-mail.h @@ -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); diff --git a/src/lib-storage/index/maildir/maildir-mail.c b/src/lib-storage/index/maildir/maildir-mail.c index 933e4d9eb7..9362ab22b1 100644 --- a/src/lib-storage/index/maildir/maildir-mail.c +++ b/src/lib-storage/index/maildir/maildir-mail.c @@ -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, diff --git a/src/lib-storage/index/mbox/mbox-mail.c b/src/lib-storage/index/mbox/mbox-mail.c index fea3337b32..9c1ae4c2b6 100644 --- a/src/lib-storage/index/mbox/mbox-mail.c +++ b/src/lib-storage/index/mbox/mbox-mail.c @@ -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, diff --git a/src/lib-storage/index/raw/raw-mail.c b/src/lib-storage/index/raw/raw-mail.c index 9e74bfdef5..9b142b91fd 100644 --- a/src/lib-storage/index/raw/raw-mail.c +++ b/src/lib-storage/index/raw/raw-mail.c @@ -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, diff --git a/src/lib-storage/mail-storage-private.h b/src/lib-storage/mail-storage-private.h index 528d47cbe5..b1a44cb300 100644 --- a/src/lib-storage/mail-storage-private.h +++ b/src/lib-storage/mail-storage-private.h @@ -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; diff --git a/src/lib-storage/mail-storage.h b/src/lib-storage/mail-storage.h index 18b0bfb8e4..2f802bba94 100644 --- a/src/lib-storage/mail-storage.h +++ b/src/lib-storage/mail-storage.h @@ -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 */ diff --git a/src/lib-storage/mail.c b/src/lib-storage/mail.c index fb7efb525d..f8852b46d8 100644 --- a/src/lib-storage/mail.c +++ b/src/lib-storage/mail.c @@ -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; diff --git a/src/lib-storage/test-mail.c b/src/lib-storage/test-mail.c index 8e3f8507e1..9e8f7cd8c3 100644 --- a/src/lib-storage/test-mail.c +++ b/src/lib-storage/test-mail.c @@ -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, diff --git a/src/plugins/virtual/virtual-mail.c b/src/plugins/virtual/virtual-mail.c index f1330114b5..f69c69a9ae 100644 --- a/src/plugins/virtual/virtual-mail.c +++ b/src/plugins/virtual/virtual-mail.c @@ -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,