From d40def1c6a5d2323b20dd7583b467dfce0ec1cec Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Tue, 10 Oct 2006 20:57:03 +0000 Subject: [PATCH] worked on sieve config load/save --- citadel/citadel.h | 1 + citadel/serv_sieve.c | 117 +++++++++++++++++++++++++++++++++++++++---- citadel/serv_sieve.h | 3 ++ 3 files changed, 112 insertions(+), 9 deletions(-) diff --git a/citadel/citadel.h b/citadel/citadel.h index c6e988a5d..b8f094973 100644 --- a/citadel/citadel.h +++ b/citadel/citadel.h @@ -235,6 +235,7 @@ enum { #define IGNETCFG "application/x-citadel-ignet-config" #define IGNETMAP "application/x-citadel-ignet-map" #define FILTERLIST "application/x-citadel-filter-list" +#define SIEVECONFIG "application/x-citadel-sieve-config" #define TRACE lprintf(CTDL_DEBUG, "Checkpoint: %s, %d\n", __FILE__, __LINE__) diff --git a/citadel/serv_sieve.c b/citadel/serv_sieve.c index 067e143fd..fae02f387 100644 --- a/citadel/serv_sieve.c +++ b/citadel/serv_sieve.c @@ -313,7 +313,6 @@ int ctdl_discard(sieve2_context_t *s, void *my) /* * Callback function to retrieve the sieve script - * FIXME fetch script from Citadel instead of hardcode */ int ctdl_getscript(sieve2_context_t *s, void *my) { @@ -368,12 +367,23 @@ void sieve_queue_room(struct ctdlroom *which_room) { /* - * We need this struct to pass a bunch of information + * We need these structs to pass a bunch of information * between sieve_do_msg() and sieve_do_room() */ + +struct sdm_script { + struct sdm_script *next; + char script_name[256]; + int script_active; + char *script_content; +}; + struct sdm_userdata { sieve2_context_t *sieve2_context; /**< for libsieve's use */ + long config_msgnum; /**< confirms that a sieve config was located */ + char config_roomname[ROOMNAMELEN]; long lastproc; /**< last message processed */ + struct sdm_script *first_script; }; @@ -429,6 +439,79 @@ void sieve_do_msg(long msgnum, void *userdata) { } + +/* + * Given the on-disk representation of our Sieve config, load + * it into an in-memory data structure. + */ +void parse_sieve_config(char *conf, struct sdm_userdata *u) { + char *ptr; + char *c; + + c = conf; + while (ptr = bmstrcasestr(conf, CTDLSIEVECONFIGSEPARATOR), ptr != NULL) { + *ptr = 0; + ptr += strlen(CTDLSIEVECONFIGSEPARATOR); + + lprintf(CTDL_DEBUG, "CONFIG: <%s>\n", c); + + /* FIXME finish this */ + + } +} + +/* + * We found the Sieve configuration for this user. + * Now do something with it. + */ +void get_sieve_config_backend(long msgnum, void *userdata) { + struct sdm_userdata *u = (struct sdm_userdata *) userdata; + struct CtdlMessage *msg; + char *conf; + + u->config_msgnum = msgnum; + msg = CtdlFetchMessage(u->config_msgnum, 1); + if (msg == NULL) { + u->config_msgnum = (-1) ; + return; + } + + conf = msg->cm_fields['M']; + msg->cm_fields['M'] = NULL; + CtdlFreeMessage(msg); + + if (conf != NULL) { + parse_sieve_config(conf, u); + free(conf); + } +} + + +/* + * Write our citadel sieve config back to disk + */ +void rewrite_ctdl_sieve_config(struct sdm_userdata *u) { + char *text; + + text = + "Content-type: application/x-citadel-sieve-config\n" + "\n" + ; + + /* Save the config */ + quickie_message("Citadel", NULL, u->config_roomname, + text, + 4, + "Sieve configuration" + ); + + /* And delete the old one */ + CtdlDeleteMessages(u->config_roomname, &u->config_msgnum, 1, "", 0); + +} + + + /* * Perform sieve processing for a single room */ @@ -437,7 +520,7 @@ void sieve_do_room(char *roomname) { struct sdm_userdata u; sieve2_context_t *sieve2_context = NULL; /* Context for sieve parser */ int res; /* Return code from libsieve calls */ - char sieveroomname[ROOMNAMELEN]; + long orig_lastproc = 0; /* * This is our callback registration table for libSieve. @@ -465,15 +548,25 @@ void sieve_do_room(char *roomname) { /* See if the user who owns this 'mailbox' has any Sieve scripts that * require execution. */ - snprintf(sieveroomname, sizeof sieveroomname, "%010ld.%s", atol(roomname), SIEVERULES); - if (getroom(&CC->room, sieveroomname) != 0) { - lprintf(CTDL_DEBUG, "<%s> does not exist. No processing is required.\n", sieveroomname); + snprintf(u.config_roomname, sizeof u.config_roomname, "%010ld.%s", atol(roomname), SIEVERULES); + if (getroom(&CC->room, u.config_roomname) != 0) { + lprintf(CTDL_DEBUG, "<%s> does not exist. No processing is required.\n", u.config_roomname); return; } - /* CtdlForEachMessage(FIXME find the sieve scripts and control record and do something */ + /* + * Find the sieve scripts and control record and do something + */ + u.config_msgnum = (-1); + CtdlForEachMessage(MSGS_LAST, 1, NULL, SIEVECONFIG, NULL, + get_sieve_config_backend, (void *)&u ); - lprintf(CTDL_DEBUG, "Performing Sieve processing for <%s>\n", roomname); + if (u.config_msgnum < 0) { + lprintf(CTDL_DEBUG, "No Sieve rules exist. No processing is required.\n"); + return; + } + + lprintf(CTDL_DEBUG, "Rules found. Performing Sieve processing for <%s>\n", roomname); if (getroom(&CC->room, roomname) != 0) { lprintf(CTDL_CRIT, "ERROR: cannot load <%s>\n", roomname); @@ -504,6 +597,7 @@ void sieve_do_room(char *roomname) { /* Do something useful */ u.sieve2_context = sieve2_context; + orig_lastproc = u.lastproc; CtdlForEachMessage(MSGS_GT, u.lastproc, NULL, NULL, NULL, sieve_do_msg, (void *) &u @@ -514,6 +608,11 @@ BAIL: if (res != SIEVE2_OK) { lprintf(CTDL_CRIT, "sieve2_free() returned %d: %s\n", res, sieve2_errstr(res)); } + + /* Rewrite the config if we have to */ + if (u.lastproc > orig_lastproc) { + rewrite_ctdl_sieve_config(&u); + } } @@ -552,7 +651,7 @@ void perform_sieve_processing(void) { -/** +/* * We don't really care about dumping the entire credits to the log * every time the server is initialized. The documentation will suffice * for that purpose. We are making a call to sieve2_credits() in order diff --git a/citadel/serv_sieve.h b/citadel/serv_sieve.h index 54c48c9e1..d70be0506 100644 --- a/citadel/serv_sieve.h +++ b/citadel/serv_sieve.h @@ -6,3 +6,6 @@ extern struct RoomProcList *sieve_list; void sieve_queue_room(struct ctdlroom *); void perform_sieve_processing(void); + +/* If you change this string you will break all of your Sieve configs. */ +#define CTDLSIEVECONFIGSEPARATOR "\n-==-\n" -- 2.30.2