libical, expat, and libsieve are now *required*.
[citadel.git] / citadel / modules / sieve / serv_sieve.c
index 508f8d2188ce71ecf06889f181de4704f235b7db..726d58d504fafd552fbee56178e427a91782993e 100644 (file)
@@ -31,6 +31,7 @@
 #include <sys/wait.h>
 #include <string.h>
 #include <limits.h>
+#include <libcitadel.h>
 #include "citadel.h"
 #include "server.h"
 #include "citserver.h"
 #include "database.h"
 #include "msgbase.h"
 #include "internet_addressing.h"
-#include "tools.h"
-
-
 #include "ctdl_module.h"
-
-
-#ifdef HAVE_LIBSIEVE
-
 #include "serv_sieve.h"
 
 struct RoomProcList *sieve_list = NULL;
@@ -104,7 +98,7 @@ int ctdl_redirect(sieve2_context_t *s, void *my)
 
        lprintf(CTDL_DEBUG, "Action is REDIRECT, recipient <%s>\n", recp);
 
-       valid = validate_recipients(recp);
+       valid = validate_recipients(recp, NULL, 0);
        if (valid == NULL) {
                lprintf(CTDL_WARNING, "REDIRECT failed: bad recipient <%s>\n", recp);
                return SIEVE2_ERROR_BADARGS;
@@ -230,7 +224,7 @@ int ctdl_reject(sieve2_context_t *s, void *my)
        lprintf(CTDL_DEBUG, "Action is REJECT\n");
 
        /* If we don't know who sent the message, do a DISCARD instead. */
-       if (strlen(cs->sender) == 0) {
+       if (IsEmptyStr(cs->sender)) {
                lprintf(CTDL_INFO, "Unknown sender.  Doing DISCARD instead of REJECT.\n");
                return ctdl_discard(s, my);
        }
@@ -386,9 +380,34 @@ int ctdl_getenvelope(sieve2_context_t *s, void *my)
 {
        struct ctdl_sieve *cs = (struct ctdl_sieve *)my;
 
-       lprintf(CTDL_DEBUG, "Action is GETENVELOPE\n");
-       sieve2_setvalue_string(s, "to", cs->envelope_to);
-       sieve2_setvalue_string(s, "from", cs->envelope_from);
+       lprintf(CTDL_DEBUG, "Action is GETENVELOPE\nEnvFrom: %s\n  EnvTo: %s\n",
+               cs->envelope_from, cs->envelope_to);
+
+       if (cs->envelope_from != NULL) {
+               if ((cs->envelope_from[0] != '@')&&(cs->envelope_from[strlen(cs->envelope_from)-1] != '@')) {
+                       sieve2_setvalue_string(s, "from", cs->envelope_from);
+               }
+               else {
+                       sieve2_setvalue_string(s, "from", "invalid_envelope_from@example.org");
+               }
+       }
+       else {
+               sieve2_setvalue_string(s, "from", "null_envelope_from@example.org");
+       }
+
+
+       if (cs->envelope_to != NULL) {
+               if ((cs->envelope_to[0] != '@') && (cs->envelope_to[strlen(cs->envelope_to)-1] != '@')) {
+                       sieve2_setvalue_string(s, "to", cs->envelope_to);
+               }
+               else {
+                       sieve2_setvalue_string(s, "to", "invalid_envelope_to@example.org");
+               }
+       }
+       else {
+               sieve2_setvalue_string(s, "to", "null_envelope_to@example.org");
+       }
+
        return SIEVE2_OK;
 }
 
@@ -481,7 +500,7 @@ void sieve_queue_room(struct ctdlroom *which_room) {
  */
 void sieve_do_msg(long msgnum, void *userdata) {
        struct sdm_userdata *u = (struct sdm_userdata *) userdata;
-       sieve2_context_t *sieve2_context = u->sieve2_context;
+       sieve2_context_t *sieve2_context;
        struct ctdl_sieve my;
        int res;
        struct CtdlMessage *msg;
@@ -489,6 +508,14 @@ void sieve_do_msg(long msgnum, void *userdata) {
        size_t headers_len = 0;
        int len = 0;
 
+       if (userdata == NULL)
+       {
+               lprintf(CTDL_EMERG, "Cant process Message <%ld>without Userdata!\n", msgnum);
+               return;
+       }
+
+       sieve2_context = u->sieve2_context;
+
        lprintf(CTDL_DEBUG, "Performing sieve processing on msg <%ld>\n", msgnum);
 
        msg = CtdlFetchMessage(msgnum, 0);
@@ -552,9 +579,11 @@ void sieve_do_msg(long msgnum, void *userdata) {
        /* Keep track of the envelope-from address (use body-from if not found) */
        if (msg->cm_fields['P'] != NULL) {
                safestrncpy(my.envelope_from, msg->cm_fields['P'], sizeof my.envelope_from);
+               stripallbut(my.envelope_from, '<', '>');
        }
        else if (msg->cm_fields['F'] != NULL) {
                safestrncpy(my.envelope_from, msg->cm_fields['F'], sizeof my.envelope_from);
+               stripallbut(my.envelope_from, '<', '>');
        }
        else {
                strcpy(my.envelope_from, "");
@@ -572,6 +601,7 @@ void sieve_do_msg(long msgnum, void *userdata) {
        /* Keep track of the envelope-to address (use body-to if not found) */
        if (msg->cm_fields['V'] != NULL) {
                safestrncpy(my.envelope_to, msg->cm_fields['V'], sizeof my.envelope_to);
+               stripallbut(my.envelope_to, '<', '>');
        }
        else if (msg->cm_fields['R'] != NULL) {
                safestrncpy(my.envelope_to, msg->cm_fields['R'], sizeof my.envelope_to);
@@ -579,6 +609,7 @@ void sieve_do_msg(long msgnum, void *userdata) {
                        strcat(my.envelope_to, "@");
                        strcat(my.envelope_to, msg->cm_fields['D']);
                }
+               stripallbut(my.envelope_to, '<', '>');
        }
        else {
                strcpy(my.envelope_to, "");
@@ -769,19 +800,23 @@ void rewrite_ctdl_sieve_config(struct sdm_userdata *u, int yes_write_to_disk) {
                sprintf(&text[strlen(text)], CTDLSIEVECONFIGSEPARATOR);
        }
 
-       /* Save the config */
-       quickie_message("Citadel", NULL, NULL, u->config_roomname,
-                       text,
-                       4,
-                       "Sieve configuration"
-       );
-       
-       free (text);
-       /* And delete the old one */
-       if (u->config_msgnum > 0) {
-               CtdlDeleteMessages(u->config_roomname, &u->config_msgnum, 1, "");
+       if (yes_write_to_disk)
+       {
+               /* Save the config */
+               quickie_message("Citadel", NULL, NULL, u->config_roomname,
+                               text,
+                               4,
+                               "Sieve configuration"
+               );
+               
+               /* And delete the old one */
+               if (u->config_msgnum > 0) {
+                       CtdlDeleteMessages(u->config_roomname, &u->config_msgnum, 1, "");
+               }
        }
 
+       free (text);
+
 }
 
 
@@ -969,7 +1004,7 @@ int msiv_setactive(struct sdm_userdata *u, char *script_name) {
 
        /* First see if the supplied value is ok */
 
-       if (strlen(script_name) == 0) {
+       if (IsEmptyStr(script_name)) {
                ok = 1;
        }
        else {
@@ -1108,9 +1143,9 @@ void cmd_msiv(char *argbuf) {
 
        if (!strcasecmp(subcmd, "putscript")) {
                extract_token(script_name, argbuf, 1, '|', sizeof script_name);
-               if (strlen(script_name) > 0) {
+               if (!IsEmptyStr(script_name)) {
                        cprintf("%d Transmit script now\n", SEND_LISTING);
-                       script_content = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0);
+                       script_content = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0, 0);
                        msiv_putscript(&u, script_name, script_content);
                        changes_made = 1;
                }
@@ -1249,26 +1284,17 @@ int serv_sieve_room(struct ctdlroom *room)
        return 0;
 }
 
-#endif /* HAVE_LIBSIEVE */
-
 CTDL_MODULE_INIT(sieve)
 {
+       if (!threading)
+       {
 
-#ifdef HAVE_LIBSIEVE
-
-       ctdl_sieve_init();
-       CtdlRegisterProtoHook(cmd_msiv, "MSIV", "Manage Sieve scripts");
-
-        CtdlRegisterRoomHook(serv_sieve_room);
-
-        CtdlRegisterSessionHook(perform_sieve_processing, EVT_HOUSE);
-
-#else  /* HAVE_LIBSIEVE */
-
-       lprintf(CTDL_INFO, "This server is missing libsieve.  Mailbox filtering will be disabled.\n");
-
-#endif /* HAVE_LIBSIEVE */
-
+               ctdl_sieve_init();
+               CtdlRegisterProtoHook(cmd_msiv, "MSIV", "Manage Sieve scripts");
+               CtdlRegisterRoomHook(serv_sieve_room);
+               CtdlRegisterSessionHook(perform_sieve_processing, EVT_HOUSE);
+       }
+       
         /* return our Subversion id for the Log */
        return "$Id$";
 }