mail-log-plugin.c revision 70ed959d547ae7ff8bbe14c30c45caca3b43322c
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen/* Copyright (c) 2007-2008 Dovecot authors, see the included COPYING file */
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "lib.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "array.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "str.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "str-sanitize.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "mail-storage-private.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "mailbox-list-private.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "mail-log-plugin.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include <stdlib.h>
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#define MAILBOX_NAME_LOG_LEN 64
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen#define MSGID_LOG_LEN 80
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen#define MAIL_LOG_CONTEXT(obj) \
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen MODULE_CONTEXT(obj, mail_log_storage_module)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#define MAIL_LOG_MAIL_CONTEXT(obj) \
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen MODULE_CONTEXT(obj, mail_log_mail_module)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#define MAIL_LOG_LIST_CONTEXT(obj) \
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen MODULE_CONTEXT(obj, mail_log_mailbox_list_module)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenenum mail_log_field {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen MAIL_LOG_FIELD_UID = 0x01,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen MAIL_LOG_FIELD_BOX = 0x02,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen MAIL_LOG_FIELD_MSGID = 0x04,
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen MAIL_LOG_FIELD_PSIZE = 0x08,
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen MAIL_LOG_FIELD_VSIZE = 0x10
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen};
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#define MAIL_LOG_DEFAULT_FIELDS \
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen (MAIL_LOG_FIELD_UID | MAIL_LOG_FIELD_BOX | \
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen MAIL_LOG_FIELD_MSGID | MAIL_LOG_FIELD_PSIZE)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenenum mail_log_event {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen MAIL_LOG_EVENT_DELETE = 0x01,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen MAIL_LOG_EVENT_UNDELETE = 0x02,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen MAIL_LOG_EVENT_EXPUNGE = 0x04,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen MAIL_LOG_EVENT_COPY = 0x08,
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen MAIL_LOG_EVENT_MAILBOX_DELETE = 0x10,
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen MAIL_LOG_EVENT_MAILBOX_RENAME = 0x20,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen MAIL_LOG_EVENT_MASK_ALL = 0x1f
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen};
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#define MAIL_LOG_DEFAULT_EVENTS MAIL_LOG_EVENT_MASK_ALL
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstatic const char *field_names[] = {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen "uid",
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen "box",
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen "msgid",
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen "size",
9398c0935613ba038cf2275ff66c43b25092cfd0Timo Sirainen "vsize",
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen NULL
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen};
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstatic const char *event_names[] = {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen "delete",
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen "undelete",
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen "expunge",
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen "copy",
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen "mailbox_delete",
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen NULL
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen};
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstruct mail_log_settings {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen enum mail_log_field fields;
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen enum mail_log_event events;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen unsigned int group_events:1;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen};
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstruct mail_log_group_changes {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen enum mail_log_event event;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen const char *data;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen ARRAY_TYPE(seq_range) uids;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen uoff_t psize_total, vsize_total;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen};
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstruct mail_log_transaction_context {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen union mailbox_transaction_module_context module_ctx;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen pool_t pool;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen ARRAY_DEFINE(group_changes, struct mail_log_group_changes);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen unsigned int changes;
3d370bb6763ac4af4a0d143ad7c93300d5ddff89Timo Sirainen};
3d370bb6763ac4af4a0d143ad7c93300d5ddff89Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenconst char *mail_log_plugin_version = PACKAGE_VERSION;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstatic struct mail_log_settings mail_log_set;
ce89e2964b6bc4925d2dd690417200a110d041c5Timo Sirainen
ce89e2964b6bc4925d2dd690417200a110d041c5Timo Sirainenstatic void (*mail_log_next_hook_mail_storage_created)
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen (struct mail_storage *storage);
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainenstatic void (*mail_log_next_hook_mailbox_list_created)
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen (struct mailbox_list *list);
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(mail_log_storage_module,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen &mail_storage_module_register);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(mail_log_mail_module, &mail_module_register);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(mail_log_mailbox_list_module,
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainen &mailbox_list_module_register);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainenstatic enum mail_log_field mail_log_field_find(const char *name)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen unsigned int i;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen for (i = 0; field_names[i] != NULL; i++) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (strcmp(name, field_names[i]) == 0)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return 1 << i;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return 0;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainenstatic enum mail_log_event mail_log_event_find(const char *name)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen{
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen unsigned int i;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen for (i = 0; event_names[i] != NULL; i++) {
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (strcmp(name, event_names[i]) == 0)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen return 1 << i;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen }
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen return 0;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstatic const char *mail_log_event_get_name(enum mail_log_event event)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen unsigned int i;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen for (i = 0; event_names[i] != NULL; i++) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if ((unsigned)event == (unsigned)(1 << i))
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return event_names[i];
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen }
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen i_unreached();
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen return NULL;
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen}
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainenstatic struct mail_log_group_changes *
bd354c19cb93c07ade79477674328a54146ea332Timo Sirainenmail_log_action_get_group(struct mail_log_transaction_context *lt,
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen enum mail_log_event event, const char *data)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen{
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen struct mail_log_group_changes *group;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen unsigned int i, count;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (!array_is_created(&lt->group_changes))
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen p_array_init(&lt->group_changes, lt->pool, 8);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
25ee72451d16374ed27fdbf829f4ec756c778352Timo Sirainen group = array_get_modifiable(&lt->group_changes, &count);
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen for (i = 0; i < count; i++) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (group[i].event == event &&
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen null_strcmp(data, group[i].data) == 0)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return &group[i];
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen group = array_append_space(&lt->group_changes);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen group->event = event;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen group->data = p_strdup(lt->pool, data);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return group;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstatic void
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenmail_log_action_add_group(struct mail_log_transaction_context *lt,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct mail *mail, enum mail_log_event event,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen const char *data)
3d370bb6763ac4af4a0d143ad7c93300d5ddff89Timo Sirainen{
0af3274706d337b2930bd34f0377f2cc2dbcd18aTimo Sirainen struct mail_log_group_changes *group;
0af3274706d337b2930bd34f0377f2cc2dbcd18aTimo Sirainen uoff_t size;
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen group = mail_log_action_get_group(lt, event, data);
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen if ((mail_log_set.fields & MAIL_LOG_FIELD_UID) != 0) {
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen if (!array_is_created(&group->uids))
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen p_array_init(&group->uids, lt->pool, 32);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen seq_range_array_add(&group->uids, 0, mail->uid);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen }
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen if ((mail_log_set.fields & MAIL_LOG_FIELD_PSIZE) != 0 &&
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainen (event & (MAIL_LOG_EVENT_EXPUNGE | MAIL_LOG_EVENT_COPY)) != 0) {
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen if (mail_get_physical_size(mail, &size) == 0)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen group->psize_total += size;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if ((mail_log_set.fields & MAIL_LOG_FIELD_VSIZE) != 0 &&
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen (event & (MAIL_LOG_EVENT_EXPUNGE | MAIL_LOG_EVENT_COPY)) != 0) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (mail_get_virtual_size(mail, &size) == 0)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen group->vsize_total += size;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainenstatic void mail_log_append_mailbox_name(string_t *str, struct mailbox *box)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen{
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen const char *mailbox_str;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen /* most operations are for INBOX, and POP3 has only INBOX,
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen so don't add it. */
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen mailbox_str = mailbox_get_name(box);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (strcmp(mailbox_str, "INBOX") != 0) {
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen str_printfa(str, "box=%s, ",
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen str_sanitize(mailbox_str, MAILBOX_NAME_LOG_LEN));
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstatic void
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainenmail_log_group(struct mailbox *box, const struct mail_log_group_changes *group)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen const struct seq_range *range;
2efe0618b62fb1e3cd41a692f02d674a54c7720eTimo Sirainen unsigned int i, count;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen string_t *str;
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen str = t_str_new(128);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen str_printfa(str, "%s: ", mail_log_event_get_name(group->event));
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen if ((mail_log_set.fields & MAIL_LOG_FIELD_UID) != 0 &&
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen array_is_created(&group->uids)) {
bd354c19cb93c07ade79477674328a54146ea332Timo Sirainen str_append(str, "uids=");
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen range = array_get(&group->uids, &count);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen for (i = 0; i < count; i++) {
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen if (i != 0)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen str_append_c(str, ',');
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen str_printfa(str, "%u", range[i].seq1);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (range[i].seq1 != range[i].seq2)
25ee72451d16374ed27fdbf829f4ec756c778352Timo Sirainen str_printfa(str, "-%u", range[i].seq2);
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen str_append(str, ", ");
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen if ((mail_log_set.fields & MAIL_LOG_FIELD_BOX) != 0)
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen mail_log_append_mailbox_name(str, box);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (group->event == MAIL_LOG_EVENT_COPY)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen str_printfa(str, "dest=%s, ", group->data);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (group->psize_total != 0)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen str_printfa(str, "size=%"PRIuUOFF_T", ", group->psize_total);
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen if (group->vsize_total != 0)
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen str_printfa(str, "size=%"PRIuUOFF_T", ", group->vsize_total);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen str_truncate(str, str_len(str)-2);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen i_info("%s", str_c(str));
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainen}
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainenstatic void
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenmail_log_group_changes(struct mailbox *box,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct mail_log_transaction_context *lt)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen const struct mail_log_group_changes *group;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen unsigned int i, count;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen group = array_get(&lt->group_changes, &count);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen for (i = 0; i < count; i++) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen T_BEGIN {
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen mail_log_group(box, &group[i]);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen } T_END;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen }
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen}
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstatic void mail_log_action(struct mailbox_transaction_context *dest_trans,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct mail *mail, enum mail_log_event event,
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen const char *data)
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen{
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen struct mail_log_transaction_context *lt = MAIL_LOG_CONTEXT(dest_trans);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen const char *msgid;
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen uoff_t size;
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen string_t *str;
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen pool_t pool;
bd354c19cb93c07ade79477674328a54146ea332Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if ((mail_log_set.events & event) == 0)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen return;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen if (lt == NULL) {
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen pool = pool_alloconly_create("mail log transaction", 1024);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen lt = p_new(pool, struct mail_log_transaction_context, 1);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen lt->pool = pool;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen MODULE_CONTEXT_SET(dest_trans, mail_log_storage_module, lt);
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen }
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen lt->changes++;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (mail_log_set.group_events) {
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen mail_log_action_add_group(lt, mail, event, data);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen str = t_str_new(128);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen str_printfa(str, "%s: ", mail_log_event_get_name(event));
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if ((mail_log_set.fields & MAIL_LOG_FIELD_UID) != 0)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen str_printfa(str, "uid=%u, ", mail->uid);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if ((mail_log_set.fields & MAIL_LOG_FIELD_BOX) != 0)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen mail_log_append_mailbox_name(str, mail->box);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (event == MAIL_LOG_EVENT_COPY)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen str_printfa(str, "dest=%s, ", data);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if ((mail_log_set.fields & MAIL_LOG_FIELD_MSGID) != 0) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (mail_get_first_header(mail, "Message-ID", &msgid) <= 0)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen msgid = "(null)";
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen str_printfa(str, "msgid=%s, ",
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen str_sanitize(msgid, MSGID_LOG_LEN));
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if ((mail_log_set.fields & MAIL_LOG_FIELD_PSIZE) != 0 &&
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen (event & (MAIL_LOG_EVENT_EXPUNGE | MAIL_LOG_EVENT_COPY)) != 0) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (mail_get_physical_size(mail, &size) == 0)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen str_printfa(str, "size=%"PRIuUOFF_T", ", size);
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if ((mail_log_set.fields & MAIL_LOG_FIELD_VSIZE) != 0 &&
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen (event & (MAIL_LOG_EVENT_EXPUNGE | MAIL_LOG_EVENT_COPY)) != 0) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (mail_get_virtual_size(mail, &size) == 0)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen str_printfa(str, "vsize=%"PRIuUOFF_T", ", size);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen str_truncate(str, str_len(str)-2);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen i_info("%s", str_c(str));
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstatic void mail_log_mail_expunge(struct mail *_mail)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen union mail_module_context *lmail = MAIL_LOG_MAIL_CONTEXT(mail);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen T_BEGIN {
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen mail_log_action(_mail->transaction, _mail,
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen MAIL_LOG_EVENT_EXPUNGE, NULL);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen } T_END;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen lmail->super.expunge(_mail);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstatic void
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenmail_log_mail_update_flags(struct mail *_mail, enum modify_type modify_type,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen enum mail_flags flags)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen union mail_module_context *lmail = MAIL_LOG_MAIL_CONTEXT(mail);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen enum mail_flags old_flags, new_flags;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen old_flags = mail_get_flags(_mail);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen lmail->super.update_flags(_mail, modify_type, flags);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen new_flags = old_flags;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen switch (modify_type) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen case MODIFY_ADD:
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen new_flags |= flags;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen break;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen case MODIFY_REMOVE:
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen new_flags &= ~flags;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen break;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen case MODIFY_REPLACE:
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen new_flags = flags;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen break;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (((old_flags ^ new_flags) & MAIL_DELETED) == 0)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen T_BEGIN {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen mail_log_action(_mail->transaction, _mail,
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen (new_flags & MAIL_DELETED) != 0 ?
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen MAIL_LOG_EVENT_DELETE :
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen MAIL_LOG_EVENT_UNDELETE, NULL);
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen } T_END;
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen}
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainenstatic struct mail *
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainenmail_log_mail_alloc(struct mailbox_transaction_context *t,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen enum mail_fetch_field wanted_fields,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct mailbox_header_lookup_ctx *wanted_headers)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen union mailbox_module_context *lbox = MAIL_LOG_CONTEXT(t->box);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen union mail_module_context *lmail;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct mail *_mail;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct mail_private *mail;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen _mail = lbox->super.mail_alloc(t, wanted_fields, wanted_headers);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen mail = (struct mail_private *)_mail;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen lmail = p_new(mail->pool, union mail_module_context, 1);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen lmail->super = mail->v;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen mail->v.update_flags = mail_log_mail_update_flags;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen mail->v.expunge = mail_log_mail_expunge;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen MODULE_CONTEXT_SET_SELF(mail, mail_log_mail_module, lmail);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return _mail;
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen}
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainenstatic int
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenmail_log_copy(struct mailbox_transaction_context *t, struct mail *mail,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen enum mail_flags flags, struct mail_keywords *keywords,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct mail *dest_mail)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen union mailbox_module_context *lbox = MAIL_LOG_CONTEXT(t->box);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen const char *name;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen if (lbox->super.copy(t, mail, flags, keywords, dest_mail) < 0)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return -1;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen T_BEGIN {
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen name = str_sanitize(mailbox_get_name(t->box),
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen MAILBOX_NAME_LOG_LEN);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen mail_log_action(t, mail, MAIL_LOG_EVENT_COPY, name);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen } T_END;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return 0;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen}
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstatic int
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenmail_log_transaction_commit(struct mailbox_transaction_context *t,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen uint32_t *uid_validity_r,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen uint32_t *first_saved_uid_r,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen uint32_t *last_saved_uid_r)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct mail_log_transaction_context *lt = MAIL_LOG_CONTEXT(t);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen union mailbox_module_context *lbox = MAIL_LOG_CONTEXT(t->box);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen if (lt != NULL) {
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen if (lt->changes > 0 && mail_log_set.group_events)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen mail_log_group_changes(t->box, lt);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen pool_unref(&lt->pool);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen }
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return lbox->super.transaction_commit(t, uid_validity_r,
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainen first_saved_uid_r,
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen last_saved_uid_r);
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainen}
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenstatic void
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenmail_log_transaction_rollback(struct mailbox_transaction_context *t)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
struct mail_log_transaction_context *lt = MAIL_LOG_CONTEXT(t);
union mailbox_module_context *lbox = MAIL_LOG_CONTEXT(t->box);
if (lt != NULL) {
if (lt->changes > 0 && !mail_log_set.group_events) {
i_info("Transaction rolled back: "
"Ignore last %u changes", lt->changes);
}
pool_unref(&lt->pool);
}
lbox->super.transaction_rollback(t);
}
static struct mailbox *
mail_log_mailbox_open(struct mail_storage *storage, const char *name,
struct istream *input, enum mailbox_open_flags flags)
{
union mail_storage_module_context *lstorage = MAIL_LOG_CONTEXT(storage);
struct mailbox *box;
union mailbox_module_context *lbox;
box = lstorage->super.mailbox_open(storage, name, input, flags);
if (box == NULL)
return NULL;
lbox = p_new(box->pool, union mailbox_module_context, 1);
lbox->super = box->v;
box->v.mail_alloc = mail_log_mail_alloc;
box->v.copy = mail_log_copy;
box->v.transaction_commit = mail_log_transaction_commit;
box->v.transaction_rollback = mail_log_transaction_rollback;
MODULE_CONTEXT_SET_SELF(box, mail_log_storage_module, lbox);
return box;
}
static int
mail_log_mailbox_list_delete(struct mailbox_list *list, const char *name)
{
union mailbox_list_module_context *llist = MAIL_LOG_LIST_CONTEXT(list);
if (llist->super.delete_mailbox(list, name) < 0)
return -1;
if ((mail_log_set.events & MAIL_LOG_EVENT_MAILBOX_DELETE) == 0)
return 0;
i_info("Mailbox deleted: %s", str_sanitize(name, MAILBOX_NAME_LOG_LEN));
return 0;
}
static int
mail_log_mailbox_list_rename(struct mailbox_list *list, const char *oldname,
const char *newname)
{
union mailbox_list_module_context *llist = MAIL_LOG_LIST_CONTEXT(list);
if (llist->super.rename_mailbox(list, oldname, newname) < 0)
return -1;
if ((mail_log_set.events & MAIL_LOG_EVENT_MAILBOX_RENAME) == 0)
return 0;
i_info("Mailbox renamed: %s -> %s",
str_sanitize(oldname, MAILBOX_NAME_LOG_LEN),
str_sanitize(newname, MAILBOX_NAME_LOG_LEN));
return 0;
}
static void mail_log_mail_storage_created(struct mail_storage *storage)
{
union mail_storage_module_context *lstorage;
if (mail_log_next_hook_mail_storage_created != NULL)
mail_log_next_hook_mail_storage_created(storage);
lstorage = p_new(storage->pool, union mail_storage_module_context, 1);
lstorage->super = storage->v;
storage->v.mailbox_open = mail_log_mailbox_open;
MODULE_CONTEXT_SET_SELF(storage, mail_log_storage_module, lstorage);
}
static void mail_log_mailbox_list_created(struct mailbox_list *list)
{
union mailbox_list_module_context *llist;
if (mail_log_next_hook_mailbox_list_created != NULL)
mail_log_next_hook_mailbox_list_created(list);
llist = p_new(list->pool, union mailbox_list_module_context, 1);
llist->super = list->v;
list->v.delete_mailbox = mail_log_mailbox_list_delete;
list->v.rename_mailbox = mail_log_mailbox_list_rename;
MODULE_CONTEXT_SET_SELF(list, mail_log_mailbox_list_module, llist);
}
static enum mail_log_field mail_log_parse_fields(const char *str)
{
const char *const *tmp;
static enum mail_log_field field, fields = 0;
for (tmp = t_strsplit_spaces(str, ", "); *tmp != NULL; tmp++) {
field = mail_log_field_find(*tmp);
if (field == 0)
i_fatal("Unknown field in mail_log_fields: '%s'", *tmp);
fields |= field;
}
return fields;
}
static enum mail_log_event mail_log_parse_events(const char *str)
{
const char *const *tmp;
static enum mail_log_event event, events = 0;
for (tmp = t_strsplit_spaces(str, ", "); *tmp != NULL; tmp++) {
event = mail_log_event_find(*tmp);
if (event == 0)
i_fatal("Unknown event in mail_log_events: '%s'", *tmp);
events |= event;
}
return events;
}
static void mail_log_read_settings(struct mail_log_settings *set)
{
const char *str;
memset(set, 0, sizeof(*set));
str = getenv("MAIL_LOG_FIELDS");
set->fields = str == NULL ? MAIL_LOG_DEFAULT_FIELDS :
mail_log_parse_fields(str);
str = getenv("MAIL_LOG_EVENTS");
set->events = str == NULL ? MAIL_LOG_DEFAULT_EVENTS :
mail_log_parse_events(str);
set->group_events = getenv("MAIL_LOG_GROUP_EVENTS") != NULL;
}
void mail_log_plugin_init(void)
{
mail_log_read_settings(&mail_log_set);
mail_log_next_hook_mail_storage_created = hook_mail_storage_created;
hook_mail_storage_created = mail_log_mail_storage_created;
mail_log_next_hook_mailbox_list_created = hook_mailbox_list_created;
hook_mailbox_list_created = mail_log_mailbox_list_created;
}
void mail_log_plugin_deinit(void)
{
hook_mail_storage_created = mail_log_next_hook_mail_storage_created;
hook_mailbox_list_created = mail_log_next_hook_mailbox_list_created;
}