virtual-mail.c revision 4542c94adb8910e0174c784754e737cec16af59c
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2008-2009 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"
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainenstruct virtual_mail {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct index_mail imail;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
7a7d2aa11e46195e2d92d6c337d7e78052a5ce67Timo Sirainen enum mail_fetch_field wanted_fields;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox_header_lookup_ctx *wanted_headers;
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen /* currently active mail */
a8fe899601735459641edae975c0fa08be8482e2Timo Sirainen struct mail *backend_mail;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen /* all allocated mails */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ARRAY_DEFINE(backend_mails, struct mail *);
111a7dda02defa4d612468cfc3c40da5240645afTimo 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
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstruct mail *
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenvirtual_mail_alloc(struct mailbox_transaction_context *t,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen enum mail_fetch_field wanted_fields,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox_header_lookup_ctx *wanted_headers)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)t->box;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_mail *vmail;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen pool_t pool;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen pool = pool_alloconly_create("vmail", 1024);
8a524e87e44ae629cf90262e92f7972ea3450c35Timo Sirainen vmail = p_new(pool, struct virtual_mail, 1);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen vmail->imail.mail.pool = pool;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen vmail->imail.mail.v = virtual_mail_vfuncs;
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen vmail->imail.mail.mail.box = t->box;
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen vmail->imail.mail.mail.transaction = t;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen array_create(&vmail->imail.mail.module_contexts, pool,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen sizeof(void *), 5);
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen vmail->imail.data_pool =
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen pool_alloconly_create("virtual index_mail", 512);
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen vmail->imail.ibox = &mbox->ibox;
d798962a54c5cda054d57a0cfc7e5f47dfa20f6eTimo Sirainen vmail->imail.trans = (struct index_transaction_context *)t;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen vmail->wanted_fields = wanted_fields;
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen if (wanted_headers != NULL) {
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen vmail->wanted_headers = wanted_headers;
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen mailbox_header_lookup_ref(wanted_headers);
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen }
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen i_array_init(&vmail->backend_mails, array_count(&mbox->backend_boxes));
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return &vmail->imail.mail.mail;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainenstatic void virtual_mail_free(struct mail *mail)
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mail **mails;
7bb371485650002935888b2f9b72b23aba5a5d9aStephan Bosch unsigned int i, count;
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen mails = array_get_modifiable(&vmail->backend_mails, &count);
84078771687fabf75819918f0f3aecdc3ed08b36Timo Sirainen for (i = 0; i < count; i++)
d798962a54c5cda054d57a0cfc7e5f47dfa20f6eTimo Sirainen mail_free(&mails[i]);
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen array_free(&vmail->backend_mails);
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen if (vmail->wanted_headers != NULL)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mailbox_header_lookup_unref(&vmail->wanted_headers);
428fb4dc39c6e9b2eb36216c396dad6096a65f8fTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen pool_unref(&vmail->imail.data_pool);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen pool_unref(&vmail->imail.mail.pool);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic struct mail *
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenbackend_mail_find(struct virtual_mail *vmail, struct mailbox *box)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mail *const *mails;
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen unsigned int i, count;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mails = array_get(&vmail->backend_mails, &count);
c64840e98649f906a7b587c259d5b9e697c37498Timo Sirainen for (i = 0; i < count; i++) {
c64840e98649f906a7b587c259d5b9e697c37498Timo Sirainen if (mails[i]->box == box)
66c0f96d704f09c88dd03b0ee13a3e9711ffe593Timo Sirainen return mails[i];
66c0f96d704f09c88dd03b0ee13a3e9711ffe593Timo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return NULL;
66c0f96d704f09c88dd03b0ee13a3e9711ffe593Timo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainenstruct mail *
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainenvirtual_mail_set_backend_mail(struct mail *mail,
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen struct virtual_backend_box *bbox)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
c64840e98649f906a7b587c259d5b9e697c37498Timo 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 :
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen mailbox_header_lookup_init(bbox->box,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen vmail->wanted_headers->headers);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen vmail->backend_mail = mail_alloc(backend_trans, vmail->wanted_fields,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen backend_headers);
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen if (backend_headers != NULL)
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen mailbox_header_lookup_unref(&backend_headers);
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen array_append(&vmail->backend_mails, &vmail->backend_mail, 1);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return vmail->backend_mail;
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen}
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void virtual_mail_set_seq(struct mail *mail, uint32_t seq)
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;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen bool expunged;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen mail_index_lookup_ext(mbox->ibox.view, seq, mbox->virtual_ext_id,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen &data, &expunged);
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen vrec = data;
28d6a9ec6b055ad6141f0961fe971543f781d4a6Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen bbox = virtual_backend_box_lookup(mbox, vrec->mailbox_id);
67770c0874918e3b73bbd1ff75b5ec91790d51dcTimo Sirainen vmail->backend_mail = backend_mail_find(vmail, bbox->box);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (vmail->backend_mail == NULL)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen virtual_mail_set_backend_mail(mail, bbox);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen vmail->lost = !mail_set_uid(vmail->backend_mail, vrec->real_uid);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen memset(&vmail->imail.data, 0, sizeof(vmail->imail.data));
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen p_clear(vmail->imail.data_pool);
f67059a0fb0ea694dfa49910c5af2ff0f60ea18eTimo Sirainen
f67059a0fb0ea694dfa49910c5af2ff0f60ea18eTimo Sirainen vmail->imail.data.seq = seq;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mail->seq = seq;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mail_index_lookup_uid(mbox->ibox.view, seq, &mail->uid);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen if (!vmail->lost) {
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen mail->expunged = vmail->backend_mail->expunged;
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen mail->has_nuls = vmail->backend_mail->has_nuls;
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen mail->has_no_nuls = vmail->backend_mail->has_no_nuls;
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen } else {
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen mail->expunged = TRUE;
fb297df915b623e8d83632abcd42182cbd86174aTimo Sirainen mail->has_nuls = FALSE;
fb297df915b623e8d83632abcd42182cbd86174aTimo Sirainen mail->has_no_nuls = FALSE;
fb297df915b623e8d83632abcd42182cbd86174aTimo Sirainen }
fb297df915b623e8d83632abcd42182cbd86174aTimo Sirainen}
fb297df915b623e8d83632abcd42182cbd86174aTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic bool virtual_mail_set_uid(struct mail *mail, uint32_t uid)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)mail->box;
dd37e2ff291fbebac1b94e8aad50f3bdf7531049Timo Sirainen uint32_t seq;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen if (!mail_index_lookup_seq(mbox->ibox.view, uid, &seq))
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return FALSE;
77a2367051db01c6fc8cc575242d8a7f5b2c1d42Timo Sirainen
77a2367051db01c6fc8cc575242d8a7f5b2c1d42Timo Sirainen virtual_mail_set_seq(mail, seq);
2128e2bebe4af374561ea2846b9d3eca3cde233eTimo Sirainen return TRUE;
2128e2bebe4af374561ea2846b9d3eca3cde233eTimo Sirainen}
77a2367051db01c6fc8cc575242d8a7f5b2c1d42Timo Sirainen
77a2367051db01c6fc8cc575242d8a7f5b2c1d42Timo Sirainenstatic void virtual_mail_set_uid_cache_updates(struct mail *mail, bool set)
77a2367051db01c6fc8cc575242d8a7f5b2c1d42Timo Sirainen{
77a2367051db01c6fc8cc575242d8a7f5b2c1d42Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
77a2367051db01c6fc8cc575242d8a7f5b2c1d42Timo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
28d6a9ec6b055ad6141f0961fe971543f781d4a6Timo Sirainen
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen p->v.set_uid_cache_updates(vmail->backend_mail, set);
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen}
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainenstatic int virtual_mail_handle_lost(struct virtual_mail *vmail)
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen{
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen if (!vmail->lost)
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen return 0;
28d6a9ec6b055ad6141f0961fe971543f781d4a6Timo Sirainen
28d6a9ec6b055ad6141f0961fe971543f781d4a6Timo Sirainen mail_set_expunged(&vmail->imail.mail.mail);
28d6a9ec6b055ad6141f0961fe971543f781d4a6Timo Sirainen return -1;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen}
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainenstatic int
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainenvirtual_mail_get_parts(struct mail *mail, const struct message_part **parts_r)
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen{
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen return -1;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen if (mail_get_parts(vmail->backend_mail, parts_r) < 0) {
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen return -1;
28d6a9ec6b055ad6141f0961fe971543f781d4a6Timo Sirainen }
28d6a9ec6b055ad6141f0961fe971543f781d4a6Timo Sirainen return 0;
28d6a9ec6b055ad6141f0961fe971543f781d4a6Timo Sirainen}
28d6a9ec6b055ad6141f0961fe971543f781d4a6Timo Sirainen
28d6a9ec6b055ad6141f0961fe971543f781d4a6Timo Sirainenstatic int
28d6a9ec6b055ad6141f0961fe971543f781d4a6Timo Sirainenvirtual_mail_get_date(struct mail *mail, time_t *date_r, int *timezone_r)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen{
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen int tz;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen if (timezone_r == NULL)
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen timezone_r = &tz;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen return -1;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen if (mail_get_date(vmail->backend_mail, date_r, timezone_r) < 0) {
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen return -1;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen }
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen return 0;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen}
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainenstatic int virtual_mail_get_received_date(struct mail *mail, time_t *date_r)
676a42c1de72aaa6149d1ffd1d26c862951798a3Timo Sirainen{
fb297df915b623e8d83632abcd42182cbd86174aTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return -1;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (mail_get_received_date(vmail->backend_mail, date_r) < 0) {
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen return -1;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen }
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen return 0;
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen}
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainenstatic int virtual_mail_get_save_date(struct mail *mail, time_t *date_r)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen{
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen return -1;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen if (mail_get_save_date(vmail->backend_mail, date_r) < 0) {
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen return -1;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen }
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen return 0;
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen}
77a2367051db01c6fc8cc575242d8a7f5b2c1d42Timo Sirainen
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainenstatic int virtual_mail_get_virtual_mail_size(struct mail *mail, uoff_t *size_r)
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen{
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen return -1;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen if (mail_get_virtual_size(vmail->backend_mail, size_r) < 0) {
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen return -1;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen }
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen return 0;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen}
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen
27f174f3b836b18cb81cd1e6534031f1f3355348Timo 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;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen return -1;
111a7dda02defa4d612468cfc3c40da5240645afTimo 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 Sirainen return -1;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen }
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen return 0;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen}
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainenstatic int
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenvirtual_mail_get_first_header(struct mail *mail, const char *field,
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen bool decode_to_utf8, const char **value_r)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen{
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen return -1;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen if (p->v.get_first_header(vmail->backend_mail, field,
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo 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;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen}
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainenstatic int
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainenvirtual_mail_get_headers(struct mail *mail, const char *field,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen bool decode_to_utf8, const char *const **value_r)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen{
111a7dda02defa4d612468cfc3c40da5240645afTimo 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 if (virtual_mail_handle_lost(vmail) < 0)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen return -1;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen if (p->v.get_headers(vmail->backend_mail, field,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen decode_to_utf8, value_r) < 0) {
7f3b826a89bcb7a72759912e99f574b28309fe1bTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen return -1;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen }
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen return 0;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen}
77d20bf99719739c8a3d1157ccc28f37f6032f94Timo Sirainen
77d20bf99719739c8a3d1157ccc28f37f6032f94Timo Sirainenstatic int
77d20bf99719739c8a3d1157ccc28f37f6032f94Timo Sirainenvirtual_mail_get_header_stream(struct mail *mail,
77d20bf99719739c8a3d1157ccc28f37f6032f94Timo Sirainen struct mailbox_header_lookup_ctx *headers,
77d20bf99719739c8a3d1157ccc28f37f6032f94Timo Sirainen struct istream **stream_r)
77d20bf99719739c8a3d1157ccc28f37f6032f94Timo Sirainen{
77d20bf99719739c8a3d1157ccc28f37f6032f94Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
77d20bf99719739c8a3d1157ccc28f37f6032f94Timo Sirainen struct mailbox_header_lookup_ctx *backend_headers;
77d20bf99719739c8a3d1157ccc28f37f6032f94Timo Sirainen int ret;
77d20bf99719739c8a3d1157ccc28f37f6032f94Timo Sirainen
77d20bf99719739c8a3d1157ccc28f37f6032f94Timo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
762d8af0b3fee4aef634f413ec61baccab827b37Timo Sirainen return -1;
762d8af0b3fee4aef634f413ec61baccab827b37Timo Sirainen
762d8af0b3fee4aef634f413ec61baccab827b37Timo Sirainen backend_headers = mailbox_header_lookup_init(vmail->backend_mail->box,
762d8af0b3fee4aef634f413ec61baccab827b37Timo Sirainen headers->headers);
762d8af0b3fee4aef634f413ec61baccab827b37Timo Sirainen ret = mail_get_header_stream(vmail->backend_mail, backend_headers,
762d8af0b3fee4aef634f413ec61baccab827b37Timo Sirainen stream_r);
762d8af0b3fee4aef634f413ec61baccab827b37Timo Sirainen mailbox_header_lookup_unref(&backend_headers);
762d8af0b3fee4aef634f413ec61baccab827b37Timo Sirainen if (ret < 0) {
77d20bf99719739c8a3d1157ccc28f37f6032f94Timo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
77d20bf99719739c8a3d1157ccc28f37f6032f94Timo Sirainen return -1;
77d20bf99719739c8a3d1157ccc28f37f6032f94Timo Sirainen }
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen return 0;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen}
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenstatic int
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenvirtual_mail_get_stream(struct mail *mail, struct message_size *hdr_size,
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen struct message_size *body_size,
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen struct istream **stream_r)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen{
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
77d20bf99719739c8a3d1157ccc28f37f6032f94Timo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen return -1;
402e999a878e0cc41a0afb830fea0a93afc75f0dTimo Sirainen if (mail_get_stream(vmail->backend_mail, hdr_size, body_size,
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen stream_r) < 0) {
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen return -1;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen }
77a2367051db01c6fc8cc575242d8a7f5b2c1d42Timo Sirainen return 0;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen}
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenstatic int
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenvirtual_mail_get_special(struct mail *mail, enum mail_fetch_field field,
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen const char **value_r)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen{
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen struct mailbox *box = vmail->backend_mail->box;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen return -1;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen if (mail_get_special(vmail->backend_mail, field, value_r) < 0) {
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen virtual_box_copy_error(mail->box, box);
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen return -1;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen }
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen return 0;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen}
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen
391970ed208650d807191e5f2fc403f20f76ce18Timo Sirainenstatic void virtual_mail_update_pop3_uidl(struct mail *mail, const char *uidl)
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen{
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen
391970ed208650d807191e5f2fc403f20f76ce18Timo Sirainen mail_update_pop3_uidl(vmail->backend_mail, uidl);
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen}
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainenstatic void virtual_mail_expunge(struct mail *mail)
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen{
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen return;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen mail_expunge(vmail->backend_mail);
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen}
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainenstatic void
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainenvirtual_mail_set_cache_corrupted(struct mail *mail, enum mail_fetch_field field)
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen{
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen return;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen mail_set_cache_corrupted(vmail->backend_mail, field);
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen}
61cf001f1944d92eb25f113ba4c08985d6e30d53Timo Sirainen
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainenstatic struct index_mail *virtual_mail_get_index_mail(struct mail *mail)
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen{
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen return (struct index_mail *)vmail->backend_mail;
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen}
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainenstruct mail_vfuncs virtual_mail_vfuncs = {
a5056d1e9dd4c430390f8b1dc874a95a2fa16380Timo Sirainen NULL,
a5056d1e9dd4c430390f8b1dc874a95a2fa16380Timo Sirainen virtual_mail_free,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen virtual_mail_set_seq,
3e0bae44b65f5c46989fcef3d1e07203f496327eTimo Sirainen virtual_mail_set_uid,
3e0bae44b65f5c46989fcef3d1e07203f496327eTimo Sirainen virtual_mail_set_uid_cache_updates,
de4d9f77d6378a416c9963963eac5ac18b75ec0bTimo Sirainen
de4d9f77d6378a416c9963963eac5ac18b75ec0bTimo Sirainen index_mail_get_flags,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen index_mail_get_keywords,
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen index_mail_get_keyword_indexes,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen index_mail_get_modseq,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen virtual_mail_get_parts,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen virtual_mail_get_date,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen virtual_mail_get_received_date,
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen virtual_mail_get_save_date,
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen virtual_mail_get_virtual_mail_size,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen virtual_mail_get_physical_size,
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen virtual_mail_get_first_header,
27f174f3b836b18cb81cd1e6534031f1f3355348Timo Sirainen virtual_mail_get_headers,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen virtual_mail_get_header_stream,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen virtual_mail_get_stream,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen virtual_mail_get_special,
5e203e846133e28d0e36ca70ef1c30e72a922c14Timo Sirainen index_mail_update_flags,
5e203e846133e28d0e36ca70ef1c30e72a922c14Timo Sirainen index_mail_update_keywords,
5e203e846133e28d0e36ca70ef1c30e72a922c14Timo Sirainen index_mail_update_modseq,
5e203e846133e28d0e36ca70ef1c30e72a922c14Timo Sirainen index_mail_update_uid,
5e203e846133e28d0e36ca70ef1c30e72a922c14Timo Sirainen virtual_mail_update_pop3_uidl,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen virtual_mail_expunge,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen virtual_mail_set_cache_corrupted,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen virtual_mail_get_index_mail
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen};
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen