virtual-mail.c revision 4ee00532a265bdfb38539d811fcd12d51210ac35
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (c) 2008-2012 Dovecot authors, see the included COPYING file */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox_header_lookup_ctx *wanted_headers;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* currently active mail */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* all allocated mails */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* mail is lost if backend_mail doesn't point to correct mail */
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainenvirtual_mail_alloc(struct mailbox_transaction_context *t,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox_header_lookup_ctx *wanted_headers)
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)t->box;
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen array_create(&vmail->imail.mail.module_contexts, pool,
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen sizeof(void *), 5);
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen pool_alloconly_create("virtual index_mail", 512);
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen vmail->imail.ibox = INDEX_STORAGE_CONTEXT(t->box);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen i_array_init(&vmail->backend_mails, array_count(&mbox->backend_boxes));
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void virtual_mail_free(struct mail *mail)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int i, count;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mails = array_get_modifiable(&vmail->backend_mails, &count);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen for (i = 0; i < count; i++)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mailbox_header_lookup_unref(&vmail->wanted_headers);
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainenstatic struct mail *
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainenbackend_mail_find(struct virtual_mail *vmail, struct mailbox *box)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int i, count;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mails = array_get(&vmail->backend_mails, &count);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen for (i = 0; i < count; i++) {
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainenvirtual_mail_set_backend_mail(struct mail *mail,
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen struct mailbox_transaction_context *backend_trans;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox_header_lookup_ctx *backend_headers;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen backend_trans = virtual_transaction_get(mail->transaction, bbox->box);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen backend_headers = vmail->wanted_headers == NULL ? NULL :
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen vmail->backend_mail = mail_alloc(backend_trans, vmail->wanted_fields,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mailbox_header_lookup_unref(&backend_headers);
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen array_append(&vmail->backend_mails, &vmail->backend_mail, 1);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void virtual_mail_set_seq(struct mail *mail, uint32_t seq, bool saving)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)mail->box;
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen mail_index_lookup_ext(mail->transaction->view, seq,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen bbox = virtual_backend_box_lookup(mbox, vrec->mailbox_id);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen vmail->backend_mail = backend_mail_find(vmail, bbox->box);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen (void)virtual_mail_set_backend_mail(mail, bbox);
fb5b342aab25d6dc96df14774eb5215dc5481546Timo Sirainen vmail->lost = !mail_set_uid(vmail->backend_mail, vrec->real_uid);
1330f999b8076b2f8eed2572c667f7482a555c1bTimo Sirainen memset(&vmail->imail.data, 0, sizeof(vmail->imail.data));
899ebb8ba3fbebaafd3e431943283719ce2b106dTimo Sirainen mail_index_lookup_uid(mail->transaction->view, seq, &mail->uid);
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen mail->expunged = vmail->backend_mail->expunged;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen mail->has_nuls = vmail->backend_mail->has_nuls;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen mail->has_no_nuls = vmail->backend_mail->has_no_nuls;
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainenstatic bool virtual_mail_set_uid(struct mail *mail, uint32_t uid)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (!mail_index_lookup_seq(mail->transaction->view, uid, &seq))
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainenstatic void virtual_mail_set_uid_cache_updates(struct mail *mail, bool set)
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen p->v.set_uid_cache_updates(vmail->backend_mail, set);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainenstatic bool virtual_mail_prefetch(struct mail *mail)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainenstatic void virtual_mail_precache(struct mail *mail)
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenvirtual_mail_add_temp_wanted_fields(struct mail *mail,
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen p->v.add_temp_wanted_fields(vmail->backend_mail, fields, headers);
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainenstatic int virtual_mail_handle_lost(struct virtual_mail *vmail)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenvirtual_mail_get_parts(struct mail *mail, struct message_part **parts_r)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen if (mail_get_parts(vmail->backend_mail, parts_r) < 0) {
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainenvirtual_mail_get_date(struct mail *mail, time_t *date_r, int *timezone_r)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen if (mail_get_date(vmail->backend_mail, date_r, timezone_r) < 0) {
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenstatic int virtual_mail_get_received_date(struct mail *mail, time_t *date_r)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen if (mail_get_received_date(vmail->backend_mail, date_r) < 0) {
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenstatic int virtual_mail_get_save_date(struct mail *mail, time_t *date_r)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen if (mail_get_save_date(vmail->backend_mail, date_r) < 0) {
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainenstatic int virtual_mail_get_virtual_mail_size(struct mail *mail, uoff_t *size_r)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen if (mail_get_virtual_size(vmail->backend_mail, size_r) < 0) {
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
5e203e846133e28d0e36ca70ef1c30e72a922c14Timo Sirainenstatic int virtual_mail_get_physical_size(struct mail *mail, uoff_t *size_r)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen if (mail_get_physical_size(vmail->backend_mail, size_r) < 0) {
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenvirtual_mail_get_first_header(struct mail *mail, const char *field,
107f6e87c6edcb29cf87195357144dea3fdda9afTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
107f6e87c6edcb29cf87195357144dea3fdda9afTimo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen if (p->v.get_first_header(vmail->backend_mail, field,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainenvirtual_mail_get_headers(struct mail *mail, const char *field,
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen bool decode_to_utf8, const char *const **value_r)
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen if (p->v.get_headers(vmail->backend_mail, field,
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenvirtual_mail_get_header_stream(struct mail *mail,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox_header_lookup_ctx *backend_headers;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen backend_headers = mailbox_header_lookup_init(vmail->backend_mail->box,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ret = mail_get_header_stream(vmail->backend_mail, backend_headers,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mailbox_header_lookup_unref(&backend_headers);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenvirtual_mail_get_stream(struct mail *mail, bool get_body,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen ret = mail_get_stream(vmail->backend_mail, hdr_size, body_size,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ret = mail_get_hdr_stream(vmail->backend_mail, hdr_size,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenvirtual_mail_get_special(struct mail *mail, enum mail_fetch_field field,
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen const char **value_r)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen struct mailbox *box = vmail->backend_mail->box;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (mail_get_special(vmail->backend_mail, field, value_r) < 0) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic struct mail *virtual_mail_get_real_mail(struct mail *mail)
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen return mail_get_real_mail(vmail->backend_mail);
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainenstatic void virtual_mail_update_pop3_uidl(struct mail *mail, const char *uidl)
66c0f96d704f09c88dd03b0ee13a3e9711ffe593Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
66c0f96d704f09c88dd03b0ee13a3e9711ffe593Timo Sirainen mail_update_pop3_uidl(vmail->backend_mail, uidl);
NULL,