Mercurial > dovecot > core-2.2
changeset 9812:f751c23561f9 HEAD
Added a notify plugin that can be used as a generic event catching framework by other plugins.
Patch by Mark Washenberger / Rackspace.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 24 Aug 2009 16:57:50 -0400 |
parents | 211853d48eaf |
children | d1cdc927ea3c |
files | configure.in src/plugins/Makefile.am src/plugins/notify/Makefile.am src/plugins/notify/notify-noop.c src/plugins/notify/notify-plugin-private.h src/plugins/notify/notify-plugin.c src/plugins/notify/notify-plugin.h src/plugins/notify/notify-storage.c |
diffstat | 8 files changed, 677 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.in Mon Aug 24 16:55:12 2009 -0400 +++ b/configure.in Mon Aug 24 16:57:50 2009 -0400 @@ -2506,6 +2506,7 @@ src/plugins/listescape/Makefile src/plugins/mail-log/Makefile src/plugins/mbox-snarf/Makefile +src/plugins/notify/Makefile src/plugins/quota/Makefile src/plugins/imap-quota/Makefile src/plugins/trash/Makefile
--- a/src/plugins/Makefile.am Mon Aug 24 16:55:12 2009 -0400 +++ b/src/plugins/Makefile.am Mon Aug 24 16:57:50 2009 -0400 @@ -22,6 +22,7 @@ listescape \ mail-log \ mbox-snarf \ + notify \ quota \ imap-quota \ trash \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plugins/notify/Makefile.am Mon Aug 24 16:57:50 2009 -0400 @@ -0,0 +1,29 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-mail \ + -I$(top_srcdir)/src/lib-imap \ + -I$(top_srcdir)/src/lib-index \ + -I$(top_srcdir)/src/lib-storage \ + -I$(top_srcdir)/src/lib-storage/index \ + -I$(top_srcdir)/src/lib-storage/index/maildir + +lib15_notify_plugin_la_LDFLAGS = -module -avoid-version + +module_LTLIBRARIES = \ + lib15_notify_plugin.la + +lib15_notify_plugin_la_SOURCES = \ + notify-plugin.c \ + notify-noop.c \ + notify-storage.c + +noinst_HEADERS = \ + notify-plugin.h + notify-plugin-private.h + +install-exec-local: + for d in imap pop3 lda; do \ + $(mkdir_p) $(DESTDIR)$(moduledir)/$$d; \ + rm -f $(DESTDIR)$(moduledir)/$$d/lib15_notify_plugin$(MODULE_SUFFIX); \ + $(LN_S) ../lib15_notify_plugin$(MODULE_SUFFIX) $(DESTDIR)$(moduledir)/$$d; \ + done
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plugins/notify/notify-noop.c Mon Aug 24 16:57:50 2009 -0400 @@ -0,0 +1,32 @@ +#include "lib.h" +#include "mail-types.h" +#include "notify-plugin.h" + +void notify_noop_mail_transaction_begin(struct mailbox_transaction_context *t ATTR_UNUSED) {} +void notify_noop_mail_save(void *txn ATTR_UNUSED, + struct mail *mail ATTR_UNUSED) {} +void notify_noop_mail_copy(void *txn ATTR_UNUSED, + struct mail *src ATTR_UNUSED, + struct mail *dst ATTR_UNUSED) {} +void notify_noop_mail_expunge(void *txn ATTR_UNUSED, + struct mail *mail ATTR_UNUSED) {} +void notify_noop_mail_update_flags(void *txn ATTR_UNUSED, + struct mail *mail ATTR_UNUSED, + enum mail_flags old_flags ATTR_UNUSED) {} +void notify_noop_mail_update_keywords(void *txn ATTR_UNUSED, + struct mail *mail ATTR_UNUSED, + const char *const *old_keywords ATTR_UNUSED) {} +void notify_noop_mail_transaction_commit(void *txn ATTR_UNUSED, + struct mail_transaction_commit_changes *changes ATTR_UNUSED) {} +void notify_noop_mail_transaction_rollback(void *txn ATTR_UNUSED) {} +void *notify_noop_mailbox_delete_begin(struct mailbox_list *list ATTR_UNUSED, + const char *name ATTR_UNUSED) { return NULL; } +void notify_noop_mailbox_delete_commit(void *txn ATTR_UNUSED, + struct mailbox_list *list ATTR_UNUSED, + const char *name ATTR_UNUSED) {} +void notify_noop_mailbox_delete_rollback(void *txn ATTR_UNUSED) {} +void notify_noop_mailbox_rename(struct mailbox_list *oldlist ATTR_UNUSED, + const char *oldname ATTR_UNUSED, + struct mailbox_list *newlist ATTR_UNUSED, + const char *newname ATTR_UNUSED, + bool rename_children ATTR_UNUSED) {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plugins/notify/notify-plugin-private.h Mon Aug 24 16:57:50 2009 -0400 @@ -0,0 +1,30 @@ +#ifndef NOTIFY_PLUGIN_PRIVATE_H +#define NOTIFY_PLUGIN_PRIVATE_H + +#include "notify-plugin.h" + +void notify_contexts_mail_transaction_begin(struct mailbox_transaction_context *t); +void notify_contexts_mail_save(struct mail *mail); +void notify_contexts_mail_copy(struct mail *src, struct mail *dst); +void notify_contexts_mail_expunge(struct mail *mail); +void notify_contexts_mail_update_flags(struct mail *mail, + enum mail_flags old_flags); +void notify_contexts_mail_update_keywords(struct mail *mail, + const char *const *old_keywords); +void notify_contexts_mail_transaction_commit(struct mailbox_transaction_context *t, + struct mail_transaction_commit_changes *changes); +void notify_contexts_mail_transaction_rollback(struct mailbox_transaction_context *t); +void notify_contexts_mailbox_delete_begin(struct mailbox_list *list, + const char *name); +void notify_contexts_mailbox_delete_commit(struct mailbox_list *list, + const char *name); +void notify_contexts_mailbox_delete_rollback(void); +void notify_contexts_mailbox_rename(struct mailbox_list *oldlist, + const char *oldname, + struct mailbox_list *newlist, + const char *newname, bool rename_children); + +void notify_plugin_init_storage(void); +void notify_plugin_deinit_storage(void); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plugins/notify/notify-plugin.c Mon Aug 24 16:57:50 2009 -0400 @@ -0,0 +1,210 @@ +#include "lib.h" +#include "llist.h" +#include "mail-storage.h" +#include "notify-plugin-private.h" + +#include <stdlib.h> + +struct notify_mail_txn { + struct notify_mail_txn *prev, *next; + struct mailbox_transaction_context *parent_mailbox_txn; + struct mail *tmp_mail; + void *txn; +}; + +struct notify_context { + struct notify_context *prev, *next; + struct notify_vfuncs v; + struct notify_mail_txn *mail_txn_list; + void *mailbox_delete_txn; +}; + +static struct notify_context *ctx_list = NULL; + +static struct notify_mail_txn * +notify_context_find_mail_txn(struct notify_context *ctx, + struct mailbox_transaction_context *t) +{ + struct notify_mail_txn *mail_txn = ctx->mail_txn_list; + + for (; mail_txn != NULL; mail_txn = mail_txn->next) { + if (mail_txn->parent_mailbox_txn == t) + return mail_txn; + } + i_panic("no notify_mail_txn found"); +} + +void notify_contexts_mail_transaction_begin(struct mailbox_transaction_context *t) +{ + struct notify_context *ctx; + struct notify_mail_txn *mail_txn; + + for (ctx = ctx_list; ctx != NULL; ctx = ctx->next) { + mail_txn = i_new(struct notify_mail_txn, 1); + mail_txn->parent_mailbox_txn = t; + mail_txn->txn = ctx->v.mail_transaction_begin(t); + DLLIST_PREPEND(&ctx->mail_txn_list, mail_txn); + } +} + +void notify_contexts_mail_save(struct mail *mail) +{ + struct notify_context *ctx; + struct notify_mail_txn *mail_txn; + + for (ctx = ctx_list; ctx != NULL; ctx = ctx->next) { + mail_txn = notify_context_find_mail_txn(ctx, mail->transaction); + ctx->v.mail_save(mail_txn->txn, mail); + } +} + +void notify_contexts_mail_copy(struct mail *src, struct mail *dst) +{ + struct notify_context *ctx; + struct notify_mail_txn *mail_txn; + + for (ctx = ctx_list; ctx != NULL; ctx = ctx->next) { + mail_txn = notify_context_find_mail_txn(ctx, dst->transaction); + ctx->v.mail_copy(mail_txn->txn, src, dst); + } +} + +void notify_contexts_mail_expunge(struct mail *mail) +{ + struct notify_context *ctx; + struct notify_mail_txn *mail_txn; + + for (ctx = ctx_list; ctx != NULL; ctx = ctx->next) { + mail_txn = notify_context_find_mail_txn(ctx, mail->transaction); + ctx->v.mail_expunge(mail_txn->txn, mail); + } +} + +void notify_contexts_mail_update_flags(struct mail *mail, + enum mail_flags old_flags) +{ + struct notify_context *ctx; + struct notify_mail_txn *mail_txn; + + for (ctx = ctx_list; ctx != NULL; ctx = ctx->next) { + mail_txn = notify_context_find_mail_txn(ctx, mail->transaction); + ctx->v.mail_update_flags(mail_txn->txn, mail, old_flags); + } +} + +void notify_contexts_mail_update_keywords(struct mail *mail, + const char *const *old_keywords) +{ + struct notify_context *ctx; + struct notify_mail_txn *mail_txn; + + for (ctx = ctx_list; ctx != NULL; ctx = ctx->next) { + mail_txn = notify_context_find_mail_txn(ctx, mail->transaction); + ctx->v.mail_update_keywords(mail_txn->txn, mail, old_keywords); + } +} + +void notify_contexts_mail_transaction_commit(struct mailbox_transaction_context *t, + struct mail_transaction_commit_changes *changes) +{ + struct notify_context *ctx; + struct notify_mail_txn *mail_txn; + + for (ctx = ctx_list; ctx != NULL; ctx = ctx->next) { + mail_txn = notify_context_find_mail_txn(ctx, t); + ctx->v.mail_transaction_commit(mail_txn->txn, changes); + DLLIST_REMOVE(&ctx->mail_txn_list, mail_txn); + i_free(mail_txn); + } +} + +void notify_contexts_mail_transaction_rollback(struct mailbox_transaction_context *t) +{ + struct notify_context *ctx; + struct notify_mail_txn *mail_txn; + + for (ctx = ctx_list; ctx != NULL; ctx = ctx->next) { + mail_txn = notify_context_find_mail_txn(ctx, t); + ctx->v.mail_transaction_rollback(mail_txn->txn); + DLLIST_REMOVE(&ctx->mail_txn_list, mail_txn); + i_free(mail_txn); + } +} + +void notify_contexts_mailbox_delete_begin(struct mailbox_list *list, + const char *name) +{ + struct notify_context *ctx; + + for (ctx = ctx_list; ctx != NULL; ctx = ctx->next) { + ctx->mailbox_delete_txn = + ctx->v.mailbox_delete_begin(list, name); + } +} + +void notify_contexts_mailbox_delete_commit(struct mailbox_list *list, + const char *name) +{ + struct notify_context *ctx; + + for (ctx = ctx_list; ctx != NULL; ctx = ctx->next) { + ctx->v.mailbox_delete_commit(ctx->mailbox_delete_txn, + list, name); + ctx->mailbox_delete_txn = NULL; + } +} + +void notify_contexts_mailbox_delete_rollback(void) +{ + struct notify_context *ctx; + + for (ctx = ctx_list; ctx != NULL; ctx = ctx->next) { + ctx->v.mailbox_delete_rollback(ctx->mailbox_delete_txn); + ctx->mailbox_delete_txn = NULL; + } +} + +void notify_contexts_mailbox_rename(struct mailbox_list *oldlist, + const char *oldname, + struct mailbox_list *newlist, + const char *newname, bool rename_children) +{ + struct notify_context *ctx; + + for (ctx = ctx_list; ctx != NULL; ctx = ctx->next) { + ctx->v.mailbox_rename(oldlist, oldname, newlist, newname, + rename_children); + } +} + +struct notify_context * +notify_register(const struct notify_vfuncs *v) +{ + struct notify_context *ctx; + + ctx = i_new(struct notify_context, 1); + ctx->v = *v; + DLLIST_PREPEND(&ctx_list, ctx); + return ctx; +} + +void notify_unregister(struct notify_context *ctx) +{ + struct notify_mail_txn *mail_txn = ctx->mail_txn_list; + + for (; mail_txn != NULL; mail_txn = mail_txn->next) + ctx->v.mail_transaction_rollback(mail_txn->txn); + ctx->v.mailbox_delete_rollback(ctx->mailbox_delete_txn); + DLLIST_REMOVE(&ctx_list, ctx); + i_free(ctx); +} + +void notify_plugin_init(void) +{ + notify_plugin_init_storage(); +} + +void notify_plugin_deinit(void) +{ + notify_plugin_deinit_storage(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plugins/notify/notify-plugin.h Mon Aug 24 16:57:50 2009 -0400 @@ -0,0 +1,63 @@ +#ifndef NOTIFY_PLUGIN_H +#define NOTIFY_PLUGIN_H + +enum mail_flags; +struct mail; +struct mail_transaction_commit_changes; +struct mail_storage; +struct mailbox_transaction_context; +struct mailbox_list; +struct notify_context; + +struct notify_vfuncs { + void *(*mail_transaction_begin)(struct mailbox_transaction_context *t); + void (*mail_save)(void *txn, struct mail *mail); + void (*mail_copy)(void *txn, struct mail *src, struct mail *dst); + void (*mail_expunge)(void *txn, struct mail *mail); + void (*mail_update_flags)(void *txn, struct mail *mail, + enum mail_flags old_flags); + void (*mail_update_keywords)(void *txn, struct mail *mail, + const char *const *old_keywords); + void (*mail_transaction_commit)(void *txn, + struct mail_transaction_commit_changes *changes); + void (*mail_transaction_rollback)(void *txn); + void *(*mailbox_delete_begin)(struct mailbox_list *list, + const char *name); + void (*mailbox_delete_commit)(void *txn, struct mailbox_list *list, + const char *name); + void (*mailbox_delete_rollback)(void *txn); + void (*mailbox_rename)(struct mailbox_list *oldlist, + const char *oldname, + struct mailbox_list *newlist, + const char *newname, bool rename_children); +}; + +void notify_noop_mail_transaction_begin(struct mailbox_transaction_context *t); +void notify_noop_mail_save(void *txn, struct mail *mail); +void notify_noop_mail_copy(void *txn, struct mail *src, struct mail *dst); +void notify_noop_mail_expunge(void *txn, struct mail *mail); +void notify_noop_mail_update_flags(void *txn, struct mail *mail, + enum mail_flags old_flags); +void notify_noop_mail_update_keywords(void *txn, struct mail *mail, + const char *const *old_keywords); +void notify_noop_mail_transaction_commit(void *txn, + struct mail_transaction_commit_changes *changes); +void notify_noop_mail_transaction_rollback(void *txn); +void *notify_noop_mailbox_delete_begin(struct mailbox_list *list, + const char *name); +void notify_noop_mailbox_delete_commit(void *txn, struct mailbox_list *list, + const char *name); +void notify_noop_mailbox_delete_rollback(void *txn); +void notify_noop_mailbox_rename(struct mailbox_list *oldlist, + const char *oldname, + struct mailbox_list *newlist, + const char *newname, bool rename_children); + +struct notify_context * +notify_register(const struct notify_vfuncs *vfuncs); +void notify_unregister(struct notify_context *ctx); + +void notify_plugin_init(void); +void notify_plugin_deinit(void); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plugins/notify/notify-storage.c Mon Aug 24 16:57:50 2009 -0400 @@ -0,0 +1,311 @@ +#include "lib.h" +#include "array.h" +#include "mail-storage-private.h" +#include "mailbox-list-private.h" +#include "notify-plugin-private.h" + +#define NOTIFY_CONTEXT(obj) \ + MODULE_CONTEXT(obj, notify_storage_module) +#define NOTIFY_MAIL_CONTEXT(obj) \ + MODULE_CONTEXT(obj, notify_mail_module) +#define NOTIFY_LIST_CONTEXT(obj) \ + MODULE_CONTEXT(obj, notify_mailbox_list_module) + +struct notify_transaction_context { + union mailbox_transaction_module_context module_ctx; + struct mail *tmp_mail; + bool save_hack; +}; + +static MODULE_CONTEXT_DEFINE_INIT(notify_storage_module, + &mail_storage_module_register); +static MODULE_CONTEXT_DEFINE_INIT(notify_mail_module, + &mail_module_register); +static MODULE_CONTEXT_DEFINE_INIT(notify_mailbox_list_module, + &mailbox_list_module_register); + +static void (*notify_next_hook_mail_storage_created) + (struct mail_storage *storage); +static void (*notify_next_hook_mailbox_list_created) + (struct mailbox_list *list); + +static void +notify_mail_expunge(struct mail *_mail) +{ + struct mail_private *mail = (struct mail_private *)_mail; + union mail_module_context *lmail = NOTIFY_MAIL_CONTEXT(mail); + + notify_contexts_mail_expunge(_mail); + lmail->super.expunge(_mail); +} + +static void +notify_mail_update_flags(struct mail *_mail, enum modify_type modify_type, + enum mail_flags flags) +{ + struct mail_private *mail = (struct mail_private *)_mail; + union mail_module_context *lmail = NOTIFY_MAIL_CONTEXT(mail); + enum mail_flags old_flags, new_flags; + + old_flags = mail_get_flags(_mail); + lmail->super.update_flags(_mail, modify_type, flags); + new_flags = mail_get_flags(_mail); + + if ((old_flags ^ new_flags) == 0) + return; + + notify_contexts_mail_update_flags(_mail, old_flags); +} + +static void +notify_mail_update_keywords(struct mail *_mail, enum modify_type modify_type, + struct mail_keywords *keywords) +{ + struct mail_private *mail = (struct mail_private *)_mail; + union mail_module_context *lmail = NOTIFY_MAIL_CONTEXT(mail); + const char *const *old_keywords, *const *new_keywords; + unsigned int i; + + old_keywords = mail_get_keywords(_mail); + lmail->super.update_keywords(_mail, modify_type, keywords); + new_keywords = mail_get_keywords(_mail); + + for (i = 0; old_keywords[i] != NULL && new_keywords[i] != NULL; i++) { + if (strcmp(old_keywords[i], new_keywords[i]) != 0) + break; + } + + if (old_keywords[i] == NULL && new_keywords[i] == NULL) + return; + + notify_contexts_mail_update_keywords(_mail, old_keywords); +} + +static struct mail * +notify_mail_alloc(struct mailbox_transaction_context *t, + enum mail_fetch_field wanted_fields, + struct mailbox_header_lookup_ctx *wanted_headers) +{ + union mailbox_module_context *lbox = NOTIFY_CONTEXT(t->box); + union mail_module_context *lmail; + struct mail *_mail; + struct mail_private *mail; + + _mail = lbox->super.mail_alloc(t, wanted_fields, wanted_headers); + mail = (struct mail_private *)_mail; + + lmail = p_new(mail->pool, union mail_module_context, 1); + lmail->super = mail->v; + + mail->v.expunge = notify_mail_expunge; + mail->v.update_flags = notify_mail_update_flags; + mail->v.update_keywords = notify_mail_update_keywords; + MODULE_CONTEXT_SET_SELF(mail, notify_mail_module, lmail); + return _mail; +} + +static int +notify_copy(struct mail_save_context *ctx, struct mail *mail) +{ + struct notify_transaction_context *lt = + NOTIFY_CONTEXT(ctx->transaction); + union mailbox_module_context *lbox = + NOTIFY_CONTEXT(ctx->transaction->box); + int ret; + + if (ctx->dest_mail == NULL) { + if (lt->tmp_mail == NULL) + lt->tmp_mail = mail_alloc(ctx->transaction, 0, NULL); + ctx->dest_mail = lt->tmp_mail; + } + + lt->save_hack = TRUE; + ret = lbox->super.copy(ctx, mail); + lt->save_hack = FALSE; + + if (ret == 0) + notify_contexts_mail_copy(mail, ctx->dest_mail); + return ret; +} + +static int +notify_save_begin(struct mail_save_context *ctx, struct istream *input) +{ + struct notify_transaction_context *lt = + NOTIFY_CONTEXT(ctx->transaction); + union mailbox_module_context *lbox = + NOTIFY_CONTEXT(ctx->transaction->box); + + if (ctx->dest_mail == NULL) { + if (lt->tmp_mail == NULL) + lt->tmp_mail = mail_alloc(ctx->transaction, 0, NULL); + ctx->dest_mail = lt->tmp_mail; + } + return lbox->super.save_begin(ctx, input); +} + +static int +notify_save_finish(struct mail_save_context *ctx) +{ + struct notify_transaction_context *lt = + NOTIFY_CONTEXT(ctx->transaction); + union mailbox_module_context *lbox = + NOTIFY_CONTEXT(ctx->transaction->box); + + if (lbox->super.save_finish(ctx) < 0) + return -1; + if (!lt->save_hack) + notify_contexts_mail_save(ctx->dest_mail); + return 0; +} + +static struct mailbox_transaction_context * +notify_transaction_begin(struct mailbox *box, + enum mailbox_transaction_flags flags) +{ + union mailbox_module_context *lbox = NOTIFY_CONTEXT(box); + struct mailbox_transaction_context *t; + struct notify_transaction_context *lt; + + t = lbox->super.transaction_begin(box, flags); + + lt = i_new(struct notify_transaction_context, 1); + MODULE_CONTEXT_SET(t, notify_storage_module, lt); + + notify_contexts_mail_transaction_begin(t); + return t; +} + +static int +notify_transaction_commit(struct mailbox_transaction_context *t, + struct mail_transaction_commit_changes *changes_r) +{ + struct notify_transaction_context *lt = NOTIFY_CONTEXT(t); + union mailbox_module_context *lbox = NOTIFY_CONTEXT(t->box); + + if (lt->tmp_mail != NULL) + mail_free(<->tmp_mail); + i_free(lt); + + if ((lbox->super.transaction_commit(t, changes_r)) < 0) { + notify_contexts_mail_transaction_rollback(t); + return -1; + } + + notify_contexts_mail_transaction_commit(t, changes_r); + return 0; +} + +static void +notify_transaction_rollback(struct mailbox_transaction_context *t) +{ + struct notify_transaction_context *lt = NOTIFY_CONTEXT(t); + union mailbox_module_context *lbox = NOTIFY_CONTEXT(t->box); + + if (lt->tmp_mail != NULL) + mail_free(<->tmp_mail); + i_free(lt); + + notify_contexts_mail_transaction_rollback(t); + lbox->super.transaction_rollback(t); +} + +static struct mailbox * +notify_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list, + const char *name, struct istream *input, + enum mailbox_flags flags) +{ + union mail_storage_module_context *lstorage = NOTIFY_CONTEXT(storage); + struct mailbox *box; + union mailbox_module_context *lbox; + + box = lstorage->super.mailbox_alloc(storage, list, name, input, flags); + + lbox = p_new(box->pool, union mailbox_module_context, 1); + lbox->super = box->v; + + box->v.mail_alloc = notify_mail_alloc; + box->v.copy = notify_copy; + box->v.save_begin = notify_save_begin; + box->v.save_finish = notify_save_finish; + box->v.transaction_begin = notify_transaction_begin; + box->v.transaction_commit = notify_transaction_commit; + box->v.transaction_rollback = notify_transaction_rollback; + MODULE_CONTEXT_SET_SELF(box, notify_storage_module, lbox); + return box; +} + +static int +notify_mailbox_list_delete(struct mailbox_list *list, const char *name) +{ + union mailbox_list_module_context *llist = NOTIFY_LIST_CONTEXT(list); + + notify_contexts_mailbox_delete_begin(list, name); + if (llist->super.delete_mailbox(list, name) < 0) { + notify_contexts_mailbox_delete_rollback(); + return -1; + } + notify_contexts_mailbox_delete_commit(list, name); + return 0; +} + +static int +notify_mailbox_list_rename(struct mailbox_list *oldlist, const char *oldname, + struct mailbox_list *newlist, const char *newname, + bool rename_children) +{ + union mailbox_list_module_context *oldllist = + NOTIFY_LIST_CONTEXT(oldlist); + + if (oldllist->super.rename_mailbox(oldlist, oldname, newlist, newname, + rename_children) < 0) + return -1; + + notify_contexts_mailbox_rename(oldlist, oldname, newlist, newname, + rename_children); + return 0; +} + +static void notify_mail_storage_created(struct mail_storage *storage) +{ + union mail_storage_module_context *lstorage; + + lstorage = p_new(storage->pool, union mail_storage_module_context, 1); + lstorage->super = storage->v; + storage->v.mailbox_alloc = notify_mailbox_alloc; + + MODULE_CONTEXT_SET_SELF(storage, notify_storage_module, lstorage); + + if (notify_next_hook_mail_storage_created != NULL) + notify_next_hook_mail_storage_created(storage); +} + +static void notify_mailbox_list_created(struct mailbox_list *list) +{ + union mailbox_list_module_context *llist; + + llist = p_new(list->pool, union mailbox_list_module_context, 1); + llist->super = list->v; + list->v.delete_mailbox = notify_mailbox_list_delete; + list->v.rename_mailbox = notify_mailbox_list_rename; + + MODULE_CONTEXT_SET_SELF(list, notify_mailbox_list_module, llist); + + if (notify_next_hook_mailbox_list_created != NULL) + notify_next_hook_mailbox_list_created(list); +} + +void notify_plugin_init_storage(void) +{ + notify_next_hook_mail_storage_created = hook_mail_storage_created; + hook_mail_storage_created = notify_mail_storage_created; + + notify_next_hook_mailbox_list_created = hook_mailbox_list_created; + hook_mailbox_list_created = notify_mailbox_list_created; +} + +void notify_plugin_deinit_storage(void) +{ + hook_mail_storage_created = notify_next_hook_mail_storage_created; + hook_mailbox_list_created = notify_next_hook_mailbox_list_created; +}