# and they're not deleted automatically (use a cronjob or something).
#lazy_expunge = .EXPUNGED/ .DELETED/ .DELETED/.EXPUNGED/
- # Events to log. Default is all.
+ # Events to log. Also available: flag_change
#mail_log_events = delete undelete expunge copy mailbox_delete mailbox_rename
# Group events within a transaction to one line.
#mail_log_group_events =
- # Available fields: uid, box, msgid, size, vsize
+ # Available fields: uid, box, msgid, size, vsize, flags
# size and vsize are available only for expunge and copy events.
#mail_log_fields = uid box msgid size
}
#include "array.h"
#include "str.h"
#include "str-sanitize.h"
+#include "imap-util.h"
#include "mail-storage-private.h"
#include "mailbox-list-private.h"
#include "mail-log-plugin.h"
MAIL_LOG_FIELD_BOX = 0x02,
MAIL_LOG_FIELD_MSGID = 0x04,
MAIL_LOG_FIELD_PSIZE = 0x08,
- MAIL_LOG_FIELD_VSIZE = 0x10
+ MAIL_LOG_FIELD_VSIZE = 0x10,
+ MAIL_LOG_FIELD_FLAGS = 0x20
};
#define MAIL_LOG_DEFAULT_FIELDS \
(MAIL_LOG_FIELD_UID | MAIL_LOG_FIELD_BOX | \
MAIL_LOG_EVENT_COPY = 0x08,
MAIL_LOG_EVENT_MAILBOX_DELETE = 0x10,
MAIL_LOG_EVENT_MAILBOX_RENAME = 0x20,
+ MAIL_LOG_EVENT_FLAG_CHANGE = 0x40,
MAIL_LOG_EVENT_MASK_ALL = 0x1f
};
-#define MAIL_LOG_DEFAULT_EVENTS MAIL_LOG_EVENT_MASK_ALL
+#define MAIL_LOG_DEFAULT_EVENTS \
+ (MAIL_LOG_EVENT_DELETE | MAIL_LOG_EVENT_UNDELETE | \
+ MAIL_LOG_EVENT_EXPUNGE | MAIL_LOG_EVENT_COPY | \
+ MAIL_LOG_EVENT_MAILBOX_DELETE | MAIL_LOG_EVENT_MAILBOX_RENAME)
static const char *field_names[] = {
"uid",
"msgid",
"size",
"vsize",
+ "flags",
NULL
};
"expunge",
"copy",
"mailbox_delete",
+ "mailbox_rename",
+ "flag_change",
NULL
};
if ((mail_log_set.fields & MAIL_LOG_FIELD_BOX) != 0)
mail_log_append_mailbox_name(str, mail->box);
-
+ if ((mail_log_set.fields & MAIL_LOG_FIELD_FLAGS) != 0) {
+ str_printfa(str, "flags=(");
+ imap_write_flags(str, mail_get_flags(mail),
+ mail_get_keywords(mail));
+ str_append(str, "), ");
+ }
if (event == MAIL_LOG_EVENT_COPY)
str_printfa(str, "dest=%s, ", data);
new_flags = flags;
break;
}
- if (((old_flags ^ new_flags) & MAIL_DELETED) == 0)
- return;
- T_BEGIN {
+ if (((old_flags ^ new_flags) & MAIL_DELETED) != 0) T_BEGIN {
mail_log_action(_mail->transaction, _mail,
(new_flags & MAIL_DELETED) != 0 ?
MAIL_LOG_EVENT_DELETE :
MAIL_LOG_EVENT_UNDELETE, NULL);
} T_END;
+
+ if ((old_flags & ~MAIL_DELETED) != (new_flags & ~MAIL_DELETED)) {
+ mail_log_action(_mail->transaction, _mail,
+ MAIL_LOG_EVENT_FLAG_CHANGE, NULL);
+ }
+}
+
+static void
+mail_log_mail_update_keywords(struct mail *_mail, enum modify_type modify_type,
+ struct mail_keywords *keywords)
+{
+ struct mail_private *mail = (struct mail_private *)_mail;
+ union mail_module_context *lmail = MAIL_LOG_MAIL_CONTEXT(mail);
+ const char *const *old_keywords, *const *new_keywords;
+ unsigned int i;
+
+ old_keywords = mail_get_keywords(_mail);
+ lmail->super.update_keywords(_mail, modify_type, keywords);
+ new_keywords = mail_get_keywords(_mail);
+
+ for (i = 0; old_keywords[i] != NULL && new_keywords[i] != NULL; i++) {
+ if (strcmp(old_keywords[i], new_keywords[i]) != 0)
+ break;
+ }
+
+ if (old_keywords[i] != NULL || new_keywords[i] != NULL) {
+ mail_log_action(_mail->transaction, _mail,
+ MAIL_LOG_EVENT_FLAG_CHANGE, NULL);
+ }
}
static struct mail *
lmail->super = mail->v;
mail->v.update_flags = mail_log_mail_update_flags;
+ mail->v.update_keywords = mail_log_mail_update_keywords;
mail->v.expunge = mail_log_mail_expunge;
MODULE_CONTEXT_SET_SELF(mail, mail_log_mail_module, lmail);
return _mail;