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__"
20 * Helper function for output_sieve_rule() to output strings with quotes escaped
22 void osr_sanitize(char *str) {
25 if (str == NULL) return;
27 for (i=0; i<len; ++i) {
31 else if (isspace(str[i])) {
37 void display_add_remove_scripts(char *message);
38 void display_rules_editor_inner_div(void);
42 * Output parseable Sieve script code based on rules input
44 void output_sieve_rule(char *hfield, char *compare, char *htext, char *sizecomp, int sizeval,
45 char *action, char *fileinto, char *redirect, char *automsg, char *final,
52 osr_sanitize(fileinto);
53 osr_sanitize(redirect);
54 osr_sanitize(automsg);
56 /* Prepare negation and match operators that will be used iff we apply a conditional */
58 if (!strcasecmp(compare, "contains")) {
62 else if (!strcasecmp(compare, "notcontains")) {
66 else if (!strcasecmp(compare, "is")) {
70 else if (!strcasecmp(compare, "isnot")) {
74 else if (!strcasecmp(compare, "matches")) {
78 else if (!strcasecmp(compare, "notmatches")) {
83 /* Now do the conditional */
85 if (!strcasecmp(hfield, "from")) {
86 serv_printf("if%s header %s \"From\" \"%s\"",
92 else if (!strcasecmp(hfield, "tocc")) {
93 serv_printf("if%s header %s [\"To\", \"Cc\"] \"%s\"",
99 else if (!strcasecmp(hfield, "subject")) {
100 serv_printf("if%s header %s \"Subject\" \"%s\"",
106 else if (!strcasecmp(hfield, "replyto")) {
107 serv_printf("if%s header %s \"Reply-to\" \"%s\"",
113 else if (!strcasecmp(hfield, "sender")) {
114 serv_printf("if%s header %s \"Sender\" \"%s\"",
120 else if (!strcasecmp(hfield, "resentfrom")) {
121 serv_printf("if%s header %s \"Resent-from\" \"%s\"",
127 else if (!strcasecmp(hfield, "resentto")) {
128 serv_printf("if%s header %s \"Resent-to\" \"%s\"",
134 else if (!strcasecmp(hfield, "xmailer")) {
135 serv_printf("if%s header %s \"X-Mailer\" \"%s\"",
141 else if (!strcasecmp(hfield, "xspamflag")) {
142 serv_printf("if%s header %s \"X-Spam-Flag\" \"%s\"",
148 else if (!strcasecmp(hfield, "xspamstatus")) {
149 serv_printf("if%s header %s \"X-Spam-Status\" \"%s\"",
155 else if (!strcasecmp(hfield, "listid")) {
156 serv_printf("if%s header %s \"List-ID\" \"%s\"",
162 else if (!strcasecmp(hfield, "envfrom")) {
163 serv_printf("if%s envelope %s \"From\" \"%s\"",
169 else if (!strcasecmp(hfield, "envto")) {
170 serv_printf("if%s envelope %s \"To\" \"%s\"",
176 else if (!strcasecmp(hfield, "size")) {
177 if (!strcasecmp(sizecomp, "larger")) {
178 serv_printf("if size :over %d", sizeval);
180 else if (!strcasecmp(sizecomp, "smaller")) {
181 serv_printf("if size :under %d", sizeval);
183 else { /* failsafe - should never get here, but just in case... */
184 serv_printf("if size :over 1");
188 /* Open braces if we're in a conditional loop */
190 if (strcasecmp(hfield, "all")) {
197 if (!strcasecmp(action, "keep")) {
198 serv_printf("keep;");
201 else if (!strcasecmp(action, "discard")) {
202 serv_printf("discard;");
205 else if (!strcasecmp(action, "reject")) {
206 serv_printf("reject \"%s\";", automsg);
209 else if (!strcasecmp(action, "fileinto")) {
210 serv_printf("fileinto \"%s\";", fileinto);
213 else if (!strcasecmp(action, "redirect")) {
214 serv_printf("redirect \"%s\";", redirect);
217 else if (!strcasecmp(action, "vacation")) {
218 serv_printf("vacation :addresses [%s]\n\"%s\";", my_addresses, automsg);
222 /* Do 'final' action */
224 if (!strcasecmp(final, "stop")) {
225 serv_printf("stop;");
229 /* Close the braces if we're in a conditional loop */
231 if (strcasecmp(hfield, "all")) {
242 * Translate the fields from the rule editor into something we can save...
244 void parse_fields_from_rule_editor(void) {
261 char encoded_rule[4096];
262 char my_addresses[4096];
264 /* Enumerate my email addresses in case they are needed for a vacation rule */
267 serv_getln(buf, sizeof buf);
268 if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
269 if (!IsEmptyStr(my_addresses)) {
270 strcat(my_addresses, ",\n");
272 strcat(my_addresses, "\"");
273 strcat(my_addresses, buf);
274 strcat(my_addresses, "\"");
277 /* Now generate the script and write it to the Citadel server */
278 serv_printf("MSIV putscript|%s|", RULES_SCRIPT);
279 serv_getln(buf, sizeof buf);
284 serv_puts("# THIS SCRIPT WAS AUTOMATICALLY GENERATED BY WEBCIT.");
286 serv_puts("# Do not attempt to manually edit it. If you do so,");
287 serv_puts("# your changes will be overwritten the next time WebCit");
288 serv_puts("# saves its mail filtering rule set. If you really want");
289 serv_puts("# to use these rules as the basis for another script,");
290 serv_puts("# copy them to another script and save that instead.");
292 serv_puts("require \"fileinto\";");
293 serv_puts("require \"reject\";");
294 serv_puts("require \"vacation\";");
295 serv_puts("require \"envelope\";");
298 for (i=0; i<MAX_RULES; ++i) {
302 sprintf(fname, "active%d", i);
303 active = !strcasecmp(BSTR(fname), "on") ;
307 sprintf(fname, "hfield%d", i);
308 safestrncpy(hfield, BSTR(fname), sizeof hfield);
310 sprintf(fname, "compare%d", i);
311 safestrncpy(compare, BSTR(fname), sizeof compare);
313 sprintf(fname, "htext%d", i);
314 safestrncpy(htext, BSTR(fname), sizeof htext);
316 sprintf(fname, "sizecomp%d", i);
317 safestrncpy(sizecomp, BSTR(fname), sizeof sizecomp);
319 sprintf(fname, "sizeval%d", i);
320 sizeval = IBSTR(fname);
322 sprintf(fname, "action%d", i);
323 safestrncpy(action, BSTR(fname), sizeof action);
325 sprintf(fname, "fileinto%d", i);
326 safestrncpy(fileinto, BSTR(fname), sizeof fileinto);
328 sprintf(fname, "redirect%d", i);
329 safestrncpy(redirect, BSTR(fname), sizeof redirect);
331 sprintf(fname, "automsg%d", i);
332 safestrncpy(automsg, BSTR(fname), sizeof automsg);
334 sprintf(fname, "final%d", i);
335 safestrncpy(final, BSTR(fname), sizeof final);
337 snprintf(rule, sizeof rule, "%d|%s|%s|%s|%s|%d|%s|%s|%s|%s|%s",
338 active, hfield, compare, htext, sizecomp, sizeval, action, fileinto,
339 redirect, automsg, final
342 CtdlEncodeBase64(encoded_rule, rule, strlen(rule)+1, 0);
343 serv_printf("# WEBCIT_RULE|%d|%s|", i, encoded_rule);
344 output_sieve_rule(hfield, compare, htext, sizecomp, sizeval,
345 action, fileinto, redirect, automsg, final, my_addresses);
361 void save_sieve(void) {
363 char script_names[MAX_SCRIPTS][64];
365 int active_script = (-1); /* this throws a 'set but not used' warning , check this ! */
370 if (!havebstr("save_button")) {
371 AppendImportantMessage(_("Cancelled. Changes were not saved."), -1);
376 parse_fields_from_rule_editor();
378 serv_puts("MSIV listscripts");
379 serv_getln(buf, sizeof(buf));
380 if (buf[0] == '1') while (serv_getln(buf, sizeof(buf)), strcmp(buf, "000")) {
381 if (num_scripts < MAX_SCRIPTS) {
382 extract_token(script_names[num_scripts], buf, 0, '|', 64);
383 if (extract_int(buf, 1) > 0) {
384 active_script = num_scripts;
390 bigaction = ibstr("bigaction");
392 if (bigaction == 0) {
393 serv_puts("MSIV setactive||");
394 serv_getln(buf, sizeof buf);
397 else if (bigaction == 1) {
398 serv_printf("MSIV setactive|%s|", RULES_SCRIPT);
399 serv_getln(buf, sizeof buf);
402 else if (bigaction == 2) {
403 serv_printf("MSIV setactive|%s|", bstr("active_script"));
404 serv_getln(buf, sizeof buf);
407 if (num_scripts > 0) {
408 for (i=0; i<num_scripts; ++i) {
410 * We only want to save the scripts from the "manually edited scripts"
411 * screen. The script that WebCit generates from its ruleset will be
412 * auto-generated by parse_fields_from_rule_editor() and saved there.
414 if (strcasecmp(script_names[i], RULES_SCRIPT)) {
415 serv_printf("MSIV putscript|%s|", script_names[i]);
416 serv_getln(buf, sizeof buf);
418 snprintf(this_name, sizeof this_name, "text_%s", script_names[i]);
419 striplt((char *)BSTR(this_name)); /* TODO: get rid of typecast*/
420 serv_write(BSTR(this_name), strlen(BSTR(this_name)));
427 AppendImportantMessage(_("Your changes have been saved."), -1);
433 * create a new script
434 * take the web environment script name and create it on the citadel server
436 void create_script(void) {
439 serv_printf("MSIV getscript|%s", bstr("script_name"));
440 serv_getln(buf, sizeof buf);
442 while (serv_getln(buf, sizeof(buf)), strcmp(buf, "000")) {
448 serv_printf("MSIV putscript|%s", bstr("script_name"));
449 serv_getln(buf, sizeof buf);
453 output_headers(1, 1, 2, 0, 0, 0);
454 do_template("sieve_add");
459 output_headers(1, 1, 2, 0, 0, 0);
460 do_template("sieve_add");
470 void delete_script(void) {
473 serv_printf("MSIV deletescript|%s", bstr("script_name"));
474 serv_getln(buf, sizeof buf);
475 output_headers(1, 1, 2, 0, 0, 0);
476 do_template("sieve_add");
483 * dummy panel indicating to the user that the server doesn't support Sieve
485 void display_no_sieve(void) {
487 output_headers(1, 1, 2, 0, 0, 0);
488 do_template("sieve_none");
493 typedef struct __SieveListing {
500 int ConditionalSieveScriptIsActive(StrBuf *Target, WCTemplputParams *TP)
502 SieveListing *SieveList = (SieveListing *)CTX;
503 return SieveList->IsActive;
505 int ConditionalSieveScriptIsRulesScript(StrBuf *Target, WCTemplputParams *TP)
507 SieveListing *SieveList = (SieveListing *)CTX;
508 return SieveList->IsActive;
510 void tmplput_SieveScriptName(StrBuf *Target, WCTemplputParams *TP)
512 SieveListing *SieveList = (SieveListing *)CTX;
513 StrBufAppendTemplate(Target, TP, SieveList->Name, 0);
515 void tmplput_SieveScriptContent(StrBuf *Target, WCTemplputParams *TP)
517 SieveListing *SieveList = (SieveListing *)CTX;
518 StrBufAppendTemplate(Target, TP, SieveList->Content, 0);
520 void FreeSieveListing(void *vSieveListing)
522 SieveListing *List = (SieveListing*) vSieveListing;
524 FreeStrBuf(&List->Name);
528 HashList *GetSieveScriptListing(StrBuf *Target, WCTemplputParams *TP)
533 int rules_script_active = 0;
534 int have_rules_script = 0;
538 SieveListing *Ruleset;
540 if (WCC->KnownSieveScripts != NULL)
541 return WCC->KnownSieveScripts;
543 serv_puts("MSIV listscripts");
545 StrBuf_ServGetln(Line);
546 if (GetServerStatus(Line, NULL) == 1)
548 WCC->KnownSieveScripts = NewHash(1, Flathash);
550 while(!Done && (StrBuf_ServGetln(Line) >= 0) )
551 if ( (StrLength(Line)==3) &&
552 !strcmp(ChrPtr(Line), "000"))
559 Ruleset = (SieveListing *) malloc(sizeof(SieveListing));
560 Ruleset->Name = NewStrBufPlain(NULL, StrLength(Line));
561 StrBufExtract_NextToken(Ruleset->Name, Line, &pch, '|');
562 Ruleset->IsActive = StrBufExtractNext_int(Line, &pch, '|');
563 Ruleset->Content = NULL;
565 if (!strcasecmp(ChrPtr(Ruleset->Name), RULES_SCRIPT))
567 Ruleset->IsRulesScript = 1;
568 have_rules_script = 1;
569 if (Ruleset->IsActive)
571 rules_script_active = 1;
572 PutBstr(HKEY("__SIEVE:RULESSCRIPT"), NewStrBufPlain(HKEY("1")));
575 Put(WCC->KnownSieveScripts, IKEY(num_scripts), Ruleset, FreeSieveListing);
580 if ((num_scripts > 0) && (rules_script_active == 0))
581 PutBstr(HKEY("__SIEVE:EXTERNAL_SCRIPT"), NewStrBufPlain(HKEY("1")));
583 if (num_scripts > have_rules_script)
591 * ok; we have custom scripts, expose that via bstr, and load the payload.
593 PutBstr(HKEY("__SIEVE:HAVE_EXTERNAL_SCRIPT"), NewStrBufPlain(HKEY("1")));
595 it = GetNewHashPos(WCC->KnownSieveScripts, 0);
596 while (GetNextHashPos(WCC->KnownSieveScripts, it, &len, &Key, &vRuleset) &&
599 Ruleset = (SieveListing *) vRuleset;
602 * its the webcit rule? we don't need to load that here.
604 if (Ruleset->IsRulesScript)
607 if (!serv_printf("MSIV getscript|%s", ChrPtr(Ruleset->Name)))
609 StrBuf_ServGetln(Line);
610 if (GetServerStatus(Line, NULL) == 1)
612 Ruleset->Content = NewStrBuf();
613 while(!Done && (rc = StrBuf_ServGetln(Line), rc >= 0) )
614 if ( (StrLength(Line)==3) &&
615 !strcmp(ChrPtr(Line), "000"))
621 if (StrLength(Ruleset->Content)>0)
622 StrBufAppendBufPlain(Ruleset->Content, HKEY("\n"), 0);
623 StrBufAppendBuf(Ruleset->Content, Line, 0);
630 return WCC->KnownSieveScripts;
634 typedef enum __eSieveHfield
653 typedef enum __eSieveCompare {
662 typedef enum __eSieveAction {
672 typedef enum __eSieveSizeComp {
677 typedef enum __eSieveFinal {
683 typedef struct __SieveRule {
687 eSieveCompare compare;
689 eSieveSizeComp sizecomp;
699 int ConditionalSieveRule_hfield(StrBuf *Target, WCTemplputParams *TP)
701 SieveRule *Rule = (SieveRule *)CTX;
703 return GetTemplateTokenNumber(Target,
710 int ConditionalSieveRule_compare(StrBuf *Target, WCTemplputParams *TP)
712 SieveRule *Rule = (SieveRule *)CTX;
713 return GetTemplateTokenNumber(Target,
720 int ConditionalSieveRule_action(StrBuf *Target, WCTemplputParams *TP)
722 SieveRule *Rule = (SieveRule *)CTX;
723 return GetTemplateTokenNumber(Target,
730 int ConditionalSieveRule_sizecomp(StrBuf *Target, WCTemplputParams *TP)
732 SieveRule *Rule = (SieveRule *)CTX;
733 return GetTemplateTokenNumber(Target,
740 int ConditionalSieveRule_final(StrBuf *Target, WCTemplputParams *TP)
742 SieveRule *Rule = (SieveRule *)CTX;
743 return GetTemplateTokenNumber(Target,
750 int ConditionalSieveRule_ThisRoom(StrBuf *Target, WCTemplputParams *TP)
752 SieveRule *Rule = (SieveRule *)CTX;
753 return GetTemplateTokenNumber(Target,
760 int ConditionalSieveRule_Active(StrBuf *Target, WCTemplputParams *TP)
762 SieveRule *Rule = (SieveRule *)CTX;
765 void tmplput_SieveRule_htext(StrBuf *Target, WCTemplputParams *TP)
767 SieveRule *Rule = (SieveRule *)CTX;
768 StrBufAppendTemplate(Target, TP, Rule->htext, 0);
770 void tmplput_SieveRule_fileinto(StrBuf *Target, WCTemplputParams *TP)
772 SieveRule *Rule = (SieveRule *)CTX;
773 StrBufAppendTemplate(Target, TP, Rule->fileinto, 0);
775 void tmplput_SieveRule_redirect(StrBuf *Target, WCTemplputParams *TP)
777 SieveRule *Rule = (SieveRule *)CTX;
778 StrBufAppendTemplate(Target, TP, Rule->redirect, 0);
780 void tmplput_SieveRule_automsg(StrBuf *Target, WCTemplputParams *TP)
782 SieveRule *Rule = (SieveRule *)CTX;
783 StrBufAppendTemplate(Target, TP, Rule->automsg, 0);
785 void tmplput_SieveRule_sizeval(StrBuf *Target, WCTemplputParams *TP)
787 SieveRule *Rule = (SieveRule *)CTX;
788 StrBufAppendPrintf(Target, "%d", Rule->sizeval);
791 void tmplput_SieveRule_lookup_FileIntoRoom(StrBuf *Target, WCTemplputParams *TP)
794 SieveRule *Rule = (SieveRule *)CTX;
796 HashList *Rooms = GetRoomListHashLKRA(Target, TP);
798 GetHash(Rooms, SKEY(Rule->fileinto), &vRoom);
799 WCC->ThisRoom = (folder*) vRoom;
802 void FreeSieveRule(void *vRule)
804 SieveRule *Rule = (SieveRule*) vRule;
806 FreeStrBuf(&Rule->htext);
807 FreeStrBuf(&Rule->fileinto);
808 FreeStrBuf(&Rule->redirect);
809 FreeStrBuf(&Rule->automsg);
814 #define WC_RULE_HEADER "# WEBCIT_RULE|"
815 HashList *GetSieveRules(StrBuf *Target, WCTemplputParams *TP)
818 StrBuf *EncodedRule = NULL;
820 const char *pch = NULL;
821 HashList *SieveRules = NULL;
823 SieveRule *Rule = NULL;
825 SieveRules = NewHash(1, Flathash);
826 serv_printf("MSIV getscript|"RULES_SCRIPT);
828 EncodedRule = NewStrBuf();
829 StrBuf_ServGetln(Line);
830 if (GetServerStatus(Line, NULL) == 1)
832 while(!Done && (StrBuf_ServGetln(Line) >= 0) )
833 if ( (StrLength(Line)==3) &&
834 !strcmp(ChrPtr(Line), "000"))
841 /* We just care for our encoded header and skip everything else */
842 if ((StrLength(Line) > sizeof(WC_RULE_HEADER) - 1) &&
843 (!strncasecmp(ChrPtr(Line), HKEY(WC_RULE_HEADER))))
845 StrBufSkip_NTokenS(Line, &pch, '|', 1);
846 n = StrBufExtractNext_int(Line, &pch, '|');
847 StrBufExtract_NextToken(EncodedRule, Line, &pch, '|');
848 StrBufDecodeBase64(EncodedRule);
850 Rule = (SieveRule*) malloc(sizeof(SieveRule));
852 Rule->htext = NewStrBufPlain (NULL, StrLength(EncodedRule));
854 Rule->fileinto = NewStrBufPlain (NULL, StrLength(EncodedRule));
855 Rule->redirect = NewStrBufPlain (NULL, StrLength(EncodedRule));
856 Rule->automsg = NewStrBufPlain (NULL, StrLength(EncodedRule));
858 /* Grab our existing values to populate */
860 Rule->active = StrBufExtractNext_int(EncodedRule, &pch, '|');
861 StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
863 Rule->hfield = (eSieveHfield) GetTokenDefine(SKEY(Line), tocc);
864 StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
865 Rule->compare = (eSieveCompare) GetTokenDefine(SKEY(Line), contains);
866 StrBufExtract_NextToken(Rule->htext, EncodedRule, &pch, '|');
867 StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
868 Rule->sizecomp = (eSieveSizeComp) GetTokenDefine(SKEY(Line), larger);
869 Rule->sizeval = StrBufExtractNext_int(EncodedRule, &pch, '|');
870 StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
871 Rule->Action = (eSieveAction) GetTokenDefine(SKEY(Line), keep);
872 StrBufExtract_NextToken(Rule->fileinto, EncodedRule, &pch, '|');
873 StrBufExtract_NextToken(Rule->redirect, EncodedRule, &pch, '|');
874 StrBufExtract_NextToken(Rule->automsg, EncodedRule, &pch, '|');
875 StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
876 Rule->final = (eSieveFinal) GetTokenDefine(SKEY(Line), econtinue);
877 Put(SieveRules, IKEY(n), Rule, FreeSieveRule);
883 while (n < MAX_RULES) {
884 Rule = (SieveRule*) malloc(sizeof(SieveRule));
885 memset(Rule, 0, sizeof(SieveRule));
886 Put(SieveRules, IKEY(n), Rule, FreeSieveRule);
892 FreeStrBuf(&EncodedRule);
898 SessionDetachModule_SIEVE
901 DeleteHash(&sess->KnownSieveScripts);
908 REGISTERTokenParamDefine(from);
909 REGISTERTokenParamDefine(tocc);
910 REGISTERTokenParamDefine(subject);
911 REGISTERTokenParamDefine(replyto);
912 REGISTERTokenParamDefine(sender);
913 REGISTERTokenParamDefine(resentfrom);
914 REGISTERTokenParamDefine(resentto);
915 REGISTERTokenParamDefine(envfrom);
916 REGISTERTokenParamDefine(envto);
917 REGISTERTokenParamDefine(xmailer);
918 REGISTERTokenParamDefine(xspamflag);
919 REGISTERTokenParamDefine(xspamstatus);
920 REGISTERTokenParamDefine(listid);
921 REGISTERTokenParamDefine(size);
922 REGISTERTokenParamDefine(all);
924 REGISTERTokenParamDefine(contains);
925 REGISTERTokenParamDefine(notcontains);
926 REGISTERTokenParamDefine(is);
927 REGISTERTokenParamDefine(isnot);
928 REGISTERTokenParamDefine(matches);
929 REGISTERTokenParamDefine(notmatches);
931 REGISTERTokenParamDefine(keep);
932 REGISTERTokenParamDefine(discard);
933 REGISTERTokenParamDefine(reject);
934 REGISTERTokenParamDefine(fileinto);
935 REGISTERTokenParamDefine(redirect);
936 REGISTERTokenParamDefine(vacation);
938 REGISTERTokenParamDefine(larger);
939 REGISTERTokenParamDefine(smaller);
941 /* these are c-keyworads, so do it by hand. */
942 RegisterTokenParamDefine(HKEY("continue"), econtinue);
943 RegisterTokenParamDefine(HKEY("stop"), estop);
945 RegisterIterator("SIEVE:SCRIPTS", 0, NULL, GetSieveScriptListing, NULL, NULL, CTX_SIEVELIST, CTX_NONE, IT_NOFLAG);
947 RegisterConditional(HKEY("COND:SIEVE:SCRIPT:ACTIVE"), 0, ConditionalSieveScriptIsActive, CTX_SIEVELIST);
948 RegisterConditional(HKEY("COND:SIEVE:SCRIPT:ISRULES"), 0, ConditionalSieveScriptIsRulesScript, CTX_SIEVELIST);
949 RegisterNamespace("SIEVE:SCRIPT:NAME", 0, 1, tmplput_SieveScriptName, NULL, CTX_SIEVELIST);
950 RegisterNamespace("SIEVE:SCRIPT:CONTENT", 0, 1, tmplput_SieveScriptContent, NULL, CTX_SIEVELIST);
953 RegisterIterator("SIEVE:RULES", 0, NULL, GetSieveRules, NULL, DeleteHash, CTX_SIEVESCRIPT, CTX_NONE, IT_NOFLAG);
955 RegisterConditional(HKEY("COND:SIEVE:ACTIVE"), 1, ConditionalSieveRule_Active, CTX_SIEVESCRIPT);
956 RegisterConditional(HKEY("COND:SIEVE:HFIELD"), 1, ConditionalSieveRule_hfield, CTX_SIEVESCRIPT);
957 RegisterConditional(HKEY("COND:SIEVE:COMPARE"), 1, ConditionalSieveRule_compare, CTX_SIEVESCRIPT);
958 RegisterConditional(HKEY("COND:SIEVE:ACTION"), 1, ConditionalSieveRule_action, CTX_SIEVESCRIPT);
959 RegisterConditional(HKEY("COND:SIEVE:SIZECOMP"), 1, ConditionalSieveRule_sizecomp, CTX_SIEVESCRIPT);
960 RegisterConditional(HKEY("COND:SIEVE:FINAL"), 1, ConditionalSieveRule_final, CTX_SIEVESCRIPT);
961 RegisterConditional(HKEY("COND:SIEVE:THISROOM"), 1, ConditionalSieveRule_ThisRoom, CTX_SIEVESCRIPT);
963 RegisterNamespace("SIEVE:SCRIPT:HTEXT", 0, 1, tmplput_SieveRule_htext, NULL, CTX_SIEVESCRIPT);
964 RegisterNamespace("SIEVE:SCRIPT:SIZE", 0, 1, tmplput_SieveRule_sizeval, NULL, CTX_SIEVESCRIPT);
965 RegisterNamespace("SIEVE:SCRIPT:FILEINTO", 0, 1, tmplput_SieveRule_fileinto, NULL, CTX_SIEVESCRIPT);
966 RegisterNamespace("SIEVE:SCRIPT:REDIRECT", 0, 1, tmplput_SieveRule_redirect, NULL, CTX_SIEVESCRIPT);
967 RegisterNamespace("SIEVE:SCRIPT:AUTOMSG", 0, 1, tmplput_SieveRule_automsg, NULL, CTX_SIEVESCRIPT);
969 /* fetch our room into WCC->ThisRoom, to evaluate while iterating over rooms with COND:THIS:THAT:ROOM */
970 RegisterNamespace("SIEVE:SCRIPT:LOOKUP_FILEINTO", 0, 1, tmplput_SieveRule_lookup_FileIntoRoom, NULL, CTX_SIEVESCRIPT);
971 WebcitAddUrlHandler(HKEY("save_sieve"), "", 0, save_sieve, 0);
972 WebcitAddUrlHandler(HKEY("create_script"), "", 0, create_script, 0);
973 WebcitAddUrlHandler(HKEY("delete_script"), "", 0, delete_script, 0);