dovecot-sieve-1.1: Added support for include extension.

dovecot at dovecot.org dovecot at dovecot.org
Fri Jul 20 11:12:47 EEST 2007


details:   http://hg.dovecot.org/dovecot-sieve-1.1/rev/48178539087b
changeset: 28:48178539087b
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Jul 20 11:12:45 2007 +0300
description:
Added support for include extension.

diffstat:

1 file changed, 95 insertions(+), 41 deletions(-)
src/sieve-cmu.c |  136 ++++++++++++++++++++++++++++++++++++++-----------------

diffs (217 lines):

diff -r 978a6225ecd7 -r 48178539087b src/sieve-cmu.c
--- a/src/sieve-cmu.c	Fri Jul 20 10:54:30 2007 +0300
+++ b/src/sieve-cmu.c	Fri Jul 20 11:12:45 2007 +0300
@@ -31,6 +31,8 @@ typedef struct script_data {
 	const char *username;
 	struct mail_namespace *namespaces;
 	struct mail_storage **storage_r;
+
+	sieve_interp_t *interp;
 	string_t *errors;
 } script_data_t;
 
@@ -58,6 +60,10 @@ typedef struct {
 	const char *temp[10];
 	buffer_t *tmp_buffer;
 } sieve_msgdata_t;
+
+static int
+dovecot_sieve_compile(script_data_t *sdata, const char *script_path,
+		      const char *compiled_path);
 
 /* gets the header "head" from msg. */
 static int getheader(void *v, const char *phead, const char ***body)
@@ -337,6 +343,58 @@ static int getbody(void *mc, const char 
     *parts_r = array_idx_modifiable(&m->return_body_parts, 0);
 
     return r;
+}
+
+static int getinclude(void *sc, const char *script, int isglobal,
+		      char *fname, size_t size)
+{
+	script_data_t *sdata = (script_data_t *) sc;
+	const char *script_path, *compiled_path, *home, *script_dir;
+	int ret;
+
+	if (strchr(script, '/') != NULL) {
+		i_info("include: '/' not allowed in script names (%s)",
+		       str_sanitize(script, 80));
+		return SIEVE_FAIL;
+	}
+
+	if (isglobal) {
+		script_dir = getenv("GLOBAL_SCRIPT_DIR");
+		if (script_dir == NULL) {
+			i_info("include: global_script_dir not set "
+			       "(wanted script %s)", str_sanitize(script, 80));
+			return SIEVE_FAIL;
+		}
+		script_path = t_strdup_printf("%s/%s", script_dir, script);
+	} else {
+		home = getenv("HOME");
+		if (home == NULL) {
+			i_info("include: home directory not set "
+			       "(wanted script %s)", str_sanitize(script, 80));
+			return SIEVE_FAIL;
+		}
+		script_path = t_strdup_printf("%s/%s", home, script);
+	}
+
+	compiled_path = t_strconcat(script_path, "c", NULL);
+	ret = dovecot_sieve_compile(sdata, script_path, compiled_path);
+	if (ret < 0) {
+		i_info("include: Error compiling script '%s'",
+		       str_sanitize(script, 80));
+		return SIEVE_FAIL;
+	}
+	if (ret == 0) {
+		i_info("include: Script not found: '%s'",
+		       str_sanitize(script, 80));
+		return SIEVE_FAIL;
+	}
+
+	if (strocpy(fname, compiled_path, size) < 0) {
+		i_info("include: Script path too long: '%s'",
+		       str_sanitize(script, 80));
+		return SIEVE_FAIL;
+	}
+	return SIEVE_OK;
 }
 
 static int sieve_redirect(void *ac, 
@@ -734,9 +792,9 @@ static sieve_interp_t *setup_sieve(void)
     res = sieve_register_body(interp, &getbody);
     if (res != SIEVE_OK)
 	i_fatal("sieve_register_body() returns %d\n", res);
-    /*res = sieve_register_include(interp, &getinclude);
-    if (res != SIEVE_OK)
-	i_fatal("sieve_registerinclude() returns %d\n", res);*/
+    res = sieve_register_include(interp, &getinclude);
+    if (res != SIEVE_OK)
+	i_fatal("sieve_registerinclude() returns %d\n", res);
     res = sieve_register_vacation(interp, &vacation);
     if (res != SIEVE_OK)
 	i_fatal("sieve_register_vacation() returns %d\n", res);
@@ -750,9 +808,27 @@ static sieve_interp_t *setup_sieve(void)
     return interp;
 }
 
+static void
+dovecot_sieve_write_error_file(script_data_t *sdata, const char *path)
+{
+	int fd;
+
+	fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
+	if (fd == -1) {
+		i_error("open(%s) failed: %m", path);
+		return;
+	}
+
+	if (write_full(fd, str_data(sdata->errors), str_len(sdata->errors)) < 0)
+		i_error("write_full(%s) failed: %m", path);
+
+	if (close(fd) < 0)
+		i_error("close() failed: %m");
+}
+
 static int
-dovecot_sieve_compile(sieve_interp_t *interp, script_data_t *sdata,
-		      const char *script_path, const char *compiled_path)
+dovecot_sieve_compile(script_data_t *sdata, const char *script_path,
+		      const char *compiled_path)
 {
 	struct stat st, st2;
 	sieve_script_t *script;
@@ -789,12 +865,21 @@ dovecot_sieve_compile(sieve_interp_t *in
 		return -1;
 	}
 
-	ret = sieve_script_parse(interp, f, sdata, &script);
+	ret = sieve_script_parse(sdata->interp, f, sdata, &script);
 	if (ret != SIEVE_OK) {
 		if (sdata->errors == NULL) {
 			sdata->errors = str_new(default_pool, 128);
 			str_printfa(sdata->errors, "parse error %d", ret);
 		}
+
+		if (getenv("DEBUG") != NULL) {
+			i_info("cmusieve: Compilation failed for %s: %s",
+			       script_path,
+			       str_sanitize(str_c(sdata->errors), 80));
+		}
+		temp_path = t_strconcat(script_path, ".err", NULL);
+		dovecot_sieve_write_error_file(sdata, temp_path);
+		str_free(&sdata->errors);
 		return -1;
 	}
 
@@ -827,56 +912,25 @@ dovecot_sieve_compile(sieve_interp_t *in
 	return 1;
 }
 
-static void
-dovecot_sieve_write_error_file(script_data_t *sdata, const char *path)
-{
-	int fd;
-
-	fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
-	if (fd == -1) {
-		i_error("open(%s) failed: %m", path);
-		return;
-	}
-
-	if (write_full(fd, str_data(sdata->errors), str_len(sdata->errors)) < 0)
-		i_error("write_full(%s) failed: %m", path);
-
-	if (close(fd) < 0)
-		i_error("close() failed: %m");
-}
-
 int cmu_sieve_run(struct mail_namespace *namespaces,
 		  struct mail_storage **storage_r, struct mail *mail,
 		  const char *script_path, const char *username,
 		  const char *mailbox)
 {
-	sieve_interp_t *interp;
 	sieve_execute_t *bytecode = NULL;
 	script_data_t sdata;
 	sieve_msgdata_t mdata;
-	const char *compiled_path, *path;
+	const char *compiled_path;
 	int ret;
-
-	interp = setup_sieve();
 
 	memset(&sdata, 0, sizeof(sdata));
 	sdata.username = username;
 	sdata.namespaces = namespaces;
 	sdata.storage_r = storage_r;
+	sdata.interp = setup_sieve();
 
 	compiled_path = t_strconcat(script_path, "c", NULL);
-	ret = dovecot_sieve_compile(interp, &sdata, script_path, compiled_path);
-
-	if (sdata.errors != NULL) {
-		if (getenv("DEBUG") != NULL) {
-			i_info("cmusieve: Compilation failed for %s: %s",
-			       script_path,
-			       str_sanitize(str_c(sdata.errors), 80));
-		}
-		path = t_strconcat(script_path, ".err", NULL);
-		dovecot_sieve_write_error_file(&sdata, path);
-		str_free(&sdata.errors);
-	}
+	ret = dovecot_sieve_compile(&sdata, script_path, compiled_path);
 	if (ret <= 0)
 		return ret;
 
@@ -896,7 +950,7 @@ int cmu_sieve_run(struct mail_namespace 
 		i_info("cmusieve: Executing script %s", compiled_path);
 
 	ret = 1;
-	if (sieve_execute_bytecode(bytecode, interp,
+	if (sieve_execute_bytecode(bytecode, sdata.interp,
 				   &sdata, &mdata) != SIEVE_OK) {
 		i_error("sieve_execute_bytecode(%s) failed", compiled_path);
 		ret = -1;


More information about the dovecot-cvs mailing list