virtual-mail.c revision 225e82df5dd1e765f4e52b80c954558f00e5a7df
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2008-2009 Dovecot authors, see the included COPYING file */
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger#include "lib.h"
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen#include "array.h"
c96eb61168670cfdd7596baba18856d3f086a093Timo Sirainen#include "index-mail.h"
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen#include "virtual-storage.h"
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen#include "virtual-transaction.h"
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainenstruct virtual_mail {
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen struct index_mail imail;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen enum mail_fetch_field wanted_fields;
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger struct mailbox_header_lookup_ctx *wanted_headers;
55d35a8b8036093b94fb1bb0f0339fc43fad52e1Timo Sirainen
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen /* currently active mail */
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen struct mail *backend_mail;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen /* all allocated mails */
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen ARRAY_DEFINE(backend_mails, struct mail *);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen /* mail is lost if backend_mail doesn't point to correct mail */
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen unsigned int lost:1;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen};
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainenstruct mail *
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainenvirtual_mail_alloc(struct mailbox_transaction_context *t,
5afa8e2edf4f313cd56e5909f92f39c3b5b7b4d3Timo Sirainen enum mail_fetch_field wanted_fields,
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen struct mailbox_header_lookup_ctx *wanted_headers)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen{
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)t->box;
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen struct virtual_mail *vmail;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen pool_t pool;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen pool = pool_alloconly_create("vmail", 1024);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen vmail = p_new(pool, struct virtual_mail, 1);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen vmail->imail.mail.pool = pool;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen vmail->imail.mail.v = virtual_mail_vfuncs;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen vmail->imail.mail.mail.box = t->box;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen vmail->imail.mail.mail.transaction = t;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen array_create(&vmail->imail.mail.module_contexts, pool,
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen sizeof(void *), 5);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen vmail->imail.data_pool =
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen pool_alloconly_create("virtual index_mail", 512);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen vmail->imail.ibox = &mbox->ibox;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen vmail->imail.trans = (struct index_transaction_context *)t;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen vmail->wanted_fields = wanted_fields;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen vmail->wanted_headers = wanted_headers;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen i_array_init(&vmail->backend_mails, array_count(&mbox->backend_boxes));
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return &vmail->imail.mail.mail;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen}
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenstatic void virtual_mail_free(struct mail *mail)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen{
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct mail **mails;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen unsigned int i, count;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen mails = array_get_modifiable(&vmail->backend_mails, &count);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen for (i = 0; i < count; i++)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen mail_free(&mails[i]);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen array_free(&vmail->backend_mails);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen pool_unref(&vmail->imail.data_pool);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen pool_unref(&vmail->imail.mail.pool);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen}
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenstatic struct mail *
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenbackend_mail_find(struct virtual_mail *vmail, struct mailbox *box)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen{
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct mail *const *mails;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen unsigned int i, count;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen mails = array_get(&vmail->backend_mails, &count);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen for (i = 0; i < count; i++) {
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (mails[i]->box == box)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return mails[i];
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen }
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return NULL;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen}
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenstruct mail *
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenvirtual_mail_set_backend_mail(struct mail *mail,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_backend_box *bbox)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen{
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct mailbox_transaction_context *backend_trans;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct mailbox_header_lookup_ctx *backend_headers;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen backend_trans = virtual_transaction_get(mail->transaction, bbox->box);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen backend_headers = vmail->wanted_headers == NULL ? NULL :
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen mailbox_header_lookup_init(bbox->box,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen vmail->wanted_headers->headers);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen vmail->backend_mail = mail_alloc(backend_trans, vmail->wanted_fields,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen backend_headers);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (backend_headers != NULL)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen mailbox_header_lookup_unref(&backend_headers);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen array_append(&vmail->backend_mails, &vmail->backend_mail, 1);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen return vmail->backend_mail;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen}
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenstatic void virtual_mail_set_seq(struct mail *mail, uint32_t seq)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen{
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)mail->box;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_backend_box *bbox;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen const struct virtual_mail_index_record *vrec;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen const void *data;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen bool expunged;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen mail_index_lookup_ext(mbox->ibox.view, seq, mbox->virtual_ext_id,
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen &data, &expunged);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen vrec = data;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
686ad6d723004b807fd558f3ef9d1f88afa7e127Timo Sirainen bbox = virtual_backend_box_lookup(mbox, vrec->mailbox_id);
303a87c31cb4aa198326694e231df53a043e63c7Timo Sirainen vmail->backend_mail = backend_mail_find(vmail, bbox->box);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen if (vmail->backend_mail == NULL)
303a87c31cb4aa198326694e231df53a043e63c7Timo Sirainen virtual_mail_set_backend_mail(mail, bbox);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen vmail->lost = !mail_set_uid(vmail->backend_mail, vrec->real_uid);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen memset(&vmail->imail.data, 0, sizeof(vmail->imail.data));
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen p_clear(vmail->imail.data_pool);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen vmail->imail.data.seq = seq;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen mail->seq = seq;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen mail_index_lookup_uid(mbox->ibox.view, seq, &mail->uid);
303a87c31cb4aa198326694e231df53a043e63c7Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen if (!vmail->lost) {
303a87c31cb4aa198326694e231df53a043e63c7Timo Sirainen mail->expunged = vmail->backend_mail->expunged;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen mail->has_nuls = vmail->backend_mail->has_nuls;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen mail->has_no_nuls = vmail->backend_mail->has_no_nuls;
303a87c31cb4aa198326694e231df53a043e63c7Timo Sirainen } else {
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen mail->expunged = TRUE;
303a87c31cb4aa198326694e231df53a043e63c7Timo Sirainen mail->has_nuls = FALSE;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen mail->has_no_nuls = FALSE;
f2bd9e507b8befdd95a983f86664febf5c19bd95Timo Sirainen }
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen}
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainenstatic bool virtual_mail_set_uid(struct mail *mail, uint32_t uid)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen{
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)mail->box;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen uint32_t seq;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (!mail_index_lookup_seq(mbox->ibox.view, uid, &seq))
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return FALSE;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen virtual_mail_set_seq(vmail->backend_mail, seq);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return TRUE;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen}
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainenstatic void virtual_mail_set_uid_cache_updates(struct mail *mail, bool set)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen{
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen p->v.set_uid_cache_updates(vmail->backend_mail, set);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen}
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenstatic int virtual_mail_handle_lost(struct virtual_mail *vmail)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen{
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (!vmail->lost)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return 0;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen mail_set_expunged(&vmail->imail.mail.mail);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return -1;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen}
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainenstatic int
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainenvirtual_mail_get_parts(struct mail *mail, const struct message_part **parts_r)
39e6fcc3e8b1ccb13087c232cb6bdea04d1a20a4Timo Sirainen{
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen return -1;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if (mail_get_parts(vmail->backend_mail, parts_r) < 0) {
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return -1;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen }
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return 0;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen}
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainenstatic int
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainenvirtual_mail_get_date(struct mail *mail, time_t *date_r, int *timezone_r)
39e6fcc3e8b1ccb13087c232cb6bdea04d1a20a4Timo Sirainen{
d64280bc41338078701e79aefaab3169686b683dTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen int tz;
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen if (timezone_r == NULL)
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen timezone_r = &tz;
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
0dab9cb35a976c49b28a11e28d5570f5191f1a7aMartti Rannanjärvi return -1;
ba5c8b0ae7460752adaf911901bf263788f62c72Phil Carmody if (mail_get_date(vmail->backend_mail, date_r, timezone_r) < 0) {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen return -1;
bc3698b8892df8003b410daea6f5bbcd20433808Timo Sirainen }
06e72c658de3ce1252594b151313df90acf73271Timo Sirainen return 0;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen}
06e72c658de3ce1252594b151313df90acf73271Timo Sirainen
06e72c658de3ce1252594b151313df90acf73271Timo Sirainenstatic int virtual_mail_get_received_date(struct mail *mail, time_t *date_r)
06e72c658de3ce1252594b151313df90acf73271Timo Sirainen{
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen return -1;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen if (mail_get_received_date(vmail->backend_mail, date_r) < 0) {
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return -1;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen }
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen return 0;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen}
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainenstatic int virtual_mail_get_save_date(struct mail *mail, time_t *date_r)
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen{
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen return -1;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen if (mail_get_save_date(vmail->backend_mail, date_r) < 0) {
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen return -1;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen }
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen return 0;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen}
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenstatic int virtual_mail_get_virtual_mail_size(struct mail *mail, uoff_t *size_r)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen{
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
07974f50bd55b06fd6d465f2c0e491794786e2faTimo Sirainen
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen return -1;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (mail_get_virtual_size(vmail->backend_mail, size_r) < 0) {
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen return -1;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen }
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen return 0;
07974f50bd55b06fd6d465f2c0e491794786e2faTimo Sirainen}
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
07974f50bd55b06fd6d465f2c0e491794786e2faTimo Sirainenstatic int virtual_mail_get_physical_size(struct mail *mail, uoff_t *size_r)
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen{
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi if (virtual_mail_handle_lost(vmail) < 0)
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi return -1;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen if (mail_get_physical_size(vmail->backend_mail, size_r) < 0) {
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen return -1;
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi }
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi return 0;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen}
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenstatic int
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainenvirtual_mail_get_first_header(struct mail *mail, const char *field,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen bool decode_to_utf8, const char **value_r)
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen{
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen
270f00aeab7bede38764291e21a314211b884ab4Timo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen return -1;
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainen if (p->v.get_first_header(vmail->backend_mail, field,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen decode_to_utf8, value_r) < 0) {
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return -1;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen }
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return 0;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen}
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
7891195e3975d554df183670dba1fcecfa0a30c3Timo Sirainenstatic int
7891195e3975d554df183670dba1fcecfa0a30c3Timo Sirainenvirtual_mail_get_headers(struct mail *mail, const char *field,
7891195e3975d554df183670dba1fcecfa0a30c3Timo Sirainen bool decode_to_utf8, const char *const **value_r)
7891195e3975d554df183670dba1fcecfa0a30c3Timo Sirainen{
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen return -1;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (p->v.get_headers(vmail->backend_mail, field,
89b3a53140d31bfa0f34378bf7ee1f52da954961Timo Sirainen decode_to_utf8, value_r) < 0) {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen return -1;
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen }
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return 0;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen}
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
bd74402ca1a39ec303075fefb1212d7e18a71531Timo Sirainenstatic int
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainenvirtual_mail_get_header_stream(struct mail *mail,
bd74402ca1a39ec303075fefb1212d7e18a71531Timo Sirainen struct mailbox_header_lookup_ctx *headers,
bd74402ca1a39ec303075fefb1212d7e18a71531Timo Sirainen struct istream **stream_r)
505561860cdfee4eac51469fd27a59983ef72e8eTimo Sirainen{
505561860cdfee4eac51469fd27a59983ef72e8eTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
505561860cdfee4eac51469fd27a59983ef72e8eTimo Sirainen struct mailbox_header_lookup_ctx *backend_headers;
505561860cdfee4eac51469fd27a59983ef72e8eTimo Sirainen int ret;
505561860cdfee4eac51469fd27a59983ef72e8eTimo Sirainen
505561860cdfee4eac51469fd27a59983ef72e8eTimo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
505561860cdfee4eac51469fd27a59983ef72e8eTimo Sirainen return -1;
270f00aeab7bede38764291e21a314211b884ab4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen backend_headers = mailbox_header_lookup_init(vmail->backend_mail->box,
c6ae908f6a2313573625d782bdd4e0ff3882c44aTimo Sirainen headers->headers);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen ret = mail_get_header_stream(vmail->backend_mail, backend_headers,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen stream_r);
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainen mailbox_header_lookup_unref(&backend_headers);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (ret < 0) {
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
ef11d3930c3602fc86349a4e3a53442df470b601Timo Sirainen return -1;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen }
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return 0;
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainen}
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
ef11d3930c3602fc86349a4e3a53442df470b601Timo Sirainenstatic int
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenvirtual_mail_get_stream(struct mail *mail, struct message_size *hdr_size,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct message_size *body_size,
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen struct istream **stream_r)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen{
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return -1;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (mail_get_stream(vmail->backend_mail, hdr_size, body_size,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen stream_r) < 0) {
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return -1;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen }
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return 0;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen}
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenstatic int
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenvirtual_mail_get_special(struct mail *mail, enum mail_fetch_field field,
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen const char **value_r)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen{
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct mailbox *box = vmail->backend_mail->box;
d64280bc41338078701e79aefaab3169686b683dTimo Sirainen
d64280bc41338078701e79aefaab3169686b683dTimo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
d64280bc41338078701e79aefaab3169686b683dTimo Sirainen return -1;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (field == MAIL_FETCH_MAILBOX_NAME) {
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen *value_r = p_strconcat(vmail->imail.data_pool,
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen box->list->ns->prefix,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen box->name, NULL);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return 0;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen }
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (mail_get_special(vmail->backend_mail, field, value_r) < 0) {
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen virtual_box_copy_error(mail->box, box);
270f00aeab7bede38764291e21a314211b884ab4Timo Sirainen return -1;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen }
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return 0;
59714981ae172b5113be7ca9b8be518b759fc86dTimo Sirainen}
59714981ae172b5113be7ca9b8be518b759fc86dTimo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenstatic void virtual_mail_update_pop3_uidl(struct mail *mail, const char *uidl)
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen{
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen mail_update_pop3_uidl(vmail->backend_mail, uidl);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen}
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainenstatic void virtual_mail_expunge(struct mail *mail)
d64280bc41338078701e79aefaab3169686b683dTimo Sirainen{
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
ccb77e2f63626ec46e5745ef4f38baa8e8e504fcTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen return;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen mail_expunge(vmail->backend_mail);
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen}
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainenstatic void
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainenvirtual_mail_set_cache_corrupted(struct mail *mail, enum mail_fetch_field field)
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen{
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen if (virtual_mail_handle_lost(vmail) < 0)
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen return;
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen mail_set_cache_corrupted(vmail->backend_mail, field);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen}
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainenstatic struct index_mail *virtual_mail_get_index_mail(struct mail *mail)
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen{
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen return (struct index_mail *)vmail->backend_mail;
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen}
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainenstruct mail_vfuncs virtual_mail_vfuncs = {
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen NULL,
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen virtual_mail_free,
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen virtual_mail_set_seq,
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen virtual_mail_set_uid,
23bdbb7b1831785c6ba6df190f6369da882d2b9dTimo Sirainen virtual_mail_set_uid_cache_updates,
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen
45c763dbebee268eda4a1e8bcc1ff82606b5ed0dTimo Sirainen index_mail_get_flags,
59714981ae172b5113be7ca9b8be518b759fc86dTimo Sirainen index_mail_get_keywords,
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen index_mail_get_keyword_indexes,
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen index_mail_get_modseq,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen virtual_mail_get_parts,
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen virtual_mail_get_date,
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen virtual_mail_get_received_date,
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen virtual_mail_get_save_date,
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen virtual_mail_get_virtual_mail_size,
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen virtual_mail_get_physical_size,
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen virtual_mail_get_first_header,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen virtual_mail_get_headers,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen virtual_mail_get_header_stream,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen virtual_mail_get_stream,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen virtual_mail_get_special,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen index_mail_update_flags,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen index_mail_update_keywords,
23bdbb7b1831785c6ba6df190f6369da882d2b9dTimo Sirainen index_mail_update_modseq,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen index_mail_update_uid,
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen virtual_mail_update_pop3_uidl,
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen virtual_mail_expunge,
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen virtual_mail_set_cache_corrupted,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen virtual_mail_get_index_mail
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen};
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen