static void index_mail_get_cached_body_size(struct index_mail *mail) { struct index_mail_data *data = &mail->data; uoff_t tmp; if (!data->hdr_size_set) return; /* we've already called get_cached_msgpart_sizes() and it didn't work. try to do this by using cached virtual size and a quick physical size lookup. */ if (!index_mail_get_cached_virtual_size(mail, &tmp)) return; if (!data->body_size_set) { if (mail_get_physical_size(&mail->mail.mail, &tmp) < 0) return; /* we should have everything now. try again. */ (void)index_mail_get_cached_virtual_size(mail, &tmp); } }
static int maildir_mail_get_virtual_size(struct mail *_mail, uoff_t *size_r) { struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box; struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; struct message_size hdr_size, body_size; struct istream *input; uoff_t old_offset; if (maildir_uidlist_is_read(mbox->uidlist) || (_mail->box->flags & MAILBOX_FLAG_POP3_SESSION) != 0) { /* try to get the size from uidlist. this is especially useful with pop3 to avoid unnecessarily opening the cache file. */ if (maildir_quick_size_lookup(mail, TRUE, &data->virtual_size) < 0) return -1; } if (data->virtual_size == (uoff_t)-1) { if (index_mail_get_cached_virtual_size(mail, size_r)) { i_assert(mail->data.virtual_size != (uoff_t)-1); maildir_handle_size_caching(mail, TRUE, TRUE); return 0; } if (maildir_quick_size_lookup(mail, TRUE, &data->virtual_size) < 0) return -1; } if (data->virtual_size != (uoff_t)-1) { data->dont_cache_fetch_fields |= MAIL_FETCH_VIRTUAL_SIZE; *size_r = data->virtual_size; return 0; } /* fallback to reading the file */ old_offset = data->stream == NULL ? 0 : data->stream->v_offset; if (mail_get_stream(_mail, &hdr_size, &body_size, &input) < 0) return -1; i_stream_seek(data->stream, old_offset); maildir_handle_size_caching(mail, FALSE, TRUE); *size_r = data->virtual_size; return 0; }
int index_mail_get_virtual_size(struct mail *_mail, uoff_t *size_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; struct message_size hdr_size, body_size; struct istream *input; uoff_t old_offset; if (index_mail_get_cached_virtual_size(mail, size_r)) return 0; old_offset = data->stream == NULL ? 0 : data->stream->v_offset; if (mail_get_stream(_mail, &hdr_size, &body_size, &input) < 0) return -1; i_stream_seek(data->stream, old_offset); i_assert(data->virtual_size != (uoff_t)-1); *size_r = data->virtual_size; return 0; }
int dbox_mail_get_virtual_size(struct mail *_mail, uoff_t *size_r) { struct dbox_mail *mail = (struct dbox_mail *)_mail; struct index_mail_data *data = &mail->imail.data; const char *value; uintmax_t size; if (index_mail_get_cached_virtual_size(&mail->imail, size_r)) return 0; if (dbox_mail_metadata_get(mail, DBOX_METADATA_VIRTUAL_SIZE, &value) < 0) return -1; if (value == NULL) return index_mail_get_virtual_size(_mail, size_r); if (str_to_uintmax_hex(value, &size) < 0 || size > (uoff_t)-1) return -1; data->virtual_size = (uoff_t)size; *size_r = data->virtual_size; return 0; }