Fleshed out the processing loop for sieve
[citadel.git] / citadel / serv_sieve.c
1 /*
2  * $Id: serv_test.c 3850 2005-09-13 14:00:24Z ajc $
3  *
4  *
5  */
6
7 #include "sysdep.h"
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <stdio.h>
11 #include <fcntl.h>
12 #include <signal.h>
13 #include <pwd.h>
14 #include <errno.h>
15 #include <sys/types.h>
16
17 #if TIME_WITH_SYS_TIME
18 # include <sys/time.h>
19 # include <time.h>
20 #else
21 # if HAVE_SYS_TIME_H
22 #  include <sys/time.h>
23 # else
24 #  include <time.h>
25 # endif
26 #endif
27
28 #include <sys/wait.h>
29 #include <string.h>
30 #include <limits.h>
31 #include "citadel.h"
32 #include "server.h"
33 #include "sysdep_decls.h"
34 #include "citserver.h"
35 #include "support.h"
36 #include "config.h"
37 #include "serv_extensions.h"
38 #include "room_ops.h"
39 #include "policy.h"
40 #include "database.h"
41 #include "msgbase.h"
42 #include "tools.h"
43
44 #ifdef HAVE_LIBSIEVE
45
46 #include <sieve2.h>
47 #include <sieve2_error.h>
48 #include "serv_sieve.h"
49
50 struct RoomProcList *sieve_list = NULL;
51
52 /*
53  * Add a room to the list of those rooms which potentially require sieve processing
54  */
55 void sieve_queue_room(struct ctdlroom *which_room) {
56         struct RoomProcList *ptr;
57
58         ptr = (struct RoomProcList *) malloc(sizeof (struct RoomProcList));
59         if (ptr == NULL) return;
60
61         safestrncpy(ptr->name, which_room->QRname, sizeof ptr->name);
62         begin_critical_section(S_SIEVELIST);
63         ptr->next = sieve_list;
64         sieve_list = ptr;
65         end_critical_section(S_SIEVELIST);
66 }
67
68
69
70 /*
71  * Perform sieve processing for one message (called by sieve_do_room() for each message)
72  */
73 void sieve_do_msg(long msgnum, void *userdata) {
74         lprintf(CTDL_DEBUG, "Performing sieve processing on msg <%ld>\n", msgnum);
75         return;
76 }
77
78
79 /*
80  * Perform sieve processing for a single room
81  * FIXME ... actually do this instead of just talking about it
82  */
83 void sieve_do_room(char *roomname) {
84
85         /* FIXME check to see if this room has any sieve scripts to run */
86
87         lprintf(CTDL_DEBUG, "Performing Sieve processing for <%s>\n", roomname);
88
89         if (getroom(&CC->room, roomname) != 0) {
90                 lprintf(CTDL_CRIT, "ERROR: cannot load <%s>\n", roomname);
91                 return;
92         }
93
94         /* Do something useful */
95         /* CtdlForEachMessage(MSGS_GT, sc.lastsent, NULL, NULL, NULL, */
96         /* FIXME figure out which messages haven't yet been processed by sieve */
97         CtdlForEachMessage(MSGS_LAST, 1, NULL, NULL, NULL,
98                 sieve_do_msg,
99                 NULL            /* data for callback could be the script? */
100         );
101 }
102
103
104 /*
105  * Perform sieve processing for all rooms which require it
106  */
107 void perform_sieve_processing(void) {
108         struct RoomProcList *ptr = NULL;
109
110         if (sieve_list != NULL) {
111                 lprintf(CTDL_DEBUG, "Begin Sieve processing\n");
112                 while (sieve_list != NULL) {
113                         char spoolroomname[ROOMNAMELEN];
114                         safestrncpy(spoolroomname, sieve_list->name, sizeof spoolroomname);
115                         begin_critical_section(S_SIEVELIST);
116
117                         /* pop this record off the list */
118                         ptr = sieve_list;
119                         sieve_list = sieve_list->next;
120                         free(ptr);
121
122                         /* invalidate any duplicate entries to prevent double processing */
123                         for (ptr=sieve_list; ptr!=NULL; ptr=ptr->next) {
124                                 if (!strcasecmp(ptr->name, spoolroomname)) {
125                                         ptr->name[0] = 0;
126                                 }
127                         }
128
129                         end_critical_section(S_SIEVELIST);
130                         if (spoolroomname[0] != 0) {
131                                 sieve_do_room(spoolroomname);
132                         }
133                 }
134         }
135 }
136
137
138
139 /**
140  *      We don't really care about dumping the entire credits to the log
141  *      every time the server is initialized.  The documentation will suffice
142  *      for that purpose.  We are making a call to sieve2_credits() in order
143  *      to demonstrate that we have successfully linked in to libsieve.
144  */
145 void log_the_sieve2_credits(void) {
146         char *cred = NULL;
147
148         cred = strdup(sieve2_credits());
149         if (cred == NULL) return;
150
151         if (strlen(cred) > 60) {
152                 strcpy(&cred[55], "...");
153         }
154
155         lprintf(CTDL_INFO, "%s\n",cred);
156         free(cred);
157 }
158
159
160 char *serv_sieve_init(void)
161 {
162         log_the_sieve2_credits();
163         return "$Id: serv_sieve.c 3850 2005-09-13 14:00:24Z ajc $";
164 }
165
166 #else   /* HAVE_LIBSIEVE */
167
168 char *serv_sieve_init(void)
169 {
170         lprintf(CTDL_INFO, "This server is missing libsieve.  Mailbox filtering will be disabled.\n");
171         return "$Id: serv_sieve.c 3850 2005-09-13 14:00:24Z ajc $";
172 }
173
174 #endif  /* HAVE_LIBSIEVE */