mail-log-plugin.c revision 5bd2cf0f30371cb0374b026322a6f52fdb20755f
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "lib.h"
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen#include "array.h"
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen#include "llist.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "str.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "str-sanitize.h"
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen#include "imap-util.h"
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen#include "mail-storage-private.h"
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen#include "mailbox-list-private.h"
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen#include "notify-plugin.h"
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen#include "mail-log-plugin.h"
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen#include <stdlib.h>
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen#define MAILBOX_NAME_LOG_LEN 64
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#define HEADER_LOG_LEN 80
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen#define MAIL_LOG_USER_CONTEXT(obj) \
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MODULE_CONTEXT(obj, mail_log_user_module)
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainenenum mail_log_field {
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen MAIL_LOG_FIELD_UID = 0x01,
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen MAIL_LOG_FIELD_BOX = 0x02,
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen MAIL_LOG_FIELD_MSGID = 0x04,
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen MAIL_LOG_FIELD_PSIZE = 0x08,
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen MAIL_LOG_FIELD_VSIZE = 0x10,
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen MAIL_LOG_FIELD_FLAGS = 0x20,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MAIL_LOG_FIELD_FROM = 0x40,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MAIL_LOG_FIELD_SUBJECT = 0x80
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainen};
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainen#define MAIL_LOG_DEFAULT_FIELDS \
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainen (MAIL_LOG_FIELD_UID | MAIL_LOG_FIELD_BOX | \
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainen MAIL_LOG_FIELD_MSGID | MAIL_LOG_FIELD_PSIZE)
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainen
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainenenum mail_log_event {
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainen MAIL_LOG_EVENT_DELETE = 0x01,
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainen MAIL_LOG_EVENT_UNDELETE = 0x02,
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainen MAIL_LOG_EVENT_EXPUNGE = 0x04,
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainen MAIL_LOG_EVENT_SAVE = 0x08,
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen MAIL_LOG_EVENT_COPY = 0x10,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MAIL_LOG_EVENT_MAILBOX_CREATE = 0x20,
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen MAIL_LOG_EVENT_MAILBOX_DELETE = 0x40,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MAIL_LOG_EVENT_MAILBOX_RENAME = 0x80,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MAIL_LOG_EVENT_FLAG_CHANGE = 0x100
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen};
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#define MAIL_LOG_DEFAULT_EVENTS \
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen (MAIL_LOG_EVENT_DELETE | MAIL_LOG_EVENT_UNDELETE | \
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MAIL_LOG_EVENT_EXPUNGE | MAIL_LOG_EVENT_SAVE | MAIL_LOG_EVENT_COPY | \
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen MAIL_LOG_EVENT_MAILBOX_DELETE | MAIL_LOG_EVENT_MAILBOX_RENAME)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
7db932bd4934cd967eeae643300aef5b91caeaeaTimo Sirainenstatic const char *field_names[] = {
7db932bd4934cd967eeae643300aef5b91caeaeaTimo Sirainen "uid",
74066569545099304b20e790df7c261883d1746bTimo Sirainen "box",
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen "msgid",
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen "size",
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen "vsize",
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen "flags",
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen "from",
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen "subject",
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen NULL
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen};
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainenstatic const char *event_names[] = {
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen "delete",
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen "undelete",
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen "expunge",
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen "save",
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen "copy",
0892446b45c195461bb7be6599f02d97e1e2c9b2Timo Sirainen "mailbox_create",
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen "mailbox_delete",
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen "mailbox_rename",
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen "flag_change",
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen NULL
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen};
9e095dd6a77097356aca8216356d4d71ef1bea45Timo Sirainen
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainenstruct mail_log_user {
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen union mail_user_module_context module_ctx;
0892446b45c195461bb7be6599f02d97e1e2c9b2Timo Sirainen
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen enum mail_log_field fields;
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen enum mail_log_event events;
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen};
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainenstruct mail_log_message {
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen struct mail_log_message *prev, *next;
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen enum mail_log_event event;
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen bool ignore;
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen const char *pretext, *text;
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen};
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainenstruct mail_log_mail_txn_context {
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen pool_t pool;
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen struct mail_log_message *messages, *messages_tail;
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen};
0a0cd45a633112a2ae6aad801c1e6afe53ab95deTimo Sirainen
e4c81823af1fc43ca3f2ce9eb4af7fc8f57b13a5Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(mail_log_user_module,
e4c81823af1fc43ca3f2ce9eb4af7fc8f57b13a5Timo Sirainen &mail_user_module_register);
0892446b45c195461bb7be6599f02d97e1e2c9b2Timo Sirainen
e4c81823af1fc43ca3f2ce9eb4af7fc8f57b13a5Timo Sirainenstatic enum mail_log_field mail_log_field_find(const char *name)
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen{
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen unsigned int i;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen for (i = 0; field_names[i] != NULL; i++) {
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen if (strcmp(name, field_names[i]) == 0)
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen return 1 << i;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen }
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen return 0;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen}
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainenstatic enum mail_log_event mail_log_event_find(const char *name)
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen{
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen unsigned int i;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen if (strcmp(name, "append") == 0) {
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen /* v1.x backwards compatibility */
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen name = "save";
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen }
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen for (i = 0; event_names[i] != NULL; i++) {
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen if (strcmp(name, event_names[i]) == 0)
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen return 1 << i;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen }
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen return 0;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen}
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainenstatic enum mail_log_field mail_log_parse_fields(const char *str)
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen{
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen const char *const *tmp;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen static enum mail_log_field field, fields = 0;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen for (tmp = t_strsplit_spaces(str, ", "); *tmp != NULL; tmp++) {
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen field = mail_log_field_find(*tmp);
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen if (field == 0)
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen i_fatal("Unknown field in mail_log_fields: '%s'", *tmp);
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen fields |= field;
61e6367a259e2473f33df42fda8ceeb3b8b48416Timo Sirainen }
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen return fields;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen}
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic enum mail_log_event mail_log_parse_events(const char *str)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen{
20344c0e814139e3c365fbb9287478f91512089eTimo Sirainen const char *const *tmp;
20344c0e814139e3c365fbb9287478f91512089eTimo Sirainen static enum mail_log_event event, events = 0;
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen for (tmp = t_strsplit_spaces(str, ", "); *tmp != NULL; tmp++) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen event = mail_log_event_find(*tmp);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (event == 0)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen i_fatal("Unknown event in mail_log_events: '%s'", *tmp);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen events |= event;
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen }
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen return events;
20344c0e814139e3c365fbb9287478f91512089eTimo Sirainen}
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic void mail_log_mail_user_created(struct mail_user *user)
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen{
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen struct mail_log_user *muser;
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen const char *str;
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen muser = p_new(user->pool, struct mail_log_user, 1);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MODULE_CONTEXT_SET(user, mail_log_user_module, muser);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen str = mail_user_plugin_getenv(user, "mail_log_fields");
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen muser->fields = str == NULL ? MAIL_LOG_DEFAULT_FIELDS :
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen mail_log_parse_fields(str);
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen str = mail_user_plugin_getenv(user, "mail_log_events");
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen muser->events = str == NULL ? MAIL_LOG_DEFAULT_EVENTS :
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen mail_log_parse_events(str);
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen}
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainenstatic void mail_log_append_mailbox_name(string_t *str, struct mail *mail)
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen{
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen const char *mailbox_str;
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen mailbox_str = mailbox_get_vname(mail->box);
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen str_printfa(str, "box=%s",
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen str_sanitize(mailbox_str, MAILBOX_NAME_LOG_LEN));
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen}
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic void
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainenmail_log_append_mail_header(string_t *str, struct mail *mail,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen const char *name, const char *header)
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen{
e3fc1874694a8ddba9552ec23f9952f74f33d1d5Timo Sirainen const char *value;
601f5f14c6cde28f0e0c6ca7c5d735315d3d48dfTimo Sirainen
601f5f14c6cde28f0e0c6ca7c5d735315d3d48dfTimo Sirainen if (mail_get_first_header(mail, header, &value) <= 0)
601f5f14c6cde28f0e0c6ca7c5d735315d3d48dfTimo Sirainen value = "";
601f5f14c6cde28f0e0c6ca7c5d735315d3d48dfTimo Sirainen str_printfa(str, "%s=%s", name, str_sanitize(value, HEADER_LOG_LEN));
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen}
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic void
9e095dd6a77097356aca8216356d4d71ef1bea45Timo Sirainenmail_log_append_uid(struct mail_log_mail_txn_context *ctx,
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen struct mail_log_message *msg, string_t *str, uint32_t uid)
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen{
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen if (uid != 0)
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen str_printfa(str, "uid=%u", uid);
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen else {
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen /* we don't know the uid yet, assign it later */
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen str_printfa(str, "uid=");
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen msg->pretext = p_strdup(ctx->pool, str_c(str));
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen str_truncate(str, 0);
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen }
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen}
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic void
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenmail_log_append_mail_message_real(struct mail_log_mail_txn_context *ctx,
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen struct mail *mail, enum mail_log_event event,
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen const char *desc)
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen{
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen struct mail_log_user *muser =
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen MAIL_LOG_USER_CONTEXT(mail->box->storage->user);
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen struct mail_log_message *msg;
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen string_t *text;
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen uoff_t size;
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen msg = p_new(ctx->pool, struct mail_log_message, 1);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen text = t_str_new(128);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen str_append(text, desc);
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen str_append(text, ": ");
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_BOX) != 0) {
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen mail_log_append_mailbox_name(text, mail);
548e394330621952db0f03dd667b70184c4a37b6Timo Sirainen str_append(text, ", ");
548e394330621952db0f03dd667b70184c4a37b6Timo Sirainen }
7d207b1e77a7b5e3fda640e353acfc86d261fedfTimo Sirainen if ((muser->fields & MAIL_LOG_FIELD_UID) != 0) {
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen if (event != MAIL_LOG_EVENT_SAVE &&
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen event != MAIL_LOG_EVENT_COPY)
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen mail_log_append_uid(ctx, msg, text, mail->uid);
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen else {
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen /* with mbox mail->uid contains the uid, but handle
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen this consistently with all mailbox formats */
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen mail_log_append_uid(ctx, msg, text, 0);
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen }
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen str_append(text, ", ");
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen }
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen if ((muser->fields & MAIL_LOG_FIELD_MSGID) != 0) {
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen mail_log_append_mail_header(text, mail, "msgid", "Message-ID");
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainen str_append(text, ", ");
7e1f68ad71d3485f1882142837b01f7a98ca8467Timo Sirainen }
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_PSIZE) != 0) {
7e1f68ad71d3485f1882142837b01f7a98ca8467Timo Sirainen if (mail_get_physical_size(mail, &size) == 0)
7e1f68ad71d3485f1882142837b01f7a98ca8467Timo Sirainen str_printfa(text, "size=%"PRIuUOFF_T, size);
7e1f68ad71d3485f1882142837b01f7a98ca8467Timo Sirainen else
7e1f68ad71d3485f1882142837b01f7a98ca8467Timo Sirainen str_printfa(text, "size=error");
a3c197999dfe2b0c8ea38cb77cfa5e95026005c0Timo Sirainen str_append(text, ", ");
a3c197999dfe2b0c8ea38cb77cfa5e95026005c0Timo Sirainen }
a3c197999dfe2b0c8ea38cb77cfa5e95026005c0Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_VSIZE) != 0) {
a3c197999dfe2b0c8ea38cb77cfa5e95026005c0Timo Sirainen if (mail_get_virtual_size(mail, &size) == 0)
a3c197999dfe2b0c8ea38cb77cfa5e95026005c0Timo Sirainen str_printfa(text, "vsize=%"PRIuUOFF_T, size);
a3c197999dfe2b0c8ea38cb77cfa5e95026005c0Timo Sirainen else
a3c197999dfe2b0c8ea38cb77cfa5e95026005c0Timo Sirainen str_printfa(text, "vsize=error");
a3c197999dfe2b0c8ea38cb77cfa5e95026005c0Timo Sirainen str_append(text, ", ");
a3c197999dfe2b0c8ea38cb77cfa5e95026005c0Timo Sirainen }
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_FROM) != 0) {
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen mail_log_append_mail_header(text, mail, "from", "From");
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen str_append(text, ", ");
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen }
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_SUBJECT) != 0) {
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen mail_log_append_mail_header(text, mail, "subject", "Subject");
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen str_append(text, ", ");
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen }
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_FLAGS) != 0) {
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen str_printfa(text, "flags=(");
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen imap_write_flags(text, mail_get_flags(mail),
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen mail_get_keywords(mail));
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen str_append(text, "), ");
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen }
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen str_truncate(text, str_len(text)-2);
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen msg->event = event;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen msg->text = p_strdup(ctx->pool, str_c(text));
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen DLLIST2_APPEND(&ctx->messages, &ctx->messages_tail, msg);
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen}
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainenstatic void mail_log_add_dummy_msg(struct mail_log_mail_txn_context *ctx,
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen enum mail_log_event event)
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen{
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen struct mail_log_message *msg;
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen msg = p_new(ctx->pool, struct mail_log_message, 1);
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen msg->event = event;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen msg->ignore = TRUE;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen DLLIST2_APPEND(&ctx->messages, &ctx->messages_tail, msg);
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen}
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainenstatic void
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainenmail_log_append_mail_message(struct mail_log_mail_txn_context *ctx,
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen struct mail *mail, enum mail_log_event event,
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen const char *desc)
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen{
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen struct mail_log_user *muser =
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen MAIL_LOG_USER_CONTEXT(mail->box->storage->user);
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen if ((muser->events & event) == 0) {
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen if (event == MAIL_LOG_EVENT_SAVE ||
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen event == MAIL_LOG_EVENT_COPY)
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen mail_log_add_dummy_msg(ctx, event);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen return;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen }
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
0611067f385a37773800225256dcd5cf6aa34212Timo Sirainen T_BEGIN {
0611067f385a37773800225256dcd5cf6aa34212Timo Sirainen mail_log_append_mail_message_real(ctx, mail, event, desc);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen } T_END;
0611067f385a37773800225256dcd5cf6aa34212Timo Sirainen}
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainenstatic void *
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainenmail_log_mail_transaction_begin(struct mailbox_transaction_context *t ATTR_UNUSED)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen{
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen pool_t pool;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mail_log_mail_txn_context *ctx;
5254d77805cd35b9356d072ba325c356c43b0d51Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen pool = pool_alloconly_create("mail-log", 2048);
3e25b17126e9536736d5da03697613e4c3af5f76Timo Sirainen ctx = p_new(pool, struct mail_log_mail_txn_context, 1);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen ctx->pool = pool;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen return ctx;
e0c3d5460d1cc0c440cb7723c8c2eef8d0afe9b9Timo Sirainen}
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic void mail_log_mail_save(void *txn, struct mail *mail)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen{
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen struct mail_log_mail_txn_context *ctx =
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen (struct mail_log_mail_txn_context *)txn;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mail_log_append_mail_message(ctx, mail, MAIL_LOG_EVENT_SAVE, "save");
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen}
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainenstatic void mail_log_mail_copy(void *txn, struct mail *src, struct mail *dst)
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen{
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen struct mail_log_mail_txn_context *ctx =
1036ad17ac837a451f6b045cac504d3efa2edb8eTimo Sirainen (struct mail_log_mail_txn_context *)txn;
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen const char *desc;
1036ad17ac837a451f6b045cac504d3efa2edb8eTimo Sirainen
1036ad17ac837a451f6b045cac504d3efa2edb8eTimo Sirainen if (strcmp(src->box->storage->name, "raw") == 0) {
1036ad17ac837a451f6b045cac504d3efa2edb8eTimo Sirainen /* special case: lda/lmtp is saving a mail */
1036ad17ac837a451f6b045cac504d3efa2edb8eTimo Sirainen desc = "save";
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen } else {
1036ad17ac837a451f6b045cac504d3efa2edb8eTimo Sirainen desc = t_strdup_printf("copy from %s",
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen str_sanitize(mailbox_get_name(src->box),
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen MAILBOX_NAME_LOG_LEN));
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen }
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainen mail_log_append_mail_message(ctx, dst, MAIL_LOG_EVENT_COPY, desc);
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainen}
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainenstatic void mail_log_mail_expunge(void *txn, struct mail *mail)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen{
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mail_log_mail_txn_context *ctx =
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen (struct mail_log_mail_txn_context *)txn;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mail_log_append_mail_message(ctx, mail, MAIL_LOG_EVENT_EXPUNGE,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen "expunge");
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen}
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic void mail_log_mail_update_flags(void *txn, struct mail *mail,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen enum mail_flags old_flags)
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainen{
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen struct mail_log_mail_txn_context *ctx =
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen (struct mail_log_mail_txn_context *)txn;
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainen enum mail_flags new_flags = mail_get_flags(mail);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (((old_flags ^ new_flags) & MAIL_DELETED) == 0) {
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen mail_log_append_mail_message(ctx, mail,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MAIL_LOG_EVENT_FLAG_CHANGE,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen "flag_change");
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen } else if ((old_flags & MAIL_DELETED) == 0) {
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen mail_log_append_mail_message(ctx, mail, MAIL_LOG_EVENT_DELETE,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen "delete");
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen } else {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mail_log_append_mail_message(ctx, mail, MAIL_LOG_EVENT_UNDELETE,
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen "undelete");
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen }
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen}
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenstatic void
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenmail_log_mail_update_keywords(void *txn, struct mail *mail,
37ab3cde96bfa4bc5304c0c348fc420aec79572dTimo Sirainen const char *const *old_keywords ATTR_UNUSED)
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen{
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen struct mail_log_mail_txn_context *ctx =
37ab3cde96bfa4bc5304c0c348fc420aec79572dTimo Sirainen (struct mail_log_mail_txn_context *)txn;
37ab3cde96bfa4bc5304c0c348fc420aec79572dTimo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mail_log_append_mail_message(ctx, mail, MAIL_LOG_EVENT_FLAG_CHANGE,
f4bbeadda12fbd7c219063db68f3e78646d83c2cTimo Sirainen "flag_change");
0b47e9f5e0181053b4d9ca7b426b0e5c185e820eTimo Sirainen}
0b47e9f5e0181053b4d9ca7b426b0e5c185e820eTimo Sirainen
abe8754852e70763e92f74caabbcc13d0917714cTimo Sirainenstatic void mail_log_save(const struct mail_log_message *msg, uint32_t uid)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen{
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen if (msg->ignore) {
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen /* not logging this save/copy */
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen } else if (msg->pretext == NULL)
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen i_info("%s", msg->text);
90b8f131849540fa374aede95edd86d47d35c09dTimo Sirainen else if (uid != 0)
90b8f131849540fa374aede95edd86d47d35c09dTimo Sirainen i_info("%s%u%s", msg->pretext, uid, msg->text);
90b8f131849540fa374aede95edd86d47d35c09dTimo Sirainen else
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen i_info("%serror%s", msg->pretext, msg->text);
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen}
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainenstatic void
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainenmail_log_mail_transaction_commit(void *txn,
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen struct mail_transaction_commit_changes *changes)
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen{
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen struct mail_log_mail_txn_context *ctx =
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen (struct mail_log_mail_txn_context *)txn;
90b8f131849540fa374aede95edd86d47d35c09dTimo Sirainen struct mail_log_message *msg;
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen struct seq_range_iter iter;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen unsigned int n = 0;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen uint32_t uid;
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen
904f9d5654b9c39edcdf32883e5e88771faf4d69Timo Sirainen seq_range_array_iter_init(&iter, &changes->saved_uids);
904f9d5654b9c39edcdf32883e5e88771faf4d69Timo Sirainen for (msg = ctx->messages; msg != NULL; msg = msg->next) {
904f9d5654b9c39edcdf32883e5e88771faf4d69Timo Sirainen if (msg->event == MAIL_LOG_EVENT_SAVE ||
904f9d5654b9c39edcdf32883e5e88771faf4d69Timo Sirainen msg->event == MAIL_LOG_EVENT_COPY) {
904f9d5654b9c39edcdf32883e5e88771faf4d69Timo Sirainen if (!seq_range_array_iter_nth(&iter, n++, &uid))
904f9d5654b9c39edcdf32883e5e88771faf4d69Timo Sirainen uid = 0;
904f9d5654b9c39edcdf32883e5e88771faf4d69Timo Sirainen mail_log_save(msg, uid);
904f9d5654b9c39edcdf32883e5e88771faf4d69Timo Sirainen } else {
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen i_assert(msg->pretext == NULL);
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen i_info("%s", msg->text);
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen }
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen }
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen i_assert(!seq_range_array_iter_nth(&iter, n, &uid));
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen pool_unref(&ctx->pool);
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen}
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainenstatic void mail_log_mail_transaction_rollback(void *txn)
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainen{
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen struct mail_log_mail_txn_context *ctx =
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen (struct mail_log_mail_txn_context *)txn;
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen pool_unref(&ctx->pool);
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen}
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainenstatic void
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainenmail_log_mailbox_create(struct mailbox *box)
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen{
14175321ddb88619015866978c05a27786ca4814Timo Sirainen struct mail_log_user *muser = MAIL_LOG_USER_CONTEXT(box->storage->user);
14175321ddb88619015866978c05a27786ca4814Timo Sirainen
14175321ddb88619015866978c05a27786ca4814Timo Sirainen if ((muser->events & MAIL_LOG_EVENT_MAILBOX_CREATE) == 0)
14175321ddb88619015866978c05a27786ca4814Timo Sirainen return;
14175321ddb88619015866978c05a27786ca4814Timo Sirainen
14175321ddb88619015866978c05a27786ca4814Timo Sirainen i_info("Mailbox created: %s",
14175321ddb88619015866978c05a27786ca4814Timo Sirainen str_sanitize(box->name, MAILBOX_NAME_LOG_LEN));
14175321ddb88619015866978c05a27786ca4814Timo Sirainen}
14175321ddb88619015866978c05a27786ca4814Timo Sirainen
14175321ddb88619015866978c05a27786ca4814Timo Sirainenstatic void
14175321ddb88619015866978c05a27786ca4814Timo Sirainenmail_log_mailbox_delete_commit(void *txn ATTR_UNUSED, struct mailbox *box)
14175321ddb88619015866978c05a27786ca4814Timo Sirainen{
14175321ddb88619015866978c05a27786ca4814Timo Sirainen struct mail_log_user *muser = MAIL_LOG_USER_CONTEXT(box->storage->user);
14175321ddb88619015866978c05a27786ca4814Timo Sirainen
14175321ddb88619015866978c05a27786ca4814Timo Sirainen if ((muser->events & MAIL_LOG_EVENT_MAILBOX_DELETE) == 0)
14175321ddb88619015866978c05a27786ca4814Timo Sirainen return;
14175321ddb88619015866978c05a27786ca4814Timo Sirainen
14175321ddb88619015866978c05a27786ca4814Timo Sirainen i_info("Mailbox deleted: %s",
14175321ddb88619015866978c05a27786ca4814Timo Sirainen str_sanitize(box->name, MAILBOX_NAME_LOG_LEN));
14175321ddb88619015866978c05a27786ca4814Timo Sirainen}
14175321ddb88619015866978c05a27786ca4814Timo Sirainen
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainenstatic void
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainenmail_log_mailbox_rename(struct mailbox *src,
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen struct mailbox *dest, bool rename_children ATTR_UNUSED)
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen{
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen struct mail_log_user *muser = MAIL_LOG_USER_CONTEXT(src->storage->user);
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen if ((muser->events & MAIL_LOG_EVENT_MAILBOX_RENAME) == 0)
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen return;
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen i_info("Mailbox renamed: %s -> %s",
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen str_sanitize(src->name, MAILBOX_NAME_LOG_LEN),
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen str_sanitize(dest->name, MAILBOX_NAME_LOG_LEN));
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen}
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainenstatic const struct notify_vfuncs mail_log_vfuncs = {
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen .mail_transaction_begin = mail_log_mail_transaction_begin,
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen .mail_save = mail_log_mail_save,
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen .mail_copy = mail_log_mail_copy,
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen .mail_expunge = mail_log_mail_expunge,
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen .mail_update_flags = mail_log_mail_update_flags,
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen .mail_update_keywords = mail_log_mail_update_keywords,
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen .mail_transaction_commit = mail_log_mail_transaction_commit,
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen .mail_transaction_rollback = mail_log_mail_transaction_rollback,
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen .mailbox_create = mail_log_mailbox_create,
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen .mailbox_delete_commit = mail_log_mailbox_delete_commit,
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen .mailbox_rename = mail_log_mailbox_rename
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen};
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainenstatic struct notify_context *mail_log_ctx;
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainenstatic struct mail_storage_hooks mail_log_mail_storage_hooks = {
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen .mail_user_created = mail_log_mail_user_created
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen};
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainenvoid mail_log_plugin_init(struct module *module)
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen{
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen mail_log_ctx = notify_register(&mail_log_vfuncs);
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen mail_storage_hooks_add(module, &mail_log_mail_storage_hooks);
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen}
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainenvoid mail_log_plugin_deinit(void)
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen{
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen mail_storage_hooks_remove(&mail_log_mail_storage_hooks);
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen notify_unregister(mail_log_ctx);
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen}
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainenconst char *mail_log_plugin_dependencies[] = { "notify", NULL };
9511a40d933181045343110c8101b75887062aaeTimo Sirainen