]> code.citadel.org Git - citadel.git/blobdiff - webcit/sieve.c
indent -kr -i8 -brf -bbb -fnc -l132 -nce on all of webcit-classic
[citadel.git] / webcit / sieve.c
index 0c4613bcac0d53d7e30a5aa3f0dfbe2354fe8c6a..528009ef3f1ebb3f9899175d6aa427631308e28d 100644 (file)
@@ -1,5 +1,6 @@
+
 /*
- * Copyright (c) 1996-2012 by the citadel.org team
+ * Copyright (c) 1996-2020 by the citadel.org team
  *
  * This program is open source software.  You can redistribute it and/or
  * modify it under the terms of the GNU General Public License version 3.
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
+ *
+ * 
+ * Implementation note: this was kind of hacked up when we switched from Sieve to custom rules.
+ * As a result there's probably some cruft in here...
+ * ajc 2020jul12
+ *
  */
 
 #include "webcit.h"
 
+CtxType CTX_SIEVELIST = CTX_NONE;
+CtxType CTX_SIEVESCRIPT = CTX_NONE;
+
 #define MAX_SCRIPTS    100
 #define MAX_RULES      50
 #define RULES_SCRIPT   "__WebCit_Generated_Script__"
 
-/*
- * Helper function for output_sieve_rule() to output strings with quotes escaped
- */
-void osr_sanitize(char *str) {
-       int i, len;
-
-       if (str == NULL) return;
-       len = strlen(str);
-       for (i=0; i<len; ++i) {
-               if (str[i]=='\"') {
-                       str[i] = '\'' ;
-               }
-               else if (isspace(str[i])) {
-                       str[i] = ' ';
-               }
-       }
-}
-
-
-/*
- * Output parseable Sieve script code based on rules input
- */
-void output_sieve_rule(char *hfield, char *compare, char *htext, char *sizecomp, int sizeval,
-                       char *action, char *fileinto, char *redirect, char *automsg, char *final,
-                       char *my_addresses)
-{
-       char *comp1 = "";
-       char *comp2 = "";
-
-       osr_sanitize(htext);
-       osr_sanitize(fileinto);
-       osr_sanitize(redirect);
-       osr_sanitize(automsg);
-
-       /* Prepare negation and match operators that will be used iff we apply a conditional */
-
-       if (!strcasecmp(compare, "contains")) {
-               comp1 = "";
-               comp2 = ":contains";
-       }
-       else if (!strcasecmp(compare, "notcontains")) {
-               comp1 = "not";
-               comp2 = ":contains";
-       }
-       else if (!strcasecmp(compare, "is")) {
-               comp1 = "";
-               comp2 = ":is";
-       }
-       else if (!strcasecmp(compare, "isnot")) {
-               comp1 = "not";
-               comp2 = ":is";
-       }
-       else if (!strcasecmp(compare, "matches")) {
-               comp1 = "";
-               comp2 = ":matches";
-       }
-       else if (!strcasecmp(compare, "notmatches")) {
-               comp1 = "not";
-               comp2 = ":matches";
-       }
-
-       /* Now do the conditional */
-
-       if (!strcasecmp(hfield, "from")) {
-               serv_printf("if%s header %s \"From\" \"%s\"",
-                       comp1, comp2,
-                       htext
-               );
-       }
-
-       else if (!strcasecmp(hfield, "tocc")) {
-               serv_printf("if%s header %s [\"To\", \"Cc\"] \"%s\"",
-                       comp1, comp2,
-                       htext
-               );
-       }
-
-       else if (!strcasecmp(hfield, "subject")) {
-               serv_printf("if%s header %s \"Subject\" \"%s\"",
-                       comp1, comp2,
-                       htext
-               );
-       }
-
-       else if (!strcasecmp(hfield, "replyto")) {
-               serv_printf("if%s header %s \"Reply-to\" \"%s\"",
-                       comp1, comp2,
-                       htext
-               );
-       }
-
-       else if (!strcasecmp(hfield, "sender")) {
-               serv_printf("if%s header %s \"Sender\" \"%s\"",
-                       comp1, comp2,
-                       htext
-               );
-       }
-
-       else if (!strcasecmp(hfield, "resentfrom")) {
-               serv_printf("if%s header %s \"Resent-from\" \"%s\"",
-                       comp1, comp2,
-                       htext
-               );
-       }
-
-       else if (!strcasecmp(hfield, "resentto")) {
-               serv_printf("if%s header %s \"Resent-to\" \"%s\"",
-                       comp1, comp2,
-                       htext
-               );
-       }
-
-       else if (!strcasecmp(hfield, "xmailer")) {
-               serv_printf("if%s header %s \"X-Mailer\" \"%s\"",
-                       comp1, comp2,
-                       htext
-               );
-       }
-
-       else if (!strcasecmp(hfield, "xspamflag")) {
-               serv_printf("if%s header %s \"X-Spam-Flag\" \"%s\"",
-                       comp1, comp2,
-                       htext
-               );
-       }
-
-       else if (!strcasecmp(hfield, "xspamstatus")) {
-               serv_printf("if%s header %s \"X-Spam-Status\" \"%s\"",
-                       comp1, comp2,
-                       htext
-               );
-       }
-
-       else if (!strcasecmp(hfield, "listid")) {
-               serv_printf("if%s header %s \"List-ID\" \"%s\"",
-                       comp1, comp2,
-                       htext
-               );
-       }
-
-       else if (!strcasecmp(hfield, "envfrom")) {
-               serv_printf("if%s envelope %s \"From\" \"%s\"",
-                       comp1, comp2,
-                       htext
-               );
-       }
-
-       else if (!strcasecmp(hfield, "envto")) {
-               serv_printf("if%s envelope %s \"To\" \"%s\"",
-                       comp1, comp2,
-                       htext
-               );
-       }
-
-       else if (!strcasecmp(hfield, "size")) {
-               if (!strcasecmp(sizecomp, "larger")) {
-                       serv_printf("if size :over %d", sizeval);
-               }
-               else if (!strcasecmp(sizecomp, "smaller")) {
-                       serv_printf("if size :under %d", sizeval);
-               }
-               else {  /* failsafe - should never get here, but just in case... */
-                       serv_printf("if size :over 1");
-               }
-       }
-
-       /* Open braces if we're in a conditional loop */
-
-       if (strcasecmp(hfield, "all")) {
-               serv_printf("{");
-       }
-
-
-       /* Do action */
-
-       if (!strcasecmp(action, "keep")) {
-               serv_printf("keep;");
-       }
-
-       else if (!strcasecmp(action, "discard")) {
-               serv_printf("discard;");
-       }
-
-       else if (!strcasecmp(action, "reject")) {
-               serv_printf("reject \"%s\";", automsg);
-       }
-
-       else if (!strcasecmp(action, "fileinto")) {
-               serv_printf("fileinto \"%s\";", fileinto);
-       }
-
-       else if (!strcasecmp(action, "redirect")) {
-               serv_printf("redirect \"%s\";", redirect);
-       }
-
-       else if (!strcasecmp(action, "vacation")) {
-               serv_printf("vacation :addresses [%s]\n\"%s\";", my_addresses, automsg);
-       }
-
-
-       /* Do 'final' action */
-
-       if (!strcasecmp(final, "stop")) {
-               serv_printf("stop;");
-       }
-
-
-       /* Close the braces if we're in a conditional loop */
-
-       if (strcasecmp(hfield, "all")) {
-               serv_printf("}");
-       }
-
-
-       /* End of rule. */
-}
-
-
 
 /*
  * Translate the fields from the rule editor into something we can save...
@@ -257,112 +49,87 @@ void parse_fields_from_rule_editor(void) {
        char rule[2048];
        char encoded_rule[4096];
        char my_addresses[4096];
-       
+
        /* Enumerate my email addresses in case they are needed for a vacation rule */
        my_addresses[0] = 0;
        serv_puts("GVEA");
        serv_getln(buf, sizeof buf);
-       if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
-               if (!IsEmptyStr(my_addresses)) {
-                       strcat(my_addresses, ",\n");
+       if (buf[0] == '1')
+               while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
+                       if (!IsEmptyStr(my_addresses)) {
+                               strcat(my_addresses, ",\n");
+                       }
+                       strcat(my_addresses, "\"");
+                       strcat(my_addresses, buf);
+                       strcat(my_addresses, "\"");
                }
-               strcat(my_addresses, "\"");
-               strcat(my_addresses, buf);
-               strcat(my_addresses, "\"");
-       }
 
        /* Now generate the script and write it to the Citadel server */
-       serv_printf("MSIV putscript|%s|", RULES_SCRIPT);
+       serv_printf("PIBR");
        serv_getln(buf, sizeof buf);
        if (buf[0] != '4') {
                return;
        }
 
-       serv_puts("# THIS SCRIPT WAS AUTOMATICALLY GENERATED BY WEBCIT.");
-       serv_puts("# ");
-       serv_puts("# Do not attempt to manually edit it.  If you do so,");
-       serv_puts("# your changes will be overwritten the next time WebCit");
-       serv_puts("# saves its mail filtering rule set.  If you really want");
-       serv_puts("# to use these rules as the basis for another script,");
-       serv_puts("# copy them to another script and save that instead.");
-       serv_puts("");
-       serv_puts("require \"fileinto\";");
-       serv_puts("require \"reject\";");
-       serv_puts("require \"vacation\";");
-       serv_puts("require \"envelope\";");
-       serv_puts("");
-
-       for (i=0; i<MAX_RULES; ++i) {
-               
+       for (i = 0; i < MAX_RULES; ++i) {
+
                strcpy(rule, "");
 
                sprintf(fname, "active%d", i);
-               active = !strcasecmp(BSTR(fname), "on") ;
+               active = !strcasecmp(BSTR(fname), "on");
 
                if (active) {
 
                        sprintf(fname, "hfield%d", i);
                        safestrncpy(hfield, BSTR(fname), sizeof hfield);
-       
+
                        sprintf(fname, "compare%d", i);
                        safestrncpy(compare, BSTR(fname), sizeof compare);
-       
+
                        sprintf(fname, "htext%d", i);
                        safestrncpy(htext, BSTR(fname), sizeof htext);
-       
+
                        sprintf(fname, "sizecomp%d", i);
                        safestrncpy(sizecomp, BSTR(fname), sizeof sizecomp);
-       
+
                        sprintf(fname, "sizeval%d", i);
                        sizeval = IBSTR(fname);
-       
+
                        sprintf(fname, "action%d", i);
                        safestrncpy(action, BSTR(fname), sizeof action);
-       
+
                        sprintf(fname, "fileinto%d", i);
                        safestrncpy(fileinto, BSTR(fname), sizeof fileinto);
-       
+
                        sprintf(fname, "redirect%d", i);
                        safestrncpy(redirect, BSTR(fname), sizeof redirect);
-       
+
                        sprintf(fname, "automsg%d", i);
                        safestrncpy(automsg, BSTR(fname), sizeof automsg);
-       
+
                        sprintf(fname, "final%d", i);
                        safestrncpy(final, BSTR(fname), sizeof final);
-       
+
                        snprintf(rule, sizeof rule, "%d|%s|%s|%s|%s|%d|%s|%s|%s|%s|%s",
-                               active, hfield, compare, htext, sizecomp, sizeval, action, fileinto,
-                               redirect, automsg, final
-                       );
-       
-                       CtdlEncodeBase64(encoded_rule, rule, strlen(rule)+1, 0);
-                       serv_printf("# WEBCIT_RULE|%d|%s|", i, encoded_rule);
-                       output_sieve_rule(hfield, compare, htext, sizecomp, sizeval,
-                                       action, fileinto, redirect, automsg, final, my_addresses);
+                                active, hfield, compare, htext, sizecomp, sizeval, action, fileinto, redirect, automsg, final);
+
+                       size_t len = CtdlEncodeBase64(encoded_rule, rule, strlen(rule) + 1, BASE64_NO_LINEBREAKS);
+                       if (encoded_rule[len - 1] == '\n') {
+                               encoded_rule[len - 1] = '\0';
+                       }
+                       serv_printf("rule|%d|%s|", i, encoded_rule);
                        serv_puts("");
                }
-
-
        }
 
-       serv_puts("stop;");
        serv_puts("000");
 }
 
 
-
 /*
  * save sieve config
  */
 void save_sieve(void) {
-       int bigaction;
-       char script_names[MAX_SCRIPTS][64];
-       int num_scripts = 0;
-       int active_script = (-1);       /* this throws a 'set but not used' warning , check this ! */
-       int i;
-       char this_name[64];
-       char buf[256];
 
        if (!havebstr("save_button")) {
                AppendImportantMessage(_("Cancelled.  Changes were not saved."), -1);
@@ -372,87 +139,13 @@ void save_sieve(void) {
 
        parse_fields_from_rule_editor();
 
-       serv_puts("MSIV listscripts");
-       serv_getln(buf, sizeof(buf));
-       if (buf[0] == '1') while (serv_getln(buf, sizeof(buf)), strcmp(buf, "000")) {
-               if (num_scripts < MAX_SCRIPTS) {
-                       extract_token(script_names[num_scripts], buf, 0, '|', 64);
-                       if (extract_int(buf, 1) > 0) {
-                               active_script = num_scripts;
-                       }
-                       ++num_scripts;
-               }
-       }
-
-       bigaction = ibstr("bigaction");
-
-       if (bigaction == 0) {
-               serv_puts("MSIV setactive||");
-               serv_getln(buf, sizeof buf);
-       }
-
-       else if (bigaction == 1) {
-               serv_printf("MSIV setactive|%s|", RULES_SCRIPT);
-               serv_getln(buf, sizeof buf);
-       }
-
-       else if (bigaction == 2) {
-               serv_printf("MSIV setactive|%s|", bstr("active_script"));
-               serv_getln(buf, sizeof buf);
-       }
-
-       if (num_scripts > 0) {
-               for (i=0; i<num_scripts; ++i) {
-                       /*
-                        * We only want to save the scripts from the "manually edited scripts"
-                        * screen.  The script that WebCit generates from its ruleset will be
-                        * auto-generated by parse_fields_from_rule_editor() and saved there.
-                        */
-                       if (strcasecmp(script_names[i], RULES_SCRIPT)) {
-                               serv_printf("MSIV putscript|%s|", script_names[i]);
-                               serv_getln(buf, sizeof buf);
-                               if (buf[0] == '4') {
-                                       snprintf(this_name, sizeof this_name, "text_%s", script_names[i]);
-                                       striplt((char *)BSTR(this_name)); /* TODO: get rid of typecast*/
-                                       serv_write(BSTR(this_name), strlen(BSTR(this_name)));
-                                       serv_puts("\n000");
-                               }
-                       }
-               }
-       }
-
        AppendImportantMessage(_("Your changes have been saved."), -1);
        display_main_menu();
        return;
 }
 
-/*
- * create a new script
- * take the web environment script name and create it on the citadel server
- */
-void create_script(void) {
-       char buf[256];
-
-       serv_printf("MSIV getscript|%s", bstr("script_name"));
-       serv_getln(buf, sizeof buf);
-       if (buf[0] == '1') {
-               while (serv_getln(buf, sizeof(buf)), strcmp(buf, "000")) {
-                       /* flush */
-               }
-               return;
-       }
-       
-       serv_printf("MSIV putscript|%s", bstr("script_name"));
-       serv_getln(buf, sizeof buf);
-       if (buf[0] == '4') {
-               serv_puts("keep;");
-               serv_puts("000");
-       output_headers(1, 1, 2, 0, 0, 0);
-       do_template("sieve_add");
-       wDumpContent(1);
-               return;
-       }
 
+void display_sieve_add_or_delete(void) {
        output_headers(1, 1, 2, 0, 0, 0);
        do_template("sieve_add");
        wDumpContent(1);
@@ -460,28 +153,12 @@ void create_script(void) {
 
 
 
-
-/*
- * delete a script
- */
-void delete_script(void) {
-       char buf[256];
-
-       serv_printf("MSIV deletescript|%s", bstr("script_name"));
-       serv_getln(buf, sizeof buf);
-       output_headers(1, 1, 2, 0, 0, 0);
-       do_template("sieve_add");
-       wDumpContent(1);
-}
-               
-
-
 /*
  * dummy panel indicating to the user that the server doesn't support Sieve
  */
 void display_no_sieve(void) {
 
-       output_headers(1, 1, 2, 0, 0, 0);
+       output_headers(1, 1, 1, 0, 0, 0);
        do_template("sieve_none");
        wDumpContent(1);
 }
@@ -494,77 +171,66 @@ typedef struct __SieveListing {
        StrBuf *Content;
 } SieveListing;
 
-int ConditionalSieveScriptIsActive(StrBuf *Target, WCTemplputParams *TP)
-{
-       SieveListing     *SieveList = (SieveListing *)CTX;
+int ConditionalSieveScriptIsActive(StrBuf * Target, WCTemplputParams * TP) {
+       SieveListing *SieveList = (SieveListing *) CTX(CTX_SIEVELIST);
        return SieveList->IsActive;
 }
-int ConditionalSieveScriptIsRulesScript(StrBuf *Target, WCTemplputParams *TP)
-{
-       SieveListing     *SieveList = (SieveListing *)CTX;
+int ConditionalSieveScriptIsRulesScript(StrBuf * Target, WCTemplputParams * TP) {
+       SieveListing *SieveList = (SieveListing *) CTX(CTX_SIEVELIST);
        return SieveList->IsActive;
 }
-void tmplput_SieveScriptName(StrBuf *Target, WCTemplputParams *TP) 
-{
-       SieveListing     *SieveList = (SieveListing *)CTX;
+void tmplput_SieveScriptName(StrBuf * Target, WCTemplputParams * TP) {
+       SieveListing *SieveList = (SieveListing *) CTX(CTX_SIEVELIST);
        StrBufAppendTemplate(Target, TP, SieveList->Name, 0);
 }
-void tmplput_SieveScriptContent(StrBuf *Target, WCTemplputParams *TP) 
-{
-       SieveListing     *SieveList = (SieveListing *)CTX;
+void tmplput_SieveScriptContent(StrBuf * Target, WCTemplputParams * TP) {
+       SieveListing *SieveList = (SieveListing *) CTX(CTX_SIEVELIST);
        StrBufAppendTemplate(Target, TP, SieveList->Content, 0);
 }
-void FreeSieveListing(void *vSieveListing)
-{
-       SieveListing *List = (SieveListing*) vSieveListing;
+void FreeSieveListing(void *vSieveListing) {
+       SieveListing *List = (SieveListing *) vSieveListing;
 
        FreeStrBuf(&List->Name);
        free(List);
 }
 
-HashList *GetSieveScriptListing(StrBuf *Target, WCTemplputParams *TP)
-{
-        wcsession *WCC = WC;
+HashList *GetSieveScriptListing(StrBuf * Target, WCTemplputParams * TP) {
+       wcsession *WCC = WC;
        StrBuf *Line;
        int num_scripts = 0;
        int rules_script_active = 0;
        int have_rules_script = 0;
        const char *pch;
-       HashPos  *it;
+       HashPos *it;
        int Done = 0;
        SieveListing *Ruleset;
 
-       if (WCC->KnownSieveScripts != NULL)
+       if (WCC->KnownSieveScripts != NULL) {
                return WCC->KnownSieveScripts;
+       }
 
        serv_puts("MSIV listscripts");
        Line = NewStrBuf();
        StrBuf_ServGetln(Line);
-       if (GetServerStatus(Line, NULL) == 1) 
-       {
+       if (GetServerStatus(Line, NULL) == 1) {
                WCC->KnownSieveScripts = NewHash(1, Flathash);
 
-               while(!Done && (StrBuf_ServGetln(Line) >= 0) )
-                       if ( (StrLength(Line)==3) && 
-                            !strcmp(ChrPtr(Line), "000")) 
-                       {
+               while (!Done && (StrBuf_ServGetln(Line) >= 0))
+                       if ((StrLength(Line) == 3) && !strcmp(ChrPtr(Line), "000")) {
                                Done = 1;
                        }
-                       else
-                       {
+                       else {
                                pch = NULL;
                                Ruleset = (SieveListing *) malloc(sizeof(SieveListing));
                                Ruleset->Name = NewStrBufPlain(NULL, StrLength(Line));
                                StrBufExtract_NextToken(Ruleset->Name, Line, &pch, '|');
-                               Ruleset->IsActive = StrBufExtractNext_int(Line, &pch, '|'); 
+                               Ruleset->IsActive = StrBufExtractNext_int(Line, &pch, '|');
                                Ruleset->Content = NULL;
 
-                               if (!strcasecmp(ChrPtr(Ruleset->Name), RULES_SCRIPT))
-                               {
+                               if (!strcasecmp(ChrPtr(Ruleset->Name), RULES_SCRIPT)) {
                                        Ruleset->IsRulesScript = 1;
                                        have_rules_script = 1;
-                                       if (Ruleset->IsActive)
-                                       {
+                                       if (Ruleset->IsActive) {
                                                rules_script_active = 1;
                                                PutBstr(HKEY("__SIEVE:RULESSCRIPT"), NewStrBufPlain(HKEY("1")));
                                        }
@@ -574,11 +240,12 @@ HashList *GetSieveScriptListing(StrBuf *Target, WCTemplputParams *TP)
                                ++num_scripts;
                        }
        }
-       if ((num_scripts > 0) && (rules_script_active == 0))
+
+       if ((num_scripts > 0) && (rules_script_active == 0)) {
                PutBstr(HKEY("__SIEVE:EXTERNAL_SCRIPT"), NewStrBufPlain(HKEY("1")));
+       }
 
-       if (num_scripts > have_rules_script)
-       {
+       if (num_scripts > have_rules_script) {
                long rc = 0;
                long len;
                const char *Key;
@@ -590,36 +257,24 @@ HashList *GetSieveScriptListing(StrBuf *Target, WCTemplputParams *TP)
                PutBstr(HKEY("__SIEVE:HAVE_EXTERNAL_SCRIPT"), NewStrBufPlain(HKEY("1")));
 
                it = GetNewHashPos(WCC->KnownSieveScripts, 0);
-               while (GetNextHashPos(WCC->KnownSieveScripts, it, &len, &Key, &vRuleset) && 
-                      (vRuleset != NULL))
-               {
+               while (GetNextHashPos(WCC->KnownSieveScripts, it, &len, &Key, &vRuleset) && (vRuleset != NULL)) {
                        Ruleset = (SieveListing *) vRuleset;
-
-                       /*
-                        * its the webcit rule? we don't need to load that here.
-                        */
-                       if (Ruleset->IsRulesScript)
-                               continue;
-
-                       if (!serv_printf("MSIV getscript|%s", ChrPtr(Ruleset->Name)))
-                               break;
+                       serv_printf("MSIV getscript|%s", ChrPtr(Ruleset->Name));
                        StrBuf_ServGetln(Line);
-                       if (GetServerStatus(Line, NULL) == 1) 
-                       {
+                       if (GetServerStatus(Line, NULL) == 1) {
                                Ruleset->Content = NewStrBuf();
-                               while(!Done && (rc = StrBuf_ServGetln(Line), rc >= 0) )
-                                       if ( (StrLength(Line)==3) && 
-                                            !strcmp(ChrPtr(Line), "000")) 
-                                       {
+                               Done = 0;
+                               while (!Done && (rc = StrBuf_ServGetln(Line), rc >= 0))
+                                       if ((StrLength(Line) == 3) && !strcmp(ChrPtr(Line), "000")) {
                                                Done = 1;
                                        }
-                                       else
-                                       {
-                                               if (StrLength(Ruleset->Content)>0)
+                                       else {
+                                               if (StrLength(Ruleset->Content) > 0)
                                                        StrBufAppendBufPlain(Ruleset->Content, HKEY("\n"), 0);
                                                StrBufAppendBuf(Ruleset->Content, Line, 0);
                                        }
-                               if (rc < 0) break;
+                               if (rc < 0)
+                                       break;
                        }
                }
        }
@@ -628,22 +283,21 @@ HashList *GetSieveScriptListing(StrBuf *Target, WCTemplputParams *TP)
 }
 
 
-typedef enum __eSieveHfield 
-{
-       from,           
-       tocc,           
-       subject,        
-       replyto,        
-       sender, 
-       resentfrom,     
-       resentto,       
-       envfrom,        
-       envto,  
-       xmailer,        
-       xspamflag,      
-       xspamstatus,    
-       listid, 
-       size,           
+typedef enum __eSieveHfield {
+       from,
+       tocc,
+       subject,
+       replyto,
+       sender,
+       resentfrom,
+       resentto,
+       envfrom,
+       envto,
+       xmailer,
+       xspamflag,
+       xspamstatus,
+       listid,
+       size,
        all
 } eSieveHfield;
 
@@ -689,128 +343,89 @@ typedef struct __SieveRule {
        StrBuf *redirect;
        StrBuf *automsg;
        eSieveFinal final;
-}SieveRule;
+} SieveRule;
+
 
 
+int ConditionalSieveRule_hfield(StrBuf * Target, WCTemplputParams * TP) {
+       SieveRule *Rule = (SieveRule *) CTX(CTX_SIEVESCRIPT);
 
-int ConditionalSieveRule_hfield(StrBuf *Target, WCTemplputParams *TP)
-{
-       SieveRule     *Rule = (SieveRule *)CTX;
-       
-        return GetTemplateTokenNumber(Target, 
-                                      TP, 
-                                      3, 
-                                      from)
-                ==
-                Rule->hfield;
+       return GetTemplateTokenNumber(Target, TP, 3, from)
+           == Rule->hfield;
 }
-int ConditionalSieveRule_compare(StrBuf *Target, WCTemplputParams *TP)
-{
-       SieveRule     *Rule = (SieveRule *)CTX;
-        return GetTemplateTokenNumber(Target, 
-                                      TP, 
-                                      3, 
-                                      contains)
-                ==
-               Rule->compare;
+int ConditionalSieveRule_compare(StrBuf * Target, WCTemplputParams * TP) {
+       SieveRule *Rule = (SieveRule *) CTX(CTX_SIEVESCRIPT);
+       return GetTemplateTokenNumber(Target, TP, 3, contains)
+           == Rule->compare;
 }
-int ConditionalSieveRule_action(StrBuf *Target, WCTemplputParams *TP)
-{
-       SieveRule     *Rule = (SieveRule *)CTX;
-        return GetTemplateTokenNumber(Target, 
-                                      TP, 
-                                      3, 
-                                      keep)
-                ==
-               Rule->Action; 
+int ConditionalSieveRule_action(StrBuf * Target, WCTemplputParams * TP) {
+       SieveRule *Rule = (SieveRule *) CTX(CTX_SIEVESCRIPT);
+       return GetTemplateTokenNumber(Target, TP, 3, keep)
+           == Rule->Action;
 }
-int ConditionalSieveRule_sizecomp(StrBuf *Target, WCTemplputParams *TP)
-{
-       SieveRule     *Rule = (SieveRule *)CTX;
-        return GetTemplateTokenNumber(Target, 
-                                      TP, 
-                                      3, 
-                                      larger)
-                ==
-               Rule->sizecomp;
+int ConditionalSieveRule_sizecomp(StrBuf * Target, WCTemplputParams * TP) {
+       SieveRule *Rule = (SieveRule *) CTX(CTX_SIEVESCRIPT);
+       return GetTemplateTokenNumber(Target, TP, 3, larger)
+           == Rule->sizecomp;
 }
-int ConditionalSieveRule_final(StrBuf *Target, WCTemplputParams *TP)
-{
-       SieveRule     *Rule = (SieveRule *)CTX;
-        return GetTemplateTokenNumber(Target, 
-                                      TP, 
-                                      3, 
-                                      econtinue)
-                ==
-               Rule->final;
+int ConditionalSieveRule_final(StrBuf * Target, WCTemplputParams * TP) {
+       SieveRule *Rule = (SieveRule *) CTX(CTX_SIEVESCRIPT);
+       return GetTemplateTokenNumber(Target, TP, 3, econtinue)
+           == Rule->final;
 }
-int ConditionalSieveRule_ThisRoom(StrBuf *Target, WCTemplputParams *TP)
-{
-       SieveRule     *Rule = (SieveRule *)CTX;
-        return GetTemplateTokenNumber(Target, 
-                                      TP, 
-                                      3, 
-                                      econtinue)
-                ==
-               Rule->final;
+int ConditionalSieveRule_ThisRoom(StrBuf * Target, WCTemplputParams * TP) {
+       SieveRule *Rule = (SieveRule *) CTX(CTX_SIEVESCRIPT);
+       return GetTemplateTokenNumber(Target, TP, 3, econtinue)
+           == Rule->final;
 }
-int ConditionalSieveRule_Active(StrBuf *Target, WCTemplputParams *TP)
-{
-       SieveRule     *Rule = (SieveRule *)CTX;
-        return Rule->active;
+int ConditionalSieveRule_Active(StrBuf * Target, WCTemplputParams * TP) {
+       SieveRule *Rule = (SieveRule *) CTX(CTX_SIEVESCRIPT);
+       return Rule->active;
 }
-void tmplput_SieveRule_htext(StrBuf *Target, WCTemplputParams *TP) 
-{
-       SieveRule     *Rule = (SieveRule *)CTX;
+void tmplput_SieveRule_htext(StrBuf * Target, WCTemplputParams * TP) {
+       SieveRule *Rule = (SieveRule *) CTX(CTX_SIEVESCRIPT);
        StrBufAppendTemplate(Target, TP, Rule->htext, 0);
 }
-void tmplput_SieveRule_fileinto(StrBuf *Target, WCTemplputParams *TP) 
-{
-       SieveRule     *Rule = (SieveRule *)CTX;
+void tmplput_SieveRule_fileinto(StrBuf * Target, WCTemplputParams * TP) {
+       SieveRule *Rule = (SieveRule *) CTX(CTX_SIEVESCRIPT);
        StrBufAppendTemplate(Target, TP, Rule->fileinto, 0);
 }
-void tmplput_SieveRule_redirect(StrBuf *Target, WCTemplputParams *TP) 
-{
-       SieveRule     *Rule = (SieveRule *)CTX;
+void tmplput_SieveRule_redirect(StrBuf * Target, WCTemplputParams * TP) {
+       SieveRule *Rule = (SieveRule *) CTX(CTX_SIEVESCRIPT);
        StrBufAppendTemplate(Target, TP, Rule->redirect, 0);
 }
-void tmplput_SieveRule_automsg(StrBuf *Target, WCTemplputParams *TP) 
-{
-       SieveRule     *Rule = (SieveRule *)CTX;
+void tmplput_SieveRule_automsg(StrBuf * Target, WCTemplputParams * TP) {
+       SieveRule *Rule = (SieveRule *) CTX(CTX_SIEVESCRIPT);
        StrBufAppendTemplate(Target, TP, Rule->automsg, 0);
 }
-void tmplput_SieveRule_sizeval(StrBuf *Target, WCTemplputParams *TP) 
-{
-       SieveRule     *Rule = (SieveRule *)CTX;
+void tmplput_SieveRule_sizeval(StrBuf * Target, WCTemplputParams * TP) {
+       SieveRule *Rule = (SieveRule *) CTX(CTX_SIEVESCRIPT);
        StrBufAppendPrintf(Target, "%d", Rule->sizeval);
 }
 
-void tmplput_SieveRule_lookup_FileIntoRoom(StrBuf *Target, WCTemplputParams *TP) 
-{
+void tmplput_SieveRule_lookup_FileIntoRoom(StrBuf * Target, WCTemplputParams * TP) {
        void *vRoom;
-       SieveRule     *Rule = (SieveRule *)CTX;
-        wcsession *WCC = WC;
+       SieveRule *Rule = (SieveRule *) CTX(CTX_SIEVESCRIPT);
+       wcsession *WCC = WC;
        HashList *Rooms = GetRoomListHashLKRA(Target, TP);
 
        GetHash(Rooms, SKEY(Rule->fileinto), &vRoom);
-       WCC->ThisRoom = (folder*) vRoom;
+       WCC->ThisRoom = (folder *) vRoom;
 }
 
-void FreeSieveRule(void *vRule)
-{
-       SieveRule *Rule = (SieveRule*) vRule;
+void FreeSieveRule(void *vRule) {
+       SieveRule *Rule = (SieveRule *) vRule;
 
        FreeStrBuf(&Rule->htext);
        FreeStrBuf(&Rule->fileinto);
        FreeStrBuf(&Rule->redirect);
        FreeStrBuf(&Rule->automsg);
-       
+
        free(Rule);
 }
 
-#define WC_RULE_HEADER "# WEBCIT_RULE|"
-HashList *GetSieveRules(StrBuf *Target, WCTemplputParams *TP)
-{
+#define WC_RULE_HEADER "rule|"
+HashList *GetSieveRules(StrBuf * Target, WCTemplputParams * TP) {
        StrBuf *Line = NULL;
        StrBuf *EncodedRule = NULL;
        int n = 0;
@@ -820,43 +435,38 @@ HashList *GetSieveRules(StrBuf *Target, WCTemplputParams *TP)
        SieveRule *Rule = NULL;
 
        SieveRules = NewHash(1, Flathash);
-       serv_printf("MSIV getscript|"RULES_SCRIPT);
+       serv_printf("GIBR");
        Line = NewStrBuf();
        EncodedRule = NewStrBuf();
        StrBuf_ServGetln(Line);
-       if (GetServerStatus(Line, NULL) == 1) 
-       {
-               while(!Done && (StrBuf_ServGetln(Line) >= 0) )
-                       if ( (StrLength(Line)==3) && 
-                            !strcmp(ChrPtr(Line), "000")) 
-                       {
+       if (GetServerStatus(Line, NULL) == 1) {
+               while (!Done && (StrBuf_ServGetln(Line) >= 0))
+                       if ((StrLength(Line) == 3) && !strcmp(ChrPtr(Line), "000")) {
                                Done = 1;
                        }
-                       else
-                       {
+                       else {
                                pch = NULL;
                                /* We just care for our encoded header and skip everything else */
-                               if ((StrLength(Line) > sizeof(WC_RULE_HEADER) - 1) &&
-                                   (!strncasecmp(ChrPtr(Line), HKEY(WC_RULE_HEADER))))
-                               {
+                               if ((StrLength(Line) > sizeof(WC_RULE_HEADER) - 1)
+                                   && (!strncasecmp(ChrPtr(Line), HKEY(WC_RULE_HEADER)))) {
                                        StrBufSkip_NTokenS(Line, &pch, '|', 1);
-                                       n = StrBufExtractNext_int(Line, &pch, '|'); 
+                                       n = StrBufExtractNext_int(Line, &pch, '|');
                                        StrBufExtract_NextToken(EncodedRule, Line, &pch, '|');
                                        StrBufDecodeBase64(EncodedRule);
 
-                                       Rule = (SieveRule*) malloc(sizeof(SieveRule));
+                                       Rule = (SieveRule *) malloc(sizeof(SieveRule));
 
-                                       Rule->htext = NewStrBufPlain (NULL, StrLength(EncodedRule));
+                                       Rule->htext = NewStrBufPlain(NULL, StrLength(EncodedRule));
 
-                                       Rule->fileinto = NewStrBufPlain (NULL, StrLength(EncodedRule));
-                                       Rule->redirect = NewStrBufPlain (NULL, StrLength(EncodedRule));
-                                       Rule->automsg = NewStrBufPlain (NULL, StrLength(EncodedRule));
+                                       Rule->fileinto = NewStrBufPlain(NULL, StrLength(EncodedRule));
+                                       Rule->redirect = NewStrBufPlain(NULL, StrLength(EncodedRule));
+                                       Rule->automsg = NewStrBufPlain(NULL, StrLength(EncodedRule));
 
                                        /* Grab our existing values to populate */
                                        pch = NULL;
                                        Rule->active = StrBufExtractNext_int(EncodedRule, &pch, '|');
                                        StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
-                                       
+
                                        Rule->hfield = (eSieveHfield) GetTokenDefine(SKEY(Line), tocc);
                                        StrBufExtract_NextToken(Line, EncodedRule, &pch, '|');
                                        Rule->compare = (eSieveCompare) GetTokenDefine(SKEY(Line), contains);
@@ -878,10 +488,10 @@ HashList *GetSieveRules(StrBuf *Target, WCTemplputParams *TP)
        }
 
        while (n < MAX_RULES) {
-               Rule = (SieveRule*) malloc(sizeof(SieveRule));
+               Rule = (SieveRule *) malloc(sizeof(SieveRule));
                memset(Rule, 0, sizeof(SieveRule));
                Put(SieveRules, IKEY(n), Rule, FreeSieveRule);
-           
+
                n++;
        }
 
@@ -891,31 +501,27 @@ HashList *GetSieveRules(StrBuf *Target, WCTemplputParams *TP)
        return SieveRules;
 }
 
-void
-SessionDetachModule_SIEVE
-(wcsession *sess)
-{
+void SessionDetachModule_SIEVE(wcsession * sess) {
        DeleteHash(&sess->KnownSieveScripts);
 }
 
-void 
-InitModule_SIEVE
-(void)
-{
-       REGISTERTokenParamDefine(from);         
-       REGISTERTokenParamDefine(tocc);         
-       REGISTERTokenParamDefine(subject);      
-       REGISTERTokenParamDefine(replyto);      
-       REGISTERTokenParamDefine(sender);       
-       REGISTERTokenParamDefine(resentfrom);   
-       REGISTERTokenParamDefine(resentto);     
-       REGISTERTokenParamDefine(envfrom);      
-       REGISTERTokenParamDefine(envto);        
-       REGISTERTokenParamDefine(xmailer);      
-       REGISTERTokenParamDefine(xspamflag);    
-       REGISTERTokenParamDefine(xspamstatus);  
-       REGISTERTokenParamDefine(listid);       
-       REGISTERTokenParamDefine(size);         
+void InitModule_SIEVE(void) {
+       RegisterCTX(CTX_SIEVELIST);
+       RegisterCTX(CTX_SIEVESCRIPT);
+       REGISTERTokenParamDefine(from);
+       REGISTERTokenParamDefine(tocc);
+       REGISTERTokenParamDefine(subject);
+       REGISTERTokenParamDefine(replyto);
+       REGISTERTokenParamDefine(sender);
+       REGISTERTokenParamDefine(resentfrom);
+       REGISTERTokenParamDefine(resentto);
+       REGISTERTokenParamDefine(envfrom);
+       REGISTERTokenParamDefine(envto);
+       REGISTERTokenParamDefine(xmailer);
+       REGISTERTokenParamDefine(xspamflag);
+       REGISTERTokenParamDefine(xspamstatus);
+       REGISTERTokenParamDefine(listid);
+       REGISTERTokenParamDefine(size);
        REGISTERTokenParamDefine(all);
 
        REGISTERTokenParamDefine(contains);
@@ -941,21 +547,21 @@ InitModule_SIEVE
 
        RegisterIterator("SIEVE:SCRIPTS", 0, NULL, GetSieveScriptListing, NULL, NULL, CTX_SIEVELIST, CTX_NONE, IT_NOFLAG);
 
-       RegisterConditional(HKEY("COND:SIEVE:SCRIPT:ACTIVE"), 0, ConditionalSieveScriptIsActive, CTX_SIEVELIST);
-       RegisterConditional(HKEY("COND:SIEVE:SCRIPT:ISRULES"), 0, ConditionalSieveScriptIsRulesScript, CTX_SIEVELIST);
+       RegisterConditional("COND:SIEVE:SCRIPT:ACTIVE", 0, ConditionalSieveScriptIsActive, CTX_SIEVELIST);
+       RegisterConditional("COND:SIEVE:SCRIPT:ISRULES", 0, ConditionalSieveScriptIsRulesScript, CTX_SIEVELIST);
        RegisterNamespace("SIEVE:SCRIPT:NAME", 0, 1, tmplput_SieveScriptName, NULL, CTX_SIEVELIST);
        RegisterNamespace("SIEVE:SCRIPT:CONTENT", 0, 1, tmplput_SieveScriptContent, NULL, CTX_SIEVELIST);
 
+
        RegisterIterator("SIEVE:RULES", 0, NULL, GetSieveRules, NULL, DeleteHash, CTX_SIEVESCRIPT, CTX_NONE, IT_NOFLAG);
 
-       RegisterConditional(HKEY("COND:SIEVE:ACTIVE"), 1, ConditionalSieveRule_Active, CTX_SIEVESCRIPT);
-       RegisterConditional(HKEY("COND:SIEVE:HFIELD"), 1, ConditionalSieveRule_hfield, CTX_SIEVESCRIPT);
-       RegisterConditional(HKEY("COND:SIEVE:COMPARE"), 1, ConditionalSieveRule_compare, CTX_SIEVESCRIPT);
-       RegisterConditional(HKEY("COND:SIEVE:ACTION"), 1, ConditionalSieveRule_action, CTX_SIEVESCRIPT);
-       RegisterConditional(HKEY("COND:SIEVE:SIZECOMP"), 1, ConditionalSieveRule_sizecomp, CTX_SIEVESCRIPT);
-       RegisterConditional(HKEY("COND:SIEVE:FINAL"), 1, ConditionalSieveRule_final, CTX_SIEVESCRIPT);
-       RegisterConditional(HKEY("COND:SIEVE:THISROOM"), 1, ConditionalSieveRule_ThisRoom, CTX_SIEVESCRIPT);
+       RegisterConditional("COND:SIEVE:ACTIVE", 1, ConditionalSieveRule_Active, CTX_SIEVESCRIPT);
+       RegisterConditional("COND:SIEVE:HFIELD", 1, ConditionalSieveRule_hfield, CTX_SIEVESCRIPT);
+       RegisterConditional("COND:SIEVE:COMPARE", 1, ConditionalSieveRule_compare, CTX_SIEVESCRIPT);
+       RegisterConditional("COND:SIEVE:ACTION", 1, ConditionalSieveRule_action, CTX_SIEVESCRIPT);
+       RegisterConditional("COND:SIEVE:SIZECOMP", 1, ConditionalSieveRule_sizecomp, CTX_SIEVESCRIPT);
+       RegisterConditional("COND:SIEVE:FINAL", 1, ConditionalSieveRule_final, CTX_SIEVESCRIPT);
+       RegisterConditional("COND:SIEVE:THISROOM", 1, ConditionalSieveRule_ThisRoom, CTX_SIEVESCRIPT);
 
        RegisterNamespace("SIEVE:SCRIPT:HTEXT", 0, 1, tmplput_SieveRule_htext, NULL, CTX_SIEVESCRIPT);
        RegisterNamespace("SIEVE:SCRIPT:SIZE", 0, 1, tmplput_SieveRule_sizeval, NULL, CTX_SIEVESCRIPT);
@@ -966,6 +572,5 @@ InitModule_SIEVE
        /* fetch our room into WCC->ThisRoom, to evaluate while iterating over rooms with COND:THIS:THAT:ROOM */
        RegisterNamespace("SIEVE:SCRIPT:LOOKUP_FILEINTO", 0, 1, tmplput_SieveRule_lookup_FileIntoRoom, NULL, CTX_SIEVESCRIPT);
        WebcitAddUrlHandler(HKEY("save_sieve"), "", 0, save_sieve, 0);
-       WebcitAddUrlHandler(HKEY("create_script"), "", 0, create_script, 0);
-       WebcitAddUrlHandler(HKEY("delete_script"), "", 0, delete_script, 0);
+       WebcitAddUrlHandler(HKEY("display_sieve_add_or_delete"), "", 0, display_sieve_add_or_delete, 0);
 }