changeset 5034:1b28e0434d85 HEAD

Added mail_log plugin to log various mail operations. Currently it logs mail copies, deletions, expunges and mailbox deletions.
author Timo Sirainen <tss@iki.fi>
date Thu, 18 Jan 2007 20:45:33 +0200
parents 612b5c358d2e
children 80f0ee36e905
files configure.in src/plugins/mail-log/.cvsignore src/plugins/mail-log/Makefile.am src/plugins/mail-log/mail-log-plugin.c src/plugins/mail-log/mail-log-plugin.h
diffstat 5 files changed, 225 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/configure.in	Thu Jan 18 19:20:49 2007 +0200
+++ b/configure.in	Thu Jan 18 20:45:33 2007 +0200
@@ -1882,6 +1882,7 @@
 src/plugins/fts-lucene/Makefile
 src/plugins/fts-squat/Makefile
 src/plugins/lazy-expunge/Makefile
+src/plugins/mail-log/Makefile
 src/plugins/quota/Makefile
 src/plugins/imap-quota/Makefile
 src/plugins/trash/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/mail-log/.cvsignore	Thu Jan 18 20:45:33 2007 +0200
@@ -0,0 +1,8 @@
+*.la
+*.lo
+*.o
+.deps
+.libs
+Makefile
+Makefile.in
+so_locations
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/mail-log/Makefile.am	Thu Jan 18 20:45:33 2007 +0200
@@ -0,0 +1,26 @@
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/lib \
+	-I$(top_srcdir)/src/lib-index \
+	-I$(top_srcdir)/src/lib-mail \
+	-I$(top_srcdir)/src/lib-storage \
+	-I$(top_srcdir)/src/lib-storage/index \
+	-I$(top_srcdir)/src/lib-storage/index/maildir
+
+lib20_mail_log_plugin_la_LDFLAGS = -module -avoid-version
+
+module_LTLIBRARIES = \
+	lib20_mail_log_plugin.la
+
+lib20_mail_log_plugin_la_SOURCES = \
+	mail-log-plugin.c
+
+noinst_HEADERS = \
+	mail-log-plugin.h
+
+install-exec-local:
+	for d in imap pop3 lda; do \
+	  $(mkdir_p) $(DESTDIR)$(moduledir)/$$d; \
+	  rm -f $(DESTDIR)$(moduledir)/$$d/lib20_mail_log_plugin.so; \
+	  $(LN_S) ../lib20_mail_log_plugin.so $(DESTDIR)$(moduledir)/$$d; \
+	done
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/mail-log/mail-log-plugin.c	Thu Jan 18 20:45:33 2007 +0200
@@ -0,0 +1,183 @@
+/* Copyright (C) 2007 Timo Sirainen */
+
+#include "lib.h"
+#include "array.h"
+#include "str-sanitize.h"
+#include "mail-storage-private.h"
+#include "mail-log-plugin.h"
+
+#define MAILBOX_NAME_LOG_LEN 64
+#define MSGID_LOG_LEN 80
+
+#define MAIL_LOG_CONTEXT(obj) \
+	*((void **)array_idx_modifiable(&(obj)->module_contexts, \
+					mail_log_storage_module_id))
+
+struct mail_log_mail_storage {
+	struct mail_storage_vfuncs super;
+};
+
+struct mail_log_mailbox {
+	struct mailbox_vfuncs super;
+};
+
+struct mail_log_mail {
+	struct mail_vfuncs super;
+};
+
+/* defined by imap, pop3, lda */
+extern void (*hook_mail_storage_created)(struct mail_storage *storage);
+
+static void (*mail_log_next_hook_mail_storage_created)
+	(struct mail_storage *storage);
+
+static unsigned int mail_log_storage_module_id = 0;
+static bool mail_log_storage_module_id_set = FALSE;
+
+static void mail_log_action(struct mail *mail, const char *action)
+{
+	const char *msgid;
+
+	msgid = mail_get_first_header(mail, "Message-ID");
+	i_info("%s: uid=%u, msgid=%s", action, mail->uid,
+	       str_sanitize(msgid, MSGID_LOG_LEN));
+}
+
+static int mail_log_mail_expunge(struct mail *_mail)
+{
+	struct mail_private *mail = (struct mail_private *)_mail;
+	struct mail_log_mail *lmail = MAIL_LOG_CONTEXT(mail);
+
+	if (lmail->super.expunge(_mail) < 0)
+		return -1;
+
+	mail_log_action(_mail, "expunged");
+	return 0;
+}
+
+static int
+mail_log_mail_update_flags(struct mail *_mail, enum modify_type modify_type,
+			   enum mail_flags flags)
+{
+	struct mail_private *mail = (struct mail_private *)_mail;
+	struct mail_log_mail *lmail = MAIL_LOG_CONTEXT(mail);
+
+	if (lmail->super.update_flags(_mail, modify_type, flags) < 0)
+		return -1;
+
+	if ((flags & MAIL_DELETED) == 0 && modify_type != MODIFY_REMOVE)
+		return 0;
+
+	mail_log_action(_mail, "deleted");
+	return 0;
+}
+
+static struct mail *
+mail_log_mail_alloc(struct mailbox_transaction_context *t,
+		    enum mail_fetch_field wanted_fields,
+		    struct mailbox_header_lookup_ctx *wanted_headers)
+{
+	struct mail_log_mailbox *lbox = MAIL_LOG_CONTEXT(t->box);
+	struct mail_log_mail *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, struct mail_log_mail, 1);
+	lmail->super = mail->v;
+
+	mail->v.update_flags = mail_log_mail_update_flags;
+	mail->v.expunge = mail_log_mail_expunge;
+	array_idx_set(&mail->module_contexts,
+		      mail_log_storage_module_id, &lmail);
+	return _mail;
+}
+
+static int
+mail_log_copy(struct mailbox_transaction_context *t, struct mail *mail,
+	      enum mail_flags flags, struct mail_keywords *keywords,
+	      struct mail *dest_mail)
+{
+	struct mail_log_mailbox *lbox = MAIL_LOG_CONTEXT(t->box);
+	const char *name;
+
+	if (lbox->super.copy(t, mail, flags, keywords, dest_mail) < 0)
+		return -1;
+
+	t_push();
+	name = str_sanitize(mailbox_get_name(t->box), MAILBOX_NAME_LOG_LEN);
+	mail_log_action(mail, t_strdup_printf("copy -> %s", name));
+	t_pop();
+	return 0;
+}
+
+static struct mailbox *
+mail_log_mailbox_open(struct mail_storage *storage, const char *name,
+		      struct istream *input, enum mailbox_open_flags flags)
+{
+	struct mail_log_mail_storage *lstorage = MAIL_LOG_CONTEXT(storage);
+	struct mailbox *box;
+	struct mail_log_mailbox *lbox;
+
+	box = lstorage->super.mailbox_open(storage, name, input, flags);
+	if (box == NULL)
+		return NULL;
+
+	lbox = p_new(box->pool, struct mail_log_mailbox, 1);
+	lbox->super = box->v;
+
+	box->v.mail_alloc = mail_log_mail_alloc;
+	box->v.copy = mail_log_copy;
+	array_idx_set(&box->module_contexts, mail_log_storage_module_id, &lbox);
+	return box;
+}
+
+static int
+mail_log_mailbox_delete(struct mail_storage *storage, const char *name)
+{
+	struct mail_log_mail_storage *lstorage = MAIL_LOG_CONTEXT(storage);
+
+	if (lstorage->super.mailbox_delete(storage, name) < 0)
+		return -1;
+
+	i_info("Mailbox deleted: %s", str_sanitize(name, MAILBOX_NAME_LOG_LEN));
+	return 0;
+}
+
+static void mail_log_mail_storage_created(struct mail_storage *storage)
+{
+	struct mail_log_mail_storage *lstorage;
+
+	if (mail_log_next_hook_mail_storage_created != NULL)
+		mail_log_next_hook_mail_storage_created(storage);
+
+	lstorage = p_new(storage->pool, struct mail_log_mail_storage, 1);
+	lstorage->super = storage->v;
+	storage->v.mailbox_open = mail_log_mailbox_open;
+	storage->v.mailbox_delete = mail_log_mailbox_delete;
+
+	if (!mail_log_storage_module_id_set) {
+		mail_log_storage_module_id = mail_storage_module_id++;
+		mail_log_storage_module_id_set = TRUE;
+	}
+
+	array_idx_set(&storage->module_contexts,
+		      mail_log_storage_module_id, &lstorage);
+}
+
+void mail_log_plugin_init(void)
+{
+	mail_log_next_hook_mail_storage_created =
+		hook_mail_storage_created;
+	hook_mail_storage_created = mail_log_mail_storage_created;
+}
+
+void mail_log_plugin_deinit(void)
+{
+	if (mail_log_storage_module_id_set) {
+		hook_mail_storage_created =
+			mail_log_next_hook_mail_storage_created;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/mail-log/mail-log-plugin.h	Thu Jan 18 20:45:33 2007 +0200
@@ -0,0 +1,7 @@
+#ifndef __MAIL_LOG_PLUGIN_H
+#define __MAIL_LOG_PLUGIN_H
+
+void mail_log_plugin_init(void);
+void mail_log_plugin_deinit(void);
+
+#endif