From e8c6d5243a95b4c2429e46b9e4c0dabb56a91009 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan.bosch@open-xchange.com> Date: Thu, 19 Sep 2024 01:04:59 +0200 Subject: [PATCH] lib-sieve: sieve-script - Split basic storage sequence object from script sequence It just returns the one storage that the provided location points to for now. --- src/lib-sieve/sieve-script-private.h | 1 + src/lib-sieve/sieve-script.c | 88 ++++++++++++++++++++------- src/lib-sieve/sieve-storage-private.h | 11 ++++ src/lib-sieve/sieve-storage.c | 51 ++++++++++++++++ src/lib-sieve/sieve-storage.h | 15 +++++ 5 files changed, 145 insertions(+), 21 deletions(-) diff --git a/src/lib-sieve/sieve-script-private.h b/src/lib-sieve/sieve-script-private.h index 475465f13..059233f11 100644 --- a/src/lib-sieve/sieve-script-private.h +++ b/src/lib-sieve/sieve-script-private.h @@ -108,6 +108,7 @@ void sieve_script_set_not_found_error(struct sieve_script *script, */ struct sieve_script_sequence { + struct sieve_storage_sequence *storage_seq; struct sieve_storage *storage; void *storage_data; }; diff --git a/src/lib-sieve/sieve-script.c b/src/lib-sieve/sieve-script.c index 7871763e8..48881c0c5 100644 --- a/src/lib-sieve/sieve-script.c +++ b/src/lib-sieve/sieve-script.c @@ -950,42 +950,92 @@ int sieve_script_sequence_create(struct sieve_instance *svinst, struct sieve_script_sequence **sseq_r, enum sieve_error *error_code_r) { - struct sieve_storage *storage; + struct sieve_storage_sequence *storage_seq; struct sieve_script_sequence *sseq; - int ret; *sseq_r = NULL; sieve_error_args_init(&error_code_r, NULL); - if (sieve_storage_create(svinst, location, 0, - &storage, error_code_r) < 0) + if (sieve_storage_sequence_create(svinst, location, + &storage_seq, error_code_r) < 0) return -1; sseq = i_new(struct sieve_script_sequence, 1); - sseq->storage = storage; - - i_assert(storage->v.script_sequence_init != NULL); - ret = storage->v.script_sequence_init(sseq); - *error_code_r = storage->error_code; + sseq->storage_seq = storage_seq; *sseq_r = sseq; - return ret; + return 0; +} + +static int +sieve_script_sequence_init_storage(struct sieve_script_sequence *sseq, + enum sieve_error *error_code_r) +{ + int ret; + + while (sseq->storage == NULL) { + ret = sieve_storage_sequence_next(sseq->storage_seq, + &sseq->storage, error_code_r); + if (ret == 0) + return 0; + if (ret < 0) { + if (*error_code_r == SIEVE_ERROR_NOT_FOUND) + continue; + return -1; + } + + struct sieve_storage *storage = sseq->storage; + + i_assert(storage->v.script_sequence_init != NULL); + *error_code_r = SIEVE_ERROR_NONE; + ret = storage->v.script_sequence_init(sseq); + *error_code_r = storage->error_code; + sieve_storage_unref(&sseq->storage); + if (ret < 0 && *error_code_r != SIEVE_ERROR_NOT_FOUND) + return -1; + } + return 1; +} + +static void +sieve_script_sequence_deinit_storage(struct sieve_script_sequence *sseq) +{ + struct sieve_storage *storage = sseq->storage; + + if (storage != NULL && storage->v.script_sequence_destroy != NULL) + storage->v.script_sequence_destroy(sseq); + sseq->storage_data = NULL; + + sieve_storage_unref(&sseq->storage); } int sieve_script_sequence_next(struct sieve_script_sequence *sseq, struct sieve_script **script_r, enum sieve_error *error_code_r) { - struct sieve_storage *storage = sseq->storage; int ret; *script_r = NULL; sieve_error_args_init(&error_code_r, NULL); - sieve_storage_clear_error(storage); - i_assert(storage->v.script_sequence_next != NULL); - ret = storage->v.script_sequence_next(sseq, script_r); - *error_code_r = storage->error_code; + while ((ret = sieve_script_sequence_init_storage(sseq, error_code_r)) > 0) { + struct sieve_storage *storage = sseq->storage; + + i_assert(storage->v.script_sequence_next != NULL); + sieve_storage_clear_error(storage); + ret = storage->v.script_sequence_next(sseq, script_r); + *error_code_r = storage->error_code; + if (ret > 0) + break; + + if (ret < 0 && *error_code_r == SIEVE_ERROR_NOT_FOUND) + ret = 0; + + sieve_script_sequence_deinit_storage(sseq); + if (ret < 0) + break; + } + return ret; } @@ -997,11 +1047,7 @@ void sieve_script_sequence_free(struct sieve_script_sequence **_sseq) return; *_sseq = NULL; - struct sieve_storage *storage = sseq->storage; - - if (storage->v.script_sequence_destroy != NULL) - storage->v.script_sequence_destroy(sseq); - - sieve_storage_unref(&storage); + sieve_script_sequence_deinit_storage(sseq); + sieve_storage_sequence_free(&sseq->storage_seq); i_free(sseq); } diff --git a/src/lib-sieve/sieve-storage-private.h b/src/lib-sieve/sieve-storage-private.h index 695b0f9bd..70f5fc88d 100644 --- a/src/lib-sieve/sieve-storage-private.h +++ b/src/lib-sieve/sieve-storage-private.h @@ -163,6 +163,17 @@ struct sieve_storage_save_context { bool finished:1; }; +/* + * Storage sequence + */ + +struct sieve_storage_sequence { + struct sieve_instance *svinst; + char *location; + + bool done:1; +}; + /* * Storage class */ diff --git a/src/lib-sieve/sieve-storage.c b/src/lib-sieve/sieve-storage.c index dee0b127c..42ef4862a 100644 --- a/src/lib-sieve/sieve-storage.c +++ b/src/lib-sieve/sieve-storage.c @@ -1622,3 +1622,54 @@ sieve_storage_get_last_error(struct sieve_storage *storage, return storage->error != NULL ? storage->error : "Unknown error"; } + +/* + * Storage sequence + */ + +int sieve_storage_sequence_create(struct sieve_instance *svinst, + const char *location, + struct sieve_storage_sequence **sseq_r, + enum sieve_error *error_code_r) +{ + *sseq_r = NULL; + sieve_error_args_init(&error_code_r, NULL); + + struct sieve_storage_sequence *sseq; + + sseq = i_new(struct sieve_storage_sequence, 1); + sseq->svinst = svinst; + sseq->location = i_strdup(location); + + *sseq_r = sseq; + return 0; +} + +int sieve_storage_sequence_next(struct sieve_storage_sequence *sseq, + struct sieve_storage **storage_r, + enum sieve_error *error_code_r) +{ + *storage_r = NULL; + sieve_error_args_init(&error_code_r, NULL); + + if (sseq->done) + return 0; + sseq->done = TRUE; + + if (sieve_storage_create(sseq->svinst, sseq->location, 0, + storage_r, error_code_r) < 0) + return -1; + return 1; +} + +void sieve_storage_sequence_free(struct sieve_storage_sequence **_sseq) +{ + struct sieve_storage_sequence *sseq = *_sseq; + + if (sseq == NULL) + return; + *_sseq = NULL; + + i_free(sseq->location); + i_free(sseq); +} diff --git a/src/lib-sieve/sieve-storage.h b/src/lib-sieve/sieve-storage.h index 5264dd1b7..61bae1373 100644 --- a/src/lib-sieve/sieve-storage.h +++ b/src/lib-sieve/sieve-storage.h @@ -180,4 +180,19 @@ int sieve_storage_get_last_change(struct sieve_storage *storage, void sieve_storage_set_modified(struct sieve_storage *storage, time_t mtime); +/* + * Storage sequence + */ + +struct sieve_storage_sequence; + +int sieve_storage_sequence_create(struct sieve_instance *svinst, + const char *location, + struct sieve_storage_sequence **sseq_r, + enum sieve_error *error_code_r); +int sieve_storage_sequence_next(struct sieve_storage_sequence *sseq, + struct sieve_storage **storage_r, + enum sieve_error *error_code_r); +void sieve_storage_sequence_free(struct sieve_storage_sequence **_sseq); + #endif -- GitLab