virtual-mail.c revision 4ee00532a265bdfb38539d811fcd12d51210ac35
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (c) 2008-2012 Dovecot authors, see the included COPYING file */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "lib.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "array.h"
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainen#include "index-mail.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "virtual-storage.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "virtual-transaction.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainenstruct virtual_mail {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct index_mail imail;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen enum mail_fetch_field wanted_fields;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox_header_lookup_ctx *wanted_headers;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* currently active mail */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mail *backend_mail;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* all allocated mails */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ARRAY(struct mail *) backend_mails;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* mail is lost if backend_mail doesn't point to correct mail */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int lost:1;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen};
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainenstruct mail *
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainenvirtual_mail_alloc(struct mailbox_transaction_context *t,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen enum mail_fetch_field wanted_fields,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox_header_lookup_ctx *wanted_headers)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)t->box;
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen struct virtual_mail *vmail;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen pool_t pool;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen pool = pool_alloconly_create("vmail", 1024);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen vmail = p_new(pool, struct virtual_mail, 1);
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen vmail->imail.mail.pool = pool;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen vmail->imail.mail.v = virtual_mail_vfuncs;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen vmail->imail.mail.mail.box = t->box;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen vmail->imail.mail.mail.transaction = t;
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen array_create(&vmail->imail.mail.module_contexts, pool,
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen sizeof(void *), 5);
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen vmail->imail.data_pool =
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen pool_alloconly_create("virtual index_mail", 512);
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen vmail->imail.ibox = INDEX_STORAGE_CONTEXT(t->box);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen vmail->wanted_fields = wanted_fields;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (wanted_headers != NULL) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen vmail->wanted_headers = wanted_headers;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mailbox_header_lookup_ref(wanted_headers);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen i_array_init(&vmail->backend_mails, array_count(&mbox->backend_boxes));
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen return &vmail->imail.mail.mail;
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen}
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void virtual_mail_free(struct mail *mail)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mail **mails;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int i, count;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mails = array_get_modifiable(&vmail->backend_mails, &count);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen for (i = 0; i < count; i++)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mail_free(&mails[i]);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen array_free(&vmail->backend_mails);
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (vmail->wanted_headers != NULL)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mailbox_header_lookup_unref(&vmail->wanted_headers);
66c0f96d704f09c88dd03b0ee13a3e9711ffe593Timo Sirainen
66c0f96d704f09c88dd03b0ee13a3e9711ffe593Timo Sirainen pool_unref(&vmail->imail.data_pool);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen pool_unref(&vmail->imail.mail.pool);
66c0f96d704f09c88dd03b0ee13a3e9711ffe593Timo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainenstatic struct mail *
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainenbackend_mail_find(struct virtual_mail *vmail, struct mailbox *box)
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mail *const *mails;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int i, count;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mails = array_get(&vmail->backend_mails, &count);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen for (i = 0; i < count; i++) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (mails[i]->box == box)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return mails[i];
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen }
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen return NULL;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainenstruct mail *
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainenvirtual_mail_set_backend_mail(struct mail *mail,
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen struct virtual_backend_box *bbox)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
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
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen backend_trans = virtual_transaction_get(mail->transaction, bbox->box);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen backend_headers = vmail->wanted_headers == NULL ? NULL :
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mailbox_header_lookup_init(bbox->box,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen vmail->wanted_headers->name);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen vmail->backend_mail = mail_alloc(backend_trans, vmail->wanted_fields,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen backend_headers);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (backend_headers != NULL)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mailbox_header_lookup_unref(&backend_headers);
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen array_append(&vmail->backend_mails, &vmail->backend_mail, 1);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return vmail->backend_mail;
67770c0874918e3b73bbd1ff75b5ec91790d51dcTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void virtual_mail_set_seq(struct mail *mail, uint32_t seq, bool saving)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)mail->box;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_backend_box *bbox;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen const struct virtual_mail_index_record *vrec;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen const void *data;
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen bool expunged;
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen i_assert(!saving);
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen mail_index_lookup_ext(mail->transaction->view, seq,
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen mbox->virtual_ext_id, &data, &expunged);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen vrec = data;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen bbox = virtual_backend_box_lookup(mbox, vrec->mailbox_id);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen vmail->backend_mail = backend_mail_find(vmail, bbox->box);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen if (vmail->backend_mail == NULL)
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));
1330f999b8076b2f8eed2572c667f7482a555c1bTimo Sirainen p_clear(vmail->imail.data_pool);
1330f999b8076b2f8eed2572c667f7482a555c1bTimo Sirainen
899ebb8ba3fbebaafd3e431943283719ce2b106dTimo Sirainen vmail->imail.data.seq = seq;
899ebb8ba3fbebaafd3e431943283719ce2b106dTimo Sirainen mail->seq = seq;
899ebb8ba3fbebaafd3e431943283719ce2b106dTimo Sirainen mail_index_lookup_uid(mail->transaction->view, seq, &mail->uid);
899ebb8ba3fbebaafd3e431943283719ce2b106dTimo Sirainen
899ebb8ba3fbebaafd3e431943283719ce2b106dTimo Sirainen if (!vmail->lost) {
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;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen } else {
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen mail->expunged = TRUE;
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen mail->has_nuls = FALSE;
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen mail->has_no_nuls = FALSE;
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen }
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen}
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainenstatic bool virtual_mail_set_uid(struct mail *mail, uint32_t uid)
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen{
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen uint32_t seq;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (!mail_index_lookup_seq(mail->transaction->view, uid, &seq))
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return FALSE;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen virtual_mail_set_seq(mail, seq, FALSE);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen return TRUE;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen}
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainenstatic void virtual_mail_set_uid_cache_updates(struct mail *mail, bool set)
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen{
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen p->v.set_uid_cache_updates(vmail->backend_mail, set);
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen}
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainenstatic bool virtual_mail_prefetch(struct mail *mail)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen{
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen return p->v.prefetch(vmail->backend_mail);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen}
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainenstatic void virtual_mail_precache(struct mail *mail)
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen{
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen p->v.precache(vmail->backend_mail);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen}
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainenstatic void
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenvirtual_mail_add_temp_wanted_fields(struct mail *mail,
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen enum mail_fetch_field fields,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen struct mailbox_header_lookup_ctx *headers)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen{
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen p->v.add_temp_wanted_fields(vmail->backend_mail, fields, headers);
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen}
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainenstatic int virtual_mail_handle_lost(struct virtual_mail *vmail)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen{
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen if (!vmail->lost)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen return 0;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen mail_set_expunged(&vmail->imail.mail.mail);
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen return -1;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen}
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenstatic int
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenvirtual_mail_get_parts(struct mail *mail, struct message_part **parts_r)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen{
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen return -1;
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 Sirainen return -1;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen }
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen return 0;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen}
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainenstatic int
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainenvirtual_mail_get_date(struct mail *mail, time_t *date_r, int *timezone_r)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen{
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen int tz;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
7f3b826a89bcb7a72759912e99f574b28309fe1bTimo Sirainen if (timezone_r == NULL)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen timezone_r = &tz;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen return -1;
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 Sirainen return -1;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen }
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen return 0;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen}
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenstatic int virtual_mail_get_received_date(struct mail *mail, time_t *date_r)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen{
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen return -1;
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 Sirainen return -1;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen }
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen return 0;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen}
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenstatic int virtual_mail_get_save_date(struct mail *mail, time_t *date_r)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen{
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen return -1;
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 Sirainen return -1;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen }
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen return 0;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen}
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainenstatic int virtual_mail_get_virtual_mail_size(struct mail *mail, uoff_t *size_r)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen{
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen return -1;
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);
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen return -1;
5e203e846133e28d0e36ca70ef1c30e72a922c14Timo Sirainen }
5e203e846133e28d0e36ca70ef1c30e72a922c14Timo Sirainen return 0;
5e203e846133e28d0e36ca70ef1c30e72a922c14Timo Sirainen}
5e203e846133e28d0e36ca70ef1c30e72a922c14Timo Sirainen
5e203e846133e28d0e36ca70ef1c30e72a922c14Timo Sirainenstatic int virtual_mail_get_physical_size(struct mail *mail, uoff_t *size_r)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen{
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen return -1;
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);
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen return -1;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen }
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen return 0;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen}
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenstatic int
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenvirtual_mail_get_first_header(struct mail *mail, const char *field,
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen bool decode_to_utf8, const char **value_r)
107f6e87c6edcb29cf87195357144dea3fdda9afTimo Sirainen{
107f6e87c6edcb29cf87195357144dea3fdda9afTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
107f6e87c6edcb29cf87195357144dea3fdda9afTimo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen return -1;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen if (p->v.get_first_header(vmail->backend_mail, field,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen decode_to_utf8, value_r) < 0) {
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen return -1;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen }
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen return 0;
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen}
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainenstatic int
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainenvirtual_mail_get_headers(struct mail *mail, const char *field,
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen bool decode_to_utf8, const char *const **value_r)
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen{
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen return -1;
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen if (p->v.get_headers(vmail->backend_mail, field,
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen decode_to_utf8, value_r) < 0) {
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return -1;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen return 0;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic int
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenvirtual_mail_get_header_stream(struct mail *mail,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox_header_lookup_ctx *headers,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct istream **stream_r)
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox_header_lookup_ctx *backend_headers;
075a53973bbdf15cc3bd2ba4872f96f3f2f00574Timo Sirainen int ret;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen return -1;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen backend_headers = mailbox_header_lookup_init(vmail->backend_mail->box,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen headers->name);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ret = mail_get_header_stream(vmail->backend_mail, backend_headers,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen stream_r);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mailbox_header_lookup_unref(&backend_headers);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (ret < 0) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return -1;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen return 0;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic int
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenvirtual_mail_get_stream(struct mail *mail, bool get_body,
d4854db53e9c141db3d02821ed857bea101b1cc2Timo Sirainen struct message_size *hdr_size,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct message_size *body_size,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct istream **stream_r)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen int ret;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return -1;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (get_body) {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen ret = mail_get_stream(vmail->backend_mail, hdr_size, body_size,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen stream_r);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen } else {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ret = mail_get_hdr_stream(vmail->backend_mail, hdr_size,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen stream_r);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
867990944f0bda3a5bd70895d5a5ebfa611d0505Timo Sirainen if (ret < 0) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
867990944f0bda3a5bd70895d5a5ebfa611d0505Timo Sirainen return -1;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen }
867990944f0bda3a5bd70895d5a5ebfa611d0505Timo Sirainen return 0;
867990944f0bda3a5bd70895d5a5ebfa611d0505Timo Sirainen}
867990944f0bda3a5bd70895d5a5ebfa611d0505Timo Sirainen
867990944f0bda3a5bd70895d5a5ebfa611d0505Timo Sirainenstatic int
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenvirtual_mail_get_special(struct mail *mail, enum mail_fetch_field field,
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen const char **value_r)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen{
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen struct mailbox *box = vmail->backend_mail->box;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return -1;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (mail_get_special(vmail->backend_mail, field, value_r) < 0) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen virtual_box_copy_error(mail->box, box);
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen return -1;
3b1bf68d26c9f2fe4a649f40cf375d52acffc81cTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return 0;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic struct mail *virtual_mail_get_real_mail(struct mail *mail)
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen{
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen return mail_get_real_mail(vmail->backend_mail);
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen}
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainenstatic void virtual_mail_update_pop3_uidl(struct mail *mail, const char *uidl)
66c0f96d704f09c88dd03b0ee13a3e9711ffe593Timo Sirainen{
66c0f96d704f09c88dd03b0ee13a3e9711ffe593Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
66c0f96d704f09c88dd03b0ee13a3e9711ffe593Timo Sirainen
66c0f96d704f09c88dd03b0ee13a3e9711ffe593Timo Sirainen mail_update_pop3_uidl(vmail->backend_mail, uidl);
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen}
static void virtual_mail_expunge(struct mail *mail)
{
struct virtual_mail *vmail = (struct virtual_mail *)mail;
if (virtual_mail_handle_lost(vmail) < 0)
return;
mail_expunge(vmail->backend_mail);
}
static void
virtual_mail_set_cache_corrupted(struct mail *mail, enum mail_fetch_field field)
{
struct virtual_mail *vmail = (struct virtual_mail *)mail;
if (virtual_mail_handle_lost(vmail) < 0)
return;
mail_set_cache_corrupted(vmail->backend_mail, field);
}
struct mail_vfuncs virtual_mail_vfuncs = {
NULL,
virtual_mail_free,
virtual_mail_set_seq,
virtual_mail_set_uid,
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,
index_mail_get_keyword_indexes,
index_mail_get_modseq,
virtual_mail_get_parts,
virtual_mail_get_date,
virtual_mail_get_received_date,
virtual_mail_get_save_date,
virtual_mail_get_virtual_mail_size,
virtual_mail_get_physical_size,
virtual_mail_get_first_header,
virtual_mail_get_headers,
virtual_mail_get_header_stream,
virtual_mail_get_stream,
index_mail_get_binary_stream,
virtual_mail_get_special,
virtual_mail_get_real_mail,
index_mail_update_flags,
index_mail_update_keywords,
index_mail_update_modseq,
virtual_mail_update_pop3_uidl,
virtual_mail_expunge,
virtual_mail_set_cache_corrupted,
NULL
};