From 6b577da37cfec5a3f21f8dc708a7610d18cc10c2 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan.bosch@open-xchange.com> Date: Fri, 1 Nov 2024 00:58:08 +0100 Subject: [PATCH] lib-sieve: storage: file: sieve-file-storage - Fully stat both storage and active path in sieve_file_storage_autodetect() Makes the autodetection more reliable and avoids later failures. --- .../storage/file/sieve-file-storage.c | 73 ++++++++++++++----- 1 file changed, 54 insertions(+), 19 deletions(-) diff --git a/src/lib-sieve/storage/file/sieve-file-storage.c b/src/lib-sieve/storage/file/sieve-file-storage.c index c6fa4773a..90fc18e48 100644 --- a/src/lib-sieve/storage/file/sieve-file-storage.c +++ b/src/lib-sieve/storage/file/sieve-file-storage.c @@ -643,9 +643,29 @@ sieve_file_storage_do_autodetect( event = storage->event; fstorage = container_of(storage, struct sieve_file_storage, storage); - if (storage_path != NULL && *storage_path != '\0') { + /* Determine what we have found so far */ + bool tried_active = FALSE; + while (!tried_active) { + if (storage_path == NULL || *storage_path == '\0') { + storage_path = active_path; + if (storage_path == NULL || *storage_path == '\0') + storage_path = SIEVE_FILE_DEFAULT_ACTIVE_PATH; + tried_active = TRUE; + } + e_debug(event, "Checking storage path %s", storage_path); + + /* Get full storage path */ + if (sieve_file_storage_get_full_path(fstorage, + &storage_path) < 0) { + *error_code_r = storage->error_code; + *error_r = t_strdup(storage->error); + sieve_storage_unref(&storage); + return -1; + } + /* Got something: stat it */ - if (sieve_file_storage_stat(fstorage, storage_path) < 0) { + ret = sieve_file_storage_stat(fstorage, storage_path); + if (ret < 0) { if (storage->error_code != SIEVE_ERROR_NOT_FOUND) { /* Error */ *error_code_r = storage->error_code; @@ -653,31 +673,46 @@ sieve_file_storage_do_autodetect( sieve_storage_unref(&storage); return -1; } - } else if (S_ISDIR(fstorage->st.st_mode)) { - /* Success */ - exists = TRUE; + if ((storage->flags & + SIEVE_STORAGE_FLAG_READWRITE) != 0) + break; } + if (ret == 0) + break; + storage_path = NULL; } - if (active_path == NULL || *active_path == '\0') { - if (storage->main_storage || - (storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0) { - e_debug(event, - "Active script path is unconfigured; " - "using default (path=%s)", - SIEVE_FILE_DEFAULT_ACTIVE_PATH); - active_path = SIEVE_FILE_DEFAULT_ACTIVE_PATH; - } else { - *error_code_r = storage->error_code; - *error_r = t_strdup(storage->error); + if (storage_path == NULL || *storage_path == '\0') { + sieve_storage_unref(&storage); + return 0; + } + + if (storage->error_code != SIEVE_ERROR_NONE) { + /* Not found */ + } else if (S_ISDIR(fstorage->st.st_mode)) { + if (tried_active) { + e_error(event, + "Active script path '%s' is a directory", + storage_path); + sieve_error_create_internal(error_code_r, error_r); sieve_storage_unref(&storage); return -1; } - } - if (!exists && active_path != NULL && *active_path != '\0' && - (storage->flags & SIEVE_STORAGE_FLAG_READWRITE) == 0) + /* Success */ + exists = TRUE; + } else if ((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) == 0) { + exists = TRUE; + active_path = storage_path; storage_path = NULL; + } + + if (active_path == NULL || *active_path == '\0') { + e_debug(event, "Active script path is unconfigured; " + "using default (path=%s)", + SIEVE_FILE_DEFAULT_ACTIVE_PATH); + active_path = SIEVE_FILE_DEFAULT_ACTIVE_PATH; + } if (sieve_file_storage_init_common(fstorage, active_path, storage_path, exists) < 0) { -- GitLab