Removed excess return from init function as it breaks the build with a
[citadel.git] / citadel / modules / dspam / serv_dspam.c
1 /*
2  * $Id: serv_dspam.c 5876 2007-12-10 23:22:03Z dothebart $
3  *
4  * This module glues libDSpam to the Citadel server in order to implement
5  * DSPAM Spamchecking 
6  *
7  * This code is released under the terms of the GNU General Public License. 
8  */
9
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>
19
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
30
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"
45
46
47 #include "ctdl_module.h"
48
49
50 #ifdef HAVE_LIBDSPAM
51
52 #undef HAVE_CONFIG_H
53 #include <dspam/libdspam.h>
54 #define HAVE_CONFIG_H
55 /*
56  * Citadel protocol to manage sieve scripts.
57  * This is basically a simplified (read: doesn't resemble IMAP) version
58  * of the 'managesieve' protocol.
59  */
60 void cmd_tspam(char *argbuf) {
61         
62
63         /* tag mails as spam or Ham */
64         /* probably do: dspam_init(ctdl_dspam_dir); dspam_process dspam_addattribute; dspam_destroy*/
65         // extract DSS_ERROR or DSS_CORPUS from the commandline. error->ham; corpus -> spam?
66 }
67
68
69
70 void ctdl_dspam_init(void) {
71
72         libdspam_init("bdb");/* <which database backend do we prefer? */
73
74 }
75
76 void dspam_do_msg(long msgnum, void *userdata) 
77 {
78         DSPAM_CTX *CTX;                 /* DSPAM Context */
79         struct CtdlMessage *msg;
80         struct _ds_spam_signature SIG;        /* signature */
81
82         CTX = *(DSPAM_CTX**) userdata;
83         msg = CtdlFetchMessage(msgnum, 0);
84         if (msg == NULL) return;
85         CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_ALL, 0, 1);
86
87         /* Call DSPAM's processor with the message text */
88         if (dspam_process (CTX, msg->cm_fields['A']) != 0)
89         {
90                 lprintf(CTDL_CRIT, "ERROR: dspam_process failed");
91                 return;
92         }
93         if (CTX->signature == NULL)
94         {
95                 lprintf(CTDL_CRIT,"No signature provided\n");
96         }
97         else
98         {
99 /* Copy to a safe place */
100
101                 SIG.data = malloc (CTX->signature->length);
102                 if (SIG.data != NULL)
103                         memcpy (SIG.data, CTX->signature->data, CTX->signature->length);
104         }
105         SIG.length = CTX->signature->length;
106         /* Print processing results */
107         printf ("Probability: %2.4f Confidence: %2.4f, Result: %s\n",
108                 CTX->probability,
109                 CTX->confidence,
110                 (CTX->result == DSR_ISSPAM) ? "Spam" : "Innocent");
111
112         //// todo: put signature into the citadel message
113         //// todo: save message; destroy message.
114 }
115
116 int serv_dspam_room(struct ctdlroom *room)
117 {
118         DSPAM_CTX *CTX;                 /* DSPAM Context */
119
120         /* scan for spam; do */
121         /* probably do: dspam_init; dspam_process dspam_addattribute; dspam_destroy*/
122 //DSS_NONE
123 //#define       DSR_ISSPAM              0x01
124 //#define DSR_ISINNOCENT                0x02
125 // dspam_init (cc->username, NULL, ctdl_dspam_home, DSM_PROCESS,
126         //                  DSF_SIGNATURE | DSF_NOISE);
127         /// todo: if roomname = spam / ham -> learn!
128         if (room->QRflags & QR_PRIVATE) /* Are we sending to a private mailbox? */
129         {
130                 char User[64];
131                 // maybe we should better get our realname here?
132                 snprintf(User, 64, "%ld", room->QRroomaide);
133
134                 CTX = dspam_init(User, 
135                                  NULL,
136                                  ctdl_dspam_dir, 
137                                  DSM_PROCESS, 
138                                  DSF_SIGNATURE | DSF_NOISE);
139         }
140         /// else -> todo: global user for public rooms etc.
141         if (CTX == NULL)
142         {
143                 lprintf(CTDL_CRIT, "ERROR: dspam_init failed!\n");
144                 return ERROR + INTERNAL_ERROR;
145         }
146         /* Use graham and robinson algorithms, graham's p-values */
147         CTX->algorithms = DSA_GRAHAM | DSA_BURTON | DSP_GRAHAM;
148
149         /* Use CHAIN tokenizer */
150         CTX->tokenizer = DSZ_CHAIN;
151
152         CtdlForEachMessage(MSGS_GT, NULL, NULL, NULL, NULL,
153                            dspam_do_msg,
154                            (void *) &CTX);
155
156         return 0;
157 }
158
159 void serv_dspam_shutdown (void)
160 {
161         libdspam_shutdown ();
162 }
163 #endif  /* HAVE_LIBDSPAM */
164
165 CTDL_MODULE_INIT(dspam)
166 {
167         if (!threading)
168         {
169 #ifdef HAVE_LIBDSPAM
170
171                 ctdl_dspam_init();
172                 CtdlRegisterCleanupHook(serv_dspam_shutdown);
173                 CtdlRegisterProtoHook(cmd_tspam, "SPAM", "Tag Message as Spam/Ham to learn DSPAM");
174
175                 CtdlRegisterRoomHook(serv_dspam_room);
176
177                 ///CtdlRegisterSessionHook(perform_dspam_processing, EVT_HOUSE);
178
179 #else   /* HAVE_LIBDSPAM */
180
181                 lprintf(CTDL_INFO, "This server is missing libdspam Spam filtering will be disabled.\n");
182
183 #endif  /* HAVE_LIBDSPAM */
184         }
185         
186         /* return our Subversion id for the Log */
187         return "$Id: serv_dspam.c 5876 2007-12-10 23:22:03Z dothebart $";
188 }
189