Ajout : dovecot-antispam + amavis + crm114.
[lhc/ateliers.git] / etc / dovecot / dovecot-antispam-call-backend-with-imap-keywords.patch
1 diff -ru a/dovecot-antispam-2.0+20120225/antispam-plugin.c b/dovecot-antispam-2.0+20120225/antispam-plugin.c
2 --- a/dovecot-antispam-2.0+20120225/antispam-plugin.c 2012-02-24 20:22:48.000000000 +0100
3 +++ b/dovecot-antispam-2.0+20120225/antispam-plugin.c 2013-07-29 07:14:51.962245023 +0200
4 @@ -246,6 +246,21 @@
5
6 return FALSE;
7 }
8 +bool keyword_is_ham(const struct antispam_config *cfg, const char *keyword)
9 +{
10 + char **k = cfg->ham_keywords;
11 +
12 + if (!cfg->ham_keywords)
13 + return FALSE;
14 +
15 + while (*k) {
16 + if (strcmp(*k, keyword) == 0)
17 + return TRUE;
18 + k++;
19 + }
20 +
21 + return FALSE;
22 +}
23
24 static int parse_folder_setting(const struct antispam_config *cfg,
25 const char *setting, char ***strings,
26 @@ -335,6 +350,17 @@
27 iter++;
28 }
29 }
30 + tmp = getenv("HAM_KEYWORDS", getenv_data);
31 + if (tmp)
32 + cfg->ham_keywords = p_strsplit(cfg->mem_pool, tmp, ";");
33 +
34 + if (cfg->ham_keywords) {
35 + iter = cfg->ham_keywords;
36 + while (*iter) {
37 + debug(&cfg->dbgcfg, "\"%s\" is ham keyword\n", *iter);
38 + iter++;
39 + }
40 + }
41
42 tmp = getenv("BACKEND", getenv_data);
43 if (tmp) {
44 diff -ru a/dovecot-antispam-2.0+20120225/antispam-plugin.h b/dovecot-antispam-2.0+20120225/antispam-plugin.h
45 --- a/dovecot-antispam-2.0+20120225/antispam-plugin.h 2013-07-31 12:45:33.000000000 +0200
46 +++ b/dovecot-antispam-2.0+20120225/antispam-plugin.h 2013-07-30 05:22:21.248730740 +0200
47 @@ -27,6 +27,7 @@
48 struct antispam_transaction_context;
49
50 enum classification {
51 + CLASS_UNSURE,
52 CLASS_NOTSPAM,
53 CLASS_SPAM,
54 };
55 @@ -72,6 +73,7 @@
56 char **unsure_folders[3]; // = { NULL, NULL, NULL };
57
58 char **spam_keywords;
59 + char **ham_keywords;
60
61 const char *signature_hdr;
62
63 @@ -178,6 +180,7 @@
64 bool mailbox_is_trash(const struct antispam_config *cfg, struct mailbox *box);
65 bool mailbox_is_unsure(const struct antispam_config *cfg, struct mailbox *box);
66 bool keyword_is_spam(const struct antispam_config *cfg, const char *keyword);
67 +bool keyword_is_ham(const struct antispam_config *cfg, const char *keyword);
68
69 struct antispam_config *
70 antispam_setup_config(const char *(getenv)(const char *env, void *data),
71 diff -ru a/dovecot-antispam-2.0+20120225/antispam-storage-2.0.c b/dovecot-antispam-2.0+20120225/antispam-storage-2.0.c
72 --- a/dovecot-antispam-2.0+20120225/antispam-storage-2.0.c 2012-02-24 20:22:48.000000000 +0100
73 +++ b/dovecot-antispam-2.0+20120225/antispam-storage-2.0.c 2013-07-31 14:52:43.277922438 +0200
74 @@ -310,21 +310,9 @@
75 const ARRAY_TYPE(keywords) *idxkwd = mail_index_get_keywords(keywords->index);
76 const char *const *keyword_names = array_get(idxkwd, &numkwds);
77 const char *const *orig_keywords;
78 - bool previous_spam_keyword, now_spam_keyword;
79 -
80 - switch (modify_type) {
81 - case MODIFY_ADD:
82 - debug(&amail->cfg->dbgcfg, "adding keyword(s)\n");
83 - break;
84 - case MODIFY_REMOVE:
85 - debug(&amail->cfg->dbgcfg, "removing keyword(s)\n");
86 - break;
87 - case MODIFY_REPLACE:
88 - debug(&amail->cfg->dbgcfg, "replacing keyword(s)\n");
89 - break;
90 - default:
91 - i_assert(0);
92 - }
93 + bool previous_spam_keyword = FALSE, previous_ham_keyword = FALSE;
94 + enum classification spam_class = CLASS_UNSURE;
95 + struct antispam_transaction_context *ast;
96
97 orig_keywords = pmail->v.get_keywords(mail);
98 if (orig_keywords) {
99 @@ -333,6 +321,8 @@
100 debug(&amail->cfg->dbgcfg, " * %s\n", *orig_keywords);
101 if (keyword_is_spam(amail->cfg, *orig_keywords))
102 previous_spam_keyword = TRUE;
103 + if (keyword_is_ham(amail->cfg, *orig_keywords))
104 + previous_ham_keyword = TRUE;
105 orig_keywords++;
106 }
107 }
108 @@ -350,29 +340,47 @@
109 case MODIFY_ADD:
110 case MODIFY_REPLACE:
111 if (keyword_is_spam(amail->cfg, keyword_names[idx]))
112 - now_spam_keyword = TRUE;
113 + spam_class = CLASS_SPAM;
114 + if (keyword_is_ham(amail->cfg, keyword_names[idx]))
115 + spam_class = CLASS_NOTSPAM;
116 break;
117 case MODIFY_REMOVE:
118 if (keyword_is_spam(amail->cfg, keyword_names[idx]))
119 - now_spam_keyword = FALSE;
120 + spam_class = CLASS_NOTSPAM;
121 + if (keyword_is_ham(amail->cfg, keyword_names[idx]))
122 + spam_class = CLASS_SPAM;
123 break;
124 default:
125 i_assert(0);
126 }
127 }
128 -
129 +
130 + debug(&amail->cfg->dbgcfg, "spam_class=%d previous_spam_keyword=%d previous_ham_keyword=%d\n",
131 + spam_class, previous_spam_keyword, previous_ham_keyword);
132 +
133 amail->module_ctx.super.update_keywords(mail, modify_type, keywords);
134 -
135 - debug(&amail->cfg->dbgcfg, "previous-spam, now-spam: %d, %d\n",
136 - previous_spam_keyword, now_spam_keyword);
137 -
138 - if (previous_spam_keyword != now_spam_keyword) {
139 - /*
140 - * Call backend here.
141 - *
142 - * TODO: It is not clear how to roll back the
143 - * keyword change if the backend fails.
144 +
145 + if (previous_spam_keyword && previous_ham_keyword) {
146 + /* NOTE: avoid to call the backend two times for the same change
147 + * once when adding one spam or ham keyword
148 + * and once when removing the other.
149 + */
150 + debug(&amail->cfg->dbgcfg, "does not run backend a second time\n");
151 + return;
152 + }
153 +
154 + if (spam_class != CLASS_UNSURE) {
155 + /* NOTE: on error, backend uses mail_storage_set_error()
156 + * which is checked in commit() where a rollback() can be done.
157 */
158 + debug(&amail->cfg->dbgcfg, "call backend->start()\n");
159 + ast = amail->cfg->backend->start(amail->cfg, mail->transaction->box);
160 + i_assert(ast != NULL);
161 + debug(&amail->cfg->dbgcfg, "call backend->handle_mail()\n");
162 + if (!amail->cfg->backend->handle_mail(amail->cfg, mail->transaction, ast, mail, spam_class)) {
163 + debug(&amail->cfg->dbgcfg, "call backend->commit()\n");
164 + amail->cfg->backend->commit(amail->cfg, mail->transaction, ast);
165 + }
166 }
167 }
168
169 @@ -401,7 +409,9 @@
170 struct antispam_mailbox *asbox = ANTISPAM_CONTEXT(ctx->box);
171 struct antispam_internal_context *ast = ANTISPAM_CONTEXT(ctx);
172
173 - if (antispam_transaction_commit(asbox->cfg, ctx, &ast->backendctx) < 0) {
174 + if ((ctx->box->storage->error != MAIL_ERROR_NONE)
175 + || antispam_transaction_commit(asbox->cfg, ctx, &ast->backendctx) < 0) {
176 + debug(&asbox->cfg->dbgcfg, "transaction rollback\n");
177 if (ast->mail)
178 mail_free(&ast->mail);
179
180 diff -ru a/dovecot-antispam-2.0+20120225/crm114-exec.c b/dovecot-antispam-2.0+20120225/crm114-exec.c
181 --- a/dovecot-antispam-2.0+20120225/crm114-exec.c 2012-02-24 20:22:48.000000000 +0100
182 +++ b/dovecot-antispam-2.0+20120225/crm114-exec.c 2013-07-30 06:00:16.266596502 +0200
183 @@ -43,6 +43,8 @@
184 case CLASS_SPAM:
185 class_arg = "--spam";
186 break;
187 + default:
188 + i_assert(0);
189 }
190
191 /*
192 diff -ru a/dovecot-antispam-2.0+20120225/dspam-exec.c b/dovecot-antispam-2.0+20120225/dspam-exec.c
193 --- a/dovecot-antispam-2.0+20120225/dspam-exec.c 2012-02-24 20:22:48.000000000 +0100
194 +++ b/dovecot-antispam-2.0+20120225/dspam-exec.c 2013-07-31 13:28:39.217464532 +0200
195 @@ -45,6 +45,8 @@
196 case CLASS_SPAM:
197 class_arg = t_strconcat("--class=", "spam", NULL);
198 break;
199 + default:
200 + i_assert(0);
201 }
202
203 /*
204 diff -ru a/dovecot-antispam-2.0+20120225/pipe.c b/dovecot-antispam-2.0+20120225/pipe.c
205 --- a/dovecot-antispam-2.0+20120225/pipe.c 2012-02-24 20:22:48.000000000 +0100
206 +++ b/dovecot-antispam-2.0+20120225/pipe.c 2013-07-31 14:16:12.164255967 +0200
207 @@ -48,6 +48,8 @@
208 dest = cfg->pipe.ham_args;
209 dest_num = cfg->pipe.spam_args_num;
210 break;
211 + default:
212 + i_assert(0);
213 }
214
215 if (!dest)