dovecot-2.2-pigeonhole: doveadm-sieve: Implemented handling the ...
pigeonhole at rename-it.nl
pigeonhole at rename-it.nl
Wed Apr 3 00:14:45 EEST 2013
details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/8b8bba6e8c2c
changeset: 1735:8b8bba6e8c2c
user: Stephan Bosch <stephan at rename-it.nl>
date: Tue Apr 02 23:14:13 2013 +0200
description:
doveadm-sieve: Implemented handling the situation when the main active script is a regular file.
Tested whether this change breaks ManageSieve and basic dsync, but not much more.
More tests pending. If you use sync be careful with this commit.
diffstat:
src/lib-sieve/sieve-plugins.c | 17 +-
src/lib-sievestorage/sieve-storage-list.c | 2 +-
src/lib-sievestorage/sieve-storage-save.c | 55 ++++-
src/lib-sievestorage/sieve-storage-save.h | 6 +
src/lib-sievestorage/sieve-storage-script.c | 95 +++++--
src/lib-sievestorage/sieve-storage-script.h | 22 +-
src/lib-sievestorage/sieve-storage.c | 67 ++--
src/plugins/doveadm-sieve/doveadm-sieve-plugin.c | 262 +++++++++++++++++-----
8 files changed, 365 insertions(+), 161 deletions(-)
diffs (truncated from 932 to 300 lines):
diff -r 5323b5e65289 -r 8b8bba6e8c2c src/lib-sieve/sieve-plugins.c
--- a/src/lib-sieve/sieve-plugins.c Thu Mar 28 22:14:21 2013 +0100
+++ b/src/lib-sieve/sieve-plugins.c Tue Apr 02 23:14:13 2013 +0200
@@ -58,7 +58,7 @@
void sieve_plugins_load
(struct sieve_instance *svinst, const char *path, const char *plugins)
{
- struct module *new_modules, *module;
+ struct module *module;
struct module_dir_load_settings mod_set;
const char **module_names;
unsigned int i;
@@ -83,22 +83,9 @@
/* Load missing plugin modules */
- new_modules = module_dir_load_missing
+ sieve_modules = module_dir_load_missing
(sieve_modules, path, plugins, &mod_set);
- if ( sieve_modules == NULL ) {
- /* No modules loaded yet */
- sieve_modules = new_modules;
- } else {
- /* Find the end of the list */
- module = sieve_modules;
- while ( module != NULL && module->next != NULL )
- module = module->next;
-
- /* Add newly loaded modules */
- module->next = new_modules;
- }
-
/* Call plugin load functions for this Sieve instance */
if ( svinst->plugins == NULL ) {
diff -r 5323b5e65289 -r 8b8bba6e8c2c src/lib-sievestorage/sieve-storage-list.c
--- a/src/lib-sievestorage/sieve-storage-list.c Thu Mar 28 22:14:21 2013 +0100
+++ b/src/lib-sievestorage/sieve-storage-list.c Tue Apr 02 23:14:13 2013 +0200
@@ -45,7 +45,7 @@
T_BEGIN {
/* Get the name of the active script */
- if ( sieve_storage_get_active_scriptfile(storage, &active) < 0) {
+ if ( sieve_storage_active_script_get_file(storage, &active) < 0) {
ctx = NULL;
} else {
pool = pool_alloconly_create("sieve_list_context", 4096);
diff -r 5323b5e65289 -r 8b8bba6e8c2c src/lib-sievestorage/sieve-storage-save.c
--- a/src/lib-sievestorage/sieve-storage-save.c Thu Mar 28 22:14:21 2013 +0100
+++ b/src/lib-sievestorage/sieve-storage-save.c Tue Apr 02 23:14:13 2013 +0200
@@ -9,6 +9,7 @@
#include "ostream.h"
#include "str.h"
#include "eacces-error.h"
+#include "safe-mkstemp.h"
#include "sieve-script.h"
#include "sieve-script-file.h"
@@ -324,7 +325,7 @@
const char *scriptname;
int ret;
- ret = sieve_storage_get_active_scriptname(ctx->storage, &scriptname);
+ ret = sieve_storage_active_script_get_name(ctx->storage, &scriptname);
if ( ret > 0 ) {
/* Is the requested script active? */
result = ( strcmp(ctx->scriptname, scriptname) == 0 );
@@ -368,3 +369,55 @@
sieve_storage_save_destroy(ctx);
}
+
+int sieve_storage_save_as_active_script(struct sieve_storage *storage,
+ struct istream *input)
+{
+ int fd;
+ string_t *temp_path;
+ struct ostream *output;
+
+ temp_path = t_str_new(256);
+ str_append(temp_path, storage->active_path);
+ str_append_c(temp_path, '.');
+ fd = safe_mkstemp_hostpid
+ (temp_path, storage->file_create_mode, (uid_t)-1, (gid_t)-1);
+ if ( fd < 0 ) {
+ if ( errno == EACCES ) {
+ sieve_storage_set_critical(storage,
+ "failed to create temporary file: %s",
+ eacces_error_get_creating("open", str_c(temp_path)));
+ } else {
+ sieve_storage_set_critical(storage,
+ "failed to create temporary file: open(%s) failed: %m",
+ str_c(temp_path));
+ }
+ return -1;
+ }
+
+ output = o_stream_create_fd(fd, 0, FALSE);
+ if (o_stream_send_istream(output, input) < 0) {
+ sieve_storage_set_critical(storage,
+ "o_stream_send_istream(%s) failed: %m", str_c(temp_path));
+ o_stream_destroy(&output);
+ (void)unlink(str_c(temp_path));
+ return -1;
+ }
+ o_stream_destroy(&output);
+
+ if (rename(str_c(temp_path), storage->active_path) < 0) {
+ if ( ENOSPACE(errno) ) {
+ sieve_storage_set_error(storage,
+ SIEVE_ERROR_NO_SPACE, "Not enough disk space");
+ } else if ( errno == EACCES ) {
+ sieve_storage_set_critical(storage,
+ "%s", eacces_error_get("rename", storage->active_path));
+ } else {
+ sieve_storage_set_critical(storage,
+ "rename(%s, %s) failed: %m", str_c(temp_path), storage->active_path);
+ }
+ }
+
+ (void)unlink(str_c(temp_path));
+ return 0;
+}
diff -r 5323b5e65289 -r 8b8bba6e8c2c src/lib-sievestorage/sieve-storage-save.h
--- a/src/lib-sievestorage/sieve-storage-save.h Thu Mar 28 22:14:21 2013 +0100
+++ b/src/lib-sievestorage/sieve-storage-save.h Tue Apr 02 23:14:13 2013 +0200
@@ -26,5 +26,11 @@
int sieve_storage_save_commit(struct sieve_save_context **ctx);
+/* Saves input directly as a regular file at the active script path.
+ * This is needed for the doveadm-sieve plugin.
+ */
+int sieve_storage_save_as_active_script(struct sieve_storage *storage,
+ struct istream *input);
+
#endif
diff -r 5323b5e65289 -r 8b8bba6e8c2c src/lib-sievestorage/sieve-storage-script.c
--- a/src/lib-sievestorage/sieve-storage-script.c Thu Mar 28 22:14:21 2013 +0100
+++ b/src/lib-sievestorage/sieve-storage-script.c Tue Apr 02 23:14:13 2013 +0200
@@ -41,7 +41,7 @@
/* Prevent initializing the active script link as a script when it
* resides in the sieve storage directory.
*/
- if ( *(storage->link_path) == '\0' ) {
+ if ( scriptname != NULL && *(storage->link_path) == '\0' ) {
const char *fname;
fname = strrchr(path, '/');
@@ -154,7 +154,7 @@
return 1;
}
-static const char *sieve_storage_parse_link
+static const char *sieve_storage_parse_active_link
(struct sieve_storage *storage, const char *link, const char **scriptname_r)
{
const char *fname, *scriptname, *scriptpath;
@@ -197,7 +197,7 @@
return fname;
}
-int sieve_storage_get_active_scriptfile
+int sieve_storage_active_script_get_file
(struct sieve_storage *storage, const char **file_r)
{
const char *link, *scriptfile;
@@ -210,7 +210,7 @@
return ret;
/* Parse the link */
- scriptfile = sieve_storage_parse_link(storage, link, NULL);
+ scriptfile = sieve_storage_parse_active_link(storage, link, NULL);
if (scriptfile == NULL) {
/* Obviously someone has been playing with our symlink,
@@ -224,7 +224,7 @@
return 1;
}
-int sieve_storage_get_active_scriptname
+int sieve_storage_active_script_get_name
(struct sieve_storage *storage, const char **name_r)
{
const char *link;
@@ -236,7 +236,7 @@
if ( (ret=sieve_storage_read_active_link(storage, &link)) <= 0 )
return ret;
- if ( sieve_storage_parse_link(storage, link, name_r) == NULL ) {
+ if ( sieve_storage_parse_active_link(storage, link, name_r) == NULL ) {
/* Obviously someone has been playing with our symlink,
* ignore this situation and report 'no active script'.
* Activation should fix this situation.
@@ -247,7 +247,13 @@
return 1;
}
-struct sieve_script *sieve_storage_get_active_script
+const char *sieve_storage_active_script_get_path
+ (struct sieve_storage *storage)
+{
+ return storage->active_path;
+}
+
+struct sieve_script *sieve_storage_active_script_get
(struct sieve_storage *storage)
{
struct sieve_script *script;
@@ -268,7 +274,7 @@
}
/* Parse the link */
- scriptfile = sieve_storage_parse_link(storage, link, NULL);
+ scriptfile = sieve_storage_parse_active_link(storage, link, NULL);
if (scriptfile == NULL) {
/* Obviously someone has been playing with our symlink,
@@ -289,6 +295,54 @@
return script;
}
+int sieve_storage_active_script_get_last_change
+(struct sieve_storage *storage, time_t *last_change_r)
+{
+ struct stat st;
+
+ /* Try direct lstat first */
+ if (lstat(storage->active_path, &st) == 0) {
+ *last_change_r = st.st_mtime;
+ return 0;
+ }
+
+ /* Check error */
+ if (errno != ENOENT) {
+ sieve_storage_set_critical(storage, "lstat(%s) failed: %m",
+ storage->active_path);
+ }
+
+ /* Fall back to statting storage directory */
+ return sieve_storage_get_last_change(storage, last_change_r);
+}
+
+int
+sieve_storage_active_script_is_no_link(struct sieve_storage *storage)
+{
+ struct stat st;
+
+ /* Stat the file */
+ if ( lstat(storage->active_path, &st) != 0 ) {
+ if ( errno != ENOENT ) {
+ sieve_storage_set_critical(storage,
+ "Failed to stat active sieve script symlink (%s): %m.",
+ storage->active_path);
+ return -1;
+ }
+ return 0;
+ }
+
+ if ( S_ISLNK( st.st_mode ) )
+ return 0;
+ if ( !S_ISREG( st.st_mode ) ) {
+ sieve_storage_set_critical( storage,
+ "Active sieve script file '%s' is no symlink nor a regular file.",
+ storage->active_path );
+ return -1;
+ }
+ return 1;
+}
+
int sieve_storage_script_is_active(struct sieve_script *script)
{
struct sieve_storage_script *st_script =
@@ -297,7 +351,7 @@
int ret = 0;
T_BEGIN {
- ret = sieve_storage_get_active_scriptfile(st_script->storage, &afile);
+ ret = sieve_storage_active_script_get_file(st_script->storage, &afile);
if ( ret > 0 ) {
/* Is the requested script active? */
@@ -486,7 +540,7 @@
* resolves automatically. This step is only necessary to provide a
* proper return value indicating whether the script was already active.
*/
- ret = sieve_storage_get_active_scriptfile(storage, &afile);
+ ret = sieve_storage_active_script_get_file(storage, &afile);
/* Is the requested script already active? */
if ( ret <= 0 || strcmp(st_script->file.filename, afile) != 0 )
@@ -545,27 +599,6 @@
return ret;
}
-int sieve_storage_get_active_script_last_change
-(struct sieve_storage *storage, time_t *last_change_r)
-{
More information about the dovecot-cvs
mailing list