mail-log-plugin.c revision bfe4a97ad6731012202b830c1219a4c10f91d72c
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2007-2012 Dovecot authors, see the included COPYING file */
1d4f710106fb498750456724628da6063e012e6dTimo Sirainen
46552a931924c2d743f045e95b08c3ce6beda91aTimo Sirainen#include "lib.h"
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen#include "array.h"
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen#include "llist.h"
d3d769026fae5d21c2d29614d3bc4579e8d79e81Timo Sirainen#include "str.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include "str-sanitize.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include "imap-util.h"
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen#include "mail-user.h"
87dbf3e85526ccde5908a611eb9a798f1d0ccac3Timo Sirainen#include "mail-storage-private.h"
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen#include "notify-plugin.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include "mail-log-plugin.h"
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen#include <stdlib.h>
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen
c4ec7cb598805b1387dc3aab59ec8f32d8cc24e1Timo Sirainen#define MAILBOX_NAME_LOG_LEN 64
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen#define HEADER_LOG_LEN 80
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#define MAIL_LOG_USER_CONTEXT(obj) \
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen MODULE_CONTEXT(obj, mail_log_user_module)
92c49f3005f4dff1a6f576fffa8112ef6d1cae7fTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenenum mail_log_field {
1d2c463d23f09f15727edae9c78b07ec6a7a27daTimo Sirainen MAIL_LOG_FIELD_UID = 0x01,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen MAIL_LOG_FIELD_BOX = 0x02,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen MAIL_LOG_FIELD_MSGID = 0x04,
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen MAIL_LOG_FIELD_PSIZE = 0x08,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen MAIL_LOG_FIELD_VSIZE = 0x10,
1d4f710106fb498750456724628da6063e012e6dTimo Sirainen MAIL_LOG_FIELD_FLAGS = 0x20,
1d4f710106fb498750456724628da6063e012e6dTimo Sirainen MAIL_LOG_FIELD_FROM = 0x40,
0b3e92b6043435c5aa9f1cf1d04b632f3e19abd9Phil Carmody MAIL_LOG_FIELD_SUBJECT = 0x80
0b3e92b6043435c5aa9f1cf1d04b632f3e19abd9Phil Carmody};
ab0d9eecd85f74acae18fe88529302e0776cc500Timo Sirainen#define MAIL_LOG_DEFAULT_FIELDS \
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen (MAIL_LOG_FIELD_UID | MAIL_LOG_FIELD_BOX | \
a7efba62b6235e5efc124cbf702ddeb547ca3665Timo Sirainen MAIL_LOG_FIELD_MSGID | MAIL_LOG_FIELD_PSIZE)
0256180043b9f55b606b523b775e8b23b1b12f83Timo Sirainen
a7efba62b6235e5efc124cbf702ddeb547ca3665Timo Sirainenenum mail_log_event {
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen MAIL_LOG_EVENT_DELETE = 0x01,
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen MAIL_LOG_EVENT_UNDELETE = 0x02,
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen MAIL_LOG_EVENT_EXPUNGE = 0x04,
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen MAIL_LOG_EVENT_SAVE = 0x08,
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen MAIL_LOG_EVENT_COPY = 0x10,
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen MAIL_LOG_EVENT_MAILBOX_CREATE = 0x20,
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen MAIL_LOG_EVENT_MAILBOX_DELETE = 0x40,
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen MAIL_LOG_EVENT_MAILBOX_RENAME = 0x80,
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen MAIL_LOG_EVENT_FLAG_CHANGE = 0x100
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen};
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen#define MAIL_LOG_DEFAULT_EVENTS \
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen (MAIL_LOG_EVENT_DELETE | MAIL_LOG_EVENT_UNDELETE | \
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen MAIL_LOG_EVENT_EXPUNGE | MAIL_LOG_EVENT_SAVE | MAIL_LOG_EVENT_COPY | \
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen MAIL_LOG_EVENT_MAILBOX_DELETE | MAIL_LOG_EVENT_MAILBOX_RENAME)
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainenstatic const char *field_names[] = {
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen "uid",
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen "box",
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen "msgid",
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen "size",
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen "vsize",
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen "flags",
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen "from",
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen "subject",
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen NULL
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen};
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainenstatic const char *event_names[] = {
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen "delete",
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen "undelete",
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen "expunge",
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen "save",
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen "copy",
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen "mailbox_create",
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen "mailbox_delete",
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen "mailbox_rename",
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen "flag_change",
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen NULL
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen};
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainenstruct mail_log_user {
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen union mail_user_module_context module_ctx;
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen enum mail_log_field fields;
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen enum mail_log_event events;
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen};
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainenstruct mail_log_message {
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen struct mail_log_message *prev, *next;
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen enum mail_log_event event;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen bool ignore;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen const char *pretext, *text;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen};
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainenstruct mail_log_mail_txn_context {
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen pool_t pool;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen struct mail_log_message *messages, *messages_tail;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen};
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(mail_log_user_module,
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen &mail_user_module_register);
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainenstatic enum mail_log_field mail_log_field_find(const char *name)
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen{
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen unsigned int i;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen for (i = 0; field_names[i] != NULL; i++) {
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen if (strcmp(name, field_names[i]) == 0)
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen return 1 << i;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen }
2b96880f2d789d125aff6a95eaa7b51f558a6a1cTimo Sirainen return 0;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen}
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen
2b96880f2d789d125aff6a95eaa7b51f558a6a1cTimo Sirainenstatic enum mail_log_event mail_log_event_find(const char *name)
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen{
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen unsigned int i;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen if (strcmp(name, "append") == 0) {
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen /* v1.x backwards compatibility */
ed16ab579bd058ec5e2b5d02bb41fdadd9e05b31Timo Sirainen name = "save";
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen for (i = 0; event_names[i] != NULL; i++) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (strcmp(name, event_names[i]) == 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return 1 << i;
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen }
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvi return 0;
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvi}
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainenstatic enum mail_log_field mail_log_parse_fields(const char *str)
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen{
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen const char *const *tmp;
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen static enum mail_log_field field, fields = 0;
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen for (tmp = t_strsplit_spaces(str, ", "); *tmp != NULL; tmp++) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen field = mail_log_field_find(*tmp);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (field == 0)
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen i_fatal("Unknown field in mail_log_fields: '%s'", *tmp);
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen fields |= field;
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen }
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen return fields;
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen}
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainenstatic enum mail_log_event mail_log_parse_events(const char *str)
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen{
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen const char *const *tmp;
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen static enum mail_log_event event, events = 0;
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen for (tmp = t_strsplit_spaces(str, ", "); *tmp != NULL; tmp++) {
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen event = mail_log_event_find(*tmp);
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen if (event == 0)
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen i_fatal("Unknown event in mail_log_events: '%s'", *tmp);
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen events |= event;
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen }
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen return events;
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen}
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainenstatic void mail_log_mail_user_created(struct mail_user *user)
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen{
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen struct mail_log_user *muser;
f059a046515f4b2b15a6c2a10a6f12f6166e39a5Timo Sirainen const char *str;
be6e55ff7c81afdc7ed9b47c6021a4f7827e4407Timo Sirainen
66ea9eaaa2d7531b3be8f633937628c94d907031Timo Sirainen muser = p_new(user->pool, struct mail_log_user, 1);
66ea9eaaa2d7531b3be8f633937628c94d907031Timo Sirainen MODULE_CONTEXT_SET(user, mail_log_user_module, muser);
66ea9eaaa2d7531b3be8f633937628c94d907031Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str = mail_user_plugin_getenv(user, "mail_log_fields");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen muser->fields = str == NULL ? MAIL_LOG_DEFAULT_FIELDS :
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_log_parse_fields(str);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str = mail_user_plugin_getenv(user, "mail_log_events");
5a250816ffc4cc5db203f9410ea99b6601c7b91aTimo Sirainen muser->events = str == NULL ? MAIL_LOG_DEFAULT_EVENTS :
5a250816ffc4cc5db203f9410ea99b6601c7b91aTimo Sirainen mail_log_parse_events(str);
46ec792dd4ccf6c34706c4774228301fafde6aa9Timo Sirainen}
46ec792dd4ccf6c34706c4774228301fafde6aa9Timo Sirainen
46ec792dd4ccf6c34706c4774228301fafde6aa9Timo Sirainenstatic void mail_log_append_mailbox_name(string_t *str, struct mail *mail)
46ec792dd4ccf6c34706c4774228301fafde6aa9Timo Sirainen{
4c6ddf2491104f917d00e6900e833e80ea02c7b6Timo Sirainen const char *mailbox_str;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mailbox_str = mailbox_get_vname(mail->box);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_printfa(str, "box=%s",
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_sanitize(mailbox_str, MAILBOX_NAME_LOG_LEN));
b045b66988bfbaa2795791e42ee724fae6f0db1cAki Tuomi}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainenstatic void
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainenmail_log_append_mail_header(string_t *str, struct mail *mail,
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Bosch const char *name, const char *header)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Bosch const char *value;
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Bosch
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Bosch if (mail_get_first_header(mail, header, &value) <= 0)
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Bosch value = "";
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Bosch str_printfa(str, "%s=%s", name, str_sanitize(value, HEADER_LOG_LEN));
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Bosch}
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Bosch
c12d96f12cac9af464ab2e59046bd59b0c06b4eaTimo Sirainenstatic void
c12d96f12cac9af464ab2e59046bd59b0c06b4eaTimo Sirainenmail_log_append_uid(struct mail_log_mail_txn_context *ctx,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_log_message *msg, string_t *str, uint32_t uid)
b6fbc235f981b10333403e2fd6d333fd351c7a3cAki Tuomi{
b6fbc235f981b10333403e2fd6d333fd351c7a3cAki Tuomi if (uid != 0)
b6fbc235f981b10333403e2fd6d333fd351c7a3cAki Tuomi str_printfa(str, "uid=%u", uid);
b6fbc235f981b10333403e2fd6d333fd351c7a3cAki Tuomi else {
b6fbc235f981b10333403e2fd6d333fd351c7a3cAki Tuomi /* we don't know the uid yet, assign it later */
b6fbc235f981b10333403e2fd6d333fd351c7a3cAki Tuomi str_printfa(str, "uid=");
be6e55ff7c81afdc7ed9b47c6021a4f7827e4407Timo Sirainen msg->pretext = p_strdup(ctx->pool, str_c(str));
b6fbc235f981b10333403e2fd6d333fd351c7a3cAki Tuomi str_truncate(str, 0);
b6fbc235f981b10333403e2fd6d333fd351c7a3cAki Tuomi }
ddbdc644a15f56f4b43596f1b8c0fc196c101445Timo Sirainen}
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen
66ea9eaaa2d7531b3be8f633937628c94d907031Timo Sirainenstatic void
66ea9eaaa2d7531b3be8f633937628c94d907031Timo Sirainenmail_log_update_wanted_fields(struct mail *mail, enum mail_log_field fields)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
66ea9eaaa2d7531b3be8f633937628c94d907031Timo Sirainen enum mail_fetch_field wanted_fields = 0;
66ea9eaaa2d7531b3be8f633937628c94d907031Timo Sirainen struct mailbox_header_lookup_ctx *wanted_headers = NULL;
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen const char *headers[4];
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen unsigned int hdr_idx = 0;
d3d769026fae5d21c2d29614d3bc4579e8d79e81Timo Sirainen
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen if ((fields & MAIL_LOG_FIELD_MSGID) != 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen headers[hdr_idx++] = "Message-ID";
5a9e240ebf8d0daaf029973973b52e415148070bTimo Sirainen if ((fields & MAIL_LOG_FIELD_FROM) != 0)
5a9e240ebf8d0daaf029973973b52e415148070bTimo Sirainen headers[hdr_idx++] = "From";
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if ((fields & MAIL_LOG_FIELD_SUBJECT) != 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen headers[hdr_idx++] = "Subject";
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen if (hdr_idx > 0) {
f059a046515f4b2b15a6c2a10a6f12f6166e39a5Timo Sirainen i_assert(hdr_idx < N_ELEMENTS(headers));
66ea9eaaa2d7531b3be8f633937628c94d907031Timo Sirainen headers[hdr_idx] = NULL;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen wanted_headers = mailbox_header_lookup_init(mail->box, headers);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if ((fields & MAIL_LOG_FIELD_PSIZE) != 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen wanted_fields |= MAIL_FETCH_PHYSICAL_SIZE;
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen if ((fields & MAIL_LOG_FIELD_VSIZE) != 0)
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen wanted_fields |= MAIL_FETCH_VIRTUAL_SIZE;
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen mail_add_temp_wanted_fields(mail, wanted_fields, wanted_headers);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (wanted_headers != NULL)
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen mailbox_header_lookup_unref(&wanted_headers);
66ea9eaaa2d7531b3be8f633937628c94d907031Timo Sirainen}
66ea9eaaa2d7531b3be8f633937628c94d907031Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenmail_log_append_mail_message_real(struct mail_log_mail_txn_context *ctx,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail *mail, enum mail_log_event event,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char *desc)
c69a177207ed18d0f0210347430a60957136bd6cJosef 'Jeff' Sipek{
b045b66988bfbaa2795791e42ee724fae6f0db1cAki Tuomi struct mail_log_user *muser =
1a1159e589def1e32b7dc25397f15146672ef73eTimo Sirainen MAIL_LOG_USER_CONTEXT(mail->box->storage->user);
1a1159e589def1e32b7dc25397f15146672ef73eTimo Sirainen struct mail_log_message *msg;
56af9dd10e7e6caeaca64395bad3f882b28ecdffTimo Sirainen string_t *text;
56af9dd10e7e6caeaca64395bad3f882b28ecdffTimo Sirainen uoff_t size;
56af9dd10e7e6caeaca64395bad3f882b28ecdffTimo Sirainen
56af9dd10e7e6caeaca64395bad3f882b28ecdffTimo Sirainen msg = p_new(ctx->pool, struct mail_log_message, 1);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* avoid parsing through the message multiple times */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_log_update_wanted_fields(mail, muser->fields);
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen text = t_str_new(128);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen str_append(text, desc);
d3d769026fae5d21c2d29614d3bc4579e8d79e81Timo Sirainen str_append(text, ": ");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_BOX) != 0) {
a117008f03ad9e2d54258b30d3fb03ffa502a448Timo Sirainen mail_log_append_mailbox_name(text, mail);
a117008f03ad9e2d54258b30d3fb03ffa502a448Timo Sirainen str_append(text, ", ");
1312cf655d3ea22c0ab6487ce710ad4060c25905Timo Sirainen }
87dbf3e85526ccde5908a611eb9a798f1d0ccac3Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_UID) != 0) {
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen if (event != MAIL_LOG_EVENT_SAVE &&
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen event != MAIL_LOG_EVENT_COPY)
87dbf3e85526ccde5908a611eb9a798f1d0ccac3Timo Sirainen mail_log_append_uid(ctx, msg, text, mail->uid);
87dbf3e85526ccde5908a611eb9a798f1d0ccac3Timo Sirainen else {
1312cf655d3ea22c0ab6487ce710ad4060c25905Timo Sirainen /* with mbox mail->uid contains the uid, but handle
1312cf655d3ea22c0ab6487ce710ad4060c25905Timo Sirainen this consistently with all mailbox formats */
1312cf655d3ea22c0ab6487ce710ad4060c25905Timo Sirainen mail_log_append_uid(ctx, msg, text, 0);
1312cf655d3ea22c0ab6487ce710ad4060c25905Timo Sirainen }
1312cf655d3ea22c0ab6487ce710ad4060c25905Timo Sirainen str_append(text, ", ");
1312cf655d3ea22c0ab6487ce710ad4060c25905Timo Sirainen }
a7efba62b6235e5efc124cbf702ddeb547ca3665Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_MSGID) != 0) {
a7efba62b6235e5efc124cbf702ddeb547ca3665Timo Sirainen mail_log_append_mail_header(text, mail, "msgid", "Message-ID");
a7efba62b6235e5efc124cbf702ddeb547ca3665Timo Sirainen str_append(text, ", ");
0256180043b9f55b606b523b775e8b23b1b12f83Timo Sirainen }
a7efba62b6235e5efc124cbf702ddeb547ca3665Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_PSIZE) != 0) {
1312cf655d3ea22c0ab6487ce710ad4060c25905Timo Sirainen if (mail_get_physical_size(mail, &size) == 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_printfa(text, "size=%"PRIuUOFF_T, size);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen else
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_printfa(text, "size=error");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append(text, ", ");
c7fca6cbb32388556d9f6d8313486cc4e4a3c058Timo Sirainen }
c7fca6cbb32388556d9f6d8313486cc4e4a3c058Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_VSIZE) != 0) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (mail_get_virtual_size(mail, &size) == 0)
c7fca6cbb32388556d9f6d8313486cc4e4a3c058Timo Sirainen str_printfa(text, "vsize=%"PRIuUOFF_T, size);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen else
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_printfa(text, "vsize=error");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append(text, ", ");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_FROM) != 0) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_log_append_mail_header(text, mail, "from", "From");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append(text, ", ");
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek }
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek if ((muser->fields & MAIL_LOG_FIELD_SUBJECT) != 0) {
a75907609d7c410c9e17beedfafbf28b4439fa8aTimo Sirainen mail_log_append_mail_header(text, mail, "subject", "Subject");
a75907609d7c410c9e17beedfafbf28b4439fa8aTimo Sirainen str_append(text, ", ");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_FLAGS) != 0) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_printfa(text, "flags=(");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen imap_write_flags(text, mail_get_flags(mail),
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_get_keywords(mail));
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append(text, "), ");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen str_truncate(text, str_len(text)-2);
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen msg->event = event;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen msg->text = p_strdup(ctx->pool, str_c(text));
ab90f702ceedb7ba445a9a592be0b213b27cbafaStephan Bosch DLLIST2_APPEND(&ctx->messages, &ctx->messages_tail, msg);
ab90f702ceedb7ba445a9a592be0b213b27cbafaStephan Bosch}
2aac7ca853f63b62ea79ef8eae9ded83ed6063a5Timo Sirainen
4de2a17e0a2aed3b57a6c1057329b6a132b56ae2Timo Sirainenstatic void mail_log_add_dummy_msg(struct mail_log_mail_txn_context *ctx,
4de2a17e0a2aed3b57a6c1057329b6a132b56ae2Timo Sirainen enum mail_log_event event)
2aac7ca853f63b62ea79ef8eae9ded83ed6063a5Timo Sirainen{
2aac7ca853f63b62ea79ef8eae9ded83ed6063a5Timo Sirainen struct mail_log_message *msg;
2aac7ca853f63b62ea79ef8eae9ded83ed6063a5Timo Sirainen
9ddd3d7d8651985e373a6c48e0ddc76b8a4ef1c7Timo Sirainen msg = p_new(ctx->pool, struct mail_log_message, 1);
4de2a17e0a2aed3b57a6c1057329b6a132b56ae2Timo Sirainen msg->event = event;
5d2e7ec2ea725c8a6a63f56b771e746f93e782ecTimo Sirainen msg->ignore = TRUE;
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen DLLIST2_APPEND(&ctx->messages, &ctx->messages_tail, msg);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenmail_log_append_mail_message(struct mail_log_mail_txn_context *ctx,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail *mail, enum mail_log_event event,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char *desc)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_log_user *muser =
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen MAIL_LOG_USER_CONTEXT(mail->box->storage->user);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if ((muser->events & event) == 0) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (event == MAIL_LOG_EVENT_SAVE ||
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen event == MAIL_LOG_EVENT_COPY)
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen mail_log_add_dummy_msg(ctx, event);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return;
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen }
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen
b833824981bc75af72adb844f8a4a992bd2f3ad3Timo Sirainen T_BEGIN {
b833824981bc75af72adb844f8a4a992bd2f3ad3Timo Sirainen mail_log_append_mail_message_real(ctx, mail, event, desc);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen } T_END;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void *
66ea9eaaa2d7531b3be8f633937628c94d907031Timo Sirainenmail_log_mail_transaction_begin(struct mailbox_transaction_context *t ATTR_UNUSED)
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen{
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen pool_t pool;
66ea9eaaa2d7531b3be8f633937628c94d907031Timo Sirainen struct mail_log_mail_txn_context *ctx;
66ea9eaaa2d7531b3be8f633937628c94d907031Timo Sirainen
66ea9eaaa2d7531b3be8f633937628c94d907031Timo Sirainen pool = pool_alloconly_create("mail-log", 2048);
66ea9eaaa2d7531b3be8f633937628c94d907031Timo Sirainen ctx = p_new(pool, struct mail_log_mail_txn_context, 1);
66ea9eaaa2d7531b3be8f633937628c94d907031Timo Sirainen ctx->pool = pool;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return ctx;
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
b84eff65e25ae86dfd6f798386577209b94838c6Timo Sirainenstatic void mail_log_mail_save(void *txn, struct mail *mail)
b84eff65e25ae86dfd6f798386577209b94838c6Timo Sirainen{
b84eff65e25ae86dfd6f798386577209b94838c6Timo Sirainen struct mail_log_mail_txn_context *ctx =
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen (struct mail_log_mail_txn_context *)txn;
04d4432f5e21ba621ef8af3cb497ef7ededa87e3Timo Sirainen
87dbf3e85526ccde5908a611eb9a798f1d0ccac3Timo Sirainen mail_log_append_mail_message(ctx, mail, MAIL_LOG_EVENT_SAVE, "save");
87dbf3e85526ccde5908a611eb9a798f1d0ccac3Timo Sirainen}
a7efba62b6235e5efc124cbf702ddeb547ca3665Timo Sirainen
a7efba62b6235e5efc124cbf702ddeb547ca3665Timo Sirainenstatic void mail_log_mail_copy(void *txn, struct mail *src, struct mail *dst)
0256180043b9f55b606b523b775e8b23b1b12f83Timo Sirainen{
0256180043b9f55b606b523b775e8b23b1b12f83Timo Sirainen struct mail_log_mail_txn_context *ctx =
a7efba62b6235e5efc124cbf702ddeb547ca3665Timo Sirainen (struct mail_log_mail_txn_context *)txn;
204ee6ed414f5e4eeb6f6c10763b55daf56f11acJosef 'Jeff' Sipek const char *desc;
204ee6ed414f5e4eeb6f6c10763b55daf56f11acJosef 'Jeff' Sipek
1312cf655d3ea22c0ab6487ce710ad4060c25905Timo Sirainen desc = t_strdup_printf("copy from %s",
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_sanitize(mailbox_get_vname(src->box),
6303191abcb37164f435ccdc56e9dbddf1288851Timo Sirainen MAILBOX_NAME_LOG_LEN));
6303191abcb37164f435ccdc56e9dbddf1288851Timo Sirainen mail_log_append_mail_message(ctx, dst,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen MAIL_LOG_EVENT_COPY, desc);
c7eb1ffb7c73cb5d9c1316bbecd02947441a40d4Timo Sirainen}
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void mail_log_mail_expunge(void *txn, struct mail *mail)
b6b7a17731a917958b6479920b3fac5ca991db6aTimo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_log_mail_txn_context *ctx =
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen (struct mail_log_mail_txn_context *)txn;
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen mail_log_append_mail_message(ctx, mail, MAIL_LOG_EVENT_EXPUNGE,
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen "expunge");
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen}
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void mail_log_mail_update_flags(void *txn, struct mail *mail,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen enum mail_flags old_flags)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
b84eff65e25ae86dfd6f798386577209b94838c6Timo Sirainen struct mail_log_mail_txn_context *ctx =
b84eff65e25ae86dfd6f798386577209b94838c6Timo Sirainen (struct mail_log_mail_txn_context *)txn;
b84eff65e25ae86dfd6f798386577209b94838c6Timo Sirainen enum mail_flags new_flags = mail_get_flags(mail);
b84eff65e25ae86dfd6f798386577209b94838c6Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (((old_flags ^ new_flags) & MAIL_DELETED) == 0) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_log_append_mail_message(ctx, mail,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen MAIL_LOG_EVENT_FLAG_CHANGE,
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen "flag_change");
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen } else if ((old_flags & MAIL_DELETED) == 0) {
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen mail_log_append_mail_message(ctx, mail, MAIL_LOG_EVENT_DELETE,
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen "delete");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen } else {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_log_append_mail_message(ctx, mail, MAIL_LOG_EVENT_UNDELETE,
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen "undelete");
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen }
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen}
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainenstatic void
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenmail_log_mail_update_keywords(void *txn, struct mail *mail,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char *const *old_keywords ATTR_UNUSED)
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen{
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen struct mail_log_mail_txn_context *ctx =
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen (struct mail_log_mail_txn_context *)txn;
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen mail_log_append_mail_message(ctx, mail, MAIL_LOG_EVENT_FLAG_CHANGE,
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen "flag_change");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainenstatic void mail_log_save(const struct mail_log_message *msg, uint32_t uid)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (msg->ignore) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* not logging this save/copy */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen } else if (msg->pretext == NULL)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_info("%s", msg->text);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen else if (uid != 0)
73f021723bffa0841bbdf371882b463a449f1ea9Timo Sirainen i_info("%s%u%s", msg->pretext, uid, msg->text);
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainen else
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_info("%serror%s", msg->pretext, msg->text);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainenstatic void
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainenmail_log_mail_transaction_commit(void *txn,
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainen struct mail_transaction_commit_changes *changes)
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainen{
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainen struct mail_log_mail_txn_context *ctx =
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen (struct mail_log_mail_txn_context *)txn;
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen struct mail_log_message *msg;
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen struct seq_range_iter iter;
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen unsigned int n = 0;
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen uint32_t uid;
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen seq_range_array_iter_init(&iter, &changes->saved_uids);
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen for (msg = ctx->messages; msg != NULL; msg = msg->next) {
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen if (msg->event == MAIL_LOG_EVENT_SAVE ||
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen msg->event == MAIL_LOG_EVENT_COPY) {
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen if (!seq_range_array_iter_nth(&iter, n++, &uid))
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen uid = 0;
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen mail_log_save(msg, uid);
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen } else {
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen i_assert(msg->pretext == NULL);
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen i_info("%s", msg->text);
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen }
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen }
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen i_assert(!seq_range_array_iter_nth(&iter, n, &uid));
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen pool_unref(&ctx->pool);
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen}
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainenstatic void mail_log_mail_transaction_rollback(void *txn)
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen{
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen struct mail_log_mail_txn_context *ctx =
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen (struct mail_log_mail_txn_context *)txn;
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen pool_unref(&ctx->pool);
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen}
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen
b1485f2691de41ed7b5f96cebda2ebcb69a5e22fTimo Sirainenstatic void
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenmail_log_mailbox_create(struct mailbox *box)
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen{
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen struct mail_log_user *muser = MAIL_LOG_USER_CONTEXT(box->storage->user);
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if ((muser->events & MAIL_LOG_EVENT_MAILBOX_CREATE) == 0)
b1485f2691de41ed7b5f96cebda2ebcb69a5e22fTimo Sirainen return;
b1485f2691de41ed7b5f96cebda2ebcb69a5e22fTimo Sirainen
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen i_info("Mailbox created: %s",
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen str_sanitize(mailbox_get_vname(box), MAILBOX_NAME_LOG_LEN));
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen}
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainenstatic void
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainenmail_log_mailbox_delete_commit(void *txn ATTR_UNUSED, struct mailbox *box)
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen{
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen struct mail_log_user *muser = MAIL_LOG_USER_CONTEXT(box->storage->user);
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen
b1485f2691de41ed7b5f96cebda2ebcb69a5e22fTimo Sirainen if ((muser->events & MAIL_LOG_EVENT_MAILBOX_DELETE) == 0)
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen return;
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen i_info("Mailbox deleted: %s",
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen str_sanitize(mailbox_get_vname(box), MAILBOX_NAME_LOG_LEN));
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen}
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainenstatic void
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainenmail_log_mailbox_rename(struct mailbox *src,
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen struct mailbox *dest, bool rename_children ATTR_UNUSED)
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen{
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen struct mail_log_user *muser = MAIL_LOG_USER_CONTEXT(src->storage->user);
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen
b1485f2691de41ed7b5f96cebda2ebcb69a5e22fTimo Sirainen if ((muser->events & MAIL_LOG_EVENT_MAILBOX_RENAME) == 0)
b1485f2691de41ed7b5f96cebda2ebcb69a5e22fTimo Sirainen return;
b1485f2691de41ed7b5f96cebda2ebcb69a5e22fTimo Sirainen
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen i_info("Mailbox renamed: %s -> %s",
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen str_sanitize(mailbox_get_vname(src), MAILBOX_NAME_LOG_LEN),
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen str_sanitize(mailbox_get_vname(dest), MAILBOX_NAME_LOG_LEN));
a1852ab4cf0a942a3fcf4ca5636a7932ebcc7970Stephan Bosch}
a1852ab4cf0a942a3fcf4ca5636a7932ebcc7970Stephan Bosch
a1852ab4cf0a942a3fcf4ca5636a7932ebcc7970Stephan Boschstatic const struct notify_vfuncs mail_log_vfuncs = {
a1852ab4cf0a942a3fcf4ca5636a7932ebcc7970Stephan Bosch .mail_transaction_begin = mail_log_mail_transaction_begin,
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen .mail_save = mail_log_mail_save,
b1485f2691de41ed7b5f96cebda2ebcb69a5e22fTimo Sirainen .mail_copy = mail_log_mail_copy,
b1485f2691de41ed7b5f96cebda2ebcb69a5e22fTimo Sirainen .mail_expunge = mail_log_mail_expunge,
b1485f2691de41ed7b5f96cebda2ebcb69a5e22fTimo Sirainen .mail_update_flags = mail_log_mail_update_flags,
b1485f2691de41ed7b5f96cebda2ebcb69a5e22fTimo Sirainen .mail_update_keywords = mail_log_mail_update_keywords,
b1485f2691de41ed7b5f96cebda2ebcb69a5e22fTimo Sirainen .mail_transaction_commit = mail_log_mail_transaction_commit,
feb8f7b9490ddef989094ee21d7d1a222ccc4cb2Timo Sirainen .mail_transaction_rollback = mail_log_mail_transaction_rollback,
b1485f2691de41ed7b5f96cebda2ebcb69a5e22fTimo Sirainen .mailbox_create = mail_log_mailbox_create,
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen .mailbox_delete_commit = mail_log_mailbox_delete_commit,
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen .mailbox_rename = mail_log_mailbox_rename
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen};
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainenstatic struct notify_context *mail_log_ctx;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic struct mail_storage_hooks mail_log_mail_storage_hooks = {
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen .mail_user_created = mail_log_mail_user_created
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen};
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mail_log_plugin_init(struct module *module)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_log_ctx = notify_register(&mail_log_vfuncs);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_storage_hooks_add(module, &mail_log_mail_storage_hooks);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mail_log_plugin_deinit(void)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_storage_hooks_remove(&mail_log_mail_storage_hooks);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen notify_unregister(mail_log_ctx);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenconst char *mail_log_plugin_dependencies[] = { "notify", NULL };
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen