bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2015-2018 Dovecot authors, see the included COPYING file */
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#include "lib.h"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#include "array.h"
a44595f7b1afc7ccbd8653598753b32899d01c76Timo Sirainen#include "ioloop.h"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#include "mail-namespace.h"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#include "mail-storage.h"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#include "mail-storage-private.h"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#include "notify-plugin.h"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#include "str.h"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#include "push-notification-drivers.h"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#include "push-notification-events.h"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#include "push-notification-events-rfc5423.h"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#include "push-notification-plugin.h"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#include "push-notification-triggers.h"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#include "push-notification-txn-mbox.h"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#include "push-notification-txn-msg.h"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#define PUSH_NOTIFICATION_CONFIG "push_notification_driver"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#define PUSH_NOTIFICATION_CONFIG_OLD "push_notification_backend"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#define PUSH_NOTIFICATION_USER_CONTEXT(obj) \
d567cc27913a45c893b4c091f84b496854d814e7Aki Tuomi MODULE_CONTEXT_REQUIRE(obj, push_notification_user_module)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic MODULE_CONTEXT_DEFINE_INIT(push_notification_user_module,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz &mail_user_module_register);
a44595f7b1afc7ccbd8653598753b32899d01c76Timo Sirainenstatic struct ioloop *main_ioloop;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarzstatic void
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarzpush_notification_transaction_init(struct push_notification_txn *ptxn)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct push_notification_driver_txn *dtxn;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct push_notification_driver_user **duser;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct mail_storage *storage;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz if (ptxn->initialized) {
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz return;
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz }
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz ptxn->initialized = TRUE;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz storage = mailbox_get_storage(ptxn->mbox);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz if (storage->user->autocreated &&
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz (strcmp(storage->name, "raw") == 0)) {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz /* no notifications for autocreated raw users */
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz return;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz }
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz array_foreach_modifiable(&ptxn->puser->driverlist->drivers, duser) {
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz dtxn = p_new(ptxn->pool, struct push_notification_driver_txn, 1);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz dtxn->duser = *duser;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz dtxn->ptxn = ptxn;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz if ((dtxn->duser->driver->v.begin_txn == NULL) ||
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz dtxn->duser->driver->v.begin_txn(dtxn)) {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz array_append(&ptxn->drivers, &dtxn, 1);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz }
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz }
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz}
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarzstatic struct push_notification_txn *
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarzpush_notification_transaction_create(struct mailbox *box,
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz struct mailbox_transaction_context *t)
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz{
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz pool_t pool;
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz struct push_notification_txn *ptxn;
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz struct mail_storage *storage;
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz pool = pool_alloconly_create("push notification transaction", 2048);
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz ptxn = p_new(pool, struct push_notification_txn, 1);
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz ptxn->mbox = box;
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz storage = mailbox_get_storage(box);
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz ptxn->muser = mail_storage_get_user(storage);
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz ptxn->pool = pool;
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz ptxn->puser = PUSH_NOTIFICATION_USER_CONTEXT(ptxn->muser);
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz ptxn->t = t;
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz ptxn->trigger = PUSH_NOTIFICATION_EVENT_TRIGGER_NONE;
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz p_array_init(&ptxn->drivers, pool, 4);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz return ptxn;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_transaction_end
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz(struct push_notification_txn *ptxn, bool success)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct push_notification_driver_txn **dtxn;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz if (ptxn->initialized) {
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz array_foreach_modifiable(&ptxn->drivers, dtxn) {
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz if ((*dtxn)->duser->driver->v.end_txn != NULL) {
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz (*dtxn)->duser->driver->v.end_txn(*dtxn, success);
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz }
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz }
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz }
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz pool_unref(&ptxn->pool);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_transaction_commit
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz(void *txn, struct mail_transaction_commit_changes *changes)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct push_notification_txn *ptxn = (struct push_notification_txn *)txn;
a44595f7b1afc7ccbd8653598753b32899d01c76Timo Sirainen struct ioloop *prev_ioloop = current_ioloop;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
a44595f7b1afc7ccbd8653598753b32899d01c76Timo Sirainen /* Make sure we're not in just any random ioloop, which could get
a44595f7b1afc7ccbd8653598753b32899d01c76Timo Sirainen destroyed soon. This way the push-notification drivers can do async
a44595f7b1afc7ccbd8653598753b32899d01c76Timo Sirainen operations that finish in the main ioloop. */
a44595f7b1afc7ccbd8653598753b32899d01c76Timo Sirainen io_loop_set_current(main_ioloop);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz if (changes == NULL) {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_txn_mbox_end(ptxn);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz } else {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_txn_msg_end(ptxn, changes);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz }
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_transaction_end(ptxn, TRUE);
a44595f7b1afc7ccbd8653598753b32899d01c76Timo Sirainen io_loop_set_current(prev_ioloop);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_mailbox_create(struct mailbox *box)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct push_notification_txn *ptxn;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz ptxn = push_notification_transaction_create(box, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_trigger_mbox_create(ptxn, box, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_transaction_commit(ptxn, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_mailbox_delete(void *txn ATTR_UNUSED,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct mailbox *box)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct push_notification_txn *ptxn;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz ptxn = push_notification_transaction_create(box, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_trigger_mbox_delete(ptxn, box, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_transaction_commit(ptxn, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_mailbox_rename(struct mailbox *src,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct mailbox *dest)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct push_notification_txn *ptxn;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz ptxn = push_notification_transaction_create(dest, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_trigger_mbox_rename(ptxn, src, dest, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_transaction_commit(ptxn, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_mailbox_subscribe(struct mailbox *box,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz bool subscribed)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct push_notification_txn *ptxn;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz ptxn = push_notification_transaction_create(box, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_trigger_mbox_subscribe(ptxn, box, subscribed, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_transaction_commit(ptxn, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_mail_save(void *txn, struct mail *mail)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
4ee5a85e75d520497bd43dbfcc6fc273f3e57ceaMichael Slusarz struct push_notification_txn *ptxn = txn;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz push_notification_transaction_init(ptxn);
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz
4ee5a85e75d520497bd43dbfcc6fc273f3e57ceaMichael Slusarz /* POST_SESSION means MTA delivery. */
23bdbb7b1831785c6ba6df190f6369da882d2b9dTimo Sirainen if ((mail->box->flags & MAILBOX_FLAG_POST_SESSION) != 0) {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_trigger_msg_save_new(ptxn, mail, NULL);
4ee5a85e75d520497bd43dbfcc6fc273f3e57ceaMichael Slusarz } else {
4ee5a85e75d520497bd43dbfcc6fc273f3e57ceaMichael Slusarz push_notification_trigger_msg_save_append(ptxn, mail, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz }
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_mail_copy(void *txn,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct mail *src ATTR_UNUSED,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct mail *dest)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
4ee5a85e75d520497bd43dbfcc6fc273f3e57ceaMichael Slusarz push_notification_mail_save(txn, dest);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_mail_expunge(void *txn, struct mail *mail)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz struct push_notification_txn *ptxn = txn;
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz push_notification_transaction_init(ptxn);
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz push_notification_trigger_msg_save_expunge(txn, mail, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzpush_notification_mail_update_flags(void *txn, struct mail *mail,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz enum mail_flags old_flags)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz struct push_notification_txn *ptxn = txn;
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz push_notification_transaction_init(ptxn);
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz push_notification_trigger_msg_flag_change(txn, mail, NULL, old_flags);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzpush_notification_mail_update_keywords(void *txn, struct mail *mail,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz const char *const *old_keywords)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz struct push_notification_txn *ptxn = txn;
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz push_notification_transaction_init(ptxn);
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz push_notification_trigger_msg_keyword_change(txn, mail, NULL, old_keywords);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void *
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzpush_notification_transaction_begin(struct mailbox_transaction_context *t)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz return push_notification_transaction_create(mailbox_transaction_get_mailbox(t), t);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_transaction_rollback(void *txn)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz struct push_notification_txn *ptxn = txn;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_transaction_end(ptxn, FALSE);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarzpush_notification_config_init(const char *config_name,
41dc355b0d4e20037a36ec05206e7880f49f4ca9Michael Slusarz struct mail_user *user,
41dc355b0d4e20037a36ec05206e7880f49f4ca9Michael Slusarz struct push_notification_driver_list *dlist)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct push_notification_driver_user *duser;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz const char *env;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz unsigned int i;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz string_t *root_name;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz root_name = t_str_new(32);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz str_append(root_name, config_name);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz for (i = 2;; i++) {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz env = mail_user_plugin_getenv(user, str_c(root_name));
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz if ((env == NULL) || (*env == '\0')) {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz break;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz }
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen if (push_notification_driver_init(user, env, user->pool, &duser) < 0) {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz break;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz }
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz // Add driver.
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz array_append(&dlist->drivers, &duser, 1);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz str_truncate(root_name, strlen(config_name));
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz str_printfa(root_name, "%d", i);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz }
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainenstatic struct push_notification_driver_list *
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainenpush_notification_driver_list_init(struct mail_user *user)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen struct push_notification_driver_list *dlist;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen dlist = p_new(user->pool, struct push_notification_driver_list, 1);
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen p_array_init(&dlist->drivers, user->pool, 4);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz push_notification_config_init(PUSH_NOTIFICATION_CONFIG, user, dlist);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz if (array_is_empty(&dlist->drivers)) {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz /* Support old configuration (it was available at time initial OX
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz * driver was first released). */
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz push_notification_config_init(PUSH_NOTIFICATION_CONFIG_OLD, user,
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz dlist);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz }
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen return dlist;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainenstatic void push_notification_user_deinit(struct mail_user *user)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen struct push_notification_user *puser = PUSH_NOTIFICATION_USER_CONTEXT(user);
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen struct push_notification_driver_list *dlist = puser->driverlist;
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen struct push_notification_driver_user **duser;
a846e6d6b4f1e9fcef4c07a5982b243a274f0a42Timo Sirainen struct ioloop *prev_ioloop = current_ioloop;
a846e6d6b4f1e9fcef4c07a5982b243a274f0a42Timo Sirainen
a846e6d6b4f1e9fcef4c07a5982b243a274f0a42Timo Sirainen /* Make sure we're in the main ioloop, so if the deinit/cleanup moves any
a846e6d6b4f1e9fcef4c07a5982b243a274f0a42Timo Sirainen I/Os or timeouts they won't get moved to some temporary ioloop. */
a846e6d6b4f1e9fcef4c07a5982b243a274f0a42Timo Sirainen io_loop_set_current(main_ioloop);
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen array_foreach_modifiable(&dlist->drivers, duser) {
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen if ((*duser)->driver->v.deinit != NULL) {
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen (*duser)->driver->v.deinit(*duser);
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen }
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen if ((*duser)->driver->v.cleanup != NULL) {
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen (*duser)->driver->v.cleanup();
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen }
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz }
a846e6d6b4f1e9fcef4c07a5982b243a274f0a42Timo Sirainen io_loop_set_current(prev_ioloop);
a846e6d6b4f1e9fcef4c07a5982b243a274f0a42Timo Sirainen
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen puser->module_ctx.super.deinit(user);
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen}
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainenstatic void push_notification_user_created(struct mail_user *user)
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen{
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen struct mail_user_vfuncs *v = user->vlast;
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen struct push_notification_user *puser;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz puser = p_new(user->pool, struct push_notification_user, 1);
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen puser->module_ctx.super = *v;
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen user->vlast = &puser->module_ctx.super;
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen v->deinit = push_notification_user_deinit;
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen puser->driverlist = push_notification_driver_list_init(user);
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz MODULE_CONTEXT_SET(user, push_notification_user_module, puser);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz/* Plugin interface. */
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzconst char *push_notification_plugin_version = DOVECOT_ABI_VERSION;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzconst char *push_notification_plugin_dependencies[] = { "notify", NULL };
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzextern struct push_notification_driver push_notification_driver_dlog;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzextern struct push_notification_driver push_notification_driver_ox;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic struct notify_context *push_notification_ctx;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic const struct notify_vfuncs push_notification_vfuncs = {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz /* Mailbox Events */
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mailbox_create = push_notification_mailbox_create,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mailbox_delete_commit = push_notification_mailbox_delete,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mailbox_rename = push_notification_mailbox_rename,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mailbox_set_subscribed = push_notification_mailbox_subscribe,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz /* Mail Events */
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mail_copy = push_notification_mail_copy,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mail_save = push_notification_mail_save,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mail_expunge = push_notification_mail_expunge,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mail_update_flags = push_notification_mail_update_flags,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mail_update_keywords = push_notification_mail_update_keywords,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mail_transaction_begin = push_notification_transaction_begin,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mail_transaction_commit = push_notification_transaction_commit,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mail_transaction_rollback = push_notification_transaction_rollback
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz};
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic struct mail_storage_hooks push_notification_storage_hooks = {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mail_user_created = push_notification_user_created
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz};
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzvoid push_notification_plugin_init(struct module *module)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_ctx = notify_register(&push_notification_vfuncs);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz mail_storage_hooks_add(module, &push_notification_storage_hooks);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_driver_register(&push_notification_driver_dlog);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_driver_register(&push_notification_driver_ox);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_event_register_rfc5423_events();
a44595f7b1afc7ccbd8653598753b32899d01c76Timo Sirainen main_ioloop = current_ioloop;
a44595f7b1afc7ccbd8653598753b32899d01c76Timo Sirainen i_assert(main_ioloop != NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzvoid push_notification_plugin_deinit(void)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz{
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_driver_unregister(&push_notification_driver_dlog);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_driver_unregister(&push_notification_driver_ox);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz
da2423165d31474f5384833fdaa6dc4c0cee28f4Timo Sirainen push_notification_event_unregister_rfc5423_events();
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz mail_storage_hooks_remove(&push_notification_storage_hooks);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz notify_unregister(push_notification_ctx);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz}