* Fixed problems related to saving vCards in config rooms. For starters, we were...
[citadel.git] / citadel / modules / dspam / serv_dspam.c
blob1c0c0d7c4e9933669a5a3913710cf192361f7775
1 /*
2 * $Id: serv_dspam.c 5876 2007-12-10 23:22:03Z dothebart $
4 * This module glues libDSpam to the Citadel server in order to implement
5 * DSPAM Spamchecking
7 * This code is released under the terms of the GNU General Public License.
8 */
10 #include "sysdep.h"
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <stdio.h>
14 #include <fcntl.h>
15 #include <ctype.h>
16 #include <pwd.h>
17 #include <errno.h>
18 #include <sys/types.h>
20 #if TIME_WITH_SYS_TIME
21 # include <sys/time.h>
22 # include <time.h>
23 #else
24 # if HAVE_SYS_TIME_H
25 # include <sys/time.h>
26 # else
27 # include <time.h>
28 # endif
29 #endif
31 #include <sys/wait.h>
32 #include <string.h>
33 #include <limits.h>
34 #include <libcitadel.h>
35 #include "citadel.h"
36 #include "server.h"
37 #include "citserver.h"
38 #include "support.h"
39 #include "config.h"
40 #include "room_ops.h"
41 #include "policy.h"
42 #include "database.h"
43 #include "msgbase.h"
44 #include "internet_addressing.h"
47 #include "ctdl_module.h"
50 #ifdef HAVE_LIBDSPAM
51 #define CONFIG_DEFAULT file_dpsam_conf
52 #define LOGDIR file_dspam_log
55 //#define HAVE_CONFIG_H
56 #include <dspam/libdspam.h>
57 //#define HAVE_CONFIG_H
59 typedef struct stringlist stringlist;
61 struct stringlist {
62 char *Str;
63 long len;
64 stringlist *Next;
69 * Citadel protocol to manage sieve scripts.
70 * This is basically a simplified (read: doesn't resemble IMAP) version
71 * of the 'managesieve' protocol.
73 void cmd_tspam(char *argbuf) {
74 char buf[SIZ];
75 long len;
76 long count;
77 stringlist *Messages;
78 stringlist *NextMsg;
80 Messages = NULL;
81 NextMsg = NULL;
82 count = 0;
83 if (CtdlAccessCheck(ac_room_aide)) return;
84 if (atoi(argbuf) == 0) {
85 cprintf("%d Ok.\n", CIT_OK);
86 return;
88 cprintf("%d Send info...\n", SEND_LISTING);
90 do {
91 len = client_getln(buf, sizeof buf);
92 if (strcmp(buf, "000")) {
93 if (Messages == NULL) {
94 Messages = malloc (sizeof (stringlist));
95 NextMsg = Messages;
97 else {
98 Messages->Next = malloc (sizeof (stringlist));
99 NextMsg = NextMsg->Next;
101 NextMsg->Next = NULL;
102 NextMsg->Str = malloc (len+1);
103 NextMsg->len = len;
104 memcpy (NextMsg->Str, buf, len + 1);/// maybe split spam /ham per line?
105 count++;
107 } while (strcmp(buf, "000"));
108 /// is there a way to filter foreachmessage by a list?
109 /* tag mails as spam or Ham */
110 /* probably do: dspam_init(ctdl_dspam_dir); dspam_process dspam_addattribute; dspam_destroy*/
111 // extract DSS_ERROR or DSS_CORPUS from the commandline. error->ham; corpus -> spam?
112 /// todo: send answer listing...
117 void ctdl_dspam_init(void) {
119 /// libdspam_init("bdb");/* <which database backend do we prefer? */
123 void dspam_do_msg(long msgnum, void *userdata)
125 char *msgtext;
126 DSPAM_CTX *CTX; /* DSPAM Context */
127 struct CtdlMessage *msg;
128 struct _ds_spam_signature SIG; /* signature */
130 CTX = *(DSPAM_CTX**) userdata;
131 msg = CtdlFetchMessage(msgnum, 0);
132 if (msg == NULL) return;
135 /* Message */
136 CC->redirect_buffer = malloc(SIZ);
137 CC->redirect_len = 0;
138 CC->redirect_alloc = SIZ;
139 CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_ALL, 0, 1, 0);
140 msgtext = CC->redirect_buffer;
141 // don't need? msglen = CC->redirect_len;
142 CC->redirect_buffer = NULL;
143 CC->redirect_len = 0;
144 CC->redirect_alloc = 0;
146 /* Call DSPAM's processor with the message text */
147 if (dspam_process (CTX, msgtext) != 0)
149 free(msgtext);
150 CtdlLogPrintf(CTDL_CRIT, "ERROR: dspam_process failed");
151 return;
153 if (CTX->signature == NULL)
155 CtdlLogPrintf(CTDL_CRIT,"No signature provided\n");
157 else
159 /* Copy to a safe place */
161 msg->cm_fields['G'] = malloc (CTX->signature->length * 2);
162 CtdlEncodeBase64(msg->cm_fields['G'], CTX->signature->data, CTX->signature->length, 0);
164 free(msgtext);
166 SIG.length = CTX->signature->length;
167 /* Print processing results */
168 CtdlLogPrintf (CTDL_DEBUG, "Probability: %2.4f Confidence: %2.4f, Result: %s\n",
169 CTX->probability,
170 CTX->confidence,
171 (CTX->result == DSR_ISSPAM) ? "Spam" : "Innocent");
173 //// todo: put signature into the citadel message
174 //// todo: save message; destroy message.
177 int serv_dspam_room(struct ctdlroom *room)
179 DSPAM_CTX *CTX; /* DSPAM Context */
181 /* scan for spam; do */
182 /* probably do: dspam_init; dspam_process dspam_addattribute; dspam_destroy*/
183 //DSS_NONE
184 //#define DSR_ISSPAM 0x01
185 //#define DSR_ISINNOCENT 0x02
186 // dspam_init (cc->username, NULL, ctdl_dspam_home, DSM_PROCESS,
187 // DSF_SIGNATURE | DSF_NOISE);
188 /// todo: if roomname = spam / ham -> learn!
189 if ((room->QRflags & QR_PRIVATE) &&/* Are we sending to a private mailbox? */
190 (strstr(room->QRname, ".Mail")!=NULL))
193 char User[64];
194 // maybe we should better get our realname here?
195 snprintf(User, 64, "%ld", room->QRroomaide);
196 extract_token(User, room->QRname, 0, '.', sizeof(User));
197 CTX = dspam_init(User,
198 NULL,
199 ctdl_dspam_dir,
200 DSM_PROCESS,
201 DSF_SIGNATURE | DSF_NOISE);
203 else return 0;////
204 /// else -> todo: global user for public rooms etc.
205 if (CTX == NULL)
207 CtdlLogPrintf(CTDL_CRIT, "ERROR: dspam_init failed!\n");
208 return ERROR + INTERNAL_ERROR;
210 /* Use graham and robinson algorithms, graham's p-values */
211 CTX->algorithms = DSA_GRAHAM | DSA_BURTON | DSP_GRAHAM;
213 /* Use CHAIN tokenizer */
214 CTX->tokenizer = DSZ_CHAIN;
216 CtdlForEachMessage(MSGS_GT, 1, NULL, NULL, NULL,
217 dspam_do_msg,
218 (void *) &CTX);
220 return 0;
223 void serv_dspam_shutdown (void)
225 libdspam_shutdown ();
227 #endif /* HAVE_LIBDSPAM */
229 CTDL_MODULE_INIT(dspam)
231 return "$Id: serv_dspam.c 5876 2007-12-10 23:22:03Z dothebart $" "disabled.";
232 if (!threading)
234 #ifdef HAVE_LIBDSPAM
236 ctdl_dspam_init();
237 CtdlRegisterCleanupHook(serv_dspam_shutdown);
238 CtdlRegisterProtoHook(cmd_tspam, "SPAM", "Tag Message as Spam/Ham to learn DSPAM");
240 CtdlRegisterRoomHook(serv_dspam_room);
242 ///CtdlRegisterSessionHook(perform_dspam_processing, EVT_HOUSE);
244 #else /* HAVE_LIBDSPAM */
246 CtdlLogPrintf(CTDL_INFO, "This server is missing libdspam Spam filtering will be disabled.\n");
248 #endif /* HAVE_LIBDSPAM */
251 /* return our Subversion id for the Log */
252 return "$Id: serv_dspam.c 5876 2007-12-10 23:22:03Z dothebart $";