/* code mostly stolen from http://www.dovecot.org/patches/1.0/copy_plugin.c */ /* make "plugins" directory right beside "src", then copy this into there and run gcc -fPIC -shared -Wall \ -I../src/lib \ -I../.. \ -I../src/lib-storage \ -I../src/lib-mail \ -I../src/lib-imap \ -I../src/imap/ \ -DHAVE_CONFIG_H spam_plugin.c -o spam_plugin.so */ #include "common.h" #include "commands.h" #include "imap-search.h" static void copy_reclassified (struct client *client, struct mail_search_arg *search_args, int is_spam) { /* TODO: iteration */ for each message in mail_search_arg do { if (is_spam) { remove message from SPAM.new-ham if it exists; /* how do I find out if that exact message exists there? */ copy message into SPAM.new-spam } else { /* similar to above */ remove message from SPAM.new-spam if it exists /* see above */ copy message into SPAM.new-ham } } } static int cmd_append_spam_plugin(struct client *client) { const char *mailbox; /* <mailbox> */ if (!client_read_string_args(client, 1, &mailbox)) return FALSE; /* TODO: is this really the best way to handle this? maybe more logic could be provided */ if (mailbox_name_equals(mailbox, "SPAM")) { client_send_tagline (client, "NO Cannot APPEND to SPAM box, sorry."); return TRUE; } return cmd_append (client); } static int cmd_copy_spam_plugin(struct client *client) { const char *messageset, *mailbox; struct mail_search_arg *search_arg; int spam_folder = 0; /* <message set> <mailbox> */ if (!client_read_string_args(client, 2, &messageset, &mailbox)) return FALSE; spam_folder = mailbox_name_equals(mailbox_get_name(client->mailbox), "SPAM") || mailbox_name_equals(mailbox, "SPAM"); if (!cmd_copy(client)) return FALSE; /* if the copy failed there's no point in doing anything with these messages */ /* only act on spam */ if ( !spam_folder ) return TRUE; /* do nothing but copying */ /* TODO: I wonder if there's a better way to get at the messages since the copy command already did this */ search_arg = imap_search_get_arg(client, messageset, client->cmd_uid); if (search_arg == NULL) return TRUE; copy_reclassified(client, search_arg, mailbox_name_equals(mailbox, "SPAM")); return TRUE; } void spam_plugin_init(void) { command_unregister("COPY"); command_unregister("APPEND"); /* i_strdup() here is a kludge to avoid crashing in commands_deinit() since modules are unloaded before it's called, this "COPY" string would otherwise point to nonexisting memory. */ command_register(i_strdup("COPY"), cmd_copy_spam_plugin); command_register(i_strdup("APPEND"), cmd_append_spam_plugin); } void spam_plugin_deinit(void) { }