From 444a7c6cc169e84b15e124bf431ad172e1f00bda Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan.bosch@open-xchange.com> Date: Sun, 29 Sep 2024 05:07:43 +0200 Subject: [PATCH] lib-sieve: sieve-storage - Pass error code from init vfunc through storage object --- src/lib-sieve/sieve-storage-private.h | 3 +- src/lib-sieve/sieve-storage.c | 4 +- .../storage/data/sieve-data-storage.c | 4 +- .../storage/dict/sieve-dict-storage.c | 5 +- .../storage/file/sieve-file-storage.c | 98 ++++++++----------- .../storage/ldap/sieve-ldap-storage.c | 4 +- 6 files changed, 45 insertions(+), 73 deletions(-) diff --git a/src/lib-sieve/sieve-storage-private.h b/src/lib-sieve/sieve-storage-private.h index 70f5fc88d..7dd007355 100644 --- a/src/lib-sieve/sieve-storage-private.h +++ b/src/lib-sieve/sieve-storage-private.h @@ -23,8 +23,7 @@ ARRAY_DEFINE_TYPE(sieve_storage_class, const struct sieve_storage *); struct sieve_storage_vfuncs { struct sieve_storage *(*alloc)(void); void (*destroy)(struct sieve_storage *storage); - int (*init)(struct sieve_storage *storage, const char *const *options, - enum sieve_error *error_code_r); + int (*init)(struct sieve_storage *storage, const char *const *options); int (*get_last_change)(struct sieve_storage *storage, time_t *last_change_r); diff --git a/src/lib-sieve/sieve-storage.c b/src/lib-sieve/sieve-storage.c index f9c964210..c4bde9f01 100644 --- a/src/lib-sieve/sieve-storage.c +++ b/src/lib-sieve/sieve-storage.c @@ -362,12 +362,12 @@ sieve_storage_init_real(struct sieve_instance *svinst, struct event *event, event_add_str(event, "script_location", storage->location); - ret = storage_class->v.init(storage, options, - error_code_r); + ret = storage_class->v.init(storage, options); i_assert(ret <= 0); } } T_END; if (ret < 0) { + *error_code_r = storage->error_code; sieve_storage_unref(&storage); return -1; } diff --git a/src/lib-sieve/storage/data/sieve-data-storage.c b/src/lib-sieve/storage/data/sieve-data-storage.c index 73906c93d..4f645532f 100644 --- a/src/lib-sieve/storage/data/sieve-data-storage.c +++ b/src/lib-sieve/storage/data/sieve-data-storage.c @@ -27,10 +27,8 @@ static struct sieve_storage *sieve_data_storage_alloc(void) static int sieve_data_storage_init(struct sieve_storage *storage ATTR_UNUSED, - const char *const *options ATTR_UNUSED, - enum sieve_error *error_code_r ATTR_UNUSED) + const char *const *options ATTR_UNUSED) { - *error_code_r = SIEVE_ERROR_NONE; return 0; } diff --git a/src/lib-sieve/storage/dict/sieve-dict-storage.c b/src/lib-sieve/storage/dict/sieve-dict-storage.c index d94ebdd5a..a8f48936d 100644 --- a/src/lib-sieve/storage/dict/sieve-dict-storage.c +++ b/src/lib-sieve/storage/dict/sieve-dict-storage.c @@ -28,8 +28,7 @@ static struct sieve_storage *sieve_dict_storage_alloc(void) static int sieve_dict_storage_init(struct sieve_storage *storage, - const char *const *options, - enum sieve_error *error_code_r) + const char *const *options) { struct sieve_dict_storage *dstorage = container_of(storage, struct sieve_dict_storage, storage); @@ -46,7 +45,6 @@ sieve_dict_storage_init(struct sieve_storage *storage, } else { sieve_storage_set_critical( storage, "Invalid option '%s'", option); - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } @@ -58,7 +56,6 @@ sieve_dict_storage_init(struct sieve_storage *storage, sieve_storage_set_critical( storage, "BUG: Sieve interpreter is initialized without a base_dir"); - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } diff --git a/src/lib-sieve/storage/file/sieve-file-storage.c b/src/lib-sieve/storage/file/sieve-file-storage.c index 72a0562f4..51cc7c4d1 100644 --- a/src/lib-sieve/storage/file/sieve-file-storage.c +++ b/src/lib-sieve/storage/file/sieve-file-storage.c @@ -47,8 +47,7 @@ sieve_file_storage_path_extend(struct sieve_file_storage *fstorage, */ static int -sieve_file_storage_stat(struct sieve_file_storage *fstorage, const char *path, - enum sieve_error *error_code_r) +sieve_file_storage_stat(struct sieve_file_storage *fstorage, const char *path) { struct sieve_storage *storage = &fstorage->storage; struct stat st; @@ -69,24 +68,22 @@ sieve_file_storage_stat(struct sieve_file_storage *fstorage, const char *path, sieve_storage_set_critical( storage, "t_abspath(%s) failed: %s", path, error); - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; break; } e_debug(storage->event, "Storage path '%s' not found", abspath); sieve_storage_set_internal_error(storage); // should be overriden - *error_code_r = SIEVE_ERROR_NOT_FOUND; + storage->error_code = SIEVE_ERROR_NOT_FOUND; break; case EACCES: sieve_storage_set_critical( storage, "Failed to stat sieve storage path: %s", eacces_error_get("stat", path)); - *error_code_r = SIEVE_ERROR_NO_PERMISSION; + storage->error_code = SIEVE_ERROR_NO_PERMISSION; break; default: sieve_storage_set_critical( storage, "Failed to stat sieve storage path: " "stat(%s) failed: %m", path); - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; break; } @@ -141,11 +138,13 @@ mkdir_verify(struct sieve_storage *storage, const char *dir, return 0; if (errno == EACCES) { - e_error(storage->event, "mkdir_verify: %s", + sieve_storage_set_critical( + storage, "mkdir_verify: %s", eacces_error_get("stat", dir)); return -1; } else if (errno != ENOENT) { - e_error(storage->event, "mkdir_verify: " + sieve_storage_set_critical( + storage, "mkdir_verify: " "stat(%s) failed: %m", dir); return -1; } @@ -159,15 +158,15 @@ mkdir_verify(struct sieve_storage *storage, const char *dir, case EEXIST: return 0; case ENOENT: - e_error(storage->event, + sieve_storage_set_critical(storage, "Storage was deleted while it was being created"); break; case EACCES: - e_error(storage->event, "%s", + sieve_storage_set_critical(storage, "%s", eacces_error_get_creating("mkdir_parents_chgrp", dir)); break; default: - e_error(storage->event, + sieve_storage_set_critical(storage, "mkdir_parents_chgrp(%s) failed: %m", dir); break; } @@ -184,11 +183,13 @@ static int check_tmp(struct sieve_storage *storage, const char *path) if (errno == ENOENT) return 0; if (errno == EACCES) { - e_error(storage->event, "check_tmp: %s", + sieve_storage_set_critical(storage, + "check_tmp: %s", eacces_error_get("stat", path)); return -1; } - e_error(storage->event, "check_tmp: stat(%s) failed: %m", path); + sieve_storage_set_critical(storage, + "check_tmp: stat(%s) failed: %m", path); return -1; } @@ -220,8 +221,7 @@ static struct sieve_storage *sieve_file_storage_alloc(void) static int sieve_file_storage_get_full_path(struct sieve_file_storage *fstorage, - const char **storage_path, - enum sieve_error *error_code_r) + const char **storage_path) { struct sieve_storage *storage = &fstorage->storage; struct sieve_instance *svinst = storage->svinst; @@ -247,7 +247,6 @@ sieve_file_storage_get_full_path(struct sieve_file_storage *fstorage, storage, "Sieve storage path '%s' is relative to home directory, " "but home directory is not available.", path); - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } } @@ -257,8 +256,7 @@ sieve_file_storage_get_full_path(struct sieve_file_storage *fstorage, static int sieve_file_storage_get_full_active_path(struct sieve_file_storage *fstorage, - const char **active_path, - enum sieve_error *error_code_r) + const char **active_path) { struct sieve_storage *storage = &fstorage->storage; struct sieve_instance *svinst = storage->svinst; @@ -282,7 +280,6 @@ sieve_file_storage_get_full_active_path(struct sieve_file_storage *fstorage, storage, "Sieve storage active script path '%s' is relative to home directory, " "but home directory is not available.", path); - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } } @@ -293,8 +290,7 @@ sieve_file_storage_get_full_active_path(struct sieve_file_storage *fstorage, static int sieve_file_storage_init_common(struct sieve_file_storage *fstorage, const char *active_path, - const char *storage_path, bool exists, - enum sieve_error *error_code_r) + const char *storage_path, bool exists) { struct sieve_storage *storage = &fstorage->storage; const char *tmp_dir, *link_path, *active_fname, *storage_dir, *error; @@ -307,8 +303,7 @@ sieve_file_storage_init_common(struct sieve_file_storage *fstorage, /* Get active script path */ - if (sieve_file_storage_get_full_active_path(fstorage, &active_path, - error_code_r) < 0) + if (sieve_file_storage_get_full_active_path(fstorage, &active_path) < 0) return -1; /* Get the filename for the active script link */ @@ -333,16 +328,14 @@ sieve_file_storage_init_common(struct sieve_file_storage *fstorage, "Path to %sscript must include the filename (path=%s)", (storage_path != NULL ? "active link/" : ""), active_path); - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } if (t_realpath(active_dir, &active_dir, &error) < 0) { if (errno != ENOENT) { - e_error(storage->event, + sieve_storage_set_critical(storage, "Failed to normalize active script directory " "(path=%s): %s", active_dir, error); - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } e_debug(storage->event, @@ -372,7 +365,6 @@ sieve_file_storage_init_common(struct sieve_file_storage *fstorage, if ((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0) { sieve_storage_set_critical(storage, "Storage path cannot be empty for write access"); - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } @@ -440,34 +432,28 @@ sieve_file_storage_init_common(struct sieve_file_storage *fstorage, /* Try to find and clean up tmp dir */ ret = check_tmp(storage, tmp_dir); - if (ret < 0) { - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; + if (ret < 0) return -1; - } /* Auto-create if necessary */ if (ret == 0 && mkdir_verify(storage, tmp_dir, dir_create_mode, file_create_gid, - file_create_gid_origin) < 0) { - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; + file_create_gid_origin) < 0) return -1; - } fstorage->dir_create_mode = dir_create_mode; fstorage->file_create_mode = file_create_mode; fstorage->file_create_gid = file_create_gid; } - if (!exists && sieve_file_storage_stat(fstorage, storage_path, - error_code_r) < 0) + if (!exists && sieve_file_storage_stat(fstorage, storage_path) < 0) return -1; if (have_link) { if (t_realpath(storage_path, &storage_path, &error) < 0) { - e_error(storage->event, + sieve_storage_set_critical(storage, "Failed to normalize storage path (path=%s): %s", storage_path, error); - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } if (active_path != NULL && *active_path != '\0') { @@ -494,8 +480,7 @@ sieve_file_storage_init_common(struct sieve_file_storage *fstorage, static int sieve_file_storage_init(struct sieve_storage *storage, - const char *const *options, - enum sieve_error *error_code_r) + const char *const *options) { struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); @@ -513,7 +498,6 @@ sieve_file_storage_init(struct sieve_storage *storage, } else { sieve_storage_set_critical( storage, "Invalid option '%s'", option); - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } @@ -523,16 +507,14 @@ sieve_file_storage_init(struct sieve_storage *storage, /* Get full storage path */ - if (sieve_file_storage_get_full_path(fstorage, &storage_path, - error_code_r) < 0) + if (sieve_file_storage_get_full_path(fstorage, &storage_path) < 0) return -1; /* Stat storage directory */ if (storage_path != NULL && *storage_path != '\0') { - if (sieve_file_storage_stat(fstorage, storage_path, - error_code_r) < 0) { - if (*error_code_r != SIEVE_ERROR_NOT_FOUND) + if (sieve_file_storage_stat(fstorage, storage_path) < 0) { + if (storage->error_code != SIEVE_ERROR_NOT_FOUND) return -1; if ((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) == 0) { /* For backwards compatibility, recognize when @@ -542,12 +524,10 @@ sieve_file_storage_init(struct sieve_storage *storage, if (active_path == NULL || *active_path == '\0') return -1; if (sieve_file_storage_get_full_active_path( - fstorage, &active_path, - error_code_r) < 0) + fstorage, &active_path) < 0) return -1; - if (sieve_file_storage_stat( - fstorage, active_path, - error_code_r) < 0) + if (sieve_file_storage_stat(fstorage, + active_path) < 0) return -1; if (!S_ISREG(fstorage->lnk_st.st_mode)) return -1; @@ -566,7 +546,6 @@ sieve_file_storage_init(struct sieve_storage *storage, sieve_storage_set_critical(storage, "Sieve storage path '%s' is not a directory, " "but it is to be opened for write access", storage_path); - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } if (active_path != NULL && *active_path != '\0') { @@ -593,8 +572,7 @@ sieve_file_storage_init(struct sieve_storage *storage, } return sieve_file_storage_init_common(fstorage, active_path, - storage_path, exists, - error_code_r); + storage_path, exists); } static void @@ -642,9 +620,8 @@ sieve_file_storage_do_init_default(struct sieve_file_storage *fstorage, if (storage_path != NULL && *storage_path != '\0') { /* Got something: stat it */ - if (sieve_file_storage_stat(fstorage, storage_path, - error_code_r) < 0) { - if (*error_code_r != SIEVE_ERROR_NOT_FOUND) { + if (sieve_file_storage_stat(fstorage, storage_path) < 0) { + if (storage->error_code != SIEVE_ERROR_NOT_FOUND) { /* Error */ return -1; } @@ -659,7 +636,7 @@ sieve_file_storage_do_init_default(struct sieve_file_storage *fstorage, sieve_storage_set_critical(storage, "Could not find storage root directory for write access; " "path was left unconfigured and autodetection failed"); - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; + *error_code_r = storage->error_code; return -1; } @@ -681,8 +658,10 @@ sieve_file_storage_do_init_default(struct sieve_file_storage *fstorage, storage_path = NULL; if (sieve_file_storage_init_common(fstorage, active_path, storage_path, - exists, error_code_r) < 0) + exists) < 0) { + *error_code_r = storage->error_code; return -1; + } return 0; } @@ -735,9 +714,10 @@ int sieve_file_storage_init_from_path(struct sieve_instance *svinst, T_BEGIN { ret = sieve_file_storage_init_common(fstorage, path, NULL, - FALSE, error_code_r); + FALSE); } T_END; if (ret < 0) { + *error_code_r = storage->error_code; sieve_storage_unref(&storage); return -1; } diff --git a/src/lib-sieve/storage/ldap/sieve-ldap-storage.c b/src/lib-sieve/storage/ldap/sieve-ldap-storage.c index a0974002e..8a7e0980c 100644 --- a/src/lib-sieve/storage/ldap/sieve-ldap-storage.c +++ b/src/lib-sieve/storage/ldap/sieve-ldap-storage.c @@ -42,8 +42,7 @@ static struct sieve_storage *sieve_ldap_storage_alloc(void) static int sieve_ldap_storage_init(struct sieve_storage *storage, - const char *const *options, - enum sieve_error *error_code_r) + const char *const *options) { struct sieve_ldap_storage *lstorage = container_of(storage, struct sieve_ldap_storage, storage); @@ -60,7 +59,6 @@ sieve_ldap_storage_init(struct sieve_storage *storage, } else { sieve_storage_set_critical( storage, "Invalid option '%s'", option); - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } -- GitLab