/* Copyright (C) 2011 Timo Sirainen, LGPLv2.1 */

/*
   eval `cat /usr/local/lib/dovecot/dovecot-config`
   gcc -fPIC -shared -DHAVE_CONFIG_H \
     `echo $DOVECOT_CFLAGS $LIBDOVECOT_INCLUDE $LIBDOVECOT_STORAGE_INCLUDE` \
     touch-plugin.c -o touch_plugin.so
*/

#include "lib.h"
#include "notify-plugin.h"

#include <stdio.h>
#include <utime.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>

#define TOUCHPATH "/tmp/dsync-new-data"

void touch_plugin_init(struct module *module);
void touch_plugin_deinit(void);

static void touch(void)
{
	if (utime(TOUCHPATH, NULL) == 0) {
	} else if (errno != ENOENT)
		i_error("utime(%s) failed: %m", TOUCHPATH);
	else {
		mode_t mask;
		int fd;

		mask = umask(0);
		fd = open(TOUCHPATH".tmp", O_RDWR | O_CREAT, 0666);
		umask(mask);
		if (fd >= 0) {
			(void)close(fd);
			(void)rename(TOUCHPATH".tmp", TOUCHPATH);
		}
		if (utime(TOUCHPATH, NULL) < 0)
			i_error("utime(%s) failed: %m", TOUCHPATH);
	}
}

static void
touch_mail_transaction_commit(void *txn ATTR_UNUSED,
			      struct mail_transaction_commit_changes *changes ATTR_UNUSED)
{
	touch();
}

static void
touch_mailbox_create(struct mailbox *box ATTR_UNUSED)
{
	touch();
}

static void
touch_mailbox_delete_commit(void *txn ATTR_UNUSED,
			    struct mailbox *box ATTR_UNUSED)
{
	touch();
}

static void
touch_mailbox_rename(struct mailbox *src ATTR_UNUSED,
		     struct mailbox *dest ATTR_UNUSED,
		     bool rename_children ATTR_UNUSED)
{
	touch();
}

static const struct notify_vfuncs touch_vfuncs = {
	.mail_transaction_commit = touch_mail_transaction_commit,
	.mailbox_create = touch_mailbox_create,
	.mailbox_delete_commit = touch_mailbox_delete_commit,
	.mailbox_rename = touch_mailbox_rename
};

static struct notify_context *touch_ctx;

void touch_plugin_init(struct module *module ATTR_UNUSED)
{
	touch_ctx = notify_register(&touch_vfuncs);
}

void touch_plugin_deinit(void)
{
	notify_unregister(touch_ctx);
}

const char *touch_plugin_dependencies[] = { "notify", NULL };
