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.
15 #define MAX_SCRIPTS 100
17 #define RULES_SCRIPT "__WebCit_Generated_Script__"
21 * Helper function for output_sieve_rule() to output strings with quotes escaped
23 void osr_sanitize(char *str) {
26 if (str == NULL) return;
28 for (i=0; i<len; ++i) {
32 else if (isspace(str[i])) {
40 * Output parseable Sieve script code based on rules input
42 void output_sieve_rule(char *hfield, char *compare, char *htext, char *sizecomp, int sizeval,
43 char *action, char *fileinto, char *redirect, char *automsg, char *final,
50 osr_sanitize(fileinto);
51 osr_sanitize(redirect);
52 osr_sanitize(automsg);
54 /* Prepare negation and match operators that will be used iff we apply a conditional */
56 if (!strcasecmp(compare, "contains")) {
60 else if (!strcasecmp(compare, "notcontains")) {
64 else if (!strcasecmp(compare, "is")) {
68 else if (!strcasecmp(compare, "isnot")) {
72 else if (!strcasecmp(compare, "matches")) {
76 else if (!strcasecmp(compare, "notmatches")) {
81 /* Now do the conditional */
83 if (!strcasecmp(hfield, "from")) {
84 serv_printf("if%s header %s \"From\" \"%s\"",
90 else if (!strcasecmp(hfield, "tocc")) {
91 serv_printf("if%s header %s [\"To\", \"Cc\"] \"%s\"",
97 else if (!strcasecmp(hfield, "subject")) {
98 serv_printf("if%s header %s \"Subject\" \"%s\"",
104 else if (!strcasecmp(hfield, "replyto")) {
105 serv_printf("if%s header %s \"Reply-to\" \"%s\"",
111 else if (!strcasecmp(hfield, "sender")) {
112 serv_printf("if%s header %s \"Sender\" \"%s\"",
118 else if (!strcasecmp(hfield, "resentfrom")) {
119 serv_printf("if%s header %s \"Resent-from\" \"%s\"",
125 else if (!strcasecmp(hfield, "resentto")) {
126 serv_printf("if%s header %s \"Resent-to\" \"%s\"",
132 else if (!strcasecmp(hfield, "xmailer")) {
133 serv_printf("if%s header %s \"X-Mailer\" \"%s\"",
139 else if (!strcasecmp(hfield, "xspamflag")) {
140 serv_printf("if%s header %s \"X-Spam-Flag\" \"%s\"",
146 else if (!strcasecmp(hfield, "xspamstatus")) {
147 serv_printf("if%s header %s \"X-Spam-Status\" \"%s\"",
153 else if (!strcasecmp(hfield, "listid")) {
154 serv_printf("if%s header %s \"List-ID\" \"%s\"",
160 else if (!strcasecmp(hfield, "envfrom")) {
161 serv_printf("if%s envelope %s \"From\" \"%s\"",
167 else if (!strcasecmp(hfield, "envto")) {
168 serv_printf("if%s envelope %s \"To\" \"%s\"",
174 else if (!strcasecmp(hfield, "size")) {
175 if (!strcasecmp(sizecomp, "larger")) {
176 serv_printf("if size :over %d", sizeval);
178 else if (!strcasecmp(sizecomp, "smaller")) {
179 serv_printf("if size :under %d", sizeval);
181 else { /* failsafe - should never get here, but just in case... */
182 serv_printf("if size :over 1");
186 /* Open braces if we're in a conditional loop */
188 if (strcasecmp(hfield, "all")) {
194 if (!strcasecmp(action, "keep")) {
195 serv_printf("keep;");
198 else if (!strcasecmp(action, "discard")) {
199 serv_printf("discard;");
202 else if (!strcasecmp(action, "reject")) {
203 serv_printf("reject \"%s\";", automsg);
206 else if (!strcasecmp(action, "fileinto")) {
207 serv_printf("fileinto \"%s\";", fileinto);
210 else if (!strcasecmp(action, "redirect")) {
211 serv_printf("redirect \"%s\";", redirect);
214 else if (!strcasecmp(action, "vacation")) {
215 serv_printf("vacation :addresses [%s]\n\"%s\";", my_addresses, automsg);
218 /* Do 'final' action */
220 if (!strcasecmp(final, "stop")) {
221 serv_printf("stop;");
224 /* Close the braces if we're in a conditional loop */
226 if (strcasecmp(hfield, "all")) {
235 * Translate the fields from the rule editor into something we can save...
237 void parse_fields_from_rule_editor(void) {
254 char encoded_rule[4096];
255 char my_addresses[4096];
257 /* Enumerate my email addresses in case they are needed for a vacation rule */
260 serv_getln(buf, sizeof buf);
261 if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
262 if (!IsEmptyStr(my_addresses)) {
263 strcat(my_addresses, ",\n");
265 strcat(my_addresses, "\"");
266 strcat(my_addresses, buf);
267 strcat(my_addresses, "\"");
270 /* Now generate the script and write it to the Citadel server */
271 serv_printf("MSIV putscript|%s|", RULES_SCRIPT);
272 serv_getln(buf, sizeof buf);
277 serv_puts("# THIS SCRIPT WAS AUTOMATICALLY GENERATED BY WEBCIT.");
279 serv_puts("# Do not attempt to manually edit it. If you do so,");
280 serv_puts("# your changes will be overwritten the next time WebCit");
281 serv_puts("# saves its mail filtering rule set. If you really want");
282 serv_puts("# to use these rules as the basis for another script,");
283 serv_puts("# copy them to another script and save that instead.");
285 serv_puts("require \"fileinto\";");
286 serv_puts("require \"reject\";");
287 serv_puts("require \"vacation\";");
288 serv_puts("require \"envelope\";");
291 for (i=0; i<MAX_RULES; ++i) {
295 sprintf(fname, "active%d", i);
296 active = !strcasecmp(BSTR(fname), "on") ;
300 sprintf(fname, "hfield%d", i);
301 safestrncpy(hfield, BSTR(fname), sizeof hfield);
303 sprintf(fname, "compare%d", i);
304 safestrncpy(compare, BSTR(fname), sizeof compare);
306 sprintf(fname, "htext%d", i);
307 safestrncpy(htext, BSTR(fname), sizeof htext);
309 sprintf(fname, "sizecomp%d", i);
310 safestrncpy(sizecomp, BSTR(fname), sizeof sizecomp);
312 sprintf(fname, "sizeval%d", i);
313 sizeval = IBSTR(fname);
315 sprintf(fname, "action%d", i);
316 safestrncpy(action, BSTR(fname), sizeof action);
318 sprintf(fname, "fileinto%d", i);
319 safestrncpy(fileinto, BSTR(fname), sizeof fileinto);
321 sprintf(fname, "redirect%d", i);
322 safestrncpy(redirect, BSTR(fname), sizeof redirect);
324 sprintf(fname, "automsg%d", i);
325 safestrncpy(automsg, BSTR(fname), sizeof automsg);
327 sprintf(fname, "final%d", i);
328 safestrncpy(final, BSTR(fname), sizeof final);
330 snprintf(rule, sizeof rule, "%d|%s|%s|%s|%s|%d|%s|%s|%s|%s|%s",
331 active, hfield, compare, htext, sizecomp, sizeval, action, fileinto,
332 redirect, automsg, final
335 CtdlEncodeBase64(encoded_rule, rule, strlen(rule)+1, 0);
336 serv_printf("# WEBCIT_RULE|%d|%s|", i, encoded_rule);
337 output_sieve_rule(hfield, compare, htext, sizecomp, sizeval,
338 action, fileinto, redirect, automsg, final, my_addresses);
353 void save_sieve(void) {
355 char script_names[MAX_SCRIPTS][64];
361 if (!havebstr("save_button")) {
362 AppendImportantMessage(_("Cancelled. Changes were not saved."), -1);
367 parse_fields_from_rule_editor();
369 serv_puts("MSIV listscripts");
370 serv_getln(buf, sizeof(buf));
371 if (buf[0] == '1') while (serv_getln(buf, sizeof(buf)), strcmp(buf, "000")) {
372 if (num_scripts < MAX_SCRIPTS) {
373 extract_token(script_names[num_scripts], buf, 0, '|', 64);
378 bigaction = ibstr("bigaction");
380 if (bigaction == 0) {
381 serv_puts("MSIV setactive||");
382 serv_getln(buf, sizeof buf);
385 else if (bigaction == 1) {
386 serv_printf("MSIV setactive|%s|", RULES_SCRIPT);
387 serv_getln(buf, sizeof buf);
390 else if (bigaction == 2) {
391 serv_printf("MSIV setactive|%s|", bstr("active_script"));
392 serv_getln(buf, sizeof buf);
395 if (num_scripts > 0) {
396 for (i=0; i<num_scripts; ++i) {
398 * We only want to save the scripts from the "manually edited scripts"
399 * screen. The script that WebCit generates from its ruleset will be
400 * auto-generated by parse_fields_from_rule_editor() and saved there.
402 if (strcasecmp(script_names[i], RULES_SCRIPT)) {
403 serv_printf("MSIV putscript|%s|", script_names[i]);
404 serv_getln(buf, sizeof buf);
406 snprintf(this_name, sizeof this_name, "text_%s", script_names[i]);
407 striplt((char *)BSTR(this_name)); /* TODO: get rid of typecast*/
408 serv_write(BSTR(this_name), strlen(BSTR(this_name)));
415 AppendImportantMessage(_("Your changes have been saved."), -1);
422 * create a new script
423 * take the web environment script name and create it on the citadel server
425 void create_script(void) {
428 serv_printf("MSIV getscript|%s", bstr("script_name"));
429 serv_getln(buf, sizeof buf);
431 while (serv_getln(buf, sizeof(buf)), strcmp(buf, "000")) {
437 serv_printf("MSIV putscript|%s", bstr("script_name"));
438 serv_getln(buf, sizeof buf);
442 output_headers(1, 1, 2, 0, 0, 0);
443 do_template("sieve_add");
448 output_headers(1, 1, 2, 0, 0, 0);
449 do_template("sieve_add");
457 void delete_script(void) {
460 serv_printf("MSIV deletescript|%s", bstr("script_name"));
461 serv_getln(buf, sizeof buf);
462 output_headers(1, 1, 2, 0, 0, 0);
463 do_template("sieve_add");
469 * dummy panel indicating to the user that the server doesn't support Sieve
471 void display_no_sieve(void) {
473 output_headers(1, 1, 2, 0, 0, 0);
474 do_template("sieve_none");
479 typedef struct __SieveListing {
486 int ConditionalSieveScriptIsActive(StrBuf *Target, WCTemplputParams *TP)
488 SieveListing *SieveList = (SieveListing *)CTX;
489 return SieveList->IsActive;
491 int ConditionalSieveScriptIsRulesScript(StrBuf *Target, WCTemplputParams *TP)
493 SieveListing *SieveList = (SieveListing *)CTX;
494 return SieveList->IsActive;
496 void tmplput_SieveScriptName(StrBuf *Target, WCTemplputParams *TP)
498 SieveListing *SieveList = (SieveListing *)CTX;
499 StrBufAppendTemplate(Target, TP, SieveList->Name, 0);
501 void tmplput_SieveScriptContent(StrBuf *Target, WCTemplputParams *TP)
503 SieveListing *SieveList = (SieveListing *)CTX;
504 StrBufAppendTemplate(Target, TP, SieveList->Content, 0);
506 void FreeSieveListing(void *vSieveListing)
508 SieveListing *List = (SieveListing*) vSieveListing;
510 FreeStrBuf(&List->Name);
514 HashList *GetSieveScriptListing(StrBuf *Target, WCTemplputParams *TP)
519 int rules_script_active = 0;
520 int have_rules_script = 0;
524 SieveListing *Ruleset;
526 if (WCC->KnownSieveScripts != NULL) {
527 return WCC->KnownSieveScripts;
530 serv_puts("MSIV listscripts");
532 StrBuf_ServGetln(Line);
533 if (GetServerStatus(Line, NULL) == 1)
535 WCC->KnownSieveScripts = NewHash(1, Flathash);
537 while(!Done && (StrBuf_ServGetln(Line) >= 0) )
538 if ( (StrLength(Line)==3) &&
539 !strcmp(ChrPtr(Line), "000"))
546 Ruleset = (SieveListing *) malloc(sizeof(SieveListing));
547 Ruleset->Name = NewStrBufPlain(NULL, StrLength(Line));
548 StrBufExtract_NextToken(Ruleset->Name, Line, &pch, '|');
549 Ruleset->IsActive = StrBufExtractNext_int(Line, &pch, '|');
550 Ruleset->Content = NULL;
552 if (!strcasecmp(ChrPtr(Ruleset->Name), RULES_SCRIPT))
554 Ruleset->IsRulesScript = 1;
555 have_rules_script = 1;
556 if (Ruleset->IsActive)
558 rules_script_active = 1;
559 PutBstr(HKEY("__SIEVE:RULESSCRIPT"), NewStrBufPlain(HKEY("1")));
562 Put(WCC->KnownSieveScripts, IKEY(num_scripts), Ruleset, FreeSieveListing);
568 if ((num_scripts > 0) && (rules_script_active == 0)) {
569 PutBstr(HKEY("__SIEVE:EXTERNAL_SCRIPT"), NewStrBufPlain(HKEY("1")));
572 if (num_scripts > have_rules_script)
580 * ok; we have custom scripts, expose that via bstr, and load the payload.
582 PutBstr(HKEY("__SIEVE:HAVE_EXTERNAL_SCRIPT"), NewStrBufPlain(HKEY("1")));
584 it = GetNewHashPos(WCC->KnownSieveScripts, 0);
585 while (GetNextHashPos(WCC->KnownSieveScripts, it, &len, &Key, &vRuleset) &&
588 Ruleset = (SieveListing *) vRuleset;
590 // FIXME add logic to skip if it's the webcit generated script
592 serv_printf("MSIV getscript|%s", ChrPtr(Ruleset->Name));
593 StrBuf_ServGetln(Line);
594 if (GetServerStatus(Line, NULL) == 1)
596 Ruleset->Content = NewStrBuf();
598 while(!Done && (rc = StrBuf_ServGetln(Line), rc >= 0) )
599 if ( (StrLength(Line)==3) &&
600 !strcmp(ChrPtr(Line), "000"))
606 if (StrLength(Ruleset->Content)>0)
607 StrBufAppendBufPlain(Ruleset->Content, HKEY("\n"), 0);
608 StrBufAppendBuf(Ruleset->Content, Line, 0);
615 return WCC->KnownSieveScripts;
619 typedef enum __eSieveHfield
638 typedef enum __eSieveCompare {
647 typedef enum __eSieveAction {
657 typedef enum __eSieveSizeComp {
662 typedef enum __eSieveFinal {
668 typedef struct __SieveRule {
672 eSieveCompare compare;
674 eSieveSizeComp sizecomp;
684 int ConditionalSieveRule_hfield(StrBuf *Target, WCTemplputParams *TP)
686 SieveRule *Rule = (SieveRule *)CTX;
688 return GetTemplateTokenNumber(Target,
695 int ConditionalSieveRule_compare(StrBuf *Target, WCTemplputParams *TP)
697 SieveRule *Rule = (SieveRule *)CTX;
698 return GetTemplateTokenNumber(Target,
705 int ConditionalSieveRule_action(StrBuf *Target, WCTemplputParams *TP)
707 SieveRule *Rule = (SieveRule *)CTX;
708 return GetTemplateTokenNumber(Target,
715 int ConditionalSieveRule_sizecomp(StrBuf *Target, WCTemplputParams *TP)
717 SieveRule *Rule = (SieveRule *)CTX;
718 return GetTemplateTokenNumber(Target,
725 int ConditionalSieveRule_final(StrBuf *Target, WCTemplputParams *TP)
727 SieveRule *Rule = (SieveRule *)CTX;
728 return GetTemplateTokenNumber(Target,
735 int ConditionalSieveRule_ThisRoom(StrBuf *Target, WCTemplputParams *TP)
737 SieveRule *Rule = (SieveRule *)CTX;
738 return GetTemplateTokenNumber(Target,
745 int ConditionalSieveRule_Active(StrBuf *Target, WCTemplputParams *TP)
747 SieveRule *Rule = (SieveRule *)CTX;
750 void tmplput_SieveRule_htext(StrBuf *Target, WCTemplputParams *TP)
752 SieveRule *Rule = (SieveRule *)CTX;
753 StrBufAppendTemplate(Target, TP, Rule->htext, 0);
755 void tmplput_SieveRule_fileinto(StrBuf *Target, WCTemplputParams *TP)
757 SieveRule *Rule = (SieveRule *)CTX;
758 StrBufAppendTemplate(Target, TP, Rule->fileinto, 0);
760 void tmplput_SieveRule_redirect(StrBuf *Target, WCTemplputParams *TP)
762 SieveRule *Rule = (SieveRule *)CTX;
763 StrBufAppendTemplate(Target, TP, Rule->redirect, 0);
765 void tmplput_SieveRule_automsg(StrBuf *Target, WCTemplputParams *TP)
767 SieveRule *Rule = (SieveRule *)CTX;
768 StrBufAppendTemplate(Target, TP, Rule->automsg, 0);
770 void tmplput_SieveRule_sizeval(StrBuf *Target, WCTemplputParams *TP)
772 SieveRule *Rule = (SieveRule *)CTX;
773 StrBufAppendPrintf(Target, "%d", Rule->sizeval);
776 void tmplput_SieveRule_lookup_FileIntoRoom(StrBuf *Target, WCTemplputParams *TP)
779 SieveRule *Rule = (SieveRule *)CTX;
781 HashList *Rooms = GetRoomListHashLKRA(Target, TP);
783 GetHash(Rooms, SKEY(Rule->fileinto), &vRoom);
784 WCC->ThisRoom = (folder*) vRoom;
787 void FreeSieveRule(void *vRule)
789 SieveRule *Rule = (SieveRule*) vRule;
791 FreeStrBuf(&Rule->htext);
792 FreeStrBuf(&Rule->fileinto);
793 FreeStrBuf(&Rule->redirect);
794 FreeStrBuf(&Rule->automsg);
799 #define WC_RULE_HEADER "# WEBCIT_RULE|"
800 HashList *GetSieveRules(StrBuf *Target, WCTemplputParams *TP)
803 StrBuf *EncodedRule = NULL;
805 const char *pch = NULL;
806 HashList *SieveRules = NULL;
808 SieveRule *Rule = NULL;
810 SieveRules = NewHash(1, Flathash);
811 serv_printf("MSIV getscript|"RULES_SCRIPT);
813 EncodedRule = NewStrBuf();
814 StrBuf_ServGetln(Line);
815 if (GetServerStatus(Line, NULL) == 1)
817 while(!Done && (StrBuf_ServGetln(Line) >= 0) )
818 if ( (StrLength(Line)==3) &&
819 !strcmp(ChrPtr(Line), "000"))
826 /* We just care for our encoded header and skip everything else */
827 if ((StrLength(Line) > sizeof(WC_RULE_HEADER) - 1) &&
828 (!strncasecmp(ChrPtr(Line), HKEY(WC_RULE_HEADER))))
830 StrBufSkip_NTokenS(Line, &pch, '|', 1);
831 n = StrBufExtractNext_int(Line, &pch, '|');
832 StrBufExtract_NextToken(EncodedRule, Line, &pch, '|');
833 StrBufDecodeBase64(EncodedRule);
835 Rule = (SieveRule*) malloc(sizeof(SieveRule));
837 Rule->htext = NewStrBufPlain (NULL, StrLength(EncodedRule));
839 Rule->fileinto = NewStrBufPlain (NULL, StrLength(EncodedRule));
840 Rule->redirect = NewStrBufPlain (NULL, StrLength(EncodedRule));
841 Rule->automsg = NewStrBufPlain (NULL, StrLength(EncodedRule));
843 /* Grab our existing values to populate */
845 Rule->active = StrBufExtractNext_int(EncodedRule, &pch, '|');
846 StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
848 Rule->hfield = (eSieveHfield) GetTokenDefine(SKEY(Line), tocc);
849 StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
850 Rule->compare = (eSieveCompare) GetTokenDefine(SKEY(Line), contains);
851 StrBufExtract_NextToken(Rule->htext, EncodedRule, &pch, '|');
852 StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
853 Rule->sizecomp = (eSieveSizeComp) GetTokenDefine(SKEY(Line), larger);
854 Rule->sizeval = StrBufExtractNext_int(EncodedRule, &pch, '|');
855 StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
856 Rule->Action = (eSieveAction) GetTokenDefine(SKEY(Line), keep);
857 StrBufExtract_NextToken(Rule->fileinto, EncodedRule, &pch, '|');
858 StrBufExtract_NextToken(Rule->redirect, EncodedRule, &pch, '|');
859 StrBufExtract_NextToken(Rule->automsg, EncodedRule, &pch, '|');
860 StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
861 Rule->final = (eSieveFinal) GetTokenDefine(SKEY(Line), econtinue);
862 Put(SieveRules, IKEY(n), Rule, FreeSieveRule);
868 while (n < MAX_RULES) {
869 Rule = (SieveRule*) malloc(sizeof(SieveRule));
870 memset(Rule, 0, sizeof(SieveRule));
871 Put(SieveRules, IKEY(n), Rule, FreeSieveRule);
877 FreeStrBuf(&EncodedRule);
883 SessionDetachModule_SIEVE
886 DeleteHash(&sess->KnownSieveScripts);
893 REGISTERTokenParamDefine(from);
894 REGISTERTokenParamDefine(tocc);
895 REGISTERTokenParamDefine(subject);
896 REGISTERTokenParamDefine(replyto);
897 REGISTERTokenParamDefine(sender);
898 REGISTERTokenParamDefine(resentfrom);
899 REGISTERTokenParamDefine(resentto);
900 REGISTERTokenParamDefine(envfrom);
901 REGISTERTokenParamDefine(envto);
902 REGISTERTokenParamDefine(xmailer);
903 REGISTERTokenParamDefine(xspamflag);
904 REGISTERTokenParamDefine(xspamstatus);
905 REGISTERTokenParamDefine(listid);
906 REGISTERTokenParamDefine(size);
907 REGISTERTokenParamDefine(all);
909 REGISTERTokenParamDefine(contains);
910 REGISTERTokenParamDefine(notcontains);
911 REGISTERTokenParamDefine(is);
912 REGISTERTokenParamDefine(isnot);
913 REGISTERTokenParamDefine(matches);
914 REGISTERTokenParamDefine(notmatches);
916 REGISTERTokenParamDefine(keep);
917 REGISTERTokenParamDefine(discard);
918 REGISTERTokenParamDefine(reject);
919 REGISTERTokenParamDefine(fileinto);
920 REGISTERTokenParamDefine(redirect);
921 REGISTERTokenParamDefine(vacation);
923 REGISTERTokenParamDefine(larger);
924 REGISTERTokenParamDefine(smaller);
926 /* these are c-keyworads, so do it by hand. */
927 RegisterTokenParamDefine(HKEY("continue"), econtinue);
928 RegisterTokenParamDefine(HKEY("stop"), estop);
930 RegisterIterator("SIEVE:SCRIPTS", 0, NULL, GetSieveScriptListing, NULL, NULL, CTX_SIEVELIST, CTX_NONE, IT_NOFLAG);
932 RegisterConditional(HKEY("COND:SIEVE:SCRIPT:ACTIVE"), 0, ConditionalSieveScriptIsActive, CTX_SIEVELIST);
933 RegisterConditional(HKEY("COND:SIEVE:SCRIPT:ISRULES"), 0, ConditionalSieveScriptIsRulesScript, CTX_SIEVELIST);
934 RegisterNamespace("SIEVE:SCRIPT:NAME", 0, 1, tmplput_SieveScriptName, NULL, CTX_SIEVELIST);
935 RegisterNamespace("SIEVE:SCRIPT:CONTENT", 0, 1, tmplput_SieveScriptContent, NULL, CTX_SIEVELIST);
938 RegisterIterator("SIEVE:RULES", 0, NULL, GetSieveRules, NULL, DeleteHash, CTX_SIEVESCRIPT, CTX_NONE, IT_NOFLAG);
940 RegisterConditional(HKEY("COND:SIEVE:ACTIVE"), 1, ConditionalSieveRule_Active, CTX_SIEVESCRIPT);
941 RegisterConditional(HKEY("COND:SIEVE:HFIELD"), 1, ConditionalSieveRule_hfield, CTX_SIEVESCRIPT);
942 RegisterConditional(HKEY("COND:SIEVE:COMPARE"), 1, ConditionalSieveRule_compare, CTX_SIEVESCRIPT);
943 RegisterConditional(HKEY("COND:SIEVE:ACTION"), 1, ConditionalSieveRule_action, CTX_SIEVESCRIPT);
944 RegisterConditional(HKEY("COND:SIEVE:SIZECOMP"), 1, ConditionalSieveRule_sizecomp, CTX_SIEVESCRIPT);
945 RegisterConditional(HKEY("COND:SIEVE:FINAL"), 1, ConditionalSieveRule_final, CTX_SIEVESCRIPT);
946 RegisterConditional(HKEY("COND:SIEVE:THISROOM"), 1, ConditionalSieveRule_ThisRoom, CTX_SIEVESCRIPT);
948 RegisterNamespace("SIEVE:SCRIPT:HTEXT", 0, 1, tmplput_SieveRule_htext, NULL, CTX_SIEVESCRIPT);
949 RegisterNamespace("SIEVE:SCRIPT:SIZE", 0, 1, tmplput_SieveRule_sizeval, NULL, CTX_SIEVESCRIPT);
950 RegisterNamespace("SIEVE:SCRIPT:FILEINTO", 0, 1, tmplput_SieveRule_fileinto, NULL, CTX_SIEVESCRIPT);
951 RegisterNamespace("SIEVE:SCRIPT:REDIRECT", 0, 1, tmplput_SieveRule_redirect, NULL, CTX_SIEVESCRIPT);
952 RegisterNamespace("SIEVE:SCRIPT:AUTOMSG", 0, 1, tmplput_SieveRule_automsg, NULL, CTX_SIEVESCRIPT);
954 /* fetch our room into WCC->ThisRoom, to evaluate while iterating over rooms with COND:THIS:THAT:ROOM */
955 RegisterNamespace("SIEVE:SCRIPT:LOOKUP_FILEINTO", 0, 1, tmplput_SieveRule_lookup_FileIntoRoom, NULL, CTX_SIEVESCRIPT);
956 WebcitAddUrlHandler(HKEY("save_sieve"), "", 0, save_sieve, 0);
957 WebcitAddUrlHandler(HKEY("create_script"), "", 0, create_script, 0);
958 WebcitAddUrlHandler(HKEY("delete_script"), "", 0, delete_script, 0);