diff --git a/src/lib-sieve/sieve-binary-file.c b/src/lib-sieve/sieve-binary-file.c index 54e65c0a115bbbfda78b266a47964a60a59d80fe..aa1fabf33f2dec1b8d8037fe0e946d7b42581579 100644 --- a/src/lib-sieve/sieve-binary-file.c +++ b/src/lib-sieve/sieve-binary-file.c @@ -68,12 +68,9 @@ sieve_binary_file_read_header(struct sieve_binary *sbin, int fd, enum sieve_error *error_code_r) { struct sieve_binary_header header; - enum sieve_error error_code; ssize_t rret; - if (error_code_r == NULL) - error_code_r = &error_code; - *error_code_r = SIEVE_ERROR_NONE; + sieve_error_args_init(&error_code_r, NULL); rret = pread(fd, &header, sizeof(header), 0); if (rret == 0) { @@ -158,15 +155,13 @@ sieve_binary_file_write_header(struct sieve_binary *sbin, int fd, if (wret < 0) { e_error(sbin->event, "update: " "failed to write to binary: %m"); - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; + *error_code_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } else if (wret != sizeof(*header)) { e_error(sbin->event, "update: " "header written partially %zd/%zu", wret, sizeof(*header)); - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; + *error_code_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } return 0; @@ -417,8 +412,7 @@ sieve_binary_do_save(struct sieve_binary *sbin, const char *path, bool update, struct sieve_binary_extension_reg *const *regs; unsigned int ext_count, i; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; + sieve_error_args_init(&error_code_r, NULL); /* Check whether saving is necessary */ if (!update && sbin->path != NULL && strcmp(sbin->path, path) == 0) { @@ -438,14 +432,12 @@ sieve_binary_do_save(struct sieve_binary *sbin, const char *path, bool update, "failed to create temporary file: %s", eacces_error_get_creating("open", str_c(temp_path))); - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NO_PERMISSION; + *error_code_r = SIEVE_ERROR_NO_PERMISSION; } else { e_error(sbin->event, "save: " "failed to create temporary file: " "open(%s) failed: %m", str_c(temp_path)); - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; + *error_code_r = SIEVE_ERROR_TEMP_FAILURE; } return -1; } @@ -457,8 +449,10 @@ sieve_binary_do_save(struct sieve_binary *sbin, const char *path, bool update, if (binext != NULL && binext->binary_pre_save != NULL && !binext->binary_pre_save(regs[i]->extension, sbin, - regs[i]->context, error_code_r)) + regs[i]->context, error_code_r)) { + i_assert(*error_code_r != SIEVE_ERROR_NONE); return -1; + } } /* Save binary */ @@ -466,8 +460,7 @@ sieve_binary_do_save(struct sieve_binary *sbin, const char *path, bool update, stream = o_stream_create_fd(fd, 0); if (!sieve_binary_save_to_stream(sbin, stream)) { result = -1; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; + *error_code_r = SIEVE_ERROR_TEMP_FAILURE; o_stream_ignore_last_errors(stream); } o_stream_destroy(&stream); @@ -485,15 +478,13 @@ sieve_binary_do_save(struct sieve_binary *sbin, const char *path, bool update, e_error(sbin->event, "save: " "failed to save binary: %s", eacces_error_get_creating("rename", path)); - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NO_PERMISSION; + *error_code_r = SIEVE_ERROR_NO_PERMISSION; } else { e_error(sbin->event, "save: " "failed to save binary: " "rename(%s, %s) failed: %m", str_c(temp_path), path); - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; + *error_code_r = SIEVE_ERROR_TEMP_FAILURE; } result = -1; } @@ -521,6 +512,7 @@ sieve_binary_do_save(struct sieve_binary *sbin, const char *path, bool update, !binext->binary_post_save(regs[i]->extension, sbin, regs[i]->context, error_code_r)) { + i_assert(*error_code_r != SIEVE_ERROR_NONE); result = -1; break; } @@ -558,28 +550,22 @@ sieve_binary_fd_open(struct sieve_binary *sbin, const char *path, { int fd; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; - fd = open(path, open_flags); if (fd < 0) { switch (errno) { case ENOENT: - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NOT_FOUND; + *error_code_r = SIEVE_ERROR_NOT_FOUND; break; case EACCES: e_error(sbin->event, "open: " "failed to open: %s", eacces_error_get("open", path)); - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NO_PERMISSION; + *error_code_r = SIEVE_ERROR_NO_PERMISSION; break; default: e_error(sbin->event, "open: " "failed to open: open(%s) failed: %m", path); - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_TEMP_FAILURE; + *error_code_r = SIEVE_ERROR_TEMP_FAILURE; break; } return -1; @@ -595,23 +581,27 @@ sieve_binary_file_open(struct sieve_binary *sbin, const char *path, int fd, ret = 0; struct stat st; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; + sieve_error_args_init(&error_code_r, NULL); fd = sieve_binary_fd_open(sbin, path, O_RDONLY, error_code_r); if (fd < 0) return -1; if (fstat(fd, &st) < 0) { - if (errno != ENOENT) + if (errno == ENOENT) + *error_code_r = SIEVE_ERROR_NOT_FOUND; + else { e_error(sbin->event, "open: fstat(%s) failed: %m", path); + *error_code_r = SIEVE_ERROR_TEMP_FAILURE; + } ret = -1; } if (ret == 0 && !S_ISREG(st.st_mode)) { e_error(sbin->event, "open: " "binary is not a regular file"); + *error_code_r = SIEVE_ERROR_TEMP_FAILURE; ret = -1; } @@ -881,8 +871,7 @@ _sieve_binary_open(struct sieve_binary *sbin, enum sieve_error *error_code_r) } if (!result) { - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NOT_VALID; + *error_code_r = SIEVE_ERROR_NOT_VALID; return FALSE; } @@ -903,8 +892,7 @@ _sieve_binary_open(struct sieve_binary *sbin, enum sieve_error *error_code_r) } T_END; if (!result) { - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NOT_VALID; + *error_code_r = SIEVE_ERROR_NOT_VALID; return FALSE; } return TRUE; @@ -921,6 +909,7 @@ int sieve_binary_open(struct sieve_instance *svinst, const char *path, i_assert(script == NULL || sieve_script_svinst(script) == svinst); *sbin_r = NULL; + sieve_error_args_init(&error_code_r, NULL); /* Create binary object */ sbin = sieve_binary_create(svinst, script); @@ -953,8 +942,7 @@ int sieve_binary_open(struct sieve_instance *svinst, const char *path, !binext->binary_open(regs[i]->extension, sbin, regs[i]->context)) { /* Extension thinks its corrupt */ - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NOT_VALID; + *error_code_r = SIEVE_ERROR_NOT_VALID; sieve_binary_unref(&sbin); return -1; } @@ -968,9 +956,8 @@ int sieve_binary_check_executable(struct sieve_binary *sbin, enum sieve_error *error_code_r, const char **client_error_r) { - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; *client_error_r = NULL; + sieve_error_args_init(&error_code_r, NULL); if (HAS_ALL_BITS(sbin->header.flags, SIEVE_BINARY_FLAG_RESOURCE_LIMIT)) { @@ -978,8 +965,7 @@ int sieve_binary_check_executable(struct sieve_binary *sbin, "Binary execution is blocked: " "Cumulative resource usage limit exceeded " "(resource limit flag is set)"); - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_RESOURCE_LIMIT; + *error_code_r = SIEVE_ERROR_RESOURCE_LIMIT; *client_error_r = "cumulative resource usage limit exceeded"; return 0; } @@ -1025,12 +1011,9 @@ sieve_binary_file_do_update_resource_usage( int sieve_binary_file_update_resource_usage(struct sieve_binary *sbin, enum sieve_error *error_code_r) { - enum sieve_error error_code; int fd, ret = 0; - if (error_code_r == NULL) - error_code_r = &error_code; - *error_code_r = SIEVE_ERROR_NONE; + sieve_error_args_init(&error_code_r, NULL); sieve_binary_file_close(&sbin->file); @@ -1042,11 +1025,14 @@ int sieve_binary_file_update_resource_usage(struct sieve_binary *sbin, } fd = sieve_binary_fd_open(sbin, sbin->path, O_RDWR, error_code_r); - if (fd < 0) + if (fd < 0) { + i_assert(*error_code_r != SIEVE_ERROR_NONE); return -1; + } ret = sieve_binary_file_do_update_resource_usage(sbin, fd, error_code_r); + i_assert(ret == 0 || *error_code_r != SIEVE_ERROR_NONE); if (close(fd) < 0) { e_error(sbin->event, "update: " diff --git a/src/lib-sieve/sieve-common.h b/src/lib-sieve/sieve-common.h index 53ccffbd1e4bf9d3cfe2ceac73f136eb9e8af48e..cedd0b6a2e01d938a1c1210a2d6b5409cddf9f20 100644 --- a/src/lib-sieve/sieve-common.h +++ b/src/lib-sieve/sieve-common.h @@ -210,6 +210,9 @@ struct sieve_instance { * Errors */ +void sieve_error_args_init(enum sieve_error **error_code_r, + const char ***error_r); + void sieve_error_create_internal(enum sieve_error *error_code_r, const char **error_r); diff --git a/src/lib-sieve/sieve-script.c b/src/lib-sieve/sieve-script.c index f60042f62e746a2e7bf9248765fb550854b7d365..b15c197accda730757d2ae5254981f35bb72c10b 100644 --- a/src/lib-sieve/sieve-script.c +++ b/src/lib-sieve/sieve-script.c @@ -118,14 +118,10 @@ int sieve_script_create(struct sieve_instance *svinst, enum sieve_error *error_code_r) { struct sieve_storage *storage; - enum sieve_error error_code; int ret; *script_r = NULL; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; - else - error_code_r = &error_code; + sieve_error_args_init(&error_code_r, NULL); if (sieve_storage_create(svinst, location, 0, &storage, error_code_r) < 0) @@ -172,13 +168,11 @@ void sieve_script_unref(struct sieve_script **_script) int sieve_script_open(struct sieve_script *script, enum sieve_error *error_code_r) { - enum sieve_error error_code; + struct sieve_storage *storage = script->storage; int ret; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; - else - error_code_r = &error_code; + sieve_error_args_init(&error_code_r, NULL); + sieve_storage_clear_error(storage); if (script->open) return 0; @@ -238,10 +232,6 @@ int sieve_script_check(struct sieve_instance *svinst, const char *location, const char *name, enum sieve_error *error_code_r) { struct sieve_script *script; - enum sieve_error error_code; - - if (error_code_r == NULL) - error_code_r = &error_code; if (sieve_script_create_open(svinst, location, name, &script, error_code_r) < 0) @@ -314,13 +304,10 @@ int sieve_script_get_stream(struct sieve_script *script, enum sieve_error *error_code_r) { struct sieve_storage *storage = script->storage; - enum sieve_error error_code; int ret; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; - else - error_code_r = &error_code; + sieve_error_args_init(&error_code_r, NULL); + sieve_storage_clear_error(storage); if (script->stream != NULL) { *stream_r = script->stream; @@ -520,14 +507,12 @@ int sieve_script_binary_load(struct sieve_script *script, struct sieve_binary **sbin_r, enum sieve_error *error_code_r) { - enum sieve_error error_code; + struct sieve_storage *storage = script->storage; int ret; *sbin_r = NULL; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; - else - error_code_r = &error_code; + sieve_error_args_init(&error_code_r, NULL); + sieve_storage_clear_error(storage); if (script->v.binary_load == NULL) { *error_code_r = SIEVE_ERROR_NOT_POSSIBLE; @@ -544,13 +529,11 @@ int sieve_script_binary_save(struct sieve_script *script, struct sieve_binary *sbin, bool update, enum sieve_error *error_code_r) { + struct sieve_storage *storage = script->storage; struct sieve_script *bin_script = sieve_binary_script(sbin); - enum sieve_error error_code; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; - else - error_code_r = &error_code; + sieve_error_args_init(&error_code_r, NULL); + sieve_storage_clear_error(storage); i_assert(bin_script == NULL || sieve_script_equals(bin_script, script)); @@ -633,6 +616,7 @@ int sieve_script_rename(struct sieve_script *script, const char *newname) int ret; i_assert(newname != NULL); + sieve_storage_clear_error(storage); /* Check script name */ if (!sieve_script_name_is_valid(newname)) { @@ -692,6 +676,7 @@ int sieve_script_delete(struct sieve_script *script, bool ignore_active) int ret = 0; i_assert(script->open); // FIXME: auto-open? + sieve_storage_clear_error(storage); /* Is the requested script active? */ if (sieve_script_is_active(script) > 0) { @@ -745,6 +730,8 @@ int sieve_script_is_active(struct sieve_script *script) { struct sieve_storage *storage = script->storage; + sieve_storage_clear_error(storage); + /* Special handling if this is a default script */ if (storage->default_storage_for != NULL) { int ret = sieve_storage_active_script_is_default( @@ -767,6 +754,7 @@ int sieve_script_activate(struct sieve_script *script, time_t mtime) int ret = 0; i_assert(script->open); // FIXME: auto-open? + sieve_storage_clear_error(storage); if (storage->default_storage_for == NULL) { i_assert((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0); @@ -882,14 +870,10 @@ int sieve_script_sequence_create(struct sieve_instance *svinst, { struct sieve_storage *storage; struct sieve_script_sequence *sseq; - enum sieve_error error_code; int ret; *sseq_r = NULL; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; - else - error_code_r = &error_code; + sieve_error_args_init(&error_code_r, NULL); if (sieve_storage_create(svinst, location, 0, &storage, error_code_r) < 0) @@ -910,13 +894,10 @@ int sieve_script_sequence_next(struct sieve_script_sequence *sseq, enum sieve_error *error_code_r) { struct sieve_storage *storage = sseq->storage; - enum sieve_error error_code; *script_r = NULL; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; - else - error_code_r = &error_code; + sieve_error_args_init(&error_code_r, NULL); + sieve_storage_clear_error(storage); i_assert(storage->v.script_sequence_next != NULL); return storage->v.script_sequence_next(sseq, script_r, error_code_r); diff --git a/src/lib-sieve/sieve-storage.c b/src/lib-sieve/sieve-storage.c index c8be0c32bcf089b411da8f98ecc4e725f207102e..b40a221eb8898f67884148347c745832cf1f423c 100644 --- a/src/lib-sieve/sieve-storage.c +++ b/src/lib-sieve/sieve-storage.c @@ -325,15 +325,8 @@ sieve_storage_init(struct sieve_instance *svinst, const char *const *options; const char *location; struct event *storage_event, *event; - enum sieve_error error_code; int ret; - *storage_r = NULL; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; - else - error_code_r = &error_code; - i_assert(storage_class->v.init != NULL); storage_event = sieve_storage_create_event(svinst, svinst->event); @@ -392,7 +385,6 @@ int sieve_storage_create(struct sieve_instance *svinst, const char *location, enum sieve_error *error_code_r) { const struct sieve_storage *storage_class; - enum sieve_error error_code; const char *data; int ret; @@ -400,10 +392,7 @@ int sieve_storage_create(struct sieve_instance *svinst, const char *location, i_assert((flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) == 0); *storage_r = NULL; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; - else - error_code_r = &error_code; + sieve_error_args_init(&error_code_r, NULL); data = location; if ((ret = sieve_storage_driver_parse(svinst, &data, @@ -512,14 +501,10 @@ int sieve_storage_create_personal(struct sieve_instance *svinst, { struct sieve_storage *storage = NULL; const char *set_default, *set_default_name; - enum sieve_error error_code; int ret; *storage_r = NULL; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; - else - error_code_r = &error_code; + sieve_error_args_init(&error_code_r, NULL); /* Check whether Sieve is disabled for this user */ if (!svinst->set->enabled) { @@ -718,27 +703,20 @@ sieve_storage_get_script_direct(struct sieve_storage *storage, const char *name, { int ret; - *script_r = NULL; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; - sieve_storage_clear_error(storage); - /* Validate script name */ if (name != NULL && !sieve_script_name_is_valid(name)) { sieve_storage_set_error(storage, SIEVE_ERROR_BAD_PARAMS, "Invalid script name '%s'.", str_sanitize(name, 80)); - if (error_code_r != NULL) - *error_code_r = storage->error_code; + *error_code_r = storage->error_code; return -1; } i_assert(storage->v.get_script != NULL); ret = storage->v.get_script(storage, name, script_r); i_assert(ret <= 0); - if (error_code_r != NULL) - *error_code_r = storage->error_code; + *error_code_r = storage->error_code; return ret; } @@ -749,6 +727,8 @@ int sieve_storage_get_script(struct sieve_storage *storage, const char *name, struct sieve_instance *svinst = storage->svinst; *script_r = NULL; + sieve_error_args_init(&error_code_r, NULL); + sieve_storage_clear_error(storage); if (sieve_storage_get_script_direct(storage, name, script_r, error_code_r) == 0) @@ -792,6 +772,8 @@ int sieve_storage_open_script(struct sieve_storage *storage, const char *name, struct sieve_script *script; *script_r = NULL; + sieve_error_args_init(&error_code_r, NULL); + sieve_storage_clear_error(storage); if (sieve_storage_get_script(storage, name, &script, error_code_r) < 0) return -1; @@ -838,11 +820,10 @@ sieve_storage_check_script_direct(struct sieve_storage *storage, enum sieve_error *error_code_r) { struct sieve_script *script; - enum sieve_error error_code; int ret; - if (error_code_r == NULL) - error_code_r = &error_code; + sieve_error_args_init(&error_code_r, NULL); + sieve_storage_clear_error(storage); if (sieve_storage_get_script_direct(storage, name, &script, error_code_r) < 0) @@ -858,10 +839,9 @@ int sieve_storage_check_script(struct sieve_storage *storage, const char *name, enum sieve_error *error_code_r) { struct sieve_script *script; - enum sieve_error error_code; - if (error_code_r == NULL) - error_code_r = &error_code; + sieve_error_args_init(&error_code_r, NULL); + sieve_storage_clear_error(storage); if (sieve_storage_open_script(storage, name, &script, error_code_r) < 0) return (*error_code_r == SIEVE_ERROR_NOT_FOUND ? 0 : -1); @@ -931,14 +911,10 @@ int sieve_storage_active_script_open(struct sieve_storage *storage, { struct sieve_instance *svinst = storage->svinst; struct sieve_script *script = NULL; - enum sieve_error error_code; int ret; *script_r = NULL; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; - else - error_code_r = &error_code; + sieve_error_args_init(&error_code_r, NULL); sieve_storage_clear_error(storage); i_assert(storage->v.active_script_open != NULL); @@ -948,7 +924,7 @@ int sieve_storage_active_script_open(struct sieve_storage *storage, if (ret == 0 || (storage->flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) != 0 || storage->default_location == NULL) { - if (ret < 0 && error_code_r != NULL) + if (ret < 0) *error_code_r = storage->error_code; *script_r = script; return ret; @@ -973,6 +949,8 @@ int sieve_storage_deactivate(struct sieve_storage *storage, time_t mtime) i_assert((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0); + sieve_storage_clear_error(storage); + i_assert(storage->v.deactivate != NULL); ret = storage->v.deactivate(storage); @@ -1014,6 +992,7 @@ int sieve_storage_list_init(struct sieve_storage *storage, struct sieve_storage_list_context *lctx; *lctx_r = NULL; + sieve_storage_clear_error(storage); i_assert(storage->v.list_init != NULL); if (storage->v.list_init(storage, &lctx) < 0) @@ -1037,6 +1016,8 @@ sieve_storage_list_next(struct sieve_storage_list_context *lctx, bool *active_r) (storage->flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) == 0); + sieve_storage_clear_error(storage); + i_assert(storage->v.list_next != NULL); scriptname = storage->v.list_next(lctx, &script_active); @@ -1137,6 +1118,8 @@ sieve_storage_save_init(struct sieve_storage *storage, const char *scriptname, { struct sieve_storage_save_context *sctx; + sieve_storage_clear_error(storage); + if (scriptname != NULL) { /* Validate script name */ if (!sieve_script_name_is_valid(scriptname)) { @@ -1186,6 +1169,8 @@ int sieve_storage_save_continue(struct sieve_storage_save_context *sctx) struct sieve_storage *storage = sctx->storage; int ret; + sieve_storage_clear_error(storage); + i_assert(storage->v.save_continue != NULL); ret = storage->v.save_continue(sctx); if (ret < 0) @@ -1198,6 +1183,8 @@ int sieve_storage_save_finish(struct sieve_storage_save_context *sctx) struct sieve_storage *storage = sctx->storage; int ret; + sieve_storage_clear_error(storage); + i_assert(!sctx->finished); sctx->finished = TRUE; @@ -1233,6 +1220,8 @@ sieve_storage_save_get_tempscript(struct sieve_storage_save_context *sctx) if (sctx->scriptobject != NULL) return sctx->scriptobject; + sieve_storage_clear_error(storage); + i_assert(storage->v.save_get_tempscript != NULL); sctx->scriptobject = storage->v.save_get_tempscript(sctx); @@ -1243,9 +1232,13 @@ sieve_storage_save_get_tempscript(struct sieve_storage_save_context *sctx) bool sieve_storage_save_will_activate(struct sieve_storage_save_context *sctx) { + struct sieve_storage *storage = sctx->storage; + if (sctx->scriptname == NULL) return FALSE; + sieve_storage_clear_error(storage); + if (sctx->active_scriptname == NULL) { const char *scriptname; @@ -1275,6 +1268,7 @@ int sieve_storage_save_commit(struct sieve_storage_save_context **_sctx) storage = sctx->storage; scriptname = sctx->scriptname; + sieve_storage_clear_error(storage); i_assert(!sctx->failed); i_assert(sctx->finished); @@ -1378,6 +1372,8 @@ int sieve_storage_save_as_active(struct sieve_storage *storage, struct event *event; int ret; + sieve_storage_clear_error(storage); + event = event_create(storage->event); event_set_append_log_prefix(event, "active script: save: "); @@ -1413,6 +1409,8 @@ int sieve_storage_save_as(struct sieve_storage *storage, struct istream *input, struct event *event; int ret; + sieve_storage_clear_error(storage); + event = sieve_storage_save_create_event(storage, name); struct event_passthrough *e = diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c index fd74d1929efeb6da0ca1dabeefcbf44a31dbf24a..2f7eb79e77ca3da8150bc062fba3f216faf3ed10 100644 --- a/src/lib-sieve/sieve.c +++ b/src/lib-sieve/sieve.c @@ -209,6 +209,8 @@ sieve_parse(struct sieve_script *script, struct sieve_error_handler *ehandler, struct sieve_parser *parser; struct sieve_ast *ast = NULL; + sieve_error_args_init(&error_code_r, NULL); + /* Parse */ parser = sieve_parser_create(script, ehandler, error_code_r); if (parser == NULL) @@ -221,12 +223,8 @@ sieve_parse(struct sieve_script *script, struct sieve_error_handler *ehandler, sieve_parser_free(&parser); - if (error_code_r != NULL) { - if (ast == NULL) - *error_code_r = SIEVE_ERROR_NOT_VALID; - else - *error_code_r = SIEVE_ERROR_NONE; - } + if (ast == NULL) + *error_code_r = SIEVE_ERROR_NOT_VALID; return ast; } @@ -235,20 +233,18 @@ bool sieve_validate(struct sieve_ast *ast, struct sieve_error_handler *ehandler, enum sieve_error *error_code_r) { bool result = TRUE; - struct sieve_validator *validator = - sieve_validator_create(ast, ehandler, flags); + struct sieve_validator *validator; + sieve_error_args_init(&error_code_r, NULL); + + validator = sieve_validator_create(ast, ehandler, flags); if (!sieve_validator_run(validator)) result = FALSE; sieve_validator_free(&validator); - if (error_code_r != NULL) { - if (!result) - *error_code_r = SIEVE_ERROR_NOT_VALID; - else - *error_code_r = SIEVE_ERROR_NONE; - } + if (!result) + *error_code_r = SIEVE_ERROR_NOT_VALID; return result; } @@ -256,20 +252,18 @@ static struct sieve_binary * sieve_generate(struct sieve_ast *ast, struct sieve_error_handler *ehandler, enum sieve_compile_flags flags, enum sieve_error *error_code_r) { - struct sieve_generator *generator = - sieve_generator_create(ast, ehandler, flags); + struct sieve_generator *generator; struct sieve_binary *sbin = NULL; + sieve_error_args_init(&error_code_r, NULL); + + generator = sieve_generator_create(ast, ehandler, flags); sbin = sieve_generator_run(generator, NULL); sieve_generator_free(&generator); - if (error_code_r != NULL) { - if (sbin == NULL) - *error_code_r = SIEVE_ERROR_NOT_VALID; - else - *error_code_r = SIEVE_ERROR_NONE; - } + if (sbin == NULL) + *error_code_r = SIEVE_ERROR_NOT_VALID; return sbin; } @@ -285,20 +279,17 @@ int sieve_compile_script(struct sieve_script *script, { struct sieve_ast *ast; struct sieve_binary *sbin; - enum sieve_error error_code; + bool no_error_result = (error_code_r == NULL); *sbin_r = NULL; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; - else - error_code_r = &error_code; + sieve_error_args_init(&error_code_r, NULL); /* Parse */ ast = sieve_parse(script, ehandler, error_code_r); if (ast == NULL) { switch (*error_code_r) { case SIEVE_ERROR_NOT_FOUND: - if (error_code_r == NULL) { + if (no_error_result) { sieve_error(ehandler, sieve_script_name(script), "script not found"); } @@ -340,19 +331,19 @@ int sieve_compile(struct sieve_instance *svinst, const char *script_location, enum sieve_error *error_code_r) { struct sieve_script *script; - enum sieve_error error_code; + bool no_error_result = (error_code_r == NULL); *sbin_r = NULL; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; - else - error_code_r = &error_code; + sieve_error_args_init(&error_code_r, NULL); if (sieve_script_create_open(svinst, script_location, script_name, &script, error_code_r) < 0) { switch (*error_code_r) { case SIEVE_ERROR_NOT_FOUND: - sieve_error(ehandler, script_name, "script not found"); + if (no_error_result) { + sieve_error(ehandler, script_name, + "script not found"); + } break; default: sieve_internal_error(ehandler, script_name, @@ -464,6 +455,7 @@ sieve_open_script_real(struct sieve_script *script, if (ret <= 0) { const char *path = sieve_binary_path(sbin); + i_assert(error != NULL); if (path != NULL) { e_debug(svinst->event, "Script binary %s cannot be executed", @@ -495,14 +487,10 @@ int sieve_open_script(struct sieve_script *script, struct sieve_binary **sbin_r, enum sieve_error *error_code_r) { - enum sieve_error error_code; int ret; *sbin_r = NULL; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; - else - error_code_r = &error_code; + sieve_error_args_init(&error_code_r, NULL); T_BEGIN { ret = sieve_open_script_real(script, ehandler, flags, @@ -518,14 +506,11 @@ int sieve_open(struct sieve_instance *svinst, const char *script_location, enum sieve_error *error_code_r) { struct sieve_script *script; - enum sieve_error error_code; + bool no_error_result = (error_code_r == NULL); int ret; *sbin_r = NULL; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; - else - error_code_r = &error_code; + sieve_error_args_init(&error_code_r, NULL); /* First open the scriptfile itself */ if (sieve_script_create_open(svinst, script_location, script_name, @@ -533,7 +518,10 @@ int sieve_open(struct sieve_instance *svinst, const char *script_location, /* Failed */ switch (*error_code_r) { case SIEVE_ERROR_NOT_FOUND: - sieve_error(ehandler, script_name, "script not found"); + if (no_error_result) { + sieve_error(ehandler, script_name, + "script not found"); + } break; default: sieve_internal_error(ehandler, script_name, @@ -1019,6 +1007,25 @@ size_t sieve_max_script_size(struct sieve_instance *svinst) "Internal error occurred. Refer to server log for more information." #define CRITICAL_MSG_STAMP CRITICAL_MSG " [%Y-%m-%d %H:%M:%S]" +void sieve_error_args_init(enum sieve_error **error_code_r, + const char ***error_r) +{ + /* Dummies */ + static enum sieve_error dummy_error_code = SIEVE_ERROR_NONE; + static const char *dummy_error = NULL; + + if (error_code_r != NULL) { + if (*error_code_r == NULL) + *error_code_r = &dummy_error_code; + **error_code_r = SIEVE_ERROR_NONE; + } + if (error_r != NULL) { + if (*error_r == NULL) + *error_r = &dummy_error; + **error_r = NULL; + } +} + void sieve_error_create_internal(enum sieve_error *error_code_r, const char **error_r) { diff --git a/src/lib-sieve/storage/file/sieve-file-storage-active.c b/src/lib-sieve/storage/file/sieve-file-storage-active.c index bcc7456e1260ea82aa69847f415b3821adca36df..9893c35e8cbb0e20d3a7172d6ec29494e8f1aadf 100644 --- a/src/lib-sieve/storage/file/sieve-file-storage-active.c +++ b/src/lib-sieve/storage/file/sieve-file-storage-active.c @@ -243,6 +243,7 @@ int sieve_file_storage_active_script_open(struct sieve_storage *storage, int ret; *script_r = NULL; + sieve_storage_clear_error(storage); /* Read the active link */ ret = sieve_file_storage_active_read_link(fstorage, &link); diff --git a/src/lib-sieve/storage/file/sieve-file-storage.c b/src/lib-sieve/storage/file/sieve-file-storage.c index cb48f1e9ad614c914c8890f87f533a56bd107630..72a0562f4e7554ff37d542211365ae88b2e09138 100644 --- a/src/lib-sieve/storage/file/sieve-file-storage.c +++ b/src/lib-sieve/storage/file/sieve-file-storage.c @@ -721,16 +721,12 @@ int sieve_file_storage_init_from_path(struct sieve_instance *svinst, { struct sieve_storage *storage; struct sieve_file_storage *fstorage; - enum sieve_error error_code; int ret; i_assert(path != NULL); *fstorage_r = NULL; - if (error_code_r != NULL) - *error_code_r = SIEVE_ERROR_NONE; - else - error_code_r = &error_code; + sieve_error_args_init(&error_code_r, NULL); ret = sieve_storage_alloc(svinst, NULL, &sieve_file_storage, "", flags, FALSE, &storage);