void dbox_mail_close(struct mail *_mail) { struct dbox_mail *mail = (struct dbox_mail *)_mail; index_mail_close(_mail); /* close the dbox file only after index is closed, since it may still try to read from it. */ if (mail->open_file != NULL) dbox_file_unref(&mail->open_file); }
int mdbox_mail_open(struct dbox_mail *mail, uoff_t *offset_r, struct dbox_file **file_r) { struct mail *_mail = &mail->imail.mail.mail; struct mdbox_mailbox *mbox = (struct mdbox_mailbox *)_mail->box; uint32_t prev_file_id = 0, map_uid = 0; bool deleted; if (_mail->lookup_abort != MAIL_LOOKUP_ABORT_NEVER) { mail_set_aborted(_mail); return -1; } do { if (mail->open_file != NULL) { /* already open */ } else if (!_mail->saving) { if (mdbox_mail_lookup(mbox, _mail->transaction->view, _mail->seq, &map_uid) < 0) return -1; if (dbox_mail_open_init(mail, map_uid) < 0) return -1; } else { /* mail is being saved in this transaction */ mail->open_file = mdbox_save_file_get_file(_mail->transaction, _mail->seq, &mail->offset); } if (!dbox_file_is_open(mail->open_file)) mail->imail.mail.stats_open_lookup_count++; if (dbox_file_open(mail->open_file, &deleted) <= 0) return -1; if (deleted) { /* either it's expunged now or moved to another file. */ struct mdbox_file *mfile = (struct mdbox_file *)mail->open_file; if (mfile->file_id == prev_file_id) { dbox_mail_set_expunged(mail, map_uid); return -1; } prev_file_id = mfile->file_id; if (mdbox_map_refresh(mbox->storage->map) < 0) return -1; dbox_file_unref(&mail->open_file); } } while (mail->open_file == NULL); *file_r = mail->open_file; *offset_r = mail->offset; return 0; }