]> code.citadel.org Git - citadel.git/blob - webcit/sieve.c
be9484b783170bd425e2996fee7c0dc26425341a
[citadel.git] / webcit / sieve.c
1 /*
2  * Copyright (c) 1996-2011 by the citadel.org team
3  *
4  * This program is open source software.  You can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 3 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */
18
19 #include "webcit.h"
20
21 #define MAX_SCRIPTS     100
22 #define MAX_RULES       50
23 #define RULES_SCRIPT    "__WebCit_Generated_Script__"
24 <<<<<<< HEAD
25
26
27 /*
28  * dummy panel indicating to the user that the server doesn't support Sieve
29  */
30 void display_no_sieve(void) {
31
32         output_headers(1, 1, 2, 0, 0, 0);
33
34         wc_printf("<div id=\"banner\">\n");
35         wc_printf("<img src=\"static/webcit_icons/essen/32x32/config.png\">");
36         wc_printf("<h1>");
37         wc_printf(_("View/edit server-side mail filters"));
38         wc_printf("</h1>\n");
39         wc_printf("</div>\n");
40
41         wc_printf("<div id=\"content\" class=\"service\">\n");
42
43         wc_printf("<table class=\"sieve_background\">"
44                 "<tr><td valign=top>\n");
45
46         wc_printf(_("This installation of Citadel was built without support for server-side mail filtering."
47                 "<br>Please contact your system administrator if you require this feature.<br>"));
48
49         wc_printf("</td></tr></table>\n");
50         wDumpContent(1);
51 }
52
53
54 /*
55  * view/edit sieve config
56  */
57 void display_sieve(void)
58 {
59         char script_names[MAX_SCRIPTS][64];
60         int num_scripts = 0;
61         int active_script = (-1);
62         char buf[SIZ];          /* Don't make this buffer smaller or it will restrict line length */
63         int i;
64         int rules_script_is_active = 0;
65
66         if (!WC->serv_info->serv_supports_sieve) {
67                 display_no_sieve();
68                 return;
69         }
70
71         memset(script_names, 0, sizeof script_names);
72
73         serv_puts("MSIV listscripts");
74         serv_getln(buf, sizeof(buf));
75         if (buf[0] == '1') while (serv_getln(buf, sizeof(buf)), strcmp(buf, "000")) {
76                 if (num_scripts < MAX_SCRIPTS) {
77                         extract_token(script_names[num_scripts], buf, 0, '|', 64);
78                         if (extract_int(buf, 1) > 0) {
79                                 active_script = num_scripts;
80                                 if (!strcasecmp(script_names[num_scripts], RULES_SCRIPT)) {
81                                         rules_script_is_active = 1;
82                                 }
83                         }
84                         ++num_scripts;
85                 }
86         }
87
88         output_headers(1, 1, 2, 0, 0, 0);
89
90         wc_printf("<script type=\"text/javascript\">                                    \n"
91                 "                                                                       \n"
92                 "var previously_active_script;                                          \n"
93                 "                                                                       \n"
94                 "function ToggleSievePanels() {                                         \n"
95                 " d = ($('sieveform').bigaction.options[$('sieveform').bigaction.selectedIndex].value); \n"
96                 " for (i=0; i<3; ++i) {                                                 \n"
97                 "  if (i == d) {                                                        \n"
98                 "   $('sievediv' + i).style.display = 'block';                          \n"
99                 "  }                                                                    \n"
100                 "  else {                                                               \n"
101                 "   $('sievediv' + i).style.display = 'none';                           \n"
102                 "  }                                                                    \n"
103                 " }                                                                     \n"
104                 "}                                                                      \n"
105                 "                                                                       \n"
106                 "function ToggleScriptPanels() {                                        \n"
107                 " d = ($('sieveform').active_script.options[$('sieveform').active_script.selectedIndex].value); \n"
108                 " if ($('script_' + previously_active_script)) {                        \n"
109                 "  $('script_' + previously_active_script).style.display = 'none';      \n"
110                 " }                                                                     \n"
111                 " $('script_' + d).style.display = 'block';                             \n"
112                 " previously_active_script = d;                                         \n"
113                 "}                                                                      \n"
114                 "                                                                       \n"
115                 "</script>                                                              \n"
116         );
117
118         wc_printf("<div id=\"banner\">\n");
119         wc_printf("<img src=\"static/webcit_icons/essen/32x32/config.png\">");
120         wc_printf("<h1>");
121         wc_printf(_("View/edit server-side mail filters"));
122         wc_printf("</h1>\n");
123         wc_printf("</div>\n");
124
125         wc_printf("<div id=\"content\" class=\"service\">\n");
126
127         wc_printf("<table class=\"sieve_background\">"
128                 "<tr><td valign=top>\n");
129
130
131         wc_printf("<form id=\"sieveform\" method=\"post\" action=\"save_sieve\">\n");
132         wc_printf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
133
134         wc_printf(_("When new mail arrives: "));
135         wc_printf("<select name=\"bigaction\" size=1 onChange=\"ToggleSievePanels();\">\n");
136
137         wc_printf("<option %s value=\"0\">", ((active_script < 0) ? "selected" : ""));
138         wc_printf(_("Leave it in my inbox without filtering"));
139         wc_printf("</option>\n");
140
141         wc_printf("<option %s value=\"1\">", ((rules_script_is_active) ? "selected" : ""));
142         wc_printf(_("Filter it according to rules selected below"));
143         wc_printf("</option>\n");
144
145         wc_printf("<option %s value=\"2\">",
146                         (((active_script >= 0) && (!rules_script_is_active)) ? "selected" : ""));
147         wc_printf(_("Filter it through a manually edited script (advanced users only)"));
148         wc_printf("</option>\n");
149
150         wc_printf("</select>");
151
152
153
154         /* The "no filtering" div */
155
156         wc_printf("<div id=\"sievediv0\" style=\"display:none\">\n");
157         wc_printf("<div align=\"center\"><br><br>");
158         wc_printf(_("Your incoming mail will not be filtered through any scripts."));
159         wc_printf("<br><br></div>\n");
160         wc_printf("</div>\n");
161
162         /* The "webcit managed scripts" div */
163
164         wc_printf("<div id=\"sievediv1\" style=\"display:none\">\n");
165         display_rules_editor_inner_div();
166         wc_printf("</div>\n");
167
168         /* The "I'm smart and can write my own Sieve scripts" div */
169
170         wc_printf("<div id=\"sievediv2\" style=\"display:none\">\n");
171
172         if (num_scripts > 0) {
173                 wc_printf(_("The currently active script is: "));
174                 wc_printf("<select name=\"active_script\" size=1 onChange=\"ToggleScriptPanels();\">\n");
175                 for (i=0; i<num_scripts; ++i) {
176                         if (strcasecmp(script_names[i], RULES_SCRIPT)) {
177                                 wc_printf("<option %s value=\"%s\">%s</option>\n",
178                                         ((active_script == i) ? "selected" : ""),
179                                         script_names[i],
180                                         script_names[i]
181                                 );
182                         }
183                 }
184                 wc_printf("</select>\n");
185         }
186
187         wc_printf("&nbsp;&nbsp;&nbsp;");
188         wc_printf("<a href=\"display_add_remove_scripts\">%s</a>\n", _("Add or delete scripts"));
189
190         wc_printf("<br>\n");
191
192         if (num_scripts > 0) {
193                 for (i=0; i<num_scripts; ++i) {
194                         if (strcasecmp(script_names[i], RULES_SCRIPT)) {
195                                 wc_printf("<div id=\"script_%s\" style=\"display:none\">\n", script_names[i]);
196                                 wc_printf("<textarea name=\"text_%s\" wrap=soft rows=20 cols=80 width=80>\n",
197                                         script_names[i]);
198                                 serv_printf("MSIV getscript|%s", script_names[i]);
199                                 serv_getln(buf, sizeof buf);
200                                 if (buf[0] == '1') while(serv_getln(buf, sizeof (buf)), strcmp(buf, "000")) {
201                                         wc_printf("%s\n", buf);
202                                 }
203                                 wc_printf("</textarea>\n");
204                                 wc_printf("</div>\n");
205                         }
206                 }
207         }
208
209         wc_printf("<script type=\"text/javascript\">    \n"
210                 "ToggleScriptPanels();                  \n"
211                 "</script>                              \n"
212         );
213
214         wc_printf("</div>\n");
215
216
217         /* The rest of this is common for all panels... */
218
219         wc_printf("<div align=\"center\"><br>");
220         wc_printf("<input type=\"submit\" name=\"save_button\" value=\"%s\">", _("Save changes"));
221         wc_printf("&nbsp;");
222         wc_printf("<input type=\"submit\" name=\"cancel_button\" value=\"%s\">\n", _("Cancel"));
223         wc_printf("</div></form>\n");
224
225         wc_printf("</td></tr></table>\n");
226
227         wc_printf("<script type=\"text/javascript\">    \n"
228                 "ToggleSievePanels();                   \n"
229                 "</script>                              \n"
230         );
231
232         wDumpContent(1);
233
234 }
235
236
237
238 =======
239 #define FOO 1
240 >>>>>>> 1423eb9402b934a3f524a9b7bfd593e9b004cc0a
241 /*
242  * Helper function for output_sieve_rule() to output strings with quotes escaped
243  */
244 void osr_sanitize(char *str) {
245         int i, len;
246
247         if (str == NULL) return;
248         len = strlen(str);
249         for (i=0; i<len; ++i) {
250                 if (str[i]=='\"') {
251                         str[i] = '\'' ;
252                 }
253                 else if (isspace(str[i])) {
254                         str[i] = ' ';
255                 }
256         }
257 }
258
259 void display_add_remove_scripts(char *message);
260
261
262
263
264
265
266 /*
267  * Output parseable Sieve script code based on rules input
268  */
269 void output_sieve_rule(char *hfield, char *compare, char *htext, char *sizecomp, int sizeval,
270                         char *action, char *fileinto, char *redirect, char *automsg, char *final,
271                         char *my_addresses)
272 {
273         char *comp1 = "";
274         char *comp2 = "";
275
276         osr_sanitize(htext);
277         osr_sanitize(fileinto);
278         osr_sanitize(redirect);
279         osr_sanitize(automsg);
280
281         /* Prepare negation and match operators that will be used iff we apply a conditional */
282
283         if (!strcasecmp(compare, "contains")) {
284                 comp1 = "";
285                 comp2 = ":contains";
286         }
287         else if (!strcasecmp(compare, "notcontains")) {
288                 comp1 = "not";
289                 comp2 = ":contains";
290         }
291         else if (!strcasecmp(compare, "is")) {
292                 comp1 = "";
293                 comp2 = ":is";
294         }
295         else if (!strcasecmp(compare, "isnot")) {
296                 comp1 = "not";
297                 comp2 = ":is";
298         }
299         else if (!strcasecmp(compare, "matches")) {
300                 comp1 = "";
301                 comp2 = ":matches";
302         }
303         else if (!strcasecmp(compare, "notmatches")) {
304                 comp1 = "not";
305                 comp2 = ":matches";
306         }
307
308         /* Now do the conditional */
309
310         if (!strcasecmp(hfield, "from")) {
311                 serv_printf("if%s header %s \"From\" \"%s\"",
312                         comp1, comp2,
313                         htext
314                 );
315         }
316
317         else if (!strcasecmp(hfield, "tocc")) {
318                 serv_printf("if%s header %s [\"To\", \"Cc\"] \"%s\"",
319                         comp1, comp2,
320                         htext
321                 );
322         }
323
324         else if (!strcasecmp(hfield, "subject")) {
325                 serv_printf("if%s header %s \"Subject\" \"%s\"",
326                         comp1, comp2,
327                         htext
328                 );
329         }
330
331         else if (!strcasecmp(hfield, "replyto")) {
332                 serv_printf("if%s header %s \"Reply-to\" \"%s\"",
333                         comp1, comp2,
334                         htext
335                 );
336         }
337
338         else if (!strcasecmp(hfield, "sender")) {
339                 serv_printf("if%s header %s \"Sender\" \"%s\"",
340                         comp1, comp2,
341                         htext
342                 );
343         }
344
345         else if (!strcasecmp(hfield, "resentfrom")) {
346                 serv_printf("if%s header %s \"Resent-from\" \"%s\"",
347                         comp1, comp2,
348                         htext
349                 );
350         }
351
352         else if (!strcasecmp(hfield, "resentto")) {
353                 serv_printf("if%s header %s \"Resent-to\" \"%s\"",
354                         comp1, comp2,
355                         htext
356                 );
357         }
358
359         else if (!strcasecmp(hfield, "xmailer")) {
360                 serv_printf("if%s header %s \"X-Mailer\" \"%s\"",
361                         comp1, comp2,
362                         htext
363                 );
364         }
365
366         else if (!strcasecmp(hfield, "xspamflag")) {
367                 serv_printf("if%s header %s \"X-Spam-Flag\" \"%s\"",
368                         comp1, comp2,
369                         htext
370                 );
371         }
372
373         else if (!strcasecmp(hfield, "xspamstatus")) {
374                 serv_printf("if%s header %s \"X-Spam-Status\" \"%s\"",
375                         comp1, comp2,
376                         htext
377                 );
378         }
379
380         else if (!strcasecmp(hfield, "listid")) {
381                 serv_printf("if%s header %s \"List-ID\" \"%s\"",
382                         comp1, comp2,
383                         htext
384                 );
385         }
386
387         else if (!strcasecmp(hfield, "envfrom")) {
388                 serv_printf("if%s envelope %s \"From\" \"%s\"",
389                         comp1, comp2,
390                         htext
391                 );
392         }
393
394         else if (!strcasecmp(hfield, "envto")) {
395                 serv_printf("if%s envelope %s \"To\" \"%s\"",
396                         comp1, comp2,
397                         htext
398                 );
399         }
400
401         else if (!strcasecmp(hfield, "size")) {
402                 if (!strcasecmp(sizecomp, "larger")) {
403                         serv_printf("if size :over %d", sizeval);
404                 }
405                 else if (!strcasecmp(sizecomp, "smaller")) {
406                         serv_printf("if size :under %d", sizeval);
407                 }
408                 else {  /* failsafe - should never get here, but just in case... */
409                         serv_printf("if size :over 1");
410                 }
411         }
412
413         /* Open braces if we're in a conditional loop */
414
415         if (strcasecmp(hfield, "all")) {
416                 serv_printf("{");
417         }
418
419
420         /* Do action */
421
422         if (!strcasecmp(action, "keep")) {
423                 serv_printf("keep;");
424         }
425
426         else if (!strcasecmp(action, "discard")) {
427                 serv_printf("discard;");
428         }
429
430         else if (!strcasecmp(action, "reject")) {
431                 serv_printf("reject \"%s\";", automsg);
432         }
433
434         else if (!strcasecmp(action, "fileinto")) {
435                 serv_printf("fileinto \"%s\";", fileinto);
436         }
437
438         else if (!strcasecmp(action, "redirect")) {
439                 serv_printf("redirect \"%s\";", redirect);
440         }
441
442         else if (!strcasecmp(action, "vacation")) {
443                 serv_printf("vacation :addresses [%s]\n\"%s\";", my_addresses, automsg);
444         }
445
446
447         /* Do 'final' action */
448
449         if (!strcasecmp(final, "stop")) {
450                 serv_printf("stop;");
451         }
452
453
454         /* Close the braces if we're in a conditional loop */
455
456         if (strcasecmp(hfield, "all")) {
457                 serv_printf("}");
458         }
459
460
461         /* End of rule. */
462 }
463
464
465
466 /*
467  * Translate the fields from the rule editor into something we can save...
468  */
469 void parse_fields_from_rule_editor(void) {
470
471         int active;
472         char hfield[256];
473         char compare[32];
474         char htext[256];
475         char sizecomp[32];
476         int sizeval;
477         char action[32];
478         char fileinto[128];
479         char redirect[256];
480         char automsg[1024];
481         char final[32];
482         int i;
483         char buf[256];
484         char fname[256];
485         char rule[2048];
486         char encoded_rule[4096];
487         char my_addresses[4096];
488         
489         /* Enumerate my email addresses in case they are needed for a vacation rule */
490         my_addresses[0] = 0;
491         serv_puts("GVEA");
492         serv_getln(buf, sizeof buf);
493         if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
494                 if (!IsEmptyStr(my_addresses)) {
495                         strcat(my_addresses, ",\n");
496                 }
497                 strcat(my_addresses, "\"");
498                 strcat(my_addresses, buf);
499                 strcat(my_addresses, "\"");
500         }
501
502         /* Now generate the script and write it to the Citadel server */
503         serv_printf("MSIV putscript|%s|", RULES_SCRIPT);
504         serv_getln(buf, sizeof buf);
505         if (buf[0] != '4') {
506                 return;
507         }
508
509         serv_puts("# THIS SCRIPT WAS AUTOMATICALLY GENERATED BY WEBCIT.");
510         serv_puts("# ");
511         serv_puts("# Do not attempt to manually edit it.  If you do so,");
512         serv_puts("# your changes will be overwritten the next time WebCit");
513         serv_puts("# saves its mail filtering rule set.  If you really want");
514         serv_puts("# to use these rules as the basis for another script,");
515         serv_puts("# copy them to another script and save that instead.");
516         serv_puts("");
517         serv_puts("require \"fileinto\";");
518         serv_puts("require \"reject\";");
519         serv_puts("require \"vacation\";");
520         serv_puts("require \"envelope\";");
521         serv_puts("");
522
523         for (i=0; i<MAX_RULES; ++i) {
524                 
525                 strcpy(rule, "");
526
527                 sprintf(fname, "active%d", i);
528                 active = !strcasecmp(BSTR(fname), "on") ;
529
530                 if (active) {
531
532                         sprintf(fname, "hfield%d", i);
533                         safestrncpy(hfield, BSTR(fname), sizeof hfield);
534         
535                         sprintf(fname, "compare%d", i);
536                         safestrncpy(compare, BSTR(fname), sizeof compare);
537         
538                         sprintf(fname, "htext%d", i);
539                         safestrncpy(htext, BSTR(fname), sizeof htext);
540         
541                         sprintf(fname, "sizecomp%d", i);
542                         safestrncpy(sizecomp, BSTR(fname), sizeof sizecomp);
543         
544                         sprintf(fname, "sizeval%d", i);
545                         sizeval = IBSTR(fname);
546         
547                         sprintf(fname, "action%d", i);
548                         safestrncpy(action, BSTR(fname), sizeof action);
549         
550                         sprintf(fname, "fileinto%d", i);
551                         safestrncpy(fileinto, BSTR(fname), sizeof fileinto);
552         
553                         sprintf(fname, "redirect%d", i);
554                         safestrncpy(redirect, BSTR(fname), sizeof redirect);
555         
556                         sprintf(fname, "automsg%d", i);
557                         safestrncpy(automsg, BSTR(fname), sizeof automsg);
558         
559                         sprintf(fname, "final%d", i);
560                         safestrncpy(final, BSTR(fname), sizeof final);
561         
562                         snprintf(rule, sizeof rule, "%d|%s|%s|%s|%s|%d|%s|%s|%s|%s|%s",
563                                 active, hfield, compare, htext, sizecomp, sizeval, action, fileinto,
564                                 redirect, automsg, final
565                         );
566         
567                         CtdlEncodeBase64(encoded_rule, rule, strlen(rule)+1, 0);
568                         serv_printf("# WEBCIT_RULE|%d|%s|", i, encoded_rule);
569                         output_sieve_rule(hfield, compare, htext, sizecomp, sizeval,
570                                         action, fileinto, redirect, automsg, final, my_addresses);
571                         serv_puts("");
572                 }
573
574
575         }
576
577         serv_puts("stop;");
578         serv_puts("000");
579 }
580
581
582
583 /*
584  * save sieve config
585  */
586 void save_sieve(void) {
587         int bigaction;
588         char script_names[MAX_SCRIPTS][64];
589         int num_scripts = 0;
590         int active_script = (-1);
591         int i;
592         char this_name[64];
593         char buf[256];
594
595         if (!havebstr("save_button")) {
596                 strcpy(WC->ImportantMessage,
597                         _("Cancelled.  Changes were not saved."));
598                 display_main_menu();
599                 return;
600         }
601
602         parse_fields_from_rule_editor();
603
604         serv_puts("MSIV listscripts");
605         serv_getln(buf, sizeof(buf));
606         if (buf[0] == '1') while (serv_getln(buf, sizeof(buf)), strcmp(buf, "000")) {
607                 if (num_scripts < MAX_SCRIPTS) {
608                         extract_token(script_names[num_scripts], buf, 0, '|', 64);
609                         if (extract_int(buf, 1) > 0) {
610                                 active_script = num_scripts;
611                         }
612                         ++num_scripts;
613                 }
614         }
615
616         bigaction = ibstr("bigaction");
617
618         if (bigaction == 0) {
619                 serv_puts("MSIV setactive||");
620                 serv_getln(buf, sizeof buf);
621         }
622
623         else if (bigaction == 1) {
624                 serv_printf("MSIV setactive|%s|", RULES_SCRIPT);
625                 serv_getln(buf, sizeof buf);
626         }
627
628         else if (bigaction == 2) {
629                 serv_printf("MSIV setactive|%s|", bstr("active_script"));
630                 serv_getln(buf, sizeof buf);
631         }
632
633         if (num_scripts > 0) {
634                 for (i=0; i<num_scripts; ++i) {
635                         /*
636                          * We only want to save the scripts from the "manually edited scripts"
637                          * screen.  The script that WebCit generates from its ruleset will be
638                          * auto-generated by parse_fields_from_rule_editor() and saved there.
639                          */
640                         if (strcasecmp(script_names[i], RULES_SCRIPT)) {
641                                 serv_printf("MSIV putscript|%s|", script_names[i]);
642                                 serv_getln(buf, sizeof buf);
643                                 if (buf[0] == '4') {
644                                         snprintf(this_name, sizeof this_name, "text_%s", script_names[i]);
645                                         striplt((char *)BSTR(this_name)); /* TODO: get rid of typecast*/
646                                         serv_write(BSTR(this_name), strlen(BSTR(this_name)));
647                                         serv_puts("\n000");
648                                 }
649                         }
650                 }
651         }
652
653         strcpy(WC->ImportantMessage, _("Your changes have been saved."));
654         display_main_menu();
655         return;
656 }
657
658 /*
659  * create a new script
660  * take the web environment script name and create it on the citadel server
661  */
662 void create_script(void) {
663         char buf[256];
664
665         serv_printf("MSIV getscript|%s", bstr("script_name"));
666         serv_getln(buf, sizeof buf);
667         if (buf[0] == '1') {
668                 while (serv_getln(buf, sizeof(buf)), strcmp(buf, "000")) {
669                         /* flush */
670                 }
671 #if FOO
672                 display_add_remove_scripts(_("A script by that name already exists."));
673 #endif
674                 return;
675         }
676         
677         serv_printf("MSIV putscript|%s", bstr("script_name"));
678         serv_getln(buf, sizeof buf);
679         if (buf[0] == '4') {
680                 serv_puts("keep;");
681                 serv_puts("000");
682 #if FOO
683                 display_add_remove_scripts(_("A new script has been created.  Return to the script editing screen to edit and activate it."));
684 #endif
685                 return;
686         }
687
688 #if FOO
689         display_add_remove_scripts(&buf[4]);
690 #endif
691 }
692
693
694
695
696 /*
697  * delete a script
698  */
699 void delete_script(void) {
700         char buf[256];
701
702         serv_printf("MSIV deletescript|%s", bstr("script_name"));
703         serv_getln(buf, sizeof buf);
704 #if FOO
705         display_add_remove_scripts(&buf[4]);
706 #endif
707 }
708                 
709
710
711 /*
712  * dummy panel indicating to the user that the server doesn't support Sieve
713  */
714 void display_no_sieve(void) {
715
716         output_headers(1, 1, 2, 0, 0, 0);
717         do_template("sieve_none");
718         wDumpContent(1);
719 }
720
721 #if FOO
722 /*
723  * view/edit sieve config
724  */
725 void display_sieve(void)
726 {
727         char script_names[MAX_SCRIPTS][64];
728         int num_scripts = 0;
729         int active_script = (-1);
730         char buf[SIZ];          /* Don't make this buffer smaller or it will restrict line length */
731         int i;
732         int rules_script_is_active = 0;
733
734         if (!WC->serv_info->serv_supports_sieve) {
735                 display_no_sieve();
736                 return;
737         }
738
739         memset(script_names, 0, sizeof script_names);
740
741         serv_puts("MSIV listscripts");
742         serv_getln(buf, sizeof(buf));
743         if (buf[0] == '1') while (serv_getln(buf, sizeof(buf)), strcmp(buf, "000")) {
744                 if (num_scripts < MAX_SCRIPTS) {
745                         extract_token(script_names[num_scripts], buf, 0, '|', 64);
746                         if (extract_int(buf, 1) > 0) {
747                                 active_script = num_scripts;
748                                 if (!strcasecmp(script_names[num_scripts], RULES_SCRIPT)) {
749                                         rules_script_is_active = 1;
750                                 }
751                         }
752                         ++num_scripts;
753                 }
754         }
755
756         output_headers(1, 1, 2, 0, 0, 0);
757
758         wc_printf("<script type=\"text/javascript\">                                    \n"
759                 "                                                                       \n"
760                 "var previously_active_script;                                          \n"
761                 "                                                                       \n"
762                 "function ToggleSievePanels() {                                         \n"
763                 " d = ($('sieveform').bigaction.options[$('sieveform').bigaction.selectedIndex].value); \n"
764                 " for (i=0; i<3; ++i) {                                                 \n"
765                 "  if (i == d) {                                                        \n"
766                 "   $('sievediv' + i).style.display = 'block';                          \n"
767                 "  }                                                                    \n"
768                 "  else {                                                               \n"
769                 "   $('sievediv' + i).style.display = 'none';                           \n"
770                 "  }                                                                    \n"
771                 " }                                                                     \n"
772                 "}                                                                      \n"
773                 "                                                                       \n"
774                 "function ToggleScriptPanels() {                                        \n"
775                 " d = ($('sieveform').active_script.options[$('sieveform').active_script.selectedIndex].value); \n"
776                 " if ($('script_' + previously_active_script)) {                        \n"
777                 "  $('script_' + previously_active_script).style.display = 'none';      \n"
778                 " }                                                                     \n"
779                 " $('script_' + d).style.display = 'block';                             \n"
780                 " previously_active_script = d;                                         \n"
781                 "}                                                                      \n"
782                 "                                                                       \n"
783                 "</script>                                                              \n"
784         );
785
786         wc_printf("<div id=\"banner\">\n");
787         wc_printf("<img src=\"static/advanpage2_48x.gif\">");
788         wc_printf("<h1>");
789         wc_printf(_("View/edit server-side mail filters"));
790         wc_printf("</h1>\n");
791         wc_printf("</div>\n");
792
793         wc_printf("<div id=\"content\" class=\"service\">\n");
794
795         wc_printf("<table class=\"sieve_background\">"
796                 "<tr><td valign=top>\n");
797
798
799         wc_printf("<form id=\"sieveform\" method=\"post\" action=\"save_sieve\">\n");
800         wc_printf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
801
802         wc_printf(_("When new mail arrives: "));
803         wc_printf("<select name=\"bigaction\" size=1 onChange=\"ToggleSievePanels();\">\n");
804
805         wc_printf("<option %s value=\"0\">", ((active_script < 0) ? "selected" : ""));
806         wc_printf(_("Leave it in my inbox without filtering"));
807         wc_printf("</option>\n");
808
809         wc_printf("<option %s value=\"1\">", ((rules_script_is_active) ? "selected" : ""));
810         wc_printf(_("Filter it according to rules selected below"));
811         wc_printf("</option>\n");
812
813         wc_printf("<option %s value=\"2\">",
814                         (((active_script >= 0) && (!rules_script_is_active)) ? "selected" : ""));
815         wc_printf(_("Filter it through a manually edited script (advanced users only)"));
816         wc_printf("</option>\n");
817
818         wc_printf("</select>");
819
820
821
822         /* The "no filtering" div */
823
824         wc_printf("<div id=\"sievediv0\" style=\"display:none\">\n");
825         wc_printf("<div align=\"center\"><br><br>");
826         wc_printf(_("Your incoming mail will not be filtered through any scripts."));
827         wc_printf("<br><br></div>\n");
828         wc_printf("</div>\n");
829
830         /* The "webcit managed scripts" div */
831
832         wc_printf("<div id=\"sievediv1\" style=\"display:none\">\n");
833         display_rules_editor_inner_div();
834         wc_printf("</div>\n");
835
836         /* The "I'm smart and can write my own Sieve scripts" div */
837
838         wc_printf("<div id=\"sievediv2\" style=\"display:none\">\n");
839
840         if (num_scripts > 0) {
841                 wc_printf(_("The currently active script is: "));
842                 wc_printf("<select name=\"active_script\" size=1 onChange=\"ToggleScriptPanels();\">\n");
843                 for (i=0; i<num_scripts; ++i) {
844                         if (strcasecmp(script_names[i], RULES_SCRIPT)) {
845                                 wc_printf("<option %s value=\"%s\">%s</option>\n",
846                                         ((active_script == i) ? "selected" : ""),
847                                         script_names[i],
848                                         script_names[i]
849                                 );
850                         }
851                 }
852                 wc_printf("</select>\n");
853         }
854
855         wc_printf("&nbsp;&nbsp;&nbsp;");
856         wc_printf("<a href=\"display_add_remove_scripts\">%s</a>\n", _("Add or delete scripts"));
857
858         wc_printf("<br>\n");
859
860         if (num_scripts > 0) {
861                 for (i=0; i<num_scripts; ++i) {
862                         if (strcasecmp(script_names[i], RULES_SCRIPT)) {
863                                 wc_printf("<div id=\"script_%s\" style=\"display:none\">\n", script_names[i]);
864                                 wc_printf("<textarea name=\"text_%s\" wrap=soft rows=20 cols=80 width=80>\n",
865                                         script_names[i]);
866                                 serv_printf("MSIV getscript|%s", script_names[i]);
867                                 serv_getln(buf, sizeof buf);
868                                 if (buf[0] == '1') while(serv_getln(buf, sizeof (buf)), strcmp(buf, "000")) {
869                                         wc_printf("%s\n", buf);
870                                 }
871                                 wc_printf("</textarea>\n");
872                                 wc_printf("</div>\n");
873                         }
874                 }
875         }
876
877         wc_printf("<script type=\"text/javascript\">    \n"
878                 "ToggleScriptPanels();                  \n"
879                 "</script>                              \n"
880         );
881
882         wc_printf("</div>\n");
883
884
885         /* The rest of this is common for all panels... */
886
887         wc_printf("<div align=\"center\"><br>");
888         wc_printf("<input type=\"submit\" name=\"save_button\" value=\"%s\">", _("Save changes"));
889         wc_printf("&nbsp;");
890         wc_printf("<input type=\"submit\" name=\"cancel_button\" value=\"%s\">\n", _("Cancel"));
891         wc_printf("</div></form>\n");
892
893         wc_printf("</td></tr></table>\n");
894
895         wc_printf("<script type=\"text/javascript\">    \n"
896                 "ToggleSievePanels();                   \n"
897                 "</script>                              \n"
898         );
899
900         wDumpContent(1);
901
902 }
903
904
905
906
907 /*
908  * show a list of available scripts to add/remove them
909  */
910 void display_add_remove_scripts(char *message)
911 {
912         char buf[256];
913         char script_name[256];
914
915         output_headers(1, 1, 2, 0, 0, 0);
916         wc_printf("<div id=\"banner\">\n");
917         wc_printf("<img src=\"static/webcit_icons/essen/32x32/config.png\">");
918         wc_printf(_("Add or delete scripts"));
919         wc_printf("</h1>\n");
920         wc_printf("</div>\n");
921         
922         wc_printf("<div id=\"content\" class=\"service\">\n");
923
924         if (message != NULL) {
925                 wc_printf("%s", message);
926         }
927
928         wc_printf("<table border=0 cellspacing=10><tr valign=top><td>\n");
929
930         do_template("beginbox_1");
931         StrBufAppendBufPlain(WC->WBuf, _("Add a new script"), -1, 0);
932         do_template("beginbox_2");
933
934         wc_printf(_("To create a new script, enter the desired "
935                 "script name in the box below and click 'Create'."));
936         wc_printf("<br><br>");
937
938         wc_printf("<center><form method=\"POST\" action=\"create_script\">\n");
939         wc_printf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
940         wc_printf(_("Script name: "));
941         wc_printf("<input type=\"text\" name=\"script_name\"><br>\n"
942                 "<input type=\"submit\" name=\"create_button\" value=\"%s\">"
943                 "</form></center>\n", _("Create"));
944
945         do_template("endbox");
946
947         do_template("beginbox_1");
948         StrBufAppendBufPlain(WC->WBuf, _("Edit scripts"), -1, 0);
949         do_template("beginbox_2");
950         wc_printf("<br><div align=center><a href=\"display_sieve\">%s</a><br><br>\n",
951                 _("Return to the script editing screen")
952         );
953         do_template("endbox");
954
955         wc_printf("</td><td>");
956
957         do_template("beginbox_1");
958         StrBufAppendBufPlain(WC->WBuf, _("Delete scripts"), -1, 0);
959         do_template("beginbox_2");
960
961         wc_printf(_("To delete an existing script, select the script "
962                 "name from the list and click 'Delete'."));
963         wc_printf("<br><br>");
964         
965         wc_printf("<center>"
966                 "<form method=\"POST\" action=\"delete_script\">\n");
967         wc_printf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
968         wc_printf("<select name=\"script_name\" size=10 style=\"width:100%%\">\n");
969
970         serv_puts("MSIV listscripts");
971         serv_getln(buf, sizeof buf);
972         if (buf[0] == '1') {
973                 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
974                         extract_token(script_name, buf, 0, '|', sizeof script_name);
975                         if ( (extract_int(buf, 1) == 0) && (strcasecmp(script_name, RULES_SCRIPT)) ) {
976                                 wc_printf("<option>");
977                                 escputs(script_name);
978                                 wc_printf("</option>\n");
979                         }
980                 }
981         }
982         wc_printf("</select><br>\n");
983
984         wc_printf("<input type=\"submit\" name=\"delete_button\" value=\"%s\" "
985                 "onClick=\"return confirm('%s');\">", _("Delete script"), _("Delete this script?"));
986         wc_printf("</form></center>\n");
987         do_template("endbox");
988
989         wc_printf("</td></tr></table>\n");
990
991         wDumpContent(1);
992 }
993
994
995
996
997
998
999 void display_rules_editor_inner_div(void) {
1000         int i, j;
1001         char buf[4096];
1002         char rules[MAX_RULES][2048];
1003
1004         struct {
1005                 char name[128];
1006         } *rooms = NULL;
1007         int num_roomnames = 0;
1008         int num_roomnames_alloc = 0;
1009
1010         int active;
1011         char hfield[256];
1012         char compare[32];
1013         char htext[256];
1014         char sizecomp[32];
1015         int sizeval;
1016         char action[32];
1017         char fileinto[128];
1018         char redirect[256];
1019         char automsg[1024];
1020         char final[32];
1021
1022         /* load the rules */
1023         memset(rules, 0, sizeof rules);
1024         serv_printf("MSIV getscript|%s", RULES_SCRIPT);
1025         serv_getln(buf, sizeof buf);
1026         if (buf[0] == '1') while(serv_getln(buf, sizeof (buf)), strcmp(buf, "000")) {
1027                 if (!strncasecmp(buf, "# WEBCIT_RULE|", 14)) {
1028                         j = extract_int(buf, 1);
1029                         remove_token(buf, 0, '|');
1030                         remove_token(buf, 0, '|');
1031                         CtdlDecodeBase64(rules[j], buf, strlen(buf));
1032                 }
1033         }
1034
1035         /* load the roomnames */
1036         serv_puts("LKRA");
1037         serv_getln(buf, sizeof buf);
1038         if (buf[0] == '1') {
1039                 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
1040                         ++num_roomnames;
1041                         if (num_roomnames > num_roomnames_alloc) {
1042                                 num_roomnames_alloc += 250;
1043                                 rooms = realloc(rooms, (num_roomnames_alloc * 128));
1044                         }
1045                         extract_token(rooms[num_roomnames-1].name, buf, 0, '|', 128);
1046                 }
1047         }
1048
1049
1050 /*
1051  * This script should get called by every onChange event...
1052  *
1053  */
1054         wc_printf("<script type=\"text/javascript\">                                    \n"
1055                 "                                                                       \n"
1056                 "var highest_active_rule = (-1);                                        \n"
1057                 "                                                                       \n"
1058                 "function UpdateRules() {                                               \n");
1059 /*
1060  * Show only the active rows...
1061  */
1062         wc_printf("  highest_active_rule = (-1);                                                \n");
1063         wc_printf("  for (i=0; i<%d; ++i) {                                             \n", MAX_RULES);
1064         wc_printf("   if ($('active'+i).checked) {                                      \n"
1065                 "     $('rule' + i).style.display = 'block';                            \n"
1066                 "     highest_active_rule = i;                                          \n"
1067                 "   }                                                                   \n"
1068                 "   else {                                                              \n"
1069                 "     $('rule' + i).style.display = 'none';                             \n"
1070                 "   }                                                                   \n"
1071                 "  }                                                                    \n");
1072 /*
1073  * Show only the fields relevant to the rules...
1074  */
1075         wc_printf("  for (i=0; i<=highest_active_rule; ++i) {                           \n"
1076                 "    d = ($('movedown'+i));                                             \n"
1077                 "    if (i < highest_active_rule) {                                     \n"
1078                 "      d.style.display = 'block';                                       \n"
1079                 "    }                                                                  \n"
1080                 "    else {                                                             \n"
1081                 "      d.style.display = 'none';                                        \n"
1082                 "    }                                                                  \n"
1083                 "    d = ($('hfield'+i).options[$('hfield'+i).selectedIndex].value);    \n"
1084                 "    if (d == 'all') {                                                  \n"
1085                 "      $('div_size'+i).style.display = 'none';                          \n"
1086                 "      $('div_compare'+i).style.display = 'none';                       \n"
1087                 "      $('div_nocompare'+i).style.display = 'block';                    \n"
1088                 "    }                                                                  \n"
1089                 "    else if (d == 'size') {                                            \n"
1090                 "      $('div_size'+i).style.display = 'block';                         \n"
1091                 "      $('div_compare'+i).style.display = 'none';                       \n"
1092                 "      $('div_nocompare'+i).style.display = 'none';                     \n"
1093                 "    }                                                                  \n"
1094                 "    else {                                                             \n"
1095                 "      $('div_size'+i).style.display = 'none';                          \n"
1096                 "      $('div_compare'+i).style.display = 'block';                      \n"
1097                 "      $('div_nocompare'+i).style.display = 'none';                     \n"
1098                 "    }                                                                  \n"
1099                 "    d = ($('action'+i).options[$('action'+i).selectedIndex].value);    \n"
1100                 "    if (d == 'fileinto') {                                             \n"
1101                 "      $('div_fileinto'+i).style.display = 'block';                     \n"
1102                 "      $('div_redirect'+i).style.display = 'none';                      \n"
1103                 "      $('div_automsg'+i).style.display = 'none';                       \n"
1104                 "    } else if (d == 'redirect') {                                      \n"
1105                 "      $('div_fileinto'+i).style.display = 'none';                      \n"
1106                 "      $('div_redirect'+i).style.display = 'block';                     \n"
1107                 "      $('div_automsg'+i).style.display = 'none';                       \n"
1108                 "    } else if ((d == 'reject') || (d == 'vacation'))  {                \n"
1109                 "      $('div_fileinto'+i).style.display = 'none';                      \n"
1110                 "      $('div_redirect'+i).style.display = 'none';                      \n"
1111                 "      $('div_automsg'+i).style.display = 'block';                      \n"
1112                 "    } else {                                                           \n"
1113                 "      $('div_fileinto'+i).style.display = 'none';                      \n"
1114                 "      $('div_redirect'+i).style.display = 'none';                      \n"
1115                 "      $('div_automsg'+i).style.display = 'none';                       \n"
1116                 "    }                                                                  \n"
1117                 "    if (highest_active_rule < %d) {                                    \n", MAX_RULES-1 );
1118         wc_printf("      $('div_addrule').style.display = 'block';                      \n"
1119                 "    } else {                                                           \n"
1120                 "      $('div_addrule').style.display = 'none';                         \n"
1121                 "    }                                                                  \n"
1122                 "  }                                                                    \n"
1123                 "}                                                                      \n"
1124 /*
1125  * Add a rule (really, just un-hide it)
1126  */
1127                 "function AddRule() {                                                   \n"
1128                 "  highest_active_rule = highest_active_rule + 1;                       \n"
1129                 "  $('active'+highest_active_rule).checked = true;                      \n"
1130                 "  UpdateRules();                                                       \n"
1131                 "}                                                                      \n"
1132 /*
1133  * Swap two rules
1134  */
1135                 "function SwapRules(ra, rb) {                                           \n"
1136                 "                                                                       \n"
1137                 "  var things = new Array();                                            \n"
1138                 "  things[0] = 'hfield';                                                \n"
1139                 "  things[1] = 'compare';                                               \n"
1140                 "  things[2] = 'htext';                                                 \n"
1141                 "  things[3] = 'action';                                                \n"
1142                 "  things[4] = 'fileinto';                                              \n"
1143                 "  things[5] = 'redirect';                                              \n"
1144                 "  things[6] = 'final';                                                 \n"
1145                 "  things[7] = 'sizecomp';                                              \n"
1146                 "  things[8] = 'sizeval';                                               \n"
1147                 "  things[9] = 'automsg';                                               \n"
1148                 "                                                                       \n"
1149                 "  for (i=0; i<=9; ++i) {                                               \n"
1150                 "    tempval=$(things[i]+ra).value;                                     \n"
1151                 "    $(things[i]+ra).value = $(things[i]+rb).value;                     \n"
1152                 "    $(things[i]+rb).value = tempval;                                   \n"
1153                 "  }                                                                    \n"
1154                 "}                                                                      \n"
1155 /*
1156  * Delete a rule (percolate the deleted rule out to the end, then deactivate it)
1157  */
1158                 "function DeleteRule(rd) {                                              \n"
1159                 "  for (j=rd; j<=highest_active_rule; ++j) {                            \n"
1160                 "    SwapRules(j, (j+1));                                               \n"
1161                 "  }                                                                    \n"
1162                 "  $('active'+highest_active_rule).checked = false;                     \n"
1163                 "}                                                                      \n"
1164                 "</script>                                                              \n"
1165         );
1166
1167
1168         wc_printf("<br>");
1169
1170         wc_printf("<table cellpadding=2 width=100%%>");
1171
1172         for (i=0; i<MAX_RULES; ++i) {
1173
1174                 /* Grab our existing values to populate */
1175                 active = extract_int(rules[i], 0);
1176                 extract_token(hfield, rules[i], 1, '|', sizeof hfield);
1177                 extract_token(compare, rules[i], 2, '|', sizeof compare);
1178                 extract_token(htext, rules[i], 3, '|', sizeof htext);
1179                 extract_token(sizecomp, rules[i], 4, '|', sizeof sizecomp);
1180                 sizeval = extract_int(rules[i], 5);
1181                 extract_token(action, rules[i], 6, '|', sizeof action);
1182                 extract_token(fileinto, rules[i], 7, '|', sizeof fileinto);
1183                 extract_token(redirect, rules[i], 8, '|', sizeof redirect);
1184                 extract_token(automsg, rules[i], 9, '|', sizeof automsg);
1185                 extract_token(final, rules[i], 10, '|', sizeof final);
1186                 
1187                 /* now generate the table row */
1188
1189                 wc_printf("<tr id=\"rule%d\" bgcolor=\"#%s\">",
1190                         i,
1191                         ((i%2) ? "DDDDDD" : "FFFFFF")
1192                 );
1193
1194                 wc_printf("<td width=5%% align=\"center\">");
1195
1196                 wc_printf("<div style=\"display:none\">");
1197                 wc_printf("<input type=\"checkbox\" name=\"active%d\" id=\"active%d\" %s>",
1198                         i, i,
1199                         (active ? "checked" : "")
1200                 );
1201                 wc_printf("</div>");
1202
1203                 if (i>0) wc_printf("<a href=\"javascript:SwapRules(%d,%d);UpdateRules();\">"
1204                         "<img border=\"0\" src=\"static/webcit_icons/up_pointer.gif\" "
1205                         "title=\"%s\"/></a>",
1206                         i-1, i, _("Move rule up") );
1207
1208                 wc_printf("<a href=\"javascript:SwapRules(%d,%d);UpdateRules();\">"
1209                         "<img id=\"movedown%d\" border=\"0\" src=\"static/webcit_icons/down_pointer.gif\" "
1210                         "title=\"%s\"/></a>",
1211                         i, i+1, i, _("Move rule down") );
1212
1213                 wc_printf("<a href=\"javascript:DeleteRule(%d);UpdateRules();\">"
1214                         "<img id=\"delete%d\" border=\"0\" src=\"static/webcit_icons/delete.gif\" "
1215                         "title=\"%s\"/></a>",
1216                         i, i, _("Delete rule") );
1217
1218                 wc_printf("</td>");
1219
1220                 wc_printf("<td width=5%% align=\"center\">");
1221                 wc_printf("<font size=+2>%d</font>", i+1);
1222                 wc_printf("</td>");
1223
1224                 wc_printf("<td width=20%%>%s ", _("If") );
1225
1226                 char *hfield_values[15][2] = {
1227                         {       "from",         _("From")               },
1228                         {       "tocc",         _("To or Cc")           },
1229                         {       "subject",      _("Subject")            },
1230                         {       "replyto",      _("Reply-to")           },
1231                         {       "sender",       _("Sender")             },
1232                         {       "resentfrom",   _("Resent-From")        },
1233                         {       "resentto",     _("Resent-To")          },
1234                         {       "envfrom",      _("Envelope From")      },
1235                         {       "envto",        _("Envelope To")        },
1236                         {       "xmailer",      _("X-Mailer")           },
1237                         {       "xspamflag",    _("X-Spam-Flag")        },
1238                         {       "xspamstatus",  _("X-Spam-Status")      },
1239                         {       "listid",       _("List-ID")            },
1240                         {       "size",         _("Message size")       },
1241                         {       "all",          _("All")                }
1242                 };
1243
1244                 wc_printf("<select id=\"hfield%d\" name=\"hfield%d\" size=1 onChange=\"UpdateRules();\">",
1245                         i, i);
1246                 for (j=0; j<15; ++j) {
1247                         wc_printf("<option %s value=\"%s\">%s</option>",
1248                                 ( (!strcasecmp(hfield, hfield_values[j][0])) ? "selected" : ""),
1249                                 hfield_values[j][0],
1250                                 hfield_values[j][1]
1251                         );
1252                 }
1253
1254                 wc_printf("</select>");
1255                 wc_printf("</td>");
1256
1257                 wc_printf("<td width=20%%>");
1258
1259                 char *compare_values[6][2] = {
1260                         {       "contains",     _("contains")           },
1261                         {       "notcontains",  _("does not contain")   },
1262                         {       "is",           _("is")                 },
1263                         {       "isnot",        _("is not")             },
1264                         {       "matches",      _("matches")            },
1265                         {       "notmatches",   _("does not match")     }
1266                 };
1267
1268                 wc_printf("<div id=\"div_compare%d\">", i);
1269                 wc_printf("<select id=\"compare%d\" name=\"compare%d\" size=1 onChange=\"UpdateRules();\">",
1270                         i, i);
1271                 for (j=0; j<6; ++j) {
1272                         wc_printf("<option %s value=\"%s\">%s</option>",
1273                                 ( (!strcasecmp(compare, compare_values[j][0])) ? "selected" : ""),
1274                                 compare_values[j][0],
1275                                 compare_values[j][1]
1276                         );
1277                 }
1278                 wc_printf("</select>");
1279
1280                 wc_printf("<input type=\"text\" id=\"htext%d\" name=\"htext%d\" value=\"", i, i);
1281                 escputs(htext);
1282                 wc_printf("\"></div>");
1283
1284                 wc_printf("<div id=\"div_nocompare%d\">", i);
1285                 wc_printf("%s", _("(All messages)"));
1286                 wc_printf("</div>");
1287
1288                 char *sizecomp_values[2][2] = {
1289                         {       "larger",       _("is larger than")     },
1290                         {       "smaller",      _("is smaller than")    }
1291                 };
1292
1293                 wc_printf("<div id=\"div_size%d\">", i);
1294                 wc_printf("<select id=\"sizecomp%d\" name=\"sizecomp%d\" size=1 onChange=\"UpdateRules();\">",
1295                         i, i);
1296                 for (j=0; j<2; ++j) {
1297                         wc_printf("<option %s value=\"%s\">%s</option>",
1298                                 ( (!strcasecmp(sizecomp, sizecomp_values[j][0])) ? "selected" : ""),
1299                                 sizecomp_values[j][0],
1300                                 sizecomp_values[j][1]
1301                         );
1302                 }
1303                 wc_printf("</select>");
1304
1305                 wc_printf("<input type=\"text\" id=\"sizeval%d\" name=\"sizeval%d\" value=\"%d\">",
1306                         i, i, sizeval);
1307                 wc_printf("bytes");
1308                 wc_printf("</div>");
1309
1310                 wc_printf("</td>");
1311
1312                 char *action_values[6][2] = {
1313                         {       "keep",         _("Keep")               },
1314                         {       "discard",      _("Discard silently")   },
1315                         {       "reject",       _("Reject")             },
1316                         {       "fileinto",     _("Move message to")    },
1317                         {       "redirect",     _("Forward to")         },
1318                         {       "vacation",     _("Vacation")           }
1319                 };
1320
1321                 wc_printf("<td width=20%%>");
1322                 wc_printf("<select id=\"action%d\" name=\"action%d\" size=1 onChange=\"UpdateRules();\">",
1323                         i, i);
1324                 for (j=0; j<6; ++j) {
1325                         wc_printf("<option %s value=\"%s\">%s</option>",
1326                                 ( (!strcasecmp(action, action_values[j][0])) ? "selected" : ""),
1327                                 action_values[j][0],
1328                                 action_values[j][1]
1329                         );
1330                 }
1331                 wc_printf("</select>");
1332
1333                 wc_printf("<div id=\"div_fileinto%d\">", i);
1334                 wc_printf("<select name=\"fileinto%d\" id=\"fileinto%d\">", i, i);
1335                 for (j=0; j<num_roomnames; ++j) {
1336                         wc_printf("<option ");
1337                         if (!strcasecmp(rooms[j].name, fileinto)) {
1338                                 wc_printf("selected ");
1339                         }
1340                         wc_printf("value=\"");
1341                         escputs(rooms[j].name);
1342                         wc_printf("\">");
1343                         escputs(rooms[j].name);
1344                         wc_printf("</option>\n");
1345                 }
1346                 wc_printf("</select>\n");
1347                 wc_printf("</div>");
1348
1349                 wc_printf("<div id=\"div_redirect%d\">", i);
1350                 wc_printf("<input type=\"text\" id=\"redirect%d\" name=\"redirect%d\" value=\"", i, i);
1351                 escputs(redirect);
1352                 wc_printf("\"></div>");
1353
1354                 wc_printf("<div id=\"div_automsg%d\">", i);
1355                 wc_printf(_("Message:"));
1356                 wc_printf("<br>");
1357                 wc_printf("<textarea name=\"automsg%d\" id=\"automsg%d\" wrap=soft rows=5>\n", i, i);
1358                 escputs(automsg);
1359                 wc_printf("</textarea>");
1360                 wc_printf("</div>");
1361
1362                 wc_printf("</td>");
1363
1364                 char *final_values[2][2] = {
1365                         {       "continue",     _("continue processing")        },
1366                         {       "stop",         _("stop")                       }
1367                 };
1368
1369                 wc_printf("<td width=10%% align=\"center\">%s</td>", _("and then") );
1370
1371                 wc_printf("<td width=20%%>");
1372                 wc_printf("<select name=\"final%d\" id=\"final%d\" size=1 onChange=\"UpdateRules();\">",
1373                         i, i);
1374                 for (j=0; j<2; ++j) {
1375                         wc_printf("<option %s value=\"%s\">%s</option>",
1376                                 ( (!strcasecmp(final, final_values[j][0])) ? "selected" : ""),
1377                                 final_values[j][0],
1378                                 final_values[j][1]
1379                         );
1380                 }
1381                 wc_printf("</select>");
1382                 wc_printf("</td>");
1383
1384                 wc_printf("</tr>\n");
1385
1386         }
1387
1388         wc_printf("</table>");
1389         wc_printf("<div id=\"div_addrule\"><a href=\"javascript:AddRule();\">%s</a><br></div>\n",
1390                 _("Add rule")
1391         );
1392
1393         wc_printf("<script type=\"text/javascript\">                                    \n");
1394         wc_printf("UpdateRules();                                                               \n");
1395         wc_printf("</script>                                                            \n");
1396
1397         free(rooms);
1398 }
1399 void _display_add_remove_scripts(void) {display_add_remove_scripts(NULL);}
1400 #endif
1401
1402
1403 typedef struct __SieveListing {
1404         int IsActive;
1405         int IsRulesScript;
1406         StrBuf *Name;
1407         StrBuf *Content;
1408 } SieveListing;
1409
1410 int ConditionalSieveScriptIsActive(StrBuf *Target, WCTemplputParams *TP)
1411 {
1412         SieveListing     *SieveList = (SieveListing *)CTX;
1413         return SieveList->IsActive;
1414 }
1415 int ConditionalSieveScriptIsRulesScript(StrBuf *Target, WCTemplputParams *TP)
1416 {
1417         SieveListing     *SieveList = (SieveListing *)CTX;
1418         return SieveList->IsActive;
1419 }
1420 void tmplput_SieveScriptName(StrBuf *Target, WCTemplputParams *TP) 
1421 {
1422         SieveListing     *SieveList = (SieveListing *)CTX;
1423         StrBufAppendTemplate(Target, TP, SieveList->Name, 0);
1424 }
1425 void tmplput_SieveScriptContent(StrBuf *Target, WCTemplputParams *TP) 
1426 {
1427         SieveListing     *SieveList = (SieveListing *)CTX;
1428         StrBufAppendTemplate(Target, TP, SieveList->Content, 0);
1429 }
1430 void FreeSieveListing(void *vSieveListing)
1431 {
1432         SieveListing *List = (SieveListing*) vSieveListing;
1433
1434         FreeStrBuf(&List->Name);
1435         free(List);
1436 }
1437
1438 HashList *GetSieveScriptListing(StrBuf *Target, WCTemplputParams *TP)
1439 {
1440         wcsession *WCC = WC;
1441         StrBuf *Line;
1442         int num_scripts = 0;
1443         int rules_script_active = 0;
1444         int have_rules_script = 0;
1445         const char *pch;
1446         HashPos  *it;
1447         int Done = 0;
1448         SieveListing *Ruleset;
1449
1450         if (WCC->KnownSieveScripts != NULL)
1451                 return WCC->KnownSieveScripts;
1452
1453         serv_puts("MSIV listscripts");
1454         Line = NewStrBuf();
1455         StrBuf_ServGetln(Line);
1456         if (GetServerStatus(Line, NULL) == 1) 
1457         {
1458                 WCC->KnownSieveScripts = NewHash(1, Flathash);
1459
1460                 while(!Done && (StrBuf_ServGetln(Line) >= 0) )
1461                         if ( (StrLength(Line)==3) && 
1462                              !strcmp(ChrPtr(Line), "000")) 
1463                         {
1464                                 Done = 1;
1465                         }
1466                         else
1467                         {
1468                                 pch = NULL;
1469                                 Ruleset = (SieveListing *) malloc(sizeof(SieveListing));
1470                                 Ruleset->Name = NewStrBufPlain(NULL, StrLength(Line));
1471                                 StrBufExtract_NextToken(Ruleset->Name, Line, &pch, '|');
1472                                 Ruleset->IsActive = StrBufExtractNext_int(Line, &pch, '|'); 
1473
1474                                 if (!strcasecmp(ChrPtr(Ruleset->Name), RULES_SCRIPT))
1475                                 {
1476                                         Ruleset->IsRulesScript = 1;
1477                                         have_rules_script = 1;
1478                                         if (Ruleset->IsActive)
1479                                         {
1480                                                 rules_script_active = 1;
1481                                                 PutBstr(HKEY("__SIEVE:RULESSCRIPT"), NewStrBufPlain(HKEY("1")));
1482                                         }
1483                                 }
1484                                 Put(WCC->KnownSieveScripts, IKEY(num_scripts), Ruleset, FreeSieveListing);
1485
1486                                 ++num_scripts;
1487                         }
1488         }
1489         if ((num_scripts > 0) && (rules_script_active == 0))
1490                 PutBstr(HKEY("__SIEVE:EXTERNAL_SCRIPT"), NewStrBufPlain(HKEY("1")));
1491
1492         if (num_scripts > have_rules_script)
1493         {
1494                 long rc;
1495                 long len;
1496                 const char *Key;
1497                 void *vRuleset;
1498
1499                 /* 
1500                  * ok; we have custom scripts, expose that via bstr, and load the payload.
1501                  */
1502                 PutBstr(HKEY("__SIEVE:HAVE_EXTERNAL_SCRIPT"), NewStrBufPlain(HKEY("1")));
1503
1504                 it = GetNewHashPos(WCC->KnownSieveScripts, 0);
1505                 while (GetNextHashPos(WCC->KnownSieveScripts, it, &len, &Key, &vRuleset) && 
1506                        (vRuleset != NULL))
1507                 {
1508                         Ruleset = (SieveListing *) vRuleset;
1509
1510                         /*
1511                          * its the webcit rule? we don't need to load that here.
1512                          */
1513                         if (Ruleset->IsRulesScript)
1514                                 continue;
1515
1516                         if (!serv_printf("MSIV getscript|%s", ChrPtr(Ruleset->Name)))
1517                                 break;
1518                         StrBuf_ServGetln(Line);
1519                         if (GetServerStatus(Line, NULL) == 1) 
1520                         {
1521                                 Ruleset->Content = NewStrBuf();
1522                                 while(!Done && (rc = StrBuf_ServGetln(Line), rc >= 0) )
1523                                         if ( (StrLength(Line)==3) && 
1524                                              !strcmp(ChrPtr(Line), "000")) 
1525                                         {
1526                                                 Done = 1;
1527                                         }
1528                                         else
1529                                         {
1530                                                 if (StrLength(Ruleset->Content)>0)
1531                                                         StrBufAppendBufPlain(Ruleset->Content, HKEY("\n"), 0);
1532                                                 StrBufAppendBuf(Ruleset->Content, Line, 0);
1533                                         }
1534                                 if (rc < 0) break;
1535                         }
1536                 }
1537         }
1538         FreeStrBuf(&Line);
1539         return WCC->KnownSieveScripts;
1540 }
1541
1542
1543 typedef enum __eSieveHfield 
1544 {
1545         from,           
1546         tocc,           
1547         subject,        
1548         replyto,        
1549         sender, 
1550         resentfrom,     
1551         resentto,       
1552         envfrom,        
1553         envto,  
1554         xmailer,        
1555         xspamflag,      
1556         xspamstatus,    
1557         listid, 
1558         size,           
1559         all
1560 } eSieveHfield;
1561
1562 typedef enum __eSieveCompare {
1563         contains,
1564         notcontains,
1565         is,
1566         isnot,
1567         matches,
1568         notmatches
1569 } eSieveCompare;
1570
1571 typedef enum __eSieveAction {
1572         keep,
1573         discard,
1574         reject,
1575         fileinto,
1576         redirect,
1577         vacation
1578 } eSieveAction;
1579
1580
1581 typedef enum __eSieveSizeComp {
1582         larger,
1583         smaller
1584 } eSieveSizeComp;
1585
1586 typedef enum __eSieveFinal {
1587         econtinue,
1588         estop
1589 } eSieveFinal;
1590
1591
1592 typedef struct __SieveRule {
1593         int active;
1594         int sizeval;
1595         eSieveHfield hfield;
1596         eSieveCompare compare;
1597         StrBuf *htext;
1598         eSieveSizeComp sizecomp;
1599         eSieveAction Action;
1600         StrBuf *fileinto;
1601         StrBuf *redirect;
1602         StrBuf *automsg;
1603         eSieveFinal final;
1604 }SieveRule;
1605
1606
1607
1608 int ConditionalSieveRule_hfield(StrBuf *Target, WCTemplputParams *TP)
1609 {
1610         SieveRule     *Rule = (SieveRule *)CTX;
1611         
1612         return GetTemplateTokenNumber(Target, 
1613                                       TP, 
1614                                       3, 
1615                                       from)
1616                 ==
1617                 Rule->hfield;
1618 }
1619 int ConditionalSieveRule_compare(StrBuf *Target, WCTemplputParams *TP)
1620 {
1621         SieveRule     *Rule = (SieveRule *)CTX;
1622         return GetTemplateTokenNumber(Target, 
1623                                       TP, 
1624                                       3, 
1625                                       contains)
1626                 ==
1627                 Rule->compare;
1628 }
1629 int ConditionalSieveRule_action(StrBuf *Target, WCTemplputParams *TP)
1630 {
1631         SieveRule     *Rule = (SieveRule *)CTX;
1632         return GetTemplateTokenNumber(Target, 
1633                                       TP, 
1634                                       3, 
1635                                       keep)
1636                 ==
1637                 Rule->Action; 
1638 }
1639 int ConditionalSieveRule_sizecomp(StrBuf *Target, WCTemplputParams *TP)
1640 {
1641         SieveRule     *Rule = (SieveRule *)CTX;
1642         return GetTemplateTokenNumber(Target, 
1643                                       TP, 
1644                                       3, 
1645                                       larger)
1646                 ==
1647                 Rule->sizecomp;
1648 }
1649 int ConditionalSieveRule_final(StrBuf *Target, WCTemplputParams *TP)
1650 {
1651         SieveRule     *Rule = (SieveRule *)CTX;
1652         return GetTemplateTokenNumber(Target, 
1653                                       TP, 
1654                                       3, 
1655                                       econtinue)
1656                 ==
1657                 Rule->final;
1658 }
1659 int ConditionalSieveRule_ThisRoom(StrBuf *Target, WCTemplputParams *TP)
1660 {
1661         SieveRule     *Rule = (SieveRule *)CTX;
1662         return GetTemplateTokenNumber(Target, 
1663                                       TP, 
1664                                       3, 
1665                                       econtinue)
1666                 ==
1667                 Rule->final;
1668 }
1669 int ConditionalSieveRule_Active(StrBuf *Target, WCTemplputParams *TP)
1670 {
1671         SieveRule     *Rule = (SieveRule *)CTX;
1672         return Rule->active;
1673 }
1674
1675
1676 /*
1677 void tmplput_SieveRule_hfield(StrBuf *Target, WCTemplputParams *TP) 
1678 {
1679         SieveRule     *Rule = (SieveRule *)CTX;
1680         StrBufAppendTemplate(Target, TP, Rule->hfield, 0);
1681 }
1682 void tmplput_SieveRule_compare(StrBuf *Target, WCTemplputParams *TP) 
1683 {
1684         SieveRule     *Rule = (SieveRule *)CTX;
1685         StrBufAppendTemplate(Target, TP, Rule->compare, 0);
1686 }
1687 */
1688 void tmplput_SieveRule_htext(StrBuf *Target, WCTemplputParams *TP) 
1689 {
1690         SieveRule     *Rule = (SieveRule *)CTX;
1691         StrBufAppendTemplate(Target, TP, Rule->htext, 0);
1692 }
1693 /*
1694 void tmplput_SieveRule_sizecomp(StrBuf *Target, WCTemplputParams *TP) 
1695 {
1696         SieveRule     *Rule = (SieveRule *)CTX;
1697         StrBufAppendTemplate(Target, TP, Rule->sizecomp, 0);
1698 }
1699 void tmplput_SieveRule_action(StrBuf *Target, WCTemplputParams *TP) 
1700 {
1701         SieveRule     *Rule = (SieveRule *)CTX;
1702         StrBufAppendTemplate(Target, TP, Rule->action, 0);
1703         }*/
1704 void tmplput_SieveRule_fileinto(StrBuf *Target, WCTemplputParams *TP) 
1705 {
1706         SieveRule     *Rule = (SieveRule *)CTX;
1707         StrBufAppendTemplate(Target, TP, Rule->fileinto, 0);
1708 }
1709 void tmplput_SieveRule_redirect(StrBuf *Target, WCTemplputParams *TP) 
1710 {
1711         SieveRule     *Rule = (SieveRule *)CTX;
1712         StrBufAppendTemplate(Target, TP, Rule->redirect, 0);
1713 }
1714 void tmplput_SieveRule_automsg(StrBuf *Target, WCTemplputParams *TP) 
1715 {
1716         SieveRule     *Rule = (SieveRule *)CTX;
1717         StrBufAppendTemplate(Target, TP, Rule->automsg, 0);
1718 }
1719 /*
1720 void tmplput_SieveRule_final(StrBuf *Target, WCTemplputParams *TP) 
1721 {
1722         SieveRule     *Rule = (SieveRule *)CTX;
1723         StrBufAppendTemplate(Target, TP, Rule->final, 0);
1724 }
1725 */
1726 void FreeSieveRule(void *vRule)
1727 {
1728         SieveRule *Rule = (SieveRule*) Rule;
1729
1730         FreeStrBuf(&Rule->htext);
1731         FreeStrBuf(&Rule->fileinto);
1732         FreeStrBuf(&Rule->redirect);
1733         FreeStrBuf(&Rule->automsg);
1734         
1735         free(Rule);
1736 }
1737
1738 #define WC_RULE_HEADER "# WEBCIT_RULE|"
1739 HashList *GetSieveRules(StrBuf *Target, WCTemplputParams *TP)
1740 {
1741         StrBuf *Line;
1742         StrBuf *EncodedRule;
1743         int n;
1744         const char *pch;
1745         HashList *SieveRules = NULL;
1746         int Done = 0;
1747         SieveRule *Rule;
1748
1749         serv_printf("MSIV getscript|"RULES_SCRIPT);
1750         Line = NewStrBuf();
1751         EncodedRule = NewStrBuf();
1752         StrBuf_ServGetln(Line);
1753         if (GetServerStatus(Line, NULL) == 1) 
1754         {
1755                 SieveRules = NewHash(1, Flathash);
1756
1757                 while(!Done && (StrBuf_ServGetln(Line) >= 0) )
1758                         if ( (StrLength(Line)==3) && 
1759                              !strcmp(ChrPtr(Line), "000")) 
1760                         {
1761                                 Done = 1;
1762                         }
1763                         else
1764                         {
1765                                 pch = NULL;
1766                                 /* We just care for our encoded header and skip everything else */
1767                                 if ((StrLength(Line) > sizeof(WC_RULE_HEADER) - 1) &&
1768                                     (!strncasecmp(ChrPtr(Line), HKEY(WC_RULE_HEADER))))
1769                                 {
1770                                         StrBufSkip_NTokenS(Line, &pch, '|', 1);
1771                                         n = StrBufExtractNext_int(Line, &pch, '|'); 
1772                                         StrBufExtract_NextToken(EncodedRule, Line, &pch, '|');
1773                                         StrBufDecodeBase64(EncodedRule);
1774
1775                                         Rule = (SieveRule*) malloc(sizeof(SieveRule));
1776
1777                                         Rule->htext = NewStrBufPlain (NULL, StrLength(EncodedRule));
1778
1779                                         Rule->fileinto = NewStrBufPlain (NULL, StrLength(EncodedRule));
1780                                         Rule->redirect = NewStrBufPlain (NULL, StrLength(EncodedRule));
1781                                         Rule->automsg = NewStrBufPlain (NULL, StrLength(EncodedRule));
1782
1783                                         /* Grab our existing values to populate */
1784                                         pch = NULL;
1785                                         Rule->active = StrBufExtractNext_int(EncodedRule, &pch, '|');
1786                                         StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
1787                                         
1788                                         Rule->hfield = (eSieveHfield) GetTokenDefine(SKEY(Line), tocc);
1789                                         StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
1790                                         Rule->compare = (eSieveCompare) GetTokenDefine(SKEY(Line), contains);
1791                                         StrBufExtract_NextToken(Rule->htext, EncodedRule, &pch, '|');
1792                                         StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
1793                                         Rule->sizecomp = (eSieveSizeComp) GetTokenDefine(SKEY(Line), larger);
1794                                         Rule->sizeval = StrBufExtractNext_int(EncodedRule, &pch, '|');
1795                                         StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
1796                                         Rule->Action = (eSieveAction) GetTokenDefine(SKEY(Line), keep);
1797                                         StrBufExtract_NextToken(Rule->fileinto, EncodedRule, &pch, '|');
1798                                         StrBufExtract_NextToken(Rule->redirect, EncodedRule, &pch, '|');
1799                                         StrBufExtract_NextToken(Rule->automsg, EncodedRule, &pch, '|');
1800                                         StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
1801                                         Rule->final = (eSieveFinal) GetTokenDefine(SKEY(Line), econtinue);
1802                                         Put(SieveRules, IKEY(n), Rule, FreeSieveRule);
1803                                 }
1804                         }
1805         }
1806
1807         FreeStrBuf(&EncodedRule);
1808         FreeStrBuf(&Line);
1809         return SieveRules;
1810 }
1811
1812 void
1813 SessionDetachModule_SIEVE
1814 (wcsession *sess)
1815 {
1816         DeleteHash(&sess->KnownSieveScripts);
1817 }
1818
1819 void 
1820 InitModule_SIEVE
1821 (void)
1822 {
1823         REGISTERTokenParamDefine(from);         
1824         REGISTERTokenParamDefine(tocc);         
1825         REGISTERTokenParamDefine(subject);      
1826         REGISTERTokenParamDefine(replyto);      
1827         REGISTERTokenParamDefine(sender);       
1828         REGISTERTokenParamDefine(resentfrom);   
1829         REGISTERTokenParamDefine(resentto);     
1830         REGISTERTokenParamDefine(envfrom);      
1831         REGISTERTokenParamDefine(envto);        
1832         REGISTERTokenParamDefine(xmailer);      
1833         REGISTERTokenParamDefine(xspamflag);    
1834         REGISTERTokenParamDefine(xspamstatus);  
1835         REGISTERTokenParamDefine(listid);       
1836         REGISTERTokenParamDefine(size);         
1837         REGISTERTokenParamDefine(all);
1838
1839         REGISTERTokenParamDefine(contains);
1840         REGISTERTokenParamDefine(notcontains);
1841         REGISTERTokenParamDefine(is);
1842         REGISTERTokenParamDefine(isnot);
1843         REGISTERTokenParamDefine(matches);
1844         REGISTERTokenParamDefine(notmatches);
1845
1846         REGISTERTokenParamDefine(keep);
1847         REGISTERTokenParamDefine(discard);
1848         REGISTERTokenParamDefine(reject);
1849         REGISTERTokenParamDefine(fileinto);
1850         REGISTERTokenParamDefine(redirect);
1851         REGISTERTokenParamDefine(vacation);
1852
1853         REGISTERTokenParamDefine(larger);
1854         REGISTERTokenParamDefine(smaller);
1855
1856         /* these are c-keyworads, so do it by hand. */
1857         RegisterTokenParamDefine(HKEY("continue"), econtinue);
1858         RegisterTokenParamDefine(HKEY("stop"), estop);
1859
1860         RegisterIterator("SIEVE:SCRIPTS", 0, NULL, GetSieveRules, NULL, NULL, CTX_SIEVELIST, CTX_NONE, IT_NOFLAG);
1861
1862         RegisterIterator("SIEVE:RULES", 0, NULL, GetSieveRules, NULL, DeleteHash, CTX_SIEVESCRIPT, CTX_NONE, IT_NOFLAG);
1863
1864         RegisterConditional(HKEY("COND:SIEVE:SCRIPT:ACTIVE"), 0, ConditionalSieveScriptIsActive, CTX_SIEVELIST);
1865         RegisterConditional(HKEY("COND:SIEVE:SCRIPT:ISRULES"), 0, ConditionalSieveScriptIsRulesScript, CTX_SIEVELIST);
1866         RegisterNamespace("SIEVE:SCRIPT:NAME", 0, 1, tmplput_SieveScriptName, NULL, CTX_ROOMS);
1867         RegisterNamespace("SIEVE:SCRIPT:CONTENT", 0, 1, tmplput_SieveScriptContent, NULL, CTX_SIEVELIST);
1868
1869  
1870         RegisterConditional(HKEY("COND:SIEVE:ACTIVE"), 1, ConditionalSieveRule_Active, CTX_SIEVESCRIPT);
1871         RegisterConditional(HKEY("COND:SIEVE:HFIELD"), 1, ConditionalSieveRule_hfield, CTX_SIEVESCRIPT);
1872         RegisterConditional(HKEY("COND:SIEVE:COMPARE"), 1, ConditionalSieveRule_compare, CTX_SIEVESCRIPT);
1873         RegisterConditional(HKEY("COND:SIEVE:ACTION"), 1, ConditionalSieveRule_action, CTX_SIEVESCRIPT);
1874         RegisterConditional(HKEY("COND:SIEVE:SIZECOMP"), 1, ConditionalSieveRule_sizecomp, CTX_SIEVESCRIPT);
1875         RegisterConditional(HKEY("COND:SIEVE:FINAL"), 1, ConditionalSieveRule_final, CTX_SIEVESCRIPT);
1876         RegisterConditional(HKEY("COND:SIEVE:THISROOM"), 1, ConditionalSieveRule_ThisRoom, CTX_SIEVESCRIPT);
1877
1878         //RegisterNamespace("SIEVE:SCRIPT:HFIELD", 0, 1, tmplput_SieveRule_hfield, NULL, CTX_SIEVESCRIPT);
1879         //RegisterNamespace("SIEVE:SCRIPT:COMPARE", 0, 1, tmplput_SieveRule_compare, NULL, CTX_SIEVESCRIPT);
1880         RegisterNamespace("SIEVE:SCRIPT:HTEXT", 0, 1, tmplput_SieveRule_htext, NULL, CTX_SIEVESCRIPT);
1881         //RegisterNamespace("SIEVE:SCRIPT:SIZECOMP", 0, 1, tmplput_SieveRule_sizecomp, NULL, CTX_SIEVESCRIPT);
1882         ///RegisterNamespace("SIEVE:SCRIPT:ACTION", 0, 1, tmplput_SieveRule_action, NULL, CTX_SIEVESCRIPT);
1883         RegisterNamespace("SIEVE:SCRIPT:FILEINTO", 0, 1, tmplput_SieveRule_fileinto, NULL, CTX_SIEVESCRIPT);
1884         RegisterNamespace("SIEVE:SCRIPT:REDIRECT", 0, 1, tmplput_SieveRule_redirect, NULL, CTX_SIEVESCRIPT);
1885         RegisterNamespace("SIEVE:SCRIPT:AUTOMSG", 0, 1, tmplput_SieveRule_automsg, NULL, CTX_SIEVESCRIPT);
1886         ///RegisterNamespace("SIEVE:SCRIPT:FINAL", 0, 1, tmplput_SieveRule_final, NULL, CTX_SIEVESCRIPT);
1887
1888 #if FOO
1889         WebcitAddUrlHandler(HKEY("display_sieve"), "", 0, display_sieve, 0);
1890         WebcitAddUrlHandler(HKEY("display_add_remove_scripts"), "", 0, _display_add_remove_scripts, 0);
1891 #endif
1892         WebcitAddUrlHandler(HKEY("save_sieve"), "", 0, save_sieve, 0);
1893
1894         WebcitAddUrlHandler(HKEY("create_script"), "", 0, create_script, 0);
1895         WebcitAddUrlHandler(HKEY("delete_script"), "", 0, delete_script, 0);
1896 }