aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--antispam-plugin.c17
-rw-r--r--antispam-plugin.h9
-rw-r--r--antispam-storage-1.0.c46
-rw-r--r--dspam-exec.c28
-rw-r--r--signature.c8
-rw-r--r--signature.h4
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(&copy_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 */