static int maildir_mail_get_physical_size(struct mail *_mail, uoff_t *size_r) { struct index_mail *mail = (struct index_mail *)_mail; struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box; struct index_mail_data *data = &mail->data; struct stat st; const char *path; int ret; if (maildir_uidlist_is_read(mbox->uidlist) || (_mail->box->flags & MAILBOX_FLAG_POP3_SESSION) != 0) { /* try to get the size from uidlist (see virtual size above) */ if (maildir_quick_size_lookup(mail, FALSE, &data->physical_size) < 0) return -1; } if (data->physical_size == (uoff_t)-1) { if (index_mail_get_physical_size(_mail, size_r) == 0) { i_assert(mail->data.physical_size != (uoff_t)-1); maildir_handle_size_caching(mail, TRUE, FALSE); return 0; } if (maildir_quick_size_lookup(mail, FALSE, &data->physical_size) < 0) return -1; } if (data->physical_size != (uoff_t)-1) { data->dont_cache_fetch_fields |= MAIL_FETCH_PHYSICAL_SIZE; *size_r = data->physical_size; return 0; } if (!_mail->saving) { ret = maildir_file_do(mbox, _mail->uid, do_stat, &st); if (ret <= 0) { if (ret == 0) mail_set_expunged(_mail); return -1; } } else { /* saved mail which hasn't been committed yet */ path = maildir_save_file_get_path(_mail->transaction, _mail->seq); if (stat(path, &st) < 0) { mail_storage_set_critical(_mail->box->storage, "stat(%s) failed: %m", path); return -1; } } data->physical_size = st.st_size; maildir_handle_size_caching(mail, FALSE, FALSE); *size_r = st.st_size; return 0; }
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; }