Mercurial > dovecot > original-hg > dovecot-1.2
view src/plugins/mail-log/mail-log-plugin.c @ 5205:f33e5ce7a73c HEAD
Fixed deleted/undeleted logging.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 28 Feb 2007 23:00:39 +0200 |
parents | 24f4a959a24c |
children | 1fffd36401eb |
line wrap: on
line source
/* Copyright (C) 2007 Timo Sirainen */ #include "lib.h" #include "array.h" #include "str-sanitize.h" #include "mail-storage-private.h" #include "mail-log-plugin.h" #define MAILBOX_NAME_LOG_LEN 64 #define MSGID_LOG_LEN 80 #define MAIL_LOG_CONTEXT(obj) \ *((void **)array_idx_modifiable(&(obj)->module_contexts, \ mail_log_storage_module_id)) struct mail_log_mail_storage { struct mail_storage_vfuncs super; }; struct mail_log_mailbox { struct mailbox_vfuncs super; }; struct mail_log_mail { struct mail_vfuncs super; }; /* defined by imap, pop3, lda */ extern void (*hook_mail_storage_created)(struct mail_storage *storage); const char *mail_log_plugin_version = PACKAGE_VERSION; static void (*mail_log_next_hook_mail_storage_created) (struct mail_storage *storage); static unsigned int mail_log_storage_module_id = 0; static bool mail_log_storage_module_id_set = FALSE; static void mail_log_action(struct mail *mail, const char *action) { const char *msgid; msgid = mail_get_first_header(mail, "Message-ID"); i_info("%s: uid=%u, msgid=%s", action, mail->uid, msgid == NULL ? "(null)" : str_sanitize(msgid, MSGID_LOG_LEN)); } static int mail_log_mail_expunge(struct mail *_mail) { struct mail_private *mail = (struct mail_private *)_mail; struct mail_log_mail *lmail = MAIL_LOG_CONTEXT(mail); if (lmail->super.expunge(_mail) < 0) return -1; mail_log_action(_mail, "expunged"); return 0; } static int mail_log_mail_update_flags(struct mail *_mail, enum modify_type modify_type, enum mail_flags flags) { struct mail_private *mail = (struct mail_private *)_mail; struct mail_log_mail *lmail = MAIL_LOG_CONTEXT(mail); enum mail_flags old_flags, new_flags; old_flags = mail_get_flags(_mail); if (lmail->super.update_flags(_mail, modify_type, flags) < 0) return -1; new_flags = old_flags; switch (modify_type) { case MODIFY_ADD: new_flags |= flags; break; case MODIFY_REMOVE: new_flags &= ~flags; break; case MODIFY_REPLACE: new_flags = flags; break; } if (((old_flags ^ new_flags) & MAIL_DELETED) == 0) return 0; mail_log_action(_mail, (new_flags & MAIL_DELETED) != 0 ? "deleted" : "undeleted"); return 0; } static struct mail * mail_log_mail_alloc(struct mailbox_transaction_context *t, enum mail_fetch_field wanted_fields, struct mailbox_header_lookup_ctx *wanted_headers) { struct mail_log_mailbox *lbox = MAIL_LOG_CONTEXT(t->box); struct mail_log_mail *lmail; struct mail *_mail; struct mail_private *mail; _mail = lbox->super.mail_alloc(t, wanted_fields, wanted_headers); mail = (struct mail_private *)_mail; lmail = p_new(mail->pool, struct mail_log_mail, 1); lmail->super = mail->v; mail->v.update_flags = mail_log_mail_update_flags; mail->v.expunge = mail_log_mail_expunge; array_idx_set(&mail->module_contexts, mail_log_storage_module_id, &lmail); return _mail; } static int mail_log_copy(struct mailbox_transaction_context *t, struct mail *mail, enum mail_flags flags, struct mail_keywords *keywords, struct mail *dest_mail) { struct mail_log_mailbox *lbox = MAIL_LOG_CONTEXT(t->box); const char *name; if (lbox->super.copy(t, mail, flags, keywords, dest_mail) < 0) return -1; t_push(); name = str_sanitize(mailbox_get_name(t->box), MAILBOX_NAME_LOG_LEN); mail_log_action(mail, t_strdup_printf("copy -> %s", name)); t_pop(); return 0; } static struct mailbox * mail_log_mailbox_open(struct mail_storage *storage, const char *name, struct istream *input, enum mailbox_open_flags flags) { struct mail_log_mail_storage *lstorage = MAIL_LOG_CONTEXT(storage); struct mailbox *box; struct mail_log_mailbox *lbox; box = lstorage->super.mailbox_open(storage, name, input, flags); if (box == NULL) return NULL; lbox = p_new(box->pool, struct mail_log_mailbox, 1); lbox->super = box->v; box->v.mail_alloc = mail_log_mail_alloc; box->v.copy = mail_log_copy; array_idx_set(&box->module_contexts, mail_log_storage_module_id, &lbox); return box; } static int mail_log_mailbox_delete(struct mail_storage *storage, const char *name) { struct mail_log_mail_storage *lstorage = MAIL_LOG_CONTEXT(storage); if (lstorage->super.mailbox_delete(storage, name) < 0) return -1; i_info("Mailbox deleted: %s", str_sanitize(name, MAILBOX_NAME_LOG_LEN)); return 0; } static void mail_log_mail_storage_created(struct mail_storage *storage) { struct mail_log_mail_storage *lstorage; if (mail_log_next_hook_mail_storage_created != NULL) mail_log_next_hook_mail_storage_created(storage); lstorage = p_new(storage->pool, struct mail_log_mail_storage, 1); lstorage->super = storage->v; storage->v.mailbox_open = mail_log_mailbox_open; storage->v.mailbox_delete = mail_log_mailbox_delete; if (!mail_log_storage_module_id_set) { mail_log_storage_module_id = mail_storage_module_id++; mail_log_storage_module_id_set = TRUE; } array_idx_set(&storage->module_contexts, mail_log_storage_module_id, &lstorage); } void mail_log_plugin_init(void) { mail_log_next_hook_mail_storage_created = hook_mail_storage_created; hook_mail_storage_created = mail_log_mail_storage_created; } void mail_log_plugin_deinit(void) { if (mail_log_storage_module_id_set) { hook_mail_storage_created = mail_log_next_hook_mail_storage_created; } }