13#include "../../sysdep.h"
26#include <libcitadel.h>
27#include "../../citadel.h"
28#include "../../server.h"
29#include "../../citserver.h"
30#include "../../support.h"
31#include "../../config.h"
32#include "../../database.h"
33#include "../../msgbase.h"
34#include "../../internet_addressing.h"
35#include "../../ctdl_module.h"
165 if (!serialized_rules) {
170 char *sr = strdup(serialized_rules);
183 while ((token = strtok_r(rest,
"\n", &rest))) {
188 if (!strncasecmp(token,
"# WEBCIT_RULE|", 14)) {
189 strcpy(token,
"rule|");
190 strcpy(&token[5], &token[14]);
194 if (!strncasecmp(token,
"rule|", 5)) {
195 remove_token(&token[5], 0,
'|');
196 char *decoded_rule =
malloc(strlen(token));
197 CtdlDecodeBase64(decoded_rule, &token[5], strlen(&token[5]));
201 memset(new_rule, 0,
sizeof(
struct irule));
205 int nt = num_tokens(decoded_rule,
'|');
207 for (t=0; t<nt; ++t) {
208 extract_token(rtoken, decoded_rule, t,
'|',
sizeof(rtoken));
270 else if (!strncasecmp(token,
"lastproc|", 5)) {
295 (IsEmptyStr(dest_folder))
296 || (!strcasecmp(dest_folder,
"INBOX"))
297 || (!strcasecmp(dest_folder,
MAILROOM))
303 safestrncpy(original_room_name,
CC->room.QRname,
sizeof original_room_name);
306 strcpy(foldername, original_room_name);
307 snprintf(&foldername[10],
sizeof(foldername)-10,
".%s", dest_folder);
312 safestrncpy(foldername, dest_folder,
sizeof foldername);
317 syslog(LOG_WARNING,
"inboxrules: target <%s> does not exist", dest_folder);
327 if (strcasecmp(original_room_name,
CC->room.QRname)) {
328 CtdlUserGoto(original_room_name, 0, 0, NULL, NULL, NULL, NULL);
340 syslog(LOG_WARNING,
"inboxrules: inbox_do_redirect() invalid recipient <%s>", rule->
redirect_to);
346 syslog(LOG_WARNING,
"inboxrules: inbox_do_redirect() invalid recipient <%s>", rule->
redirect_to);
351 syslog(LOG_WARNING,
"inboxrules: inbox_do_redirect() invalid recipient <%s>", rule->
redirect_to);
358 syslog(LOG_WARNING,
"inboxrules: cannot reload message %ld for forwarding", msgnum);
387 if (reject_text == NULL) {
391 "Content-type: text/plain\n"
393 "The message was refused by the recipient's mail filtering program.\n"
394 "The reason given was as follows:\n"
410 "Delivery status notification"
434 StrBuf *u = NewStrBuf();
435 StrBufPrintf(u,
"vacation/%x/%x/%x",
436 HashLittle(sender, strlen(sender)),
445 StrBuf *reject_text = NewStrBuf();
446 if (reject_text == NULL) {
450 StrBufPrintf(reject_text,
451 "Content-type: text/plain\n"
467 "Delivery status notification"
469 FreeStrBuf(&reject_text);
480 int headers_loaded = 0;
482 int metadata_loaded = 0;
484 int rule_activated = 0;
485 char compare_me[
SIZ];
486 int compare_compound = 0;
487 int keep_message = 1;
490 syslog(LOG_DEBUG,
"inboxrules: processing message #%ld which is higher than %ld, we are in %s", msgnum, ii->
lastproc,
CC->room.QRname);
493 syslog(LOG_DEBUG,
"inboxrules: rule set is empty");
512 if (!headers_loaded) {
513 syslog(LOG_DEBUG,
"inboxrules: loading headers for message %ld", msgnum);
529 syslog(LOG_DEBUG,
"inboxrules: loading all of message %ld", msgnum);
542 if (!metadata_loaded) {
543 syslog(LOG_DEBUG,
"inboxrules: loading metadata for message %ld", msgnum);
549 syslog(LOG_DEBUG,
"inboxrules: this is an always-on rule");
552 syslog(LOG_DEBUG,
"inboxrules: unknown rule key");
557 compare_compound = 0;
561 snprintf(compare_me,
sizeof compare_me,
"%s|%s",
565 compare_compound = 1;
579 if (!IsEmptyStr(compare_me)) {
580 strcat(compare_me,
",");
582 safestrncpy(&compare_me[strlen(compare_me)], msg->
cm_fields[
eCarbonCopY], (
sizeof compare_me - strlen(compare_me)));
639 syslog(LOG_DEBUG,
"Value of field to compare is: <%s>", compare_me);
642 if (compare_compound) {
643 char *sep = strchr(compare_me,
'|');
655 syslog(LOG_DEBUG,
"substring match: %d", substring_match);
656 syslog(LOG_DEBUG,
"exact match: %d", exact_match);
660 rule_activated = substring_match;
664 rule_activated = !substring_match;
667 rule_activated = exact_match;
670 rule_activated = !exact_match;
690 syslog(LOG_WARNING,
"inboxrules: an unknown field comparison was encountered");
696 if (rule_activated) {
697 syslog(LOG_DEBUG,
"inboxrules: rule activated");
725 syslog(LOG_DEBUG,
"inboxrules: stop processing");
732 syslog(LOG_DEBUG,
"inboxrules: rule not activated");
741 syslog(LOG_DEBUG,
"inboxrules: delete %ld from inbox", msgnum);
763 strcpy(username,
CC->user.fullname);
765 if (
CC->user.msgnum_inboxrules <= 0) {
781 if (ii->
lastproc >
CC->user.lastproc_inboxrules) {
788 long original_lastproc = ii->
lastproc;
789 syslog(LOG_DEBUG,
"inboxrules: for %s, messages newer than %ld",
CC->user.fullname, original_lastproc);
792 snprintf(roomname,
sizeof roomname,
"%010ld.%s", usernum,
MAILROOM);
798 if (ii->
lastproc > original_lastproc) {
847 long usernum = atol(room->
QRname);
898 while ((token = strtok_r(rest,
"\n", &rest))) {
901 if (!strncasecmp(token,
"# WEBCIT_RULE|", 14)) {
902 strcpy(token,
"rule|");
903 strcpy(&token[5], &token[14]);
907 if (!strncasecmp(token,
"rule|", 5)) {
911 cprintf(
"# invalid rule found : %s\n", token);
927 long old_msgnum =
CC->user.msgnum_inboxrules;
930 long new_msgnum =
quickie_message(
"Citadel", NULL, NULL, userconfigroomname, new_config,
FMT_RFC822,
"inbox rules configuration");
932 CC->user.msgnum_inboxrules = new_msgnum;
933 CC->user.lastproc_inboxrules = new_msgnum;
935 if (old_msgnum > 0) {
936 syslog(LOG_DEBUG,
"Deleting old message %ld from %s", old_msgnum, userconfigroomname);
953 StrBuf *NewConfig = NewStrBufPlain(
"Content-type: application/x-citadel-sieve-config; charset=UTF-8\nContent-transfer-encoding: 8bit\n\n", -1);
956 char *rest = newrules;
957 while ((token = strtok_r(rest,
"\n", &rest))) {
959 if (!strncasecmp(token,
"rule|", 5)) {
960 StrBufAppendBufPlain(NewConfig, token, -1, 0);
961 StrBufAppendBufPlain(NewConfig, HKEY(
"\n"), 0);
966 FreeStrBuf(&NewConfig);
long CtdlGetConfigLong(char *key)
void CtdlMailboxName(char *buf, size_t n, const struct ctdluser *who, const char *prefix)
int CtdlGetRoom(struct ctdlroom *qrbuf, const char *room_name)
int CtdlGetUserByNumber(struct ctdluser *usbuf, long number)
void CtdlRegisterSessionHook(void(*fcn_ptr)(void), int EventType, int Priority)
void CtdlRegisterRoomHook(int(*fcn_ptr)(struct ctdlroom *))
int CtdlGetUserLock(struct ctdluser *usbuf, char *name)
void CtdlPutUserLock(struct ctdluser *usbuf)
void CtdlUserGoto(char *where, int display_result, int transiently, int *msgs, int *new, long *oldest, long *newest)
void CtdlRegisterProtoHook(void(*handler)(char *), char *cmd, char *desc)
int CheckIfAlreadySeen(StrBuf *guid)
struct recptypes * validate_recipients(char *supplied_recipients, const char *RemoteIdentifier, int Flags)
void free_recipients(struct recptypes *valid)
void CM_Free(struct CtdlMessage *msg)
void GetMetaData(struct MetaData *smibuf, long msgnum)
int CtdlForEachMessage(int mode, long ref, char *search_string, char *content_type, struct CtdlMessage *compare, ForEachMsgCallback CallBack, void *userdata)
struct CtdlMessage * CtdlFetchMessage(long msgnum, int with_body)
int CM_IsEmpty(struct CtdlMessage *Msg, eMsgField which)
int CtdlDeleteMessages(const char *room_name, long *dmsgnums, int num_dmsgnums, char *content_type)
long CtdlSubmitMsg(struct CtdlMessage *msg, struct recptypes *recps, const char *force)
char * CtdlReadMessageBody(char *terminator, long tlen, size_t maxlen, StrBuf *exist, int crlf)
long quickie_message(char *from, char *fromaddr, char *to, char *room, char *text, int format_type, char *subject)
int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newmsgs, int do_repl_check, struct CtdlMessage *supplied_msg, int suppress_refcount_adj)
void inbox_do_vacation(struct irule *rule, struct CtdlMessage *msg)
void free_inbox_rules(struct inboxrules *ibr)
char * ctdl_module_init_sieve(void)
int serv_inboxrules_roomhook(struct ctdlroom *room)
void inbox_do_reject(struct irule *rule, struct CtdlMessage *msg)
struct inboxrules * deserialize_inbox_rules(char *serialized_rules)
int inbox_do_fileinto(struct irule *rule, long msgnum)
void rewrite_rules_to_disk(const char *new_config)
long * users_requiring_inbox_processing
void cmd_pibr(char *argbuf)
void inbox_do_msg(long msgnum, void *userdata)
void cmd_gibr(char *argbuf)
int inbox_do_redirect(struct irule *rule, long msgnum)
void do_inbox_processing_for_user(long usernum)
void perform_inbox_processing(void)
char file_into[ROOMNAMELEN]
char autoreply_message[SIZ]
void cprintf(const char *format,...)
void unbuffer_output(void)