2 * Copyright (c) 1996-2012 by the citadel.org team
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 version 3.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * FIXME: add logic to exclude the webcit-generated script from the manual script selection
17 CtxType CTX_SIEVELIST = CTX_NONE;
18 CtxType CTX_SIEVESCRIPT = CTX_NONE;
20 #define MAX_SCRIPTS 100
22 #define RULES_SCRIPT "__WebCit_Generated_Script__"
26 * Helper function for output_sieve_rule() to output strings with quotes escaped
28 void osr_sanitize(char *str) {
31 if (str == NULL) return;
33 for (i=0; i<len; ++i) {
37 else if (isspace(str[i])) {
45 * Output parseable Sieve script code based on rules input
47 void output_sieve_rule(char *hfield, char *compare, char *htext, char *sizecomp, int sizeval,
48 char *action, char *fileinto, char *redirect, char *automsg, char *final,
55 osr_sanitize(fileinto);
56 osr_sanitize(redirect);
57 osr_sanitize(automsg);
59 /* Prepare negation and match operators that will be used iff we apply a conditional */
61 if (!strcasecmp(compare, "contains")) {
65 else if (!strcasecmp(compare, "notcontains")) {
69 else if (!strcasecmp(compare, "is")) {
73 else if (!strcasecmp(compare, "isnot")) {
77 else if (!strcasecmp(compare, "matches")) {
81 else if (!strcasecmp(compare, "notmatches")) {
86 /* Now do the conditional */
88 if (!strcasecmp(hfield, "from")) {
89 serv_printf("if%s header %s \"From\" \"%s\"",
95 else if (!strcasecmp(hfield, "tocc")) {
96 serv_printf("if%s header %s [\"To\", \"Cc\"] \"%s\"",
102 else if (!strcasecmp(hfield, "subject")) {
103 serv_printf("if%s header %s \"Subject\" \"%s\"",
109 else if (!strcasecmp(hfield, "replyto")) {
110 serv_printf("if%s header %s \"Reply-to\" \"%s\"",
116 else if (!strcasecmp(hfield, "sender")) {
117 serv_printf("if%s header %s \"Sender\" \"%s\"",
123 else if (!strcasecmp(hfield, "resentfrom")) {
124 serv_printf("if%s header %s \"Resent-from\" \"%s\"",
130 else if (!strcasecmp(hfield, "resentto")) {
131 serv_printf("if%s header %s \"Resent-to\" \"%s\"",
137 else if (!strcasecmp(hfield, "xmailer")) {
138 serv_printf("if%s header %s \"X-Mailer\" \"%s\"",
144 else if (!strcasecmp(hfield, "xspamflag")) {
145 serv_printf("if%s header %s \"X-Spam-Flag\" \"%s\"",
151 else if (!strcasecmp(hfield, "xspamstatus")) {
152 serv_printf("if%s header %s \"X-Spam-Status\" \"%s\"",
158 else if (!strcasecmp(hfield, "listid")) {
159 serv_printf("if%s header %s \"List-ID\" \"%s\"",
165 else if (!strcasecmp(hfield, "envfrom")) {
166 serv_printf("if%s envelope %s \"From\" \"%s\"",
172 else if (!strcasecmp(hfield, "envto")) {
173 serv_printf("if%s envelope %s \"To\" \"%s\"",
179 else if (!strcasecmp(hfield, "size")) {
180 if (!strcasecmp(sizecomp, "larger")) {
181 serv_printf("if size :over %d", sizeval);
183 else if (!strcasecmp(sizecomp, "smaller")) {
184 serv_printf("if size :under %d", sizeval);
186 else { /* failsafe - should never get here, but just in case... */
187 serv_printf("if size :over 1");
191 /* Open braces if we're in a conditional loop */
193 if (strcasecmp(hfield, "all")) {
199 if (!strcasecmp(action, "keep")) {
200 serv_printf("keep;");
203 else if (!strcasecmp(action, "discard")) {
204 serv_printf("discard;");
207 else if (!strcasecmp(action, "reject")) {
208 serv_printf("reject \"%s\";", automsg);
211 else if (!strcasecmp(action, "fileinto")) {
212 serv_printf("fileinto \"%s\";", fileinto);
215 else if (!strcasecmp(action, "redirect")) {
216 serv_printf("redirect \"%s\";", redirect);
219 else if (!strcasecmp(action, "vacation")) {
220 serv_printf("vacation :addresses [%s]\n\"%s\";", my_addresses, automsg);
223 /* Do 'final' action */
225 if (!strcasecmp(final, "stop")) {
226 serv_printf("stop;");
229 /* Close the braces if we're in a conditional loop */
231 if (strcasecmp(hfield, "all")) {
240 * Translate the fields from the rule editor into something we can save...
242 void parse_fields_from_rule_editor(void) {
259 char encoded_rule[4096];
260 char my_addresses[4096];
262 /* Enumerate my email addresses in case they are needed for a vacation rule */
265 serv_getln(buf, sizeof buf);
266 if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
267 if (!IsEmptyStr(my_addresses)) {
268 strcat(my_addresses, ",\n");
270 strcat(my_addresses, "\"");
271 strcat(my_addresses, buf);
272 strcat(my_addresses, "\"");
275 /* Now generate the script and write it to the Citadel server */
276 serv_printf("MSIV putscript|%s|", RULES_SCRIPT);
277 serv_getln(buf, sizeof buf);
282 serv_puts("# THIS SCRIPT WAS AUTOMATICALLY GENERATED BY WEBCIT.");
284 serv_puts("# Do not attempt to manually edit it. If you do so,");
285 serv_puts("# your changes will be overwritten the next time WebCit");
286 serv_puts("# saves its mail filtering rule set. If you really want");
287 serv_puts("# to use these rules as the basis for another script,");
288 serv_puts("# copy them to another script and save that instead.");
290 serv_puts("require \"fileinto\";");
291 serv_puts("require \"reject\";");
292 serv_puts("require \"vacation\";");
293 serv_puts("require \"envelope\";");
296 for (i=0; i<MAX_RULES; ++i) {
300 sprintf(fname, "active%d", i);
301 active = !strcasecmp(BSTR(fname), "on") ;
305 sprintf(fname, "hfield%d", i);
306 safestrncpy(hfield, BSTR(fname), sizeof hfield);
308 sprintf(fname, "compare%d", i);
309 safestrncpy(compare, BSTR(fname), sizeof compare);
311 sprintf(fname, "htext%d", i);
312 safestrncpy(htext, BSTR(fname), sizeof htext);
314 sprintf(fname, "sizecomp%d", i);
315 safestrncpy(sizecomp, BSTR(fname), sizeof sizecomp);
317 sprintf(fname, "sizeval%d", i);
318 sizeval = IBSTR(fname);
320 sprintf(fname, "action%d", i);
321 safestrncpy(action, BSTR(fname), sizeof action);
323 sprintf(fname, "fileinto%d", i);
324 safestrncpy(fileinto, BSTR(fname), sizeof fileinto);
326 sprintf(fname, "redirect%d", i);
327 safestrncpy(redirect, BSTR(fname), sizeof redirect);
329 sprintf(fname, "automsg%d", i);
330 safestrncpy(automsg, BSTR(fname), sizeof automsg);
332 sprintf(fname, "final%d", i);
333 safestrncpy(final, BSTR(fname), sizeof final);
335 snprintf(rule, sizeof rule, "%d|%s|%s|%s|%s|%d|%s|%s|%s|%s|%s",
336 active, hfield, compare, htext, sizecomp, sizeval, action, fileinto,
337 redirect, automsg, final
340 CtdlEncodeBase64(encoded_rule, rule, strlen(rule)+1, 0);
341 serv_printf("# WEBCIT_RULE|%d|%s|", i, encoded_rule);
342 output_sieve_rule(hfield, compare, htext, sizecomp, sizeval,
343 action, fileinto, redirect, automsg, final, my_addresses);
358 void save_sieve(void) {
360 char script_names[MAX_SCRIPTS][64];
366 if (!havebstr("save_button")) {
367 AppendImportantMessage(_("Cancelled. Changes were not saved."), -1);
372 parse_fields_from_rule_editor();
374 serv_puts("MSIV listscripts");
375 serv_getln(buf, sizeof(buf));
376 if (buf[0] == '1') while (serv_getln(buf, sizeof(buf)), strcmp(buf, "000")) {
377 if (num_scripts < MAX_SCRIPTS) {
378 extract_token(script_names[num_scripts], buf, 0, '|', 64);
383 bigaction = ibstr("bigaction");
385 if (bigaction == 0) {
386 serv_puts("MSIV setactive||");
387 serv_getln(buf, sizeof buf);
390 else if (bigaction == 1) {
391 serv_printf("MSIV setactive|%s|", RULES_SCRIPT);
392 serv_getln(buf, sizeof buf);
395 else if (bigaction == 2) {
396 serv_printf("MSIV setactive|%s|", bstr("active_script"));
397 serv_getln(buf, sizeof buf);
400 if (num_scripts > 0) {
401 for (i=0; i<num_scripts; ++i) {
403 * We only want to save the scripts from the "manually edited scripts"
404 * screen. The script that WebCit generates from its ruleset will be
405 * auto-generated by parse_fields_from_rule_editor() and saved there.
407 if (strcasecmp(script_names[i], RULES_SCRIPT)) {
408 serv_printf("MSIV putscript|%s|", script_names[i]);
409 serv_getln(buf, sizeof buf);
411 snprintf(this_name, sizeof this_name, "text_%s", script_names[i]);
412 striplt((char *)BSTR(this_name)); /* TODO: get rid of typecast*/
413 serv_write(BSTR(this_name), strlen(BSTR(this_name)));
420 AppendImportantMessage(_("Your changes have been saved."), -1);
426 void display_sieve_add_or_delete(void) {
427 output_headers(1, 1, 2, 0, 0, 0);
428 do_template("sieve_add");
435 * create a new script
436 * take the web environment script name and create it on the citadel server
438 void create_script(void) {
441 serv_printf("MSIV getscript|%s", bstr("script_name"));
442 serv_getln(buf, sizeof buf);
443 if (buf[0] == '1') { // does script exist already?
444 while (serv_getln(buf, sizeof(buf)), strcmp(buf, "000")) {
445 // yes -- flush the output
449 // no -- safe to create a new one by this name
450 serv_printf("MSIV putscript|%s", bstr("script_name"));
451 serv_getln(buf, sizeof buf);
458 display_sieve_add_or_delete();
465 void delete_script(void) {
468 serv_printf("MSIV deletescript|%s", bstr("script_name"));
469 serv_getln(buf, sizeof buf);
470 display_sieve_add_or_delete();
475 * dummy panel indicating to the user that the server doesn't support Sieve
477 void display_no_sieve(void) {
479 output_headers(1, 1, 1, 0, 0, 0);
480 do_template("sieve_none");
485 typedef struct __SieveListing {
492 int ConditionalSieveScriptIsActive(StrBuf *Target, WCTemplputParams *TP)
494 SieveListing *SieveList = (SieveListing *)CTX(CTX_SIEVELIST);
495 return SieveList->IsActive;
497 int ConditionalSieveScriptIsRulesScript(StrBuf *Target, WCTemplputParams *TP)
499 SieveListing *SieveList = (SieveListing *)CTX(CTX_SIEVELIST);
500 return SieveList->IsActive;
502 void tmplput_SieveScriptName(StrBuf *Target, WCTemplputParams *TP)
504 SieveListing *SieveList = (SieveListing *)CTX(CTX_SIEVELIST);
505 StrBufAppendTemplate(Target, TP, SieveList->Name, 0);
507 void tmplput_SieveScriptContent(StrBuf *Target, WCTemplputParams *TP)
509 SieveListing *SieveList = (SieveListing *)CTX(CTX_SIEVELIST);
510 StrBufAppendTemplate(Target, TP, SieveList->Content, 0);
512 void FreeSieveListing(void *vSieveListing)
514 SieveListing *List = (SieveListing*) vSieveListing;
516 FreeStrBuf(&List->Name);
520 HashList *GetSieveScriptListing(StrBuf *Target, WCTemplputParams *TP)
525 int rules_script_active = 0;
526 int have_rules_script = 0;
530 SieveListing *Ruleset;
532 if (WCC->KnownSieveScripts != NULL) {
533 return WCC->KnownSieveScripts;
536 serv_puts("MSIV listscripts");
538 StrBuf_ServGetln(Line);
539 if (GetServerStatus(Line, NULL) == 1)
541 WCC->KnownSieveScripts = NewHash(1, Flathash);
543 while(!Done && (StrBuf_ServGetln(Line) >= 0) )
544 if ( (StrLength(Line)==3) &&
545 !strcmp(ChrPtr(Line), "000"))
552 Ruleset = (SieveListing *) malloc(sizeof(SieveListing));
553 Ruleset->Name = NewStrBufPlain(NULL, StrLength(Line));
554 StrBufExtract_NextToken(Ruleset->Name, Line, &pch, '|');
555 Ruleset->IsActive = StrBufExtractNext_int(Line, &pch, '|');
556 Ruleset->Content = NULL;
558 if (!strcasecmp(ChrPtr(Ruleset->Name), RULES_SCRIPT))
560 Ruleset->IsRulesScript = 1;
561 have_rules_script = 1;
562 if (Ruleset->IsActive)
564 rules_script_active = 1;
565 PutBstr(HKEY("__SIEVE:RULESSCRIPT"), NewStrBufPlain(HKEY("1")));
568 Put(WCC->KnownSieveScripts, IKEY(num_scripts), Ruleset, FreeSieveListing);
574 if ((num_scripts > 0) && (rules_script_active == 0)) {
575 PutBstr(HKEY("__SIEVE:EXTERNAL_SCRIPT"), NewStrBufPlain(HKEY("1")));
578 if (num_scripts > have_rules_script)
586 * ok; we have custom scripts, expose that via bstr, and load the payload.
588 PutBstr(HKEY("__SIEVE:HAVE_EXTERNAL_SCRIPT"), NewStrBufPlain(HKEY("1")));
590 it = GetNewHashPos(WCC->KnownSieveScripts, 0);
591 while (GetNextHashPos(WCC->KnownSieveScripts, it, &len, &Key, &vRuleset) &&
594 Ruleset = (SieveListing *) vRuleset;
595 serv_printf("MSIV getscript|%s", ChrPtr(Ruleset->Name));
596 StrBuf_ServGetln(Line);
597 if (GetServerStatus(Line, NULL) == 1)
599 Ruleset->Content = NewStrBuf();
601 while(!Done && (rc = StrBuf_ServGetln(Line), rc >= 0) )
602 if ( (StrLength(Line)==3) &&
603 !strcmp(ChrPtr(Line), "000"))
609 if (StrLength(Ruleset->Content)>0)
610 StrBufAppendBufPlain(Ruleset->Content, HKEY("\n"), 0);
611 StrBufAppendBuf(Ruleset->Content, Line, 0);
618 return WCC->KnownSieveScripts;
622 typedef enum __eSieveHfield
641 typedef enum __eSieveCompare {
650 typedef enum __eSieveAction {
660 typedef enum __eSieveSizeComp {
665 typedef enum __eSieveFinal {
671 typedef struct __SieveRule {
675 eSieveCompare compare;
677 eSieveSizeComp sizecomp;
687 int ConditionalSieveRule_hfield(StrBuf *Target, WCTemplputParams *TP)
689 SieveRule *Rule = (SieveRule *)CTX(CTX_SIEVESCRIPT);
691 return GetTemplateTokenNumber(Target,
698 int ConditionalSieveRule_compare(StrBuf *Target, WCTemplputParams *TP)
700 SieveRule *Rule = (SieveRule *)CTX(CTX_SIEVESCRIPT);
701 return GetTemplateTokenNumber(Target,
708 int ConditionalSieveRule_action(StrBuf *Target, WCTemplputParams *TP)
710 SieveRule *Rule = (SieveRule *)CTX(CTX_SIEVESCRIPT);
711 return GetTemplateTokenNumber(Target,
718 int ConditionalSieveRule_sizecomp(StrBuf *Target, WCTemplputParams *TP)
720 SieveRule *Rule = (SieveRule *)CTX(CTX_SIEVESCRIPT);
721 return GetTemplateTokenNumber(Target,
728 int ConditionalSieveRule_final(StrBuf *Target, WCTemplputParams *TP)
730 SieveRule *Rule = (SieveRule *)CTX(CTX_SIEVESCRIPT);
731 return GetTemplateTokenNumber(Target,
738 int ConditionalSieveRule_ThisRoom(StrBuf *Target, WCTemplputParams *TP)
740 SieveRule *Rule = (SieveRule *)CTX(CTX_SIEVESCRIPT);
741 return GetTemplateTokenNumber(Target,
748 int ConditionalSieveRule_Active(StrBuf *Target, WCTemplputParams *TP)
750 SieveRule *Rule = (SieveRule *)CTX(CTX_SIEVESCRIPT);
753 void tmplput_SieveRule_htext(StrBuf *Target, WCTemplputParams *TP)
755 SieveRule *Rule = (SieveRule *)CTX(CTX_SIEVESCRIPT);
756 StrBufAppendTemplate(Target, TP, Rule->htext, 0);
758 void tmplput_SieveRule_fileinto(StrBuf *Target, WCTemplputParams *TP)
760 SieveRule *Rule = (SieveRule *)CTX(CTX_SIEVESCRIPT);
761 StrBufAppendTemplate(Target, TP, Rule->fileinto, 0);
763 void tmplput_SieveRule_redirect(StrBuf *Target, WCTemplputParams *TP)
765 SieveRule *Rule = (SieveRule *)CTX(CTX_SIEVESCRIPT);
766 StrBufAppendTemplate(Target, TP, Rule->redirect, 0);
768 void tmplput_SieveRule_automsg(StrBuf *Target, WCTemplputParams *TP)
770 SieveRule *Rule = (SieveRule *)CTX(CTX_SIEVESCRIPT);
771 StrBufAppendTemplate(Target, TP, Rule->automsg, 0);
773 void tmplput_SieveRule_sizeval(StrBuf *Target, WCTemplputParams *TP)
775 SieveRule *Rule = (SieveRule *)CTX(CTX_SIEVESCRIPT);
776 StrBufAppendPrintf(Target, "%d", Rule->sizeval);
779 void tmplput_SieveRule_lookup_FileIntoRoom(StrBuf *Target, WCTemplputParams *TP)
782 SieveRule *Rule = (SieveRule *)CTX(CTX_SIEVESCRIPT);
784 HashList *Rooms = GetRoomListHashLKRA(Target, TP);
786 GetHash(Rooms, SKEY(Rule->fileinto), &vRoom);
787 WCC->ThisRoom = (folder*) vRoom;
790 void FreeSieveRule(void *vRule)
792 SieveRule *Rule = (SieveRule*) vRule;
794 FreeStrBuf(&Rule->htext);
795 FreeStrBuf(&Rule->fileinto);
796 FreeStrBuf(&Rule->redirect);
797 FreeStrBuf(&Rule->automsg);
802 #define WC_RULE_HEADER "# WEBCIT_RULE|"
803 HashList *GetSieveRules(StrBuf *Target, WCTemplputParams *TP)
806 StrBuf *EncodedRule = NULL;
808 const char *pch = NULL;
809 HashList *SieveRules = NULL;
811 SieveRule *Rule = NULL;
813 SieveRules = NewHash(1, Flathash);
814 serv_printf("MSIV getscript|"RULES_SCRIPT);
816 EncodedRule = NewStrBuf();
817 StrBuf_ServGetln(Line);
818 if (GetServerStatus(Line, NULL) == 1)
820 while(!Done && (StrBuf_ServGetln(Line) >= 0) )
821 if ( (StrLength(Line)==3) &&
822 !strcmp(ChrPtr(Line), "000"))
829 /* We just care for our encoded header and skip everything else */
830 if ((StrLength(Line) > sizeof(WC_RULE_HEADER) - 1) &&
831 (!strncasecmp(ChrPtr(Line), HKEY(WC_RULE_HEADER))))
833 StrBufSkip_NTokenS(Line, &pch, '|', 1);
834 n = StrBufExtractNext_int(Line, &pch, '|');
835 StrBufExtract_NextToken(EncodedRule, Line, &pch, '|');
836 StrBufDecodeBase64(EncodedRule);
838 Rule = (SieveRule*) malloc(sizeof(SieveRule));
840 Rule->htext = NewStrBufPlain (NULL, StrLength(EncodedRule));
842 Rule->fileinto = NewStrBufPlain (NULL, StrLength(EncodedRule));
843 Rule->redirect = NewStrBufPlain (NULL, StrLength(EncodedRule));
844 Rule->automsg = NewStrBufPlain (NULL, StrLength(EncodedRule));
846 /* Grab our existing values to populate */
848 Rule->active = StrBufExtractNext_int(EncodedRule, &pch, '|');
849 StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
851 Rule->hfield = (eSieveHfield) GetTokenDefine(SKEY(Line), tocc);
852 StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
853 Rule->compare = (eSieveCompare) GetTokenDefine(SKEY(Line), contains);
854 StrBufExtract_NextToken(Rule->htext, EncodedRule, &pch, '|');
855 StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
856 Rule->sizecomp = (eSieveSizeComp) GetTokenDefine(SKEY(Line), larger);
857 Rule->sizeval = StrBufExtractNext_int(EncodedRule, &pch, '|');
858 StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
859 Rule->Action = (eSieveAction) GetTokenDefine(SKEY(Line), keep);
860 StrBufExtract_NextToken(Rule->fileinto, EncodedRule, &pch, '|');
861 StrBufExtract_NextToken(Rule->redirect, EncodedRule, &pch, '|');
862 StrBufExtract_NextToken(Rule->automsg, EncodedRule, &pch, '|');
863 StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
864 Rule->final = (eSieveFinal) GetTokenDefine(SKEY(Line), econtinue);
865 Put(SieveRules, IKEY(n), Rule, FreeSieveRule);
871 while (n < MAX_RULES) {
872 Rule = (SieveRule*) malloc(sizeof(SieveRule));
873 memset(Rule, 0, sizeof(SieveRule));
874 Put(SieveRules, IKEY(n), Rule, FreeSieveRule);
880 FreeStrBuf(&EncodedRule);
886 SessionDetachModule_SIEVE
889 DeleteHash(&sess->KnownSieveScripts);
896 RegisterCTX(CTX_SIEVELIST);
897 RegisterCTX(CTX_SIEVESCRIPT);
898 REGISTERTokenParamDefine(from);
899 REGISTERTokenParamDefine(tocc);
900 REGISTERTokenParamDefine(subject);
901 REGISTERTokenParamDefine(replyto);
902 REGISTERTokenParamDefine(sender);
903 REGISTERTokenParamDefine(resentfrom);
904 REGISTERTokenParamDefine(resentto);
905 REGISTERTokenParamDefine(envfrom);
906 REGISTERTokenParamDefine(envto);
907 REGISTERTokenParamDefine(xmailer);
908 REGISTERTokenParamDefine(xspamflag);
909 REGISTERTokenParamDefine(xspamstatus);
910 REGISTERTokenParamDefine(listid);
911 REGISTERTokenParamDefine(size);
912 REGISTERTokenParamDefine(all);
914 REGISTERTokenParamDefine(contains);
915 REGISTERTokenParamDefine(notcontains);
916 REGISTERTokenParamDefine(is);
917 REGISTERTokenParamDefine(isnot);
918 REGISTERTokenParamDefine(matches);
919 REGISTERTokenParamDefine(notmatches);
921 REGISTERTokenParamDefine(keep);
922 REGISTERTokenParamDefine(discard);
923 REGISTERTokenParamDefine(reject);
924 REGISTERTokenParamDefine(fileinto);
925 REGISTERTokenParamDefine(redirect);
926 REGISTERTokenParamDefine(vacation);
928 REGISTERTokenParamDefine(larger);
929 REGISTERTokenParamDefine(smaller);
931 /* these are c-keyworads, so do it by hand. */
932 RegisterTokenParamDefine(HKEY("continue"), econtinue);
933 RegisterTokenParamDefine(HKEY("stop"), estop);
935 RegisterIterator("SIEVE:SCRIPTS", 0, NULL, GetSieveScriptListing, NULL, NULL, CTX_SIEVELIST, CTX_NONE, IT_NOFLAG);
937 RegisterConditional("COND:SIEVE:SCRIPT:ACTIVE", 0, ConditionalSieveScriptIsActive, CTX_SIEVELIST);
938 RegisterConditional("COND:SIEVE:SCRIPT:ISRULES", 0, ConditionalSieveScriptIsRulesScript, CTX_SIEVELIST);
939 RegisterNamespace("SIEVE:SCRIPT:NAME", 0, 1, tmplput_SieveScriptName, NULL, CTX_SIEVELIST);
940 RegisterNamespace("SIEVE:SCRIPT:CONTENT", 0, 1, tmplput_SieveScriptContent, NULL, CTX_SIEVELIST);
943 RegisterIterator("SIEVE:RULES", 0, NULL, GetSieveRules, NULL, DeleteHash, CTX_SIEVESCRIPT, CTX_NONE, IT_NOFLAG);
945 RegisterConditional("COND:SIEVE:ACTIVE", 1, ConditionalSieveRule_Active, CTX_SIEVESCRIPT);
946 RegisterConditional("COND:SIEVE:HFIELD", 1, ConditionalSieveRule_hfield, CTX_SIEVESCRIPT);
947 RegisterConditional("COND:SIEVE:COMPARE", 1, ConditionalSieveRule_compare, CTX_SIEVESCRIPT);
948 RegisterConditional("COND:SIEVE:ACTION", 1, ConditionalSieveRule_action, CTX_SIEVESCRIPT);
949 RegisterConditional("COND:SIEVE:SIZECOMP", 1, ConditionalSieveRule_sizecomp, CTX_SIEVESCRIPT);
950 RegisterConditional("COND:SIEVE:FINAL", 1, ConditionalSieveRule_final, CTX_SIEVESCRIPT);
951 RegisterConditional("COND:SIEVE:THISROOM", 1, ConditionalSieveRule_ThisRoom, CTX_SIEVESCRIPT);
953 RegisterNamespace("SIEVE:SCRIPT:HTEXT", 0, 1, tmplput_SieveRule_htext, NULL, CTX_SIEVESCRIPT);
954 RegisterNamespace("SIEVE:SCRIPT:SIZE", 0, 1, tmplput_SieveRule_sizeval, NULL, CTX_SIEVESCRIPT);
955 RegisterNamespace("SIEVE:SCRIPT:FILEINTO", 0, 1, tmplput_SieveRule_fileinto, NULL, CTX_SIEVESCRIPT);
956 RegisterNamespace("SIEVE:SCRIPT:REDIRECT", 0, 1, tmplput_SieveRule_redirect, NULL, CTX_SIEVESCRIPT);
957 RegisterNamespace("SIEVE:SCRIPT:AUTOMSG", 0, 1, tmplput_SieveRule_automsg, NULL, CTX_SIEVESCRIPT);
959 /* fetch our room into WCC->ThisRoom, to evaluate while iterating over rooms with COND:THIS:THAT:ROOM */
960 RegisterNamespace("SIEVE:SCRIPT:LOOKUP_FILEINTO", 0, 1, tmplput_SieveRule_lookup_FileIntoRoom, NULL, CTX_SIEVESCRIPT);
961 WebcitAddUrlHandler(HKEY("save_sieve"), "", 0, save_sieve, 0);
962 WebcitAddUrlHandler(HKEY("create_script"), "", 0, create_script, 0);
963 WebcitAddUrlHandler(HKEY("delete_script"), "", 0, delete_script, 0);
964 WebcitAddUrlHandler(HKEY("display_sieve_add_or_delete"), "", 0, display_sieve_add_or_delete, 0);