From 7e18cd0bd19e1767a9f4651b7c00ab19085bfb79 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Thu, 11 Oct 2012 20:26:03 +0200 Subject: [PATCH] lib-sieve: Further improved handling of quota errors. Added means to log user errors/warnings as info in master log. Previous change was inadequate because an error was still logged. --- src/lib-sieve/sieve-actions.c | 12 ++-- src/lib-sieve/sieve-error-private.h | 3 +- src/lib-sieve/sieve-error.c | 76 +++++++++++++++++++++--- src/lib-sieve/sieve-error.h | 17 ++++++ src/lib-sieve/sieve-result.c | 21 ++++++- src/lib-sieve/sieve-result.h | 6 ++ src/plugins/lda-sieve/lda-sieve-plugin.c | 18 +++++- 7 files changed, 135 insertions(+), 18 deletions(-) diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c index cfa443591..f90bf36ab 100644 --- a/src/lib-sieve/sieve-actions.c +++ b/src/lib-sieve/sieve-actions.c @@ -604,13 +604,15 @@ static void act_store_log_status (mailbox_get_storage(trans->box), &error_code); } - if ( error_code != MAIL_ERROR_NOTFOUND && error_code != MAIL_ERROR_PARAMS && - error_code != MAIL_ERROR_NOSPACE) - { - sieve_result_global_error(aenv, "failed to store into mailbox %s: %s", + if ( error_code == MAIL_ERROR_NOTFOUND || + error_code == MAIL_ERROR_PARAMS ) { + sieve_result_error(aenv, "failed to store into mailbox %s: %s", mailbox_name, errstr); + } else if ( error_code == MAIL_ERROR_NOSPACE ) { + sieve_result_global_log_error + (aenv, "failed to store into mailbox %s: %s", mailbox_name, errstr); } else { - sieve_result_error(aenv, "failed to store into mailbox %s: %s", + sieve_result_global_error(aenv, "failed to store into mailbox %s: %s", mailbox_name, errstr); } diff --git a/src/lib-sieve/sieve-error-private.h b/src/lib-sieve/sieve-error-private.h index 7a30cbcae..50d03a732 100644 --- a/src/lib-sieve/sieve-error-private.h +++ b/src/lib-sieve/sieve-error-private.h @@ -11,7 +11,8 @@ */ enum sieve_error_flags { - SIEVE_ERROR_FLAG_GLOBAL = (1 << 0) + SIEVE_ERROR_FLAG_GLOBAL = (1 << 0), + SIEVE_ERROR_FLAG_GLOBAL_MAX_INFO = (1 << 1), }; /* diff --git a/src/lib-sieve/sieve-error.c b/src/lib-sieve/sieve-error.c index b14bef8d7..30c2a2f57 100644 --- a/src/lib-sieve/sieve-error.c +++ b/src/lib-sieve/sieve-error.c @@ -84,11 +84,17 @@ void sieve_direct_verror VA_COPY(args_copy, args); - svinst->system_ehandler->verror - (svinst->system_ehandler, 0, location, fmt, args_copy); + if ( (flags & SIEVE_ERROR_FLAG_GLOBAL_MAX_INFO) != 0 ) { + svinst->system_ehandler->vinfo + (svinst->system_ehandler, 0, location, fmt, args_copy); + } else { + svinst->system_ehandler->verror + (svinst->system_ehandler, 0, location, fmt, args_copy); + } } - if ( ehandler == NULL ) return; + if ( ehandler == NULL ) + return; if ( ehandler->parent != NULL || sieve_errors_more_allowed(ehandler) ) { if ( ehandler->verror != NULL ) @@ -111,11 +117,17 @@ void sieve_direct_vwarning VA_COPY(args_copy, args); - svinst->system_ehandler->vwarning - (svinst->system_ehandler, 0, location, fmt, args_copy); + if ( (flags & SIEVE_ERROR_FLAG_GLOBAL_MAX_INFO) != 0 ) { + svinst->system_ehandler->vinfo + (svinst->system_ehandler, 0, location, fmt, args_copy); + } else { + svinst->system_ehandler->vwarning + (svinst->system_ehandler, 0, location, fmt, args_copy); + } } - if ( ehandler == NULL ) return; + if ( ehandler == NULL ) + return; if ( ehandler->vwarning != NULL ) ehandler->vwarning(ehandler, flags, location, fmt, args); @@ -140,7 +152,8 @@ void sieve_direct_vinfo (svinst->system_ehandler, 0, location, fmt, args_copy); } - if ( ehandler == NULL ) return; + if ( ehandler == NULL ) + return; if ( ehandler->parent != NULL || ehandler->log_info ) { if ( ehandler->vinfo != NULL ) @@ -164,7 +177,8 @@ void sieve_direct_vdebug (svinst->system_ehandler, 0, location, fmt, args_copy); } - if ( ehandler == NULL ) return; + if ( ehandler == NULL ) + return; if ( ehandler->parent != NULL || ehandler->log_debug ) { if ( ehandler->vdebug != NULL ) @@ -300,6 +314,24 @@ void sieve_global_vinfo (svinst, ehandler, SIEVE_ERROR_FLAG_GLOBAL, location, fmt, args); } +void sieve_global_info_verror +(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, + const char *location, const char *fmt, va_list args) +{ + sieve_direct_verror(svinst, ehandler, + (SIEVE_ERROR_FLAG_GLOBAL | SIEVE_ERROR_FLAG_GLOBAL_MAX_INFO), + location, fmt, args); +} + +void sieve_global_info_vwarning +(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, + const char *location, const char *fmt, va_list args) +{ + sieve_direct_vwarning(svinst, ehandler, + (SIEVE_ERROR_FLAG_GLOBAL | SIEVE_ERROR_FLAG_GLOBAL_MAX_INFO), + location, fmt, args); +} + void sieve_global_error (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const char *location, const char *fmt, ...) @@ -342,6 +374,34 @@ void sieve_global_info va_end(args); } +void sieve_global_info_error +(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, + const char *location, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + + T_BEGIN { + sieve_global_info_verror(svinst, ehandler, location, fmt, args); + } T_END; + + va_end(args); +} + +void sieve_global_info_warning +(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, + const char *location, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + + T_BEGIN { + sieve_global_info_vwarning(svinst, ehandler, location, fmt, args); + } T_END; + + va_end(args); +} + /* * Default (user) error functions */ diff --git a/src/lib-sieve/sieve-error.h b/src/lib-sieve/sieve-error.h index cafd9347c..3fc36dc8d 100644 --- a/src/lib-sieve/sieve-error.h +++ b/src/lib-sieve/sieve-error.h @@ -30,6 +30,11 @@ typedef void (*sieve_error_func_t) (struct sieve_error_handler *ehandler, const char *location, const char *fmt, ...) ATTR_FORMAT(3, 4); +typedef void (*sieve_sys_error_vfunc_t) + (struct sieve_instance *svinst, const char *fmt, va_list args); +typedef void (*sieve_sys_error_func_t) + (struct sieve_instance *svinst, const char *fmt, ...) ATTR_FORMAT(2, 3); + /* * System errors */ @@ -70,6 +75,12 @@ void sieve_global_vwarning void sieve_global_vinfo (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const char *location, const char *fmt, va_list args); +void sieve_global_info_verror + (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, + const char *location, const char *fmt, va_list args); +void sieve_global_info_vwarning + (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, + const char *location, const char *fmt, va_list args); void sieve_global_error (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, @@ -80,6 +91,12 @@ void sieve_global_warning void sieve_global_info (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const char *location, const char *fmt, ...) ATTR_FORMAT(4, 5); +void sieve_global_info_error + (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, + const char *location, const char *fmt, ...) ATTR_FORMAT(4, 5); +void sieve_global_info_warning + (struct sieve_instance *svinst, struct sieve_error_handler *ehandler, + const char *location, const char *fmt, ...) ATTR_FORMAT(4, 5); /* * Main (user) error functions diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c index b3ca760fd..2f9fc9241 100644 --- a/src/lib-sieve/sieve-result.c +++ b/src/lib-sieve/sieve-result.c @@ -272,7 +272,6 @@ void sieve_result_global_warning va_end(args); } - void sieve_result_log (const struct sieve_action_exec_env *aenv, const char *fmt, ...) { @@ -293,6 +292,26 @@ void sieve_result_global_log va_end(args); } +void sieve_result_global_log_error +(const struct sieve_action_exec_env *aenv, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + sieve_global_info_verror(aenv->svinst, aenv->ehandler, NULL, fmt, args); + va_end(args); +} + +void sieve_result_global_log_warning +(const struct sieve_action_exec_env *aenv, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + sieve_global_info_vwarning(aenv->svinst, aenv->ehandler, NULL, fmt, args); + va_end(args); +} + /* * Result composition */ diff --git a/src/lib-sieve/sieve-result.h b/src/lib-sieve/sieve-result.h index 0533f5da3..04ceaa126 100644 --- a/src/lib-sieve/sieve-result.h +++ b/src/lib-sieve/sieve-result.h @@ -103,6 +103,12 @@ void sieve_result_log (const struct sieve_action_exec_env *aenv, const char *fmt, ...) ATTR_FORMAT(2, 3); void sieve_result_global_log +(const struct sieve_action_exec_env *aenv, const char *fmt, ...) + ATTR_FORMAT(2, 3); +void sieve_result_global_log_error +(const struct sieve_action_exec_env *aenv, const char *fmt, ...) + ATTR_FORMAT(2, 3); +void sieve_result_global_log_warning (const struct sieve_action_exec_env *aenv, const char *fmt, ...) ATTR_FORMAT(2, 3); diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c index 128e125d9..a2ebc7a8e 100644 --- a/src/plugins/lda-sieve/lda-sieve-plugin.c +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c @@ -353,17 +353,29 @@ static int lda_sieve_handle_exec_status (struct lda_sieve_run_context *srctx, struct sieve_script *script, int status) { struct sieve_instance *svinst = srctx->svinst; + struct sieve_exec_status *estatus = srctx->scriptenv->exec_status; const char *userlog_notice = ""; + sieve_sys_error_func_t error_func = sieve_sys_error; int ret; + if ( estatus != NULL && estatus->last_storage != NULL ) { + enum mail_error mail_error; + + mail_storage_get_last_error(estatus->last_storage, &mail_error); + + /* Don't bother administrator too much with benign errors */ + if ( mail_error == MAIL_ERROR_NOSPACE ) + error_func = sieve_sys_info; + } + if ( script == srctx->user_script && srctx->userlog != NULL ) { userlog_notice = t_strdup_printf - (" (user logfile %s may reveal additional details)", srctx->userlog); + (" (user logfile %s should reveal additional details)", srctx->userlog); } switch ( status ) { case SIEVE_EXEC_FAILURE: - sieve_sys_error(svinst, + error_func(svinst, "execution of script %s failed, but implicit keep was successful%s", sieve_script_location(script), userlog_notice); ret = 1; @@ -376,7 +388,7 @@ static int lda_sieve_handle_exec_status ret = -1; break; case SIEVE_EXEC_KEEP_FAILED: - sieve_sys_error(svinst, + error_func(svinst, "script %s failed with unsuccessful implicit keep%s", sieve_script_location(script), userlog_notice); ret = -1; -- GitLab