diff options
-rw-r--r-- | antispam-plugin.c | 17 | ||||
-rw-r--r-- | antispam-plugin.h | 9 | ||||
-rw-r--r-- | antispam-storage-1.0.c | 46 | ||||
-rw-r--r-- | dspam-exec.c | 28 | ||||
-rw-r--r-- | signature.c | 8 | ||||
-rw-r--r-- | signature.h | 4 |
6 files changed, 75 insertions, 37 deletions
diff --git a/antispam-plugin.c b/antispam-plugin.c index 556d631..993c8c1 100644 --- a/antispam-plugin.c +++ b/antispam-plugin.c @@ -31,8 +31,8 @@ #include "lib.h" #include "str.h" #include "client.h" -#include "ostream.h" -#include "imap-search.h" +#include "mail-storage-private.h" + /* defined by imap, pop3, lda */ extern void (*hook_mail_storage_created)(struct mail_storage *storage); @@ -48,14 +48,13 @@ static char *default_spam_folders[] = { }; static char **spam_folders = default_spam_folders; -static bool mailbox_in_list(struct mail_storage *storage, struct mailbox *box, - char **list) +static bool mailbox_in_list(struct mailbox *box, char **list) { if (!list) return FALSE; while (*list) { - if (mailbox_equals(box, storage, *list)) + if (mailbox_equals(box, box->storage, *list)) return TRUE; list++; } @@ -63,14 +62,14 @@ static bool mailbox_in_list(struct mail_storage *storage, struct mailbox *box, return FALSE; } -bool mailbox_is_spam(struct mail_storage *storage, struct mailbox *box) +bool mailbox_is_spam(struct mailbox *box) { - return mailbox_in_list(storage, box, spam_folders); + return mailbox_in_list(box, spam_folders); } -bool mailbox_is_trash(struct mail_storage *storage, struct mailbox *box) +bool mailbox_is_trash(struct mailbox *box) { - return mailbox_in_list(storage, box, trash_folders); + return mailbox_in_list(box, trash_folders); } void antispam_init(void) diff --git a/antispam-plugin.h b/antispam-plugin.h index 7d9003b..de5dca3 100644 --- a/antispam-plugin.h +++ b/antispam-plugin.h @@ -20,10 +20,11 @@ void backend_init(pool_t pool); void backend_exit(void); int backend_handle_mail(struct mailbox_transaction_context *t, struct antispam_transaction_context *ast, - struct mail *mail); + struct mail *mail, bool from_spam); struct antispam_transaction_context *backend_start(struct mailbox *box); void backend_rollback(struct antispam_transaction_context *ast); -int backend_commit(struct antispam_transaction_context *ast); +int backend_commit(struct mailbox_transaction_context *ctx, + struct antispam_transaction_context *ast); #ifdef CONFIG_DEBUG void debug(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); @@ -36,7 +37,7 @@ static inline void debug(const char *fmt, ...) void antispam_mail_storage_created(struct mail_storage *storage); void (*antispam_next_hook_mail_storage_created)(struct mail_storage *storage); -bool mailbox_is_spam(struct mail_storage *storage, struct mailbox *box); -bool mailbox_is_trash(struct mail_storage *storage, struct mailbox *box); +bool mailbox_is_spam(struct mailbox *box); +bool mailbox_is_trash(struct mailbox *box); #endif /* _ANTISPAM_PLUGIN_H */ diff --git a/antispam-storage-1.0.c b/antispam-storage-1.0.c index 73a7993..e8aa6bb 100644 --- a/antispam-storage-1.0.c +++ b/antispam-storage-1.0.c @@ -25,9 +25,17 @@ struct antispam_mail_storage { struct antispam *antispam; }; +enum mailbox_move_type { + MMT_UNINTERESTING, + MMT_FROM_SPAM, + MMT_TO_SPAM, +}; + struct antispam_mailbox { struct mailbox_vfuncs super; + enum mailbox_move_type movetype; + unsigned int save_hack:1; }; @@ -50,17 +58,33 @@ antispam_copy(struct mailbox_transaction_context *t, struct mail *mail, else copy_dest_mail = mail_alloc(t, MAIL_FETCH_PHYSICAL_SIZE, NULL); + i_assert(mail->box); + asbox->save_hack = FALSE; + asbox->movetype = MMT_UNINTERESTING; + + if (!mailbox_is_trash(mail->box) && + !mailbox_is_trash(t->box)) { + bool src_spam = mailbox_is_spam(mail->box); + bool dst_spam = mailbox_is_spam(t->box); + + if (src_spam && !dst_spam) + asbox->movetype = MMT_FROM_SPAM; + else if (!src_spam && dst_spam) + asbox->movetype = MMT_TO_SPAM; + } + if (asbox->super.copy(t, mail, flags, keywords, copy_dest_mail) < 0) return -1; /* * If copying used saving internally, we already have treated the mail */ - if (asbox->save_hack) + if (asbox->save_hack || asbox->movetype == MMT_UNINTERESTING) ret = 0; else - ret = backend_handle_mail(t, ast, copy_dest_mail); + ret = backend_handle_mail(t, ast, copy_dest_mail, + asbox->movetype == MMT_FROM_SPAM); if (copy_dest_mail != dest_mail) mail_free(©_dest_mail); @@ -87,7 +111,11 @@ static int antispam_save_finish(struct mail_save_context *ctx, return -1; asbox->save_hack = TRUE; - ret = backend_handle_mail(ctx->transaction, ast, save_dest_mail); + if (asbox->movetype != MMT_UNINTERESTING) + ret = backend_handle_mail(ctx->transaction, ast, save_dest_mail, + asbox->movetype == MMT_FROM_SPAM); + else + ret = 0; if (save_dest_mail != dest_mail) mail_free(&save_dest_mail); @@ -102,8 +130,6 @@ antispam_transaction_begin(struct mailbox *box) ast = backend_start(box); i_assert(ast != NULL); - debug("antispam: transaction %p begins on %s\n", ast, box->name); - return ast; } @@ -112,21 +138,19 @@ antispam_transaction_rollback(struct antispam_transaction_context **_ast) { struct antispam_transaction_context *ast = *_ast; - debug("antispam: transaction %p rolled back\n", ast); - backend_rollback(ast); *_ast = NULL; } static int -antispam_transaction_commit(struct antispam_transaction_context **_ast) +antispam_transaction_commit(struct mailbox_transaction_context *ctx, + struct antispam_transaction_context **_ast) { struct antispam_transaction_context *ast = *_ast; int ret; - ret = backend_commit(ast); + ret = backend_commit(ctx, ast); *_ast = NULL; - debug("antispam: transaction %p commit: %d\n", ast, ret); return ret; } @@ -152,7 +176,7 @@ antispam_mailbox_transaction_commit(struct mailbox_transaction_context *ctx, struct antispam_mailbox *asbox = ANTISPAM_CONTEXT(ctx->box); struct antispam_transaction_context *ast = ANTISPAM_CONTEXT(ctx); - if (antispam_transaction_commit(&ast) < 0) { + if (antispam_transaction_commit(ctx, &ast) < 0) { asbox->super.transaction_rollback(ctx); return -1; } else diff --git a/dspam-exec.c b/dspam-exec.c index 92f016c..229b6fb 100644 --- a/dspam-exec.c +++ b/dspam-exec.c @@ -24,6 +24,7 @@ #include <fcntl.h> #include "lib.h" +#include "mail-storage-private.h" #include "antispam-plugin.h" #include "signature.h" @@ -34,7 +35,7 @@ static int extra_args_num = 0; #define FIXED_ARGS_NUM 6 -static int call_dspam(pool_t pool, const char *signature, bool is_spam) +static int call_dspam(const char *signature, bool from_spam) { pid_t pid; const char *class_arg; @@ -42,10 +43,10 @@ static int call_dspam(pool_t pool, const char *signature, bool is_spam) int pipes[2]; sign_arg = t_strconcat("--signature=", signature, NULL); - if (is_spam) - class_arg = t_strconcat("--class=", "spam", NULL); - else + if (from_spam) class_arg = t_strconcat("--class=", "innocent", NULL); + else + class_arg = t_strconcat("--class=", "spam", NULL); /* * For dspam stderr; dspam seems to not always exit with a @@ -101,7 +102,7 @@ static int call_dspam(pool_t pool, const char *signature, bool is_spam) int sz = sizeof(char *) * (FIXED_ARGS_NUM + extra_args_num); int i; - argv = p_malloc(pool, sz); + argv = i_malloc(sz); memset(argv, 0, sz); close(0); @@ -159,25 +160,32 @@ void backend_rollback(struct antispam_transaction_context *ast) i_free(ast); } -int backend_commit(struct antispam_transaction_context *ast) +int backend_commit(struct mailbox_transaction_context *ctx, + struct antispam_transaction_context *ast) { struct siglist *item = ast->siglist; + int ret = 0; while (item) { - debug("antispam: got signature %s\n", item->sig); + if (call_dspam(item->sig, item->from_spam)) { + ret = -1; + mail_storage_set_error(ctx->box->storage, + "Failed to call dspam"); + break; + } item = item->next; } signature_list_free(&ast->siglist); i_free(ast); - return 0; + return ret; } int backend_handle_mail(struct mailbox_transaction_context *t, struct antispam_transaction_context *ast, - struct mail *mail) + struct mail *mail, bool from_spam) { - return signature_extract(t, mail, &ast->siglist); + return signature_extract(t, mail, &ast->siglist, from_spam); } #if 0 diff --git a/signature.c b/signature.c index df04623..4588126 100644 --- a/signature.c +++ b/signature.c @@ -15,7 +15,8 @@ void signature_init(void) } int signature_extract(struct mailbox_transaction_context *t, - struct mail *mail, struct siglist **list) + struct mail *mail, struct siglist **list, + bool from_spam) { const char *signature; struct siglist *item; @@ -29,8 +30,11 @@ int signature_extract(struct mailbox_transaction_context *t, item = i_new(struct siglist, 1); item->next = *list; - *list = item; + item->from_spam = from_spam; item->sig = i_strdup(signature); + + *list = item; + return 0; } diff --git a/signature.h b/signature.h index ad3841a..a015fd3 100644 --- a/signature.h +++ b/signature.h @@ -7,11 +7,13 @@ struct siglist { struct siglist *next; char *sig; + bool from_spam; }; void signature_init(void); int signature_extract(struct mailbox_transaction_context *t, - struct mail *mail, struct siglist **list); + struct mail *mail, struct siglist **list, + bool from_spam); void signature_list_free(struct siglist **list); #endif /* _ANTISPAM_SIGNATURE_H */ |