Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8791:93c25cfe2760 HEAD
virtual: Added support for saving/copying messages to virtual mailboxes.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 26 Feb 2009 18:30:02 -0500 |
parents | 7224c45d4719 |
children | 75aed0ddfcb1 |
files | src/plugins/virtual/Makefile.am src/plugins/virtual/virtual-config.c src/plugins/virtual/virtual-mail.c src/plugins/virtual/virtual-save.c src/plugins/virtual/virtual-storage.c src/plugins/virtual/virtual-storage.h src/plugins/virtual/virtual-transaction.c src/plugins/virtual/virtual-transaction.h |
diffstat | 8 files changed, 179 insertions(+), 33 deletions(-) [+] |
line wrap: on
line diff
--- a/src/plugins/virtual/Makefile.am Thu Feb 26 18:29:18 2009 -0500 +++ b/src/plugins/virtual/Makefile.am Thu Feb 26 18:30:02 2009 -0500 @@ -17,12 +17,14 @@ virtual-plugin.c \ virtual-search.c \ virtual-storage.c \ + virtual-save.c \ virtual-sync.c \ virtual-transaction.c noinst_HEADERS = \ virtual-plugin.h \ - virtual-storage.h + virtual-storage.h \ + virtual-transaction.h install-exec-local: for d in imap pop3 lda; do \
--- a/src/plugins/virtual/virtual-config.c Thu Feb 26 18:29:18 2009 -0500 +++ b/src/plugins/virtual/virtual-config.c Thu Feb 26 18:30:02 2009 -0500 @@ -125,6 +125,14 @@ name = bbox->name[0] == '-' ? bbox->name + 1 : bbox->name; bbox->glob = imap_match_init(ctx->pool, name, TRUE, ctx->sep); ctx->have_wildcards = TRUE; + } else if (bbox->name[0] == '!') { + /* save messages here */ + if (ctx->mbox->save_bbox != NULL) { + *error_r = "Multiple save mailboxes defined"; + return -1; + } + bbox->name++; + ctx->mbox->save_bbox = bbox; } array_append(&ctx->mbox->backend_boxes, &bbox, 1); return 0;
--- a/src/plugins/virtual/virtual-mail.c Thu Feb 26 18:29:18 2009 -0500 +++ b/src/plugins/virtual/virtual-mail.c Thu Feb 26 18:30:02 2009 -0500 @@ -4,6 +4,7 @@ #include "array.h" #include "index-mail.h" #include "virtual-storage.h" +#include "virtual-transaction.h" struct virtual_mail { struct index_mail imail; @@ -75,13 +76,32 @@ return NULL; } +struct mail * +virtual_mail_set_backend_mail(struct mail *mail, + struct virtual_backend_box *bbox) +{ + struct virtual_mail *vmail = (struct virtual_mail *)mail; + struct mailbox_transaction_context *backend_trans; + struct mailbox_header_lookup_ctx *backend_headers; + + backend_trans = virtual_transaction_get(mail->transaction, bbox->box); + + backend_headers = vmail->wanted_headers == NULL ? NULL : + mailbox_header_lookup_init(bbox->box, + vmail->wanted_headers->headers); + vmail->backend_mail = mail_alloc(backend_trans, vmail->wanted_fields, + backend_headers); + if (backend_headers != NULL) + mailbox_header_lookup_unref(&backend_headers); + array_append(&vmail->backend_mails, &vmail->backend_mail, 1); + return vmail->backend_mail; +} + static void virtual_mail_set_seq(struct mail *mail, uint32_t seq) { struct virtual_mail *vmail = (struct virtual_mail *)mail; struct virtual_mailbox *mbox = (struct virtual_mailbox *)mail->box; struct virtual_backend_box *bbox; - struct mailbox_transaction_context *backend_trans; - struct mailbox_header_lookup_ctx *backend_headers; const struct virtual_mail_index_record *vrec; const void *data; bool expunged; @@ -92,20 +112,8 @@ bbox = virtual_backend_box_lookup(mbox, vrec->mailbox_id); vmail->backend_mail = backend_mail_find(vmail, bbox->box); - if (vmail->backend_mail == NULL) { - backend_trans = - virtual_transaction_get(mail->transaction, bbox->box); - - backend_headers = vmail->wanted_headers == NULL ? NULL : - mailbox_header_lookup_init(bbox->box, - vmail->wanted_headers->headers); - vmail->backend_mail = mail_alloc(backend_trans, - vmail->wanted_fields, - backend_headers); - if (backend_headers != NULL) - mailbox_header_lookup_unref(&backend_headers); - array_append(&vmail->backend_mails, &vmail->backend_mail, 1); - } + if (vmail->backend_mail == NULL) + virtual_mail_set_backend_mail(mail, bbox); if (!mail_set_uid(vmail->backend_mail, vrec->real_uid)) i_unreached(); memset(&vmail->imail.data, 0, sizeof(vmail->imail.data));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plugins/virtual/virtual-save.c Thu Feb 26 18:30:02 2009 -0500 @@ -0,0 +1,93 @@ +/* Copyright (c) 2009 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "virtual-transaction.h" +#include "virtual-storage.h" + +struct virtual_save_context { + struct mail_save_context ctx; + struct mail_save_context *backend_save_ctx; +}; + +struct mail_save_context * +virtual_save_alloc(struct mailbox_transaction_context *_t) +{ + struct virtual_transaction_context *t = + (struct virtual_transaction_context *)_t; + struct virtual_mailbox *mbox = (struct virtual_mailbox *)_t->box; + struct mailbox_transaction_context *backend_trans; + struct virtual_save_context *ctx; + + if (t->save_ctx != NULL) + return &t->save_ctx->ctx; + + ctx = t->save_ctx = i_new(struct virtual_save_context, 1); + ctx->ctx.transaction = &t->ictx.mailbox_ctx; + + if (mbox->save_bbox != NULL) { + backend_trans = + virtual_transaction_get(_t, mbox->save_bbox->box); + ctx->backend_save_ctx = mailbox_save_alloc(backend_trans); + } + return &ctx->ctx; +} + +int virtual_save_begin(struct mail_save_context *_ctx, struct istream *input) +{ + struct virtual_save_context *ctx = (struct virtual_save_context *)_ctx; + struct virtual_mailbox *mbox = + (struct virtual_mailbox *)_ctx->transaction->box; + struct mail *mail; + + if (ctx->backend_save_ctx == NULL) { + mail_storage_set_error(_ctx->transaction->box->storage, + MAIL_ERROR_NOTPOSSIBLE, + "Can't save messages to this virtual mailbox"); + return -1; + } + + mailbox_save_set_flags(ctx->backend_save_ctx, _ctx->flags, + _ctx->keywords); + mailbox_save_set_received_date(ctx->backend_save_ctx, + _ctx->received_date, + _ctx->received_tz_offset); + mailbox_save_set_from_envelope(ctx->backend_save_ctx, + _ctx->from_envelope); + mailbox_save_set_guid(ctx->backend_save_ctx, _ctx->guid); + + if (_ctx->dest_mail != NULL) { + mail = virtual_mail_set_backend_mail(_ctx->dest_mail, + mbox->save_bbox); + mailbox_save_set_dest_mail(ctx->backend_save_ctx, mail); + } + return mailbox_save_begin(&ctx->backend_save_ctx, input); +} + +int virtual_save_continue(struct mail_save_context *_ctx) +{ + struct virtual_save_context *ctx = (struct virtual_save_context *)_ctx; + + return mailbox_save_continue(ctx->backend_save_ctx); +} + +int virtual_save_finish(struct mail_save_context *_ctx) +{ + struct virtual_save_context *ctx = (struct virtual_save_context *)_ctx; + + return mailbox_save_finish(&ctx->backend_save_ctx); +} + +void virtual_save_cancel(struct mail_save_context *_ctx) +{ + struct virtual_save_context *ctx = (struct virtual_save_context *)_ctx; + + if (ctx->backend_save_ctx != NULL) + mailbox_save_cancel(&ctx->backend_save_ctx); +} + +void virtual_save_free(struct virtual_save_context *ctx) +{ + if (ctx->backend_save_ctx != NULL) + mailbox_save_cancel(&ctx->backend_save_ctx); + i_free(ctx); +}
--- a/src/plugins/virtual/virtual-storage.c Thu Feb 26 18:29:18 2009 -0500 +++ b/src/plugins/virtual/virtual-storage.c Thu Feb 26 18:30:02 2009 -0500 @@ -10,6 +10,7 @@ #include "mail-copy.h" #include "mail-search.h" #include "virtual-plugin.h" +#include "virtual-transaction.h" #include "virtual-storage.h" #include <stdio.h> @@ -668,11 +669,11 @@ virtual_search_deinit, virtual_search_next_nonblock, virtual_search_next_update_seq, - NULL, - NULL, - NULL, - NULL, - NULL, + virtual_save_alloc, + virtual_save_begin, + virtual_save_continue, + virtual_save_finish, + virtual_save_cancel, mail_storage_copy, index_storage_is_inconsistent }
--- a/src/plugins/virtual/virtual-storage.h Thu Feb 26 18:29:18 2009 -0500 +++ b/src/plugins/virtual/virtual-storage.h Thu Feb 26 18:30:02 2009 -0500 @@ -13,6 +13,8 @@ #define VIRTUAL_CONTEXT(obj) \ MODULE_CONTEXT(obj, virtual_storage_module) +struct virtual_save_context; + struct virtual_mail_index_header { /* Increased by one each time the header is modified */ uint32_t change_counter; @@ -108,6 +110,8 @@ /* Mailboxes this virtual mailbox consists of, sorted by mailbox_id */ ARRAY_TYPE(virtual_backend_box) backend_boxes; + /* backend mailbox where to save messages when saving to this mailbox */ + struct virtual_backend_box *save_bbox; ARRAY_TYPE(mailbox_virtual_patterns) list_include_patterns; ARRAY_TYPE(mailbox_virtual_patterns) list_exclude_patterns; @@ -129,9 +133,6 @@ virtual_backend_box_lookup_name(struct virtual_mailbox *mbox, const char *name); struct virtual_backend_box * virtual_backend_box_lookup(struct virtual_mailbox *mbox, uint32_t mailbox_id); -struct mailbox_transaction_context * -virtual_transaction_get(struct mailbox_transaction_context *trans, - struct mailbox *backend_box); struct mail_search_context * virtual_search_init(struct mailbox_transaction_context *t, @@ -146,10 +147,21 @@ virtual_mail_alloc(struct mailbox_transaction_context *t, enum mail_fetch_field wanted_fields, struct mailbox_header_lookup_ctx *wanted_headers); +struct mail * +virtual_mail_set_backend_mail(struct mail *mail, + struct virtual_backend_box *bbox); struct mailbox_sync_context * virtual_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags); +struct mail_save_context * +virtual_save_alloc(struct mailbox_transaction_context *t); +int virtual_save_begin(struct mail_save_context *ctx, struct istream *input); +int virtual_save_continue(struct mail_save_context *ctx); +int virtual_save_finish(struct mail_save_context *ctx); +void virtual_save_cancel(struct mail_save_context *ctx); +void virtual_save_free(struct virtual_save_context *ctx); + void virtual_copy_error(struct mail_storage *dest, struct mail_storage *src); void virtual_box_copy_error(struct mailbox *dest, struct mailbox *src);
--- a/src/plugins/virtual/virtual-transaction.c Thu Feb 26 18:29:18 2009 -0500 +++ b/src/plugins/virtual/virtual-transaction.c Thu Feb 26 18:30:02 2009 -0500 @@ -3,14 +3,7 @@ #include "lib.h" #include "array.h" #include "virtual-storage.h" - -struct virtual_transaction_context { - struct index_transaction_context ictx; - union mail_index_transaction_module_context module_ctx; - - ARRAY_DEFINE(backend_transactions, - struct mailbox_transaction_context *); -}; +#include "virtual-transaction.h" static void (*next_hook_mail_index_transaction_created) (struct mail_index_transaction *t) = NULL; @@ -44,6 +37,9 @@ unsigned int i, count; int ret = 0; + if (dt->save_ctx != NULL) + virtual_save_free(dt->save_ctx); + bt = array_get_modifiable(&dt->backend_transactions, &count); for (i = 0; i < count; i++) { if (mailbox_transaction_commit(&bt[i]) < 0) @@ -63,6 +59,9 @@ struct mailbox_transaction_context **bt; unsigned int i, count; + if (dt->save_ctx != NULL) + virtual_save_free(dt->save_ctx); + bt = array_get_modifiable(&dt->backend_transactions, &count); for (i = 0; i < count; i++) mailbox_transaction_rollback(&bt[i]);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plugins/virtual/virtual-transaction.h Thu Feb 26 18:30:02 2009 -0500 @@ -0,0 +1,23 @@ +#ifndef VIRTUAL_TRANSACTION_H +#define VIRTUAL_TRANSACTION_H + +#include "index-storage.h" + +struct virtual_transaction_context { + struct index_transaction_context ictx; + union mail_index_transaction_module_context module_ctx; + + struct virtual_save_context *save_ctx; + + ARRAY_DEFINE(backend_transactions, + struct mailbox_transaction_context *); +}; + +struct mailbox_transaction_context * +virtual_transaction_get(struct mailbox_transaction_context *trans, + struct mailbox *backend_box); + +void virtual_transaction_class_init(void); +void virtual_transaction_class_deinit(void); + +#endif