From 79d351aeb072fcc29ef230115efc9569e421e0ac Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Tue, 22 Jul 2008 20:14:45 +0200 Subject: [PATCH] Made utility functions for neatly handing system errors, warnings and notices. --- TODO | 1 - .../plugins/include/ext-include-binary.c | 6 +- src/lib-sieve/sieve-binary.c | 56 ++++++------- src/lib-sieve/sieve-error.c | 25 +++--- src/lib-sieve/sieve-error.h | 80 ++++++++++++++----- src/lib-sieve/sieve-extensions.c | 3 +- src/lib-sieve/sieve-script.c | 4 +- src/plugins/lda-sieve/lda-sieve-plugin.c | 16 ++-- 8 files changed, 114 insertions(+), 77 deletions(-) diff --git a/TODO b/TODO index f8e7a7e4d..88606a22c 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,4 @@ Next (in order of descending priority/precedence): -* Make utility functions for handling sieve system errors. * Review sieve-address parsing implementation for past-end checks * Improve handling of old/corrupt binaries. diff --git a/src/lib-sieve/plugins/include/ext-include-binary.c b/src/lib-sieve/plugins/include/ext-include-binary.c index c651dd9c6..51d933a84 100644 --- a/src/lib-sieve/plugins/include/ext-include-binary.c +++ b/src/lib-sieve/plugins/include/ext-include-binary.c @@ -177,7 +177,7 @@ static bool ext_include_binary_open(struct sieve_binary *sbin) offset = 0; if ( !sieve_binary_read_integer(sbin, &offset, &depcount) ) { - i_error("sieve: include: failed to read include count " + sieve_sys_error("include: failed to read include count " "for dependency block %d of binary %s", block, sieve_binary_path(sbin)); return FALSE; } @@ -197,14 +197,14 @@ static bool ext_include_binary_open(struct sieve_binary *sbin) !sieve_binary_read_byte(sbin, &offset, &location) || !sieve_binary_read_string(sbin, &offset, &script_name) ) { /* Binary is corrupt, recompile */ - i_error("sieve: include: failed to read included script " + sieve_sys_error("include: failed to read included script " "from dependency block %d of binary %s", block, sieve_binary_path(sbin)); return FALSE; } if ( location >= EXT_INCLUDE_LOCATION_INVALID ) { /* Binary is corrupt, recompile */ - i_error("sieve: include: dependency block %d of binary %s " + sieve_sys_error("include: dependency block %d of binary %s " "reports invalid script location (id %d).", block, sieve_binary_path(sbin), location); return FALSE; diff --git a/src/lib-sieve/sieve-binary.c b/src/lib-sieve/sieve-binary.c index 03f5c7991..336ec9b7c 100644 --- a/src/lib-sieve/sieve-binary.c +++ b/src/lib-sieve/sieve-binary.c @@ -508,7 +508,7 @@ static bool _save_block_index_record header.offset = block->offset; if ( !_save_full(stream, &header, sizeof(header)) ) { - i_error("sieve: failed to save block index header %d: %m", id); + sieve_sys_error("failed to save block index header %d: %m", id); return FALSE; } @@ -545,7 +545,7 @@ static bool _sieve_binary_save header.blocks = blk_count; if ( !_save_aligned(stream, &header, sizeof(header), NULL) ) { - i_error("sieve: failed to save binary header: %m"); + sieve_sys_error("failed to save binary header: %m"); return FALSE; } @@ -605,7 +605,7 @@ bool sieve_binary_save temp_path = t_strconcat(path, ".tmp", NULL); fd = open(temp_path, O_CREAT | O_TRUNC | O_WRONLY, 0600); if ( fd < 0 ) { - i_error("sieve: open(%s) failed for binary save: %m", temp_path); + sieve_sys_error("open(%s) failed for binary save: %m", temp_path); return FALSE; } @@ -614,11 +614,11 @@ bool sieve_binary_save o_stream_destroy(&stream); if (close(fd) < 0) - i_error("sieve: close(fd) failed for binary save: %m"); + sieve_sys_error("close(fd) failed for binary save: %m"); /* Replace any original binary atomically */ if (result && (rename(temp_path, path) < 0)) { - i_error("sieve: rename(%s, %s) failed for binary save: %m", + sieve_sys_error("rename(%s, %s) failed for binary save: %m", temp_path, path); result = FALSE; } @@ -643,14 +643,14 @@ static bool sieve_binary_file_open if ( (fd=open(path, O_RDONLY)) < 0 ) { if ( errno != ENOENT ) { - i_error("sieve: binary open(%s) failed: %m", path); + sieve_sys_error("binary open(%s) failed: %m", path); } return FALSE; } if ( fstat(fd, &st) < 0 ) { if ( errno != ENOENT ) { - i_error("sieve: binary stat(%s) failed: %m", path); + sieve_sys_error("binary stat(%s) failed: %m", path); } return FALSE; } @@ -665,8 +665,7 @@ static void sieve_binary_file_close(struct sieve_binary_file **file) { if ( (*file)->fd != -1 ) { if ( close((*file)->fd) < 0 ) { - sieve_system_error( - "sieve: binary close(fd) failed: %m"); + sieve_sys_error("binary close(fd) failed: %m"); } } @@ -744,14 +743,14 @@ static bool _file_memory_load(struct sieve_binary_file *file) /* Return to beginning of the file */ if ( lseek(file->fd, 0, SEEK_SET) == (off_t) -1 ) { - i_error("sieve: failed to seek() in binary %s: %m", file->path); + sieve_sys_error("failed to seek() in binary %s: %m", file->path); return FALSE; } /* Read the whole file into memory */ while (size > 0) { if ( (ret=read(file->fd, indata, size)) <= 0 ) { - i_error("sieve: failed to read from binary %s: %m", file->path); + sieve_sys_error("failed to read from binary %s: %m", file->path); break; } @@ -788,7 +787,7 @@ static struct sieve_binary_file *_file_memory_open(const char *path) return &file->binfile; } -#endif /* file_lazy is currently unused */ +#endif /* file_memory is currently unused */ /* File open in lazy mode (only read what is needed into memory) */ @@ -804,7 +803,7 @@ static bool _file_lazy_read /* Seek to the correct position */ if ( *offset != file->offset && lseek(file->fd, *offset, SEEK_SET) == (off_t) -1 ) { - i_error("sieve: failed to seek(fd, %lld, SEEK_SET) in binary %s: %m", + sieve_sys_error("failed to seek(fd, %lld, SEEK_SET) in binary %s: %m", (long long) *offset, file->path); return FALSE; } @@ -813,10 +812,10 @@ static bool _file_lazy_read while (insize > 0) { if ( (ret=read(file->fd, indata, insize)) <= 0 ) { if ( ret == 0 ) - i_error("sieve: binary %s is truncated (more data expected)", + sieve_sys_error("binary %s is truncated (more data expected)", file->path); else - i_error("sieve: failed to read from binary %s: %m", file->path); + sieve_sys_error("failed to read from binary %s: %m", file->path); break; } @@ -895,12 +894,12 @@ static struct sieve_binary_block *_load_block struct sieve_binary_block *block; if ( header == NULL ) { - i_error("sieve: block %d of loaded binary %s is truncated", id, sbin->path); + sieve_sys_error("block %d of loaded binary %s is truncated", id, sbin->path); return NULL; } if ( header->id != id ) { - i_error("sieve: block %d of loaded binary %s has unexpected id %d", id, + sieve_sys_error("block %d of loaded binary %s has unexpected id %d", id, sbin->path, header->id); return NULL; } @@ -908,14 +907,14 @@ static struct sieve_binary_block *_load_block block = sieve_binary_block_get(sbin, id); if ( block == NULL ) { - i_error("sieve: !!BUG!!: block %d missing in index (impossible) " + sieve_sys_error("!!BUG!!: block %d missing in index (impossible) " "of binary %s", id, sbin->path); return NULL; } block->buffer = sbin->file->load_buffer(sbin->file, offset, header->size); if ( block->buffer == NULL ) { - i_error("sieve: block %d of loaded binary %s has invalid size %d", + sieve_sys_error("block %d of loaded binary %s has invalid size %d", id, sbin->path, header->size); return NULL; } @@ -946,13 +945,13 @@ static bool _load_block_index_record struct sieve_binary_block *block; if ( record == NULL ) { - i_error("sieve: failed to read index record for block %d in binary %s", + sieve_sys_error("failed to read index record for block %d in binary %s", id, sbin->path); return FALSE; } if ( record->id != id ) { - i_error("sieve: block index record %d of loaded binary %s " + sieve_sys_error("block index record %d of loaded binary %s " "has unexpected id %d", id, sbin->path, record->id); return FALSE; } @@ -986,7 +985,7 @@ static bool _sieve_binary_load_extensions(struct sieve_binary *sbin) ext_id = sieve_extension_get_by_name(str_c(extension), NULL); if ( ext_id < 0 ) { - i_error("sieve: loaded binary %s requires unknown extension '%s'", + sieve_sys_error("loaded binary %s requires unknown extension '%s'", sbin->path, str_c(extension)); result = FALSE; } else { @@ -1017,12 +1016,12 @@ static bool _sieve_binary_open(struct sieve_binary *sbin) T_BEGIN { header = LOAD_HEADER(sbin, &offset, const struct sieve_binary_header); if ( header == NULL ) { - i_error("sieve: opened binary %s is not even large enough " + sieve_sys_error("opened binary %s is not even large enough " "to contain a header.", sbin->path); result = FALSE; } else if ( header->magic != SIEVE_BINARY_MAGIC ) { if ( header->magic != SIEVE_BINARY_MAGIC_OTHER_ENDIAN ) - i_error("sieve: opened binary %s has corrupted header (0x%08x)", + sieve_sys_error("opened binary %s has corrupted header (0x%08x)", sbin->path, header->magic); result = FALSE; } else if ( result && ( @@ -1031,7 +1030,7 @@ static bool _sieve_binary_open(struct sieve_binary *sbin) /* Binary is of different version. Caller will have to recompile */ result = FALSE; } else if ( result && header->blocks == 0 ) { - i_error("sieve: opened binary %s contains no blocks", sbin->path); + sieve_sys_error("opened binary %s contains no blocks", sbin->path); result = FALSE; } else { blk_count = header->blocks; @@ -1045,7 +1044,8 @@ static bool _sieve_binary_open(struct sieve_binary *sbin) for ( i = 0; i < blk_count && result; i++ ) { T_BEGIN { if ( !_load_block_index_record(sbin, &offset, i) ) { - i_error("sieve: block index record %d of opened binary %s is corrupt", + sieve_sys_error( + "block index record %d of opened binary %s is corrupt", i, sbin->path); result = FALSE; } @@ -1061,7 +1061,7 @@ static bool _sieve_binary_open(struct sieve_binary *sbin) if ( extensions == NULL ) { result = FALSE; } else if ( !_sieve_binary_load_extensions(sbin) ) { - i_error("sieve: extension block of opened binary %s is corrupt", + sieve_sys_error("extension block of opened binary %s is corrupt", sbin->path); result = FALSE; } @@ -1091,7 +1091,7 @@ static bool _sieve_binary_load(struct sieve_binary *sbin) for ( i = 1; result && i < blk_count; i++ ) { T_BEGIN { if ( _load_block(sbin, &offset, i) == NULL ) { - i_error("sieve: block %d of loaded binary %s is corrupt", + sieve_sys_error("block %d of loaded binary %s is corrupt", i, sbin->path); result = FALSE; } diff --git a/src/lib-sieve/sieve-error.c b/src/lib-sieve/sieve-error.c index eb88d8b5a..88f002670 100644 --- a/src/lib-sieve/sieve-error.c +++ b/src/lib-sieve/sieve-error.c @@ -37,9 +37,9 @@ void sieve_verror if ( ehandler->log_master ) { if ( location == NULL || *location == '\0' ) - i_error("sieve: %s", t_strdup_vprintf(fmt, args)); + sieve_sys_verror(fmt, args); else - i_error("sieve: %s: %s", location, t_strdup_vprintf(fmt, args)); + sieve_sys_error("%s: %s", t_strdup_vprintf(fmt, args)); } if ( sieve_errors_more_allowed(ehandler) ) { @@ -56,9 +56,9 @@ void sieve_vwarning if ( ehandler->log_master ) { if ( location == NULL || *location == '\0' ) - i_warning("sieve: %s", t_strdup_vprintf(fmt, args)); + sieve_sys_vwarning(fmt, args); else - i_warning("sieve: %s: %s", location, t_strdup_vprintf(fmt, args)); + sieve_sys_warning("sieve: %s: %s", location, t_strdup_vprintf(fmt, args)); } ehandler->vwarning(ehandler, location, fmt, args); @@ -73,9 +73,9 @@ void sieve_vinfo if ( ehandler->log_master ) { if ( location == NULL || *location == '\0' ) - i_info("sieve: %s", t_strdup_vprintf(fmt, args)); + sieve_sys_vinfo(fmt, args); else - i_info("sieve: %s: %s", location, t_strdup_vprintf(fmt, args)); + sieve_sys_info("%s: %s", location, t_strdup_vprintf(fmt, args)); } if ( ehandler->log_info ) @@ -92,9 +92,9 @@ void sieve_vcritical tm = localtime(&ioloop_time); if ( location == NULL || *location == '\0' ) - i_error("sieve: %s", t_strdup_vprintf(fmt, args)); + sieve_sys_verror(fmt, args); else - i_error("sieve: %s: %s", location, t_strdup_vprintf(fmt, args)); + sieve_sys_error("%s: %s", location, t_strdup_vprintf(fmt, args)); if ( ehandler == NULL ) return; @@ -341,7 +341,7 @@ static void sieve_logfile_start(struct sieve_logfile_ehandler *ehandler) fd = open(ehandler->logfile, O_CREAT | O_APPEND | O_WRONLY, 0600); if (fd == -1) { - i_error("sieve: Failed to open logfile %s (logging to STDERR): %m", + sieve_sys_error("failed to open logfile %s (logging to STDERR): %m", ehandler->logfile); fd = STDERR_FILENO; } @@ -351,9 +351,8 @@ static void sieve_logfile_start(struct sieve_logfile_ehandler *ehandler) ostream = o_stream_create_fd(fd, 0, FALSE); if ( ostream == NULL ) { /* Can't we do anything else in this most awkward situation? */ - i_error("sieve: Failed to open log stream on open file %s. " - "Nothing will be logged.", - ehandler->logfile); + sieve_sys_error("failed to open log stream on open file %s: " + "normal messages will not be logged!", ehandler->logfile); } ehandler->fd = fd; @@ -418,7 +417,7 @@ static void sieve_logfile_free o_stream_destroy(&(handler->stream)); if ( handler->fd != STDERR_FILENO ){ if ( close(handler->fd) < 0 ) { - i_error("sieve_logfile_free: close(fd) failed for logfile '%s': %m", + sieve_sys_error("close(fd) failed for logfile '%s': %m", handler->logfile); } } diff --git a/src/lib-sieve/sieve-error.h b/src/lib-sieve/sieve-error.h index 888fe1606..ab2743a96 100644 --- a/src/lib-sieve/sieve-error.h +++ b/src/lib-sieve/sieve-error.h @@ -9,10 +9,65 @@ struct sieve_script; struct sieve_error_handler; +/* + * Types + */ + typedef void (*sieve_error_vfunc_t) (struct sieve_error_handler *ehandler, const char *location, const char *fmt, va_list args); +/* + * System errors + * + * FIXME: Low-level access to the Dovecot logging functions would be nice. + */ + +static inline void sieve_sys_verror(const char *fmt, va_list args) +{ + i_error("sieve: %s", t_strdup_vprintf(fmt, args)); +} + +static inline void sieve_sys_vwarning(const char *fmt, va_list args) +{ + i_warning("sieve: %s", t_strdup_vprintf(fmt, args)); +} + +static inline void sieve_sys_vinfo(const char *fmt, va_list args) +{ + i_info("sieve: %s", t_strdup_vprintf(fmt, args)); +} + +static inline void sieve_sys_error(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + + T_BEGIN { sieve_sys_verror(fmt, args); } T_END; + + va_end(args); +} + +static inline void sieve_sys_warning(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + + T_BEGIN { sieve_sys_vwarning(fmt, args); } T_END; + + va_end(args); +} + +static inline void sieve_sys_info(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + + T_BEGIN { sieve_sys_vinfo(fmt, args); } T_END; + + va_end(args); +} + /* For these functions it is the responsibility of the caller to * manage the datastack. */ @@ -53,9 +108,7 @@ inline static void sieve_error va_list args; va_start(args, fmt); - T_BEGIN { - sieve_verror(ehandler, location, fmt, args); - } T_END; + T_BEGIN { sieve_verror(ehandler, location, fmt, args); } T_END; va_end(args); } @@ -67,9 +120,7 @@ inline static void sieve_warning va_list args; va_start(args, fmt); - T_BEGIN { - sieve_vwarning(ehandler, location, fmt, args); - } T_END; + T_BEGIN { sieve_vwarning(ehandler, location, fmt, args); } T_END; va_end(args); } @@ -81,9 +132,7 @@ inline static void sieve_info va_list args; va_start(args, fmt); - T_BEGIN { - sieve_vinfo(ehandler, location, fmt, args); - } T_END; + T_BEGIN { sieve_vinfo(ehandler, location, fmt, args); } T_END; va_end(args); } @@ -95,9 +144,7 @@ inline static void sieve_critical va_list args; va_start(args, fmt); - T_BEGIN { - sieve_vcritical(ehandler, location, fmt, args); - } T_END; + T_BEGIN { sieve_vcritical(ehandler, location, fmt, args); } T_END; va_end(args); } @@ -115,15 +162,6 @@ bool sieve_errors_more_allowed(struct sieve_error_handler *ehandler); void sieve_error_handler_ref(struct sieve_error_handler *ehandler); void sieve_error_handler_unref(struct sieve_error_handler **ehandler); -/* - * System errors - * These are just macros for now - */ - -#define sieve_system_error(...) i_error(__VA_ARGS__) -#define sieve_system_warning(...) i_warning(__VA_ARGS__) -#define sieve_system_info(...) i_info(__VA_ARGS__) - /* * Error handlers */ diff --git a/src/lib-sieve/sieve-extensions.c b/src/lib-sieve/sieve-extensions.c index f86b6e67e..bbb694481 100644 --- a/src/lib-sieve/sieve-extensions.c +++ b/src/lib-sieve/sieve-extensions.c @@ -4,6 +4,7 @@ #include "hash.h" #include "array.h" +#include "sieve-error.h" #include "sieve-extensions-private.h" /* Static pre-declarations */ @@ -139,7 +140,7 @@ int sieve_extension_register(const struct sieve_extension *extension) hash_insert(extension_index, (void *) extension->name, (void *) ereg); if ( extension->load != NULL && !extension->load(ext_id) ) { - i_error("sieve: failed to load '%s' extension support.", extension->name); + sieve_sys_error("failed to load '%s' extension support.", extension->name); return -1; } diff --git a/src/lib-sieve/sieve-script.c b/src/lib-sieve/sieve-script.c index 49ea0a827..777163024 100644 --- a/src/lib-sieve/sieve-script.c +++ b/src/lib-sieve/sieve-script.c @@ -189,8 +189,8 @@ struct istream *sieve_script_open if ( result == NULL ) { /* Something went wrong, close the fd */ if ( close(fd) != 0 ) { - sieve_system_error( - "sieve_script_open: close(fd) failed for sieve script %s: %m", + sieve_sys_error( + "close(fd) failed for sieve script %s: %m", script->path); } } diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c index f735ed82a..6b8be27f4 100644 --- a/src/plugins/lda-sieve/lda-sieve-plugin.c +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c @@ -43,7 +43,7 @@ static const char *lda_sieve_get_path(void) } } else { if (home == NULL) { - i_error("Per-user script path is unknown. See " + sieve_sys_error("per-user script path is unknown. See " "http://wiki.dovecot.org/LDA/Sieve#location"); return NULL; } @@ -53,7 +53,7 @@ static const char *lda_sieve_get_path(void) if (stat(script_path, &st) < 0) { if (errno != ENOENT) - i_error("stat(%s) failed: %m", script_path); + sieve_sys_error("stat(%s) failed: %m", script_path); /* use global script instead, if one exists */ script_path = getenv("SIEVE_GLOBAL_PATH"); @@ -98,11 +98,11 @@ static int lda_sieve_run /* Open the script */ if ( debug ) - i_info("sieve: Opening script %s", script_path); + sieve_sys_info("opening script %s", script_path); if ( (sbin=sieve_open(script_path, ehandler)) == NULL ) { - i_error("sieve: Failed to open script %s. " - "Log should be available as %s", script_path, scriptlog); + sieve_sys_error("failed to open script %s; " + "log should be available as %s", script_path, scriptlog); sieve_error_handler_unref(&ehandler); return -1; @@ -136,12 +136,12 @@ static int lda_sieve_run /* Execute the script */ if ( debug ) - i_info("sieve: Executing (in-memory) script %s", script_path); + sieve_sys_info("executing (in-memory) script %s", script_path); ret = sieve_execute(sbin, &msgdata, &scriptenv, ehandler, NULL); if ( ret < 0 ) - i_error("sieve: Failed to execute script %s", script_path); + sieve_sys_error("failed to execute script %s", script_path); /* Clean up */ sieve_close(&sbin); @@ -164,7 +164,7 @@ static int lda_sieve_deliver_mail return 0; if (getenv("DEBUG") != NULL) - i_info("sieve: Using sieve path: %s", script_path); + sieve_sys_info("using sieve path: %s", script_path); /* Run the script */ -- GitLab