virtual-mail.c revision 225e82df5dd1e765f4e52b80c954558f00e5a7df
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2008-2009 Dovecot authors, see the included COPYING file */
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger struct mailbox_header_lookup_ctx *wanted_headers;
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen /* currently active mail */
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen /* all allocated mails */
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen /* mail is lost if backend_mail doesn't point to correct mail */
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainenvirtual_mail_alloc(struct mailbox_transaction_context *t,
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen struct mailbox_header_lookup_ctx *wanted_headers)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)t->box;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen array_create(&vmail->imail.mail.module_contexts, pool,
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen sizeof(void *), 5);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen pool_alloconly_create("virtual index_mail", 512);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen vmail->imail.trans = (struct index_transaction_context *)t;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen i_array_init(&vmail->backend_mails, array_count(&mbox->backend_boxes));
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenstatic void virtual_mail_free(struct mail *mail)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen unsigned int i, count;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen mails = array_get_modifiable(&vmail->backend_mails, &count);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen for (i = 0; i < count; i++)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenstatic struct mail *
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenbackend_mail_find(struct virtual_mail *vmail, struct mailbox *box)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen unsigned int i, count;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen mails = array_get(&vmail->backend_mails, &count);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen for (i = 0; i < count; i++) {
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenvirtual_mail_set_backend_mail(struct mail *mail,
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;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen backend_trans = virtual_transaction_get(mail->transaction, bbox->box);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen backend_headers = vmail->wanted_headers == NULL ? NULL :
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen vmail->backend_mail = mail_alloc(backend_trans, vmail->wanted_fields,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen mailbox_header_lookup_unref(&backend_headers);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen array_append(&vmail->backend_mails, &vmail->backend_mail, 1);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenstatic void virtual_mail_set_seq(struct mail *mail, uint32_t seq)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)mail->box;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen mail_index_lookup_ext(mbox->ibox.view, seq, mbox->virtual_ext_id,
686ad6d723004b807fd558f3ef9d1f88afa7e127Timo Sirainen bbox = virtual_backend_box_lookup(mbox, vrec->mailbox_id);
303a87c31cb4aa198326694e231df53a043e63c7Timo Sirainen vmail->backend_mail = backend_mail_find(vmail, bbox->box);
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 mail_index_lookup_uid(mbox->ibox.view, seq, &mail->uid);
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;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainenstatic bool virtual_mail_set_uid(struct mail *mail, uint32_t uid)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)mail->box;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (!mail_index_lookup_seq(mbox->ibox.view, uid, &seq))
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen virtual_mail_set_seq(vmail->backend_mail, seq);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainenstatic void virtual_mail_set_uid_cache_updates(struct mail *mail, bool set)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen p->v.set_uid_cache_updates(vmail->backend_mail, set);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenstatic int virtual_mail_handle_lost(struct virtual_mail *vmail)
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainenvirtual_mail_get_parts(struct mail *mail, const struct message_part **parts_r)
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if (mail_get_parts(vmail->backend_mail, parts_r) < 0) {
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainenvirtual_mail_get_date(struct mail *mail, time_t *date_r, int *timezone_r)
d64280bc41338078701e79aefaab3169686b683dTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
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);
06e72c658de3ce1252594b151313df90acf73271Timo Sirainenstatic int virtual_mail_get_received_date(struct mail *mail, time_t *date_r)
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
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);
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainenstatic int virtual_mail_get_save_date(struct mail *mail, time_t *date_r)
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
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);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenstatic int virtual_mail_get_virtual_mail_size(struct mail *mail, uoff_t *size_r)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
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);
07974f50bd55b06fd6d465f2c0e491794786e2faTimo Sirainenstatic int virtual_mail_get_physical_size(struct mail *mail, uoff_t *size_r)
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
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 Sirainenvirtual_mail_get_first_header(struct mail *mail, const char *field,
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainen if (p->v.get_first_header(vmail->backend_mail, field,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
7891195e3975d554df183670dba1fcecfa0a30c3Timo Sirainenvirtual_mail_get_headers(struct mail *mail, const char *field,
7891195e3975d554df183670dba1fcecfa0a30c3Timo Sirainen bool decode_to_utf8, const char *const **value_r)
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen struct mail_private *p = (struct mail_private *)vmail->backend_mail;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (p->v.get_headers(vmail->backend_mail, field,
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainenvirtual_mail_get_header_stream(struct mail *mail,
505561860cdfee4eac51469fd27a59983ef72e8eTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
505561860cdfee4eac51469fd27a59983ef72e8eTimo Sirainen struct mailbox_header_lookup_ctx *backend_headers;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen backend_headers = mailbox_header_lookup_init(vmail->backend_mail->box,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen ret = mail_get_header_stream(vmail->backend_mail, backend_headers,
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainen mailbox_header_lookup_unref(&backend_headers);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenvirtual_mail_get_stream(struct mail *mail, struct message_size *hdr_size,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (mail_get_stream(vmail->backend_mail, hdr_size, body_size,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen virtual_box_copy_error(mail->box, vmail->backend_mail->box);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenvirtual_mail_get_special(struct mail *mail, enum mail_fetch_field field,
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen const char **value_r)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct mailbox *box = vmail->backend_mail->box;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen *value_r = p_strconcat(vmail->imail.data_pool,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (mail_get_special(vmail->backend_mail, field, value_r) < 0) {
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenstatic void virtual_mail_update_pop3_uidl(struct mail *mail, const char *uidl)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen mail_update_pop3_uidl(vmail->backend_mail, uidl);
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainenstatic void virtual_mail_expunge(struct mail *mail)
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainenvirtual_mail_set_cache_corrupted(struct mail *mail, enum mail_fetch_field field)
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen mail_set_cache_corrupted(vmail->backend_mail, field);
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainenstatic struct index_mail *virtual_mail_get_index_mail(struct mail *mail)
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen struct virtual_mail *vmail = (struct virtual_mail *)mail;
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen return (struct index_mail *)vmail->backend_mail;