X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fsieve%2Fserv_sieve.c;h=4ca061eae79afe883ad94705a018e3f64bc4caee;hb=7c3b87a0790f8ce7ac49022ddb3d64075f5dea61;hp=46957b5971740a6f02ee7c06962eef7cc9b53841;hpb=a2fda4eafb51bbf58c04471522aa2d0f116c797e;p=citadel.git diff --git a/citadel/modules/sieve/serv_sieve.c b/citadel/modules/sieve/serv_sieve.c index 46957b597..4ca061eae 100644 --- a/citadel/modules/sieve/serv_sieve.c +++ b/citadel/modules/sieve/serv_sieve.c @@ -4,7 +4,21 @@ * This module glues libSieve to the Citadel server in order to implement * the Sieve mailbox filtering language (RFC 3028). * - * This code is released under the terms of the GNU General Public License. + * Copyright (c) 1987-2010 by the citadel.org team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "sysdep.h" @@ -37,7 +51,6 @@ #include "citserver.h" #include "support.h" #include "config.h" -#include "room_ops.h" #include "policy.h" #include "database.h" #include "msgbase.h" @@ -116,7 +129,7 @@ int ctdl_redirect(sieve2_context_t *s, void *my) return SIEVE2_ERROR_BADARGS; } - CtdlSubmitMsg(msg, valid, NULL); + CtdlSubmitMsg(msg, valid, NULL, 0); cs->cancel_implicit_keep = 1; free_recipients(valid); CtdlFreeMessage(msg); @@ -164,12 +177,12 @@ int ctdl_fileinto(sieve2_context_t *s, void *my) /* First try a mailbox name match (check personal mail folders first) */ snprintf(foldername, sizeof foldername, "%010ld.%s", cs->usernum, dest_folder); - c = getroom(&CC->room, foldername); + c = CtdlGetRoom(&CC->room, foldername); /* Then a regular room name match (public and private rooms) */ if (c != 0) { safestrncpy(foldername, dest_folder, sizeof foldername); - c = getroom(&CC->room, foldername); + c = CtdlGetRoom(&CC->room, foldername); } if (c != 0) { @@ -178,13 +191,13 @@ int ctdl_fileinto(sieve2_context_t *s, void *my) } /* Yes, we actually have to go there */ - usergoto(NULL, 0, 0, NULL, NULL); + CtdlUserGoto(NULL, 0, 0, NULL, NULL); - c = CtdlSaveMsgPointersInRoom(NULL, &cs->msgnum, 1, 0, NULL); + c = CtdlSaveMsgPointersInRoom(NULL, &cs->msgnum, 1, 0, NULL, 0); /* Go back to the room we came from */ if (strcasecmp(original_room_name, CC->room.QRname)) { - usergoto(original_room_name, 0, 0, NULL, NULL); + CtdlUserGoto(original_room_name, 0, 0, NULL, NULL); } if (c == 0) { @@ -342,6 +355,7 @@ int ctdl_vacation(sieve2_context_t *s, void *my) /* If we get to this point, create a new record. */ vptr = malloc(sizeof(struct sdm_vacation)); + memset(vptr, 0, sizeof(struct sdm_vacation)); vptr->timestamp = time(NULL); safestrncpy(vptr->fromaddr, cs->sender, sizeof vptr->fromaddr); vptr->next = cs->u->first_vacation; @@ -508,9 +522,9 @@ void sieve_do_msg(long msgnum, void *userdata) { size_t headers_len = 0; int len = 0; - if (userdata == NULL) + if (u == NULL) { - CtdlLogPrintf(CTDL_EMERG, "Cant process Message <%ld>without Userdata!\n", msgnum); + CtdlLogPrintf(CTDL_EMERG, "Can't process message <%ld> without userdata!\n", msgnum); return; } @@ -518,16 +532,20 @@ void sieve_do_msg(long msgnum, void *userdata) { CtdlLogPrintf(CTDL_DEBUG, "Performing sieve processing on msg <%ld>\n", msgnum); - msg = CtdlFetchMessage(msgnum, 0); + /* + * Make sure you include message body so you can get those second-level headers ;) + */ + msg = CtdlFetchMessage(msgnum, 1); if (msg == NULL) return; /* * Grab the message headers so we can feed them to libSieve. + * Use HEADERS_ONLY rather than HEADERS_FAST in order to include second-level headers. */ CC->redirect_buffer = malloc(SIZ); CC->redirect_len = 0; CC->redirect_alloc = SIZ; - CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_ONLY, 0, 1); + CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_ONLY, 0, 1, 0); my.rfc822headers = CC->redirect_buffer; headers_len = CC->redirect_len; CC->redirect_buffer = NULL; @@ -744,33 +762,28 @@ void get_sieve_config_backend(long msgnum, void *userdata) { * otherwise it just frees the data structures.) */ void rewrite_ctdl_sieve_config(struct sdm_userdata *u, int yes_write_to_disk) { - char *text; + StrBuf *text; struct sdm_script *sptr; struct sdm_vacation *vptr; - size_t tsize; - - text = malloc(1024); - tsize = 1024; - snprintf(text, 1024, - "Content-type: application/x-citadel-sieve-config\n" - "\n" - CTDLSIEVECONFIGSEPARATOR - "lastproc|%ld" - CTDLSIEVECONFIGSEPARATOR - , - u->lastproc - ); + + text = NewStrBufPlain(NULL, SIZ); + StrBufPrintf(text, + "Content-type: application/x-citadel-sieve-config\n" + "\n" + CTDLSIEVECONFIGSEPARATOR + "lastproc|%ld" + CTDLSIEVECONFIGSEPARATOR + , + u->lastproc + ); while (u->first_script != NULL) { - size_t tlen; - tlen = strlen(text); - tsize = tlen + strlen(u->first_script->script_content) +256; - text = realloc(text, tsize); - sprintf(&text[strlen(text)], "script|%s|%d|%s" CTDLSIEVECONFIGSEPARATOR, - u->first_script->script_name, - u->first_script->script_active, - u->first_script->script_content - ); + StrBufAppendPrintf(text, + "script|%s|%d|%s" CTDLSIEVECONFIGSEPARATOR, + u->first_script->script_name, + u->first_script->script_active, + u->first_script->script_content + ); sptr = u->first_script; u->first_script = u->first_script->next; free(sptr->script_content); @@ -779,32 +792,26 @@ void rewrite_ctdl_sieve_config(struct sdm_userdata *u, int yes_write_to_disk) { if (u->first_vacation != NULL) { - tsize = strlen(text) + 256; - for (vptr = u->first_vacation; vptr != NULL; vptr = vptr->next) { - tsize += strlen(vptr->fromaddr + 32); - } - text = realloc(text, tsize); - - sprintf(&text[strlen(text)], "vacation|\n"); + StrBufAppendPrintf(text, "vacation|\n"); while (u->first_vacation != NULL) { if ( (time(NULL) - u->first_vacation->timestamp) < (MAX_VACATION * 86400)) { - sprintf(&text[strlen(text)], "%s|%ld\n", - u->first_vacation->fromaddr, - u->first_vacation->timestamp - ); + StrBufAppendPrintf(text, "%s|%ld\n", + u->first_vacation->fromaddr, + u->first_vacation->timestamp + ); } vptr = u->first_vacation; u->first_vacation = u->first_vacation->next; free(vptr); } - sprintf(&text[strlen(text)], CTDLSIEVECONFIGSEPARATOR); + StrBufAppendPrintf(text, CTDLSIEVECONFIGSEPARATOR); } if (yes_write_to_disk) { /* Save the config */ quickie_message("Citadel", NULL, NULL, u->config_roomname, - text, + ChrPtr(text), 4, "Sieve configuration" ); @@ -815,7 +822,7 @@ void rewrite_ctdl_sieve_config(struct sdm_userdata *u, int yes_write_to_disk) { } } - free (text); + FreeStrBuf (&text); } @@ -865,7 +872,7 @@ void sieve_do_room(char *roomname) { * require execution. */ snprintf(u.config_roomname, sizeof u.config_roomname, "%010ld.%s", atol(roomname), USERCONFIGROOM); - if (getroom(&CC->room, u.config_roomname) != 0) { + if (CtdlGetRoom(&CC->room, u.config_roomname) != 0) { CtdlLogPrintf(CTDL_DEBUG, "<%s> does not exist. No processing is required.\n", u.config_roomname); return; } @@ -884,7 +891,7 @@ void sieve_do_room(char *roomname) { CtdlLogPrintf(CTDL_DEBUG, "Rules found. Performing Sieve processing for <%s>\n", roomname); - if (getroom(&CC->room, roomname) != 0) { + if (CtdlGetRoom(&CC->room, roomname) != 0) { CtdlLogPrintf(CTDL_CRIT, "ERROR: cannot load <%s>\n", roomname); return; } @@ -973,7 +980,7 @@ void msiv_load(struct sdm_userdata *u) { strcpy(hold_rm, CC->room.QRname); /* save current room */ /* Take a spin through the user's personal address book */ - if (getroom(&CC->room, USERCONFIGROOM) == 0) { + if (CtdlGetRoom(&CC->room, USERCONFIGROOM) == 0) { u->config_msgnum = (-1); strcpy(u->config_roomname, CC->room.QRname); @@ -983,11 +990,20 @@ void msiv_load(struct sdm_userdata *u) { } if (strcmp(CC->room.QRname, hold_rm)) { - getroom(&CC->room, hold_rm); /* return to saved room */ + CtdlGetRoom(&CC->room, hold_rm); /* return to saved room */ } } void msiv_store(struct sdm_userdata *u, int yes_write_to_disk) { +/* + * Initialise the sieve configs last processed message number. + * We don't need to get the highest message number for the users inbox since the systems + * highest message number will be higher than that and loer than this scripts message number + * This prevents this new script from processing any old messages in the inbox. + * Most importantly it will prevent vacation messages being sent to lots of old messages + * in the inbox. + */ + u->lastproc = CtdlGetCurrentMessageNumber(); rewrite_ctdl_sieve_config(u, yes_write_to_disk); } @@ -1145,7 +1161,7 @@ void cmd_msiv(char *argbuf) { extract_token(script_name, argbuf, 1, '|', sizeof script_name); if (!IsEmptyStr(script_name)) { cprintf("%d Transmit script now\n", SEND_LISTING); - script_content = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0, 0); + script_content = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0); msiv_putscript(&u, script_name, script_content); changes_made = 1; }