diff --git a/src/lib-sieve-tool/sieve-tool.c b/src/lib-sieve-tool/sieve-tool.c index 35827436bcc171e6130a98de0a3b996c700340c6..80dca2e6c60cb72ac130ed9bb337c83802253268 100644 --- a/src/lib-sieve-tool/sieve-tool.c +++ b/src/lib-sieve-tool/sieve-tool.c @@ -41,7 +41,7 @@ struct sieve_tool { char *username; char *homedir; - + char *sieve_extensions; ARRAY_TYPE(const_string) sieve_plugins; @@ -515,8 +515,8 @@ struct sieve_binary *sieve_tool_script_compile { struct sieve_error_handler *ehandler; struct sieve_binary *sbin; - - ehandler = sieve_stderr_ehandler_create(0); + + ehandler = sieve_stderr_ehandler_create(svinst, 0); sieve_error_handler_accept_infolog(ehandler, TRUE); if ( (sbin = sieve_compile(svinst, filename, name, ehandler, NULL)) == NULL ) @@ -526,14 +526,14 @@ struct sieve_binary *sieve_tool_script_compile return sbin; } - + struct sieve_binary *sieve_tool_script_open (struct sieve_instance *svinst, const char *filename) { struct sieve_error_handler *ehandler; struct sieve_binary *sbin; - - ehandler = sieve_stderr_ehandler_create(0); + + ehandler = sieve_stderr_ehandler_create(svinst, 0); sieve_error_handler_accept_infolog(ehandler, TRUE); if ( (sbin = sieve_open(svinst, filename, NULL, ehandler, NULL)) == NULL ) { @@ -542,7 +542,7 @@ struct sieve_binary *sieve_tool_script_open } sieve_error_handler_unref(&ehandler); - + sieve_save(sbin, NULL, FALSE, NULL); return sbin; } @@ -561,7 +561,7 @@ void sieve_tool_dump_binary_to(struct sieve_binary *sbin, const char *filename) i_fatal("Failed to create stream for sieve code dump."); } } - + /* * Commandline option parsing */ diff --git a/src/lib-sieve/plugins/include/ext-include-binary.c b/src/lib-sieve/plugins/include/ext-include-binary.c index 45e9e7a787d96572a37e12090e5e74c0b60750f8..02d90f29b323916c8f14d3c3408aa19aade5b006 100644 --- a/src/lib-sieve/plugins/include/ext-include-binary.c +++ b/src/lib-sieve/plugins/include/ext-include-binary.c @@ -233,6 +233,7 @@ static bool ext_include_binary_save static bool ext_include_binary_open (const struct sieve_extension *ext, struct sieve_binary *sbin, void *context) { + struct sieve_instance *svinst = ext->svinst; struct ext_include_binary_context *binctx = (struct ext_include_binary_context *) context; struct sieve_binary_block *sblock; @@ -245,7 +246,8 @@ static bool ext_include_binary_open offset = 0; if ( !sieve_binary_read_unsigned(sblock, &offset, &depcount) ) { - sieve_sys_error("include: failed to read include count " + sieve_sys_error(svinst, + "include: failed to read include count " "for dependency block %d of binary %s", block_id, sieve_binary_path(sbin)); return FALSE; @@ -253,7 +255,8 @@ static bool ext_include_binary_open /* Check include limit */ if ( depcount > EXT_INCLUDE_MAX_INCLUDES ) { - sieve_sys_error("include: binary %s includes too many scripts (%u > %u)", + sieve_sys_error(svinst, + "include: binary %s includes too many scripts (%u > %u)", sieve_binary_path(sbin), depcount, EXT_INCLUDE_MAX_INCLUDES); return FALSE; } @@ -272,14 +275,16 @@ static bool ext_include_binary_open !sieve_binary_read_byte(sblock, &offset, &location) || !sieve_binary_read_string(sblock, &offset, &script_name) ) { /* Binary is corrupt, recompile */ - sieve_sys_error("include: failed to read included script " + sieve_sys_error(svinst, + "include: failed to read included script " "from dependency block %d of binary %s", block_id, sieve_binary_path(sbin)); return FALSE; } if ( (inc_block=sieve_binary_block_get(sbin, inc_block_id)) == NULL ) { - sieve_sys_error("include: failed to find block %d for included script " + sieve_sys_error(svinst, + "include: failed to find block %d for included script " "from dependency block %d of binary %s", inc_block_id, block_id, sieve_binary_path(sbin)); @@ -288,7 +293,8 @@ static bool ext_include_binary_open if ( location >= EXT_INCLUDE_LOCATION_INVALID ) { /* Binary is corrupt, recompile */ - sieve_sys_error("include: dependency block %d of binary %s " + sieve_sys_error(svinst, + "include: dependency block %d of binary %s " "reports invalid script location (id %d)", block_id, sieve_binary_path(sbin), location); return FALSE; diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c index 8e94fde8c312c5f609eac7966eb630eefdcfaad7..5d4fb6579901dd093dfbbfd6475212f30217637a 100644 --- a/src/lib-sieve/plugins/include/ext-include-common.c +++ b/src/lib-sieve/plugins/include/ext-include-common.c @@ -84,7 +84,7 @@ const char *ext_include_get_script_directory if ( sieve_dir == NULL ) { if ( home == NULL ) { - sieve_sys_error( + sieve_sys_error(svinst, "include: sieve_dir and home not set for :personal script include " "(wanted script '%s')", str_sanitize(script_name, 80)); return NULL; @@ -101,7 +101,7 @@ const char *ext_include_get_script_directory sieve_dir = sieve_setting_get(svinst, "sieve_global_dir"); if (sieve_dir == NULL) { - sieve_sys_error( + sieve_sys_error(svinst, "include: sieve_global_dir not set for :global script include " "(wanted script '%s')", str_sanitize(script_name, 80)); return NULL; diff --git a/src/lib-sieve/plugins/include/ext-include-variables.c b/src/lib-sieve/plugins/include/ext-include-variables.c index 093eb19fc6ff0f6cd583d1916b2a29fea3082a03..85eb93818813bb8b9a85412c1b3dc896249504a6 100644 --- a/src/lib-sieve/plugins/include/ext-include-variables.c +++ b/src/lib-sieve/plugins/include/ext-include-variables.c @@ -104,7 +104,8 @@ bool ext_include_variables_load /* Sanity assert */ i_assert( *global_vars_r == NULL ); - *global_vars_r = sieve_variable_scope_binary_read(this_ext, sblock, offset); + *global_vars_r = sieve_variable_scope_binary_read + (this_ext->svinst, this_ext, sblock, offset); return ( *global_vars_r != NULL ); } diff --git a/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c b/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c index 139f161d75202bdb1ea3e7f79e99ba64aea94d8f..5ac75d316688312655f46e34e7ddacad41bc81f1 100644 --- a/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c +++ b/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c @@ -248,8 +248,8 @@ bool ext_spamvirustest_load (const struct sieve_extension *ext, void **context) { struct ext_spamvirustest_data *ext_data = - (struct ext_spamvirustest_data *) *context; - struct sieve_instance *svinst = ext->svinst; + (struct ext_spamvirustest_data *) *context; + struct sieve_instance *svinst = ext->svinst; const char *ext_name, *status_header, *max_header, *status_type, *max_value; enum ext_spamvirustest_status_type type; @@ -300,7 +300,8 @@ bool ext_spamvirustest_load } else if ( strcmp(status_type, "text") == 0 ) { type = EXT_SPAMVIRUSTEST_STATUS_TYPE_TEXT; } else { - sieve_sys_error("%s: invalid status type '%s'", ext_name, status_type); + sieve_sys_error(svinst, + "%s: invalid status type '%s'", ext_name, status_type); return FALSE; } @@ -309,24 +310,28 @@ bool ext_spamvirustest_load if ( type != EXT_SPAMVIRUSTEST_STATUS_TYPE_TEXT ) { if ( max_header != NULL && max_value != NULL ) { - sieve_sys_error("%s: sieve_%s_max_header and sieve_%s_max_value " + sieve_sys_error(svinst, + "%s: sieve_%s_max_header and sieve_%s_max_value " "cannot both be configured", ext_name, ext_name, ext_name); return TRUE; } if ( max_header == NULL && max_value == NULL ) { - sieve_sys_error("%s: none of sieve_%s_max_header or sieve_%s_max_value " + sieve_sys_error(svinst, + "%s: none of sieve_%s_max_header or sieve_%s_max_value " "is configured", ext_name, ext_name, ext_name); return TRUE; } } else { if ( max_header != NULL ) { - sieve_sys_warning("%s: setting sieve_%s_max_header has no meaning " + sieve_sys_warning(svinst, + "%s: setting sieve_%s_max_header has no meaning " "for sieve_%s_status_type=text", ext_name, ext_name, ext_name); } if ( max_value != NULL ) { - sieve_sys_warning("%s: setting sieve_%s_max_value has no meaning " + sieve_sys_warning(svinst, + "%s: setting sieve_%s_max_value has no meaning " "for sieve_%s_status_type=text", ext_name, ext_name, ext_name); } } @@ -339,7 +344,8 @@ bool ext_spamvirustest_load if ( !ext_spamvirustest_header_spec_parse (&ext_data->status_header, ext_data->pool, status_header, &error) ) { - sieve_sys_error("%s: invalid status header specification " + sieve_sys_error(svinst, + "%s: invalid status header specification " "'%s': %s", ext_name, status_header, error); result = FALSE; } @@ -350,7 +356,8 @@ bool ext_spamvirustest_load if ( max_header != NULL && !ext_spamvirustest_header_spec_parse (&ext_data->max_header, ext_data->pool, max_header, &error) ) { - sieve_sys_error("%s: invalid max header specification " + sieve_sys_error(svinst, + "%s: invalid max header specification " "'%s': %s", ext_name, max_header, error); result = FALSE; } @@ -360,7 +367,8 @@ bool ext_spamvirustest_load if ( result && max_value != NULL ) { if ( !ext_spamvirustest_parse_decimal_value (max_value, &ext_data->max_value, &error) ) { - sieve_sys_error("%s: invalid max value specification " + sieve_sys_error(svinst, + "%s: invalid max value specification " "'%s': %s", ext_name, max_value, error); result = FALSE; } @@ -387,8 +395,9 @@ bool ext_spamvirustest_load if ( result ) { *context = (void *) ext_data; } else { - sieve_sys_warning("%s: extension not configured, " - "tests will always match against \"0\"", ext_name); + sieve_sys_warning(svinst, + "%s: extension not configured, tests will always match against \"0\"", + ext_name); ext_spamvirustest_unload(ext); *context = NULL; } diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.c b/src/lib-sieve/plugins/variables/ext-variables-common.c index d184162a342330454b3f7c74482c72c53ff57204..1bfab81ceecdc8cc128413ec4bb6ec5a904fcd77 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-common.c +++ b/src/lib-sieve/plugins/variables/ext-variables-common.c @@ -301,8 +301,8 @@ void sieve_variable_scope_binary_unref } struct sieve_variable_scope_binary *sieve_variable_scope_binary_read -(const struct sieve_extension *ext, struct sieve_binary_block *sblock, - sieve_size_t *address) +(struct sieve_instance *svinst, const struct sieve_extension *ext, + struct sieve_binary_block *sblock, sieve_size_t *address) { struct sieve_variable_scope *scope; struct sieve_variable_scope_binary *scpbin; @@ -314,13 +314,15 @@ struct sieve_variable_scope_binary *sieve_variable_scope_binary_read /* Read scope size */ if ( !sieve_binary_read_unsigned(sblock, address, &scope_size) ) { - sieve_sys_error("%s: variable scope: failed to read size", ext_name); + sieve_sys_error + (svinst, "%s: variable scope: failed to read size", ext_name); return NULL; } /* Check size limit */ if ( scope_size > EXT_VARIABLES_MAX_SCOPE_SIZE ) { - sieve_sys_error("%s: variable scope: size exceeds the limit (%u > %u)", + sieve_sys_error(svinst, + "%s: variable scope: size exceeds the limit (%u > %u)", ext_name, scope_size, EXT_VARIABLES_MAX_SCOPE_SIZE ); return NULL; } @@ -328,7 +330,8 @@ struct sieve_variable_scope_binary *sieve_variable_scope_binary_read /* Read offset */ pc = *address; if ( !sieve_binary_read_offset(sblock, address, &end_offset) ) { - sieve_sys_error("%s: variable scope: failed to read end offset", ext_name); + sieve_sys_error(svinst, + "%s: variable scope: failed to read end offset", ext_name); return NULL; } @@ -349,6 +352,7 @@ struct sieve_variable_scope *sieve_variable_scope_binary_get (struct sieve_variable_scope_binary *scpbin) { const struct sieve_extension *ext = scpbin->scope->ext; + struct sieve_instance *svinst = ext->svinst; const char *ext_name = ( ext == NULL ? "variables" : sieve_extension_name(ext) ); unsigned int i; @@ -362,8 +366,8 @@ struct sieve_variable_scope *sieve_variable_scope_binary_get string_t *identifier; if (!sieve_binary_read_string(scpbin->sblock, address, &identifier) ) { - sieve_sys_error - ("%s: variable scope: failed to read variable name", ext_name); + sieve_sys_error(svinst, + "%s: variable scope: failed to read variable name", ext_name); return NULL; } @@ -714,7 +718,8 @@ bool ext_variables_interpreter_load struct ext_variables_interpreter_context *ctx; struct sieve_variable_scope_binary *scpbin; - scpbin = sieve_variable_scope_binary_read(NULL, renv->sblock, address); + scpbin = sieve_variable_scope_binary_read + (renv->svinst, NULL, renv->sblock, address); if ( scpbin == NULL ) return FALSE; diff --git a/src/lib-sieve/plugins/variables/sieve-ext-variables.h b/src/lib-sieve/plugins/variables/sieve-ext-variables.h index 6540ef6d584ef72c876fe5d08372e9f4bf7c4011..40ba9e5f09862aea44773d55c549e582e1fb2692 100644 --- a/src/lib-sieve/plugins/variables/sieve-ext-variables.h +++ b/src/lib-sieve/plugins/variables/sieve-ext-variables.h @@ -92,8 +92,8 @@ struct sieve_variable_scope *sieve_variable_scope_binary_dump (const struct sieve_extension *ext, const struct sieve_dumptime_env *denv, sieve_size_t *address); struct sieve_variable_scope_binary *sieve_variable_scope_binary_read - (const struct sieve_extension *ext, struct sieve_binary_block *sblock, - sieve_size_t *address); + (struct sieve_instance *svinst, const struct sieve_extension *ext, + struct sieve_binary_block *sblock, sieve_size_t *address); struct sieve_variable_scope *sieve_variable_scope_binary_get (struct sieve_variable_scope_binary *scpbin); diff --git a/src/lib-sieve/sieve-binary-file.c b/src/lib-sieve/sieve-binary-file.c index ea6306dd4dce1a5763ff951e5fd3e6ef93ef9f8b..01013aa3c54764d1a5c52be2d7b27dd95f479803 100644 --- a/src/lib-sieve/sieve-binary-file.c +++ b/src/lib-sieve/sieve-binary-file.c @@ -64,10 +64,12 @@ struct sieve_binary_block_header { * Saving the binary to a file. */ -static inline bool _save_skip(struct ostream *stream, size_t size) +static inline bool _save_skip +(struct sieve_binary *sbin, struct ostream *stream, size_t size) { if ( (o_stream_seek(stream, stream->offset + size)) <= 0 ) { - sieve_sys_error("binary save: failed to skip output stream " + sieve_sys_error(sbin->svinst, + "binary save: failed to skip output stream " "to position %"PRIuUOFF_T": %s", stream->offset + size, strerror(stream->stream_errno)); return FALSE; @@ -77,12 +79,13 @@ static inline bool _save_skip(struct ostream *stream, size_t size) } static inline bool _save_skip_aligned -(struct ostream *stream, size_t size, uoff_t *offset) +(struct sieve_binary *sbin, struct ostream *stream, size_t size, + uoff_t *offset) { uoff_t aligned_offset = SIEVE_BINARY_ALIGN(stream->offset); if ( (o_stream_seek(stream, aligned_offset + size)) <= 0 ) { - sieve_sys_error("binary save: failed to skip output stream " + sieve_sys_error(sbin->svinst, "binary save: failed to skip output stream " "to position %"PRIuUOFF_T": %s", aligned_offset + size, strerror(stream->stream_errno)); return FALSE; @@ -95,7 +98,8 @@ static inline bool _save_skip_aligned } /* FIXME: Is this even necessary for a file? */ -static bool _save_full(struct ostream *stream, const void *data, size_t size) +static bool _save_full +(struct sieve_binary *sbin, struct ostream *stream, const void *data, size_t size) { size_t bytes_left = size; const void *pdata = data; @@ -104,7 +108,8 @@ static bool _save_full(struct ostream *stream, const void *data, size_t size) ssize_t ret; if ( (ret=o_stream_send(stream, pdata, bytes_left)) <= 0 ) { - sieve_sys_error("binary save: failed to write %"PRIuSIZE_T" bytes " + sieve_sys_error(sbin->svinst, + "binary save: failed to write %"PRIuSIZE_T" bytes " "to output stream: %s", bytes_left, strerror(stream->stream_errno)); return FALSE; } @@ -117,7 +122,8 @@ static bool _save_full(struct ostream *stream, const void *data, size_t size) } static bool _save_aligned -(struct ostream *stream, const void *data, size_t size, uoff_t *offset) +(struct sieve_binary *sbin, struct ostream *stream, const void *data, + size_t size, uoff_t *offset) { uoff_t aligned_offset = SIEVE_BINARY_ALIGN(stream->offset); @@ -125,11 +131,11 @@ static bool _save_aligned /* Align the data by adding zeroes to the output stream */ if ( stream->offset < aligned_offset ) { - if ( !_save_skip(stream, aligned_offset - stream->offset) ) + if ( !_save_skip(sbin, stream, aligned_offset - stream->offset) ) return FALSE; } - if ( !_save_full(stream, data, size) ) + if ( !_save_full(sbin, stream, data, size) ) return FALSE; o_stream_uncork(stream); @@ -157,11 +163,11 @@ static bool _save_block block_header.id = id; block_header.size = size; - if ( !_save_aligned(stream, &block_header, + if ( !_save_aligned(sbin, stream, &block_header, sizeof(block_header), &block->offset) ) return FALSE; - return _save_aligned(stream, data, size, NULL); + return _save_aligned(sbin, stream, data, size, NULL); } static bool _save_block_index_record @@ -179,8 +185,9 @@ static bool _save_block_index_record header.ext_id = block->ext_index; header.offset = block->offset; - if ( !_save_full(stream, &header, sizeof(header)) ) { - sieve_sys_error("binary save: failed to save block index header %d", id); + if ( !_save_full(sbin, stream, &header, sizeof(header)) ) { + sieve_sys_error(sbin->svinst, + "binary save: failed to save block index header %d", id); return FALSE; } @@ -215,14 +222,14 @@ static bool _sieve_binary_save header.version_minor = SIEVE_BINARY_VERSION_MINOR; header.blocks = blk_count; - if ( !_save_aligned(stream, &header, sizeof(header), NULL) ) { - sieve_sys_error("binary save: failed to save header"); + if ( !_save_aligned(sbin, stream, &header, sizeof(header), NULL) ) { + sieve_sys_error(sbin->svinst, "binary save: failed to save header"); return FALSE; } /* Skip block index for now */ - if ( !_save_skip_aligned(stream, + if ( !_save_skip_aligned(sbin, stream, sizeof(struct sieve_binary_block_index) * blk_count, &block_index) ) return FALSE; @@ -277,7 +284,8 @@ int sieve_binary_save /* Use default path if none is specified */ if ( path == NULL ) { if ( sbin->script == NULL ) { - sieve_sys_error("binary save: cannot determine default path " + sieve_sys_error(sbin->svinst, + "binary save: cannot determine default path " "with missing script object"); if ( error_r != NULL ) *error_r = SIEVE_ERROR_NOT_POSSIBLE; @@ -289,7 +297,7 @@ int sieve_binary_save /* Check whether saving is necessary */ if ( !update && sbin->path != NULL && strcmp(sbin->path, path) == 0 ) { if ( sbin->svinst->debug ) { - sieve_sys_debug("binary save: not saving binary %s, " + sieve_sys_debug(sbin->svinst, "binary save: not saving binary %s, " "because it is already stored", path); } return 0; @@ -302,13 +310,15 @@ int sieve_binary_save fd = safe_mkstemp_hostpid(temp_path, save_mode, (uid_t)-1, (gid_t)-1); if ( fd < 0 ) { if ( errno == EACCES ) { - sieve_sys_error("binary save: failed to create temporary file: %s", + sieve_sys_error(sbin->svinst, + "binary save: failed to create temporary file: %s", eacces_error_get_creating("open", str_c(temp_path))); if ( error_r != NULL ) *error_r = SIEVE_ERROR_NO_PERM; } else { - sieve_sys_error("binary save: failed to create temporary file: " - "open(%s) failed: %m", str_c(temp_path)); + sieve_sys_error(sbin->svinst, + "binary save: failed to create temporary file: open(%s) failed: %m", + str_c(temp_path)); if ( error_r != NULL ) *error_r = SIEVE_ERROR_TEMP_FAIL; } @@ -327,19 +337,20 @@ int sieve_binary_save /* Close saved binary */ if ( close(fd) < 0 ) { - sieve_sys_error("binary save: failed to close temporary file: " + sieve_sys_error(sbin->svinst, + "binary save: failed to close temporary file: " "close(fd=%s) failed: %m", str_c(temp_path)); } /* Replace any original binary atomically */ if ( result && (rename(str_c(temp_path), path) < 0) ) { if ( errno == EACCES ) { - sieve_sys_error("binary save: failed to save binary: %s", + sieve_sys_error(sbin->svinst, "binary save: failed to save binary: %s", eacces_error_get_creating("rename", path)); if ( error_r != NULL ) *error_r = SIEVE_ERROR_NO_PERM; } else { - sieve_sys_error("binary save: failed to save binary: " + sieve_sys_error(sbin->svinst, "binary save: failed to save binary: " "rename(%s, %s) failed: %m", str_c(temp_path), path); if ( error_r != NULL ) *error_r = SIEVE_ERROR_TEMP_FAIL; @@ -350,8 +361,9 @@ int sieve_binary_save if ( result < 0 ) { /* Get rid of temp output (if any) */ if ( unlink(str_c(temp_path)) < 0 && errno != ENOENT ) { - sieve_sys_error("binary save: failed to clean up after error: " - "unlink(%s) failed: %m", str_c(temp_path)); + sieve_sys_error(sbin->svinst, + "binary save: failed to clean up after error: unlink(%s) failed: %m", + str_c(temp_path)); } } else { if ( sbin->path == NULL ) { @@ -367,7 +379,8 @@ int sieve_binary_save */ bool sieve_binary_file_open -(struct sieve_binary_file *file, const char *path, enum sieve_error *error_r) +(struct sieve_binary_file *file, + struct sieve_instance *svinst, const char *path, enum sieve_error *error_r) { int fd; bool result = TRUE; @@ -383,13 +396,13 @@ bool sieve_binary_file_open *error_r = SIEVE_ERROR_NOT_FOUND; break; case EACCES: - sieve_sys_error("binary open: failed to open: %s", + sieve_sys_error(svinst, "binary open: failed to open: %s", eacces_error_get("open", path)); if ( error_r != NULL ) *error_r = SIEVE_ERROR_NO_PERM; break; default: - sieve_sys_error("binary open: failed to open: " + sieve_sys_error(svinst, "binary open: failed to open: " "open(%s) failed: %m", path); if ( error_r != NULL ) *error_r = SIEVE_ERROR_TEMP_FAIL; @@ -400,24 +413,27 @@ bool sieve_binary_file_open if ( fstat(fd, &st) < 0 ) { if ( errno != ENOENT ) { - sieve_sys_error("binary open: fstat(fd=%s) failed: %m", path); + sieve_sys_error(svinst, + "binary open: fstat(fd=%s) failed: %m", path); } result = FALSE; } if ( result && !S_ISREG(st.st_mode) ) { - sieve_sys_error("binary open: %s is not a regular file", path); + sieve_sys_error(svinst, + "binary open: %s is not a regular file", path); result = FALSE; } if ( !result ) { if ( close(fd) < 0 ) { - sieve_sys_error("binary open: close(fd=%s) failed after error: %m", - path); + sieve_sys_error(svinst, + "binary open: close(fd=%s) failed after error: %m", path); } return FALSE; } + file->svinst = svinst; file->fd = fd; file->st = st; @@ -428,8 +444,9 @@ void sieve_binary_file_close(struct sieve_binary_file **file) { if ( (*file)->fd != -1 ) { if ( close((*file)->fd) < 0 ) { - sieve_sys_error("binary close: failed to close: " - "close(fd=%s) failed: %m", (*file)->path); + sieve_sys_error((*file)->svinst, + "binary close: failed to close: close(fd=%s) failed: %m", + (*file)->path); } } @@ -557,6 +574,7 @@ static struct sieve_binary_file *_file_memory_open(const char *path) static bool _file_lazy_read (struct sieve_binary_file *file, off_t *offset, void *buffer, size_t size) { + struct sieve_instance *svinst = file->svinst; int ret; void *indata = buffer; size_t insize = size; @@ -566,7 +584,7 @@ static bool _file_lazy_read /* Seek to the correct position */ if ( *offset != file->offset && lseek(file->fd, *offset, SEEK_SET) == (off_t) -1 ) { - sieve_sys_error("binary read:" + sieve_sys_error(svinst, "binary read:" "failed to seek(fd, %lld, SEEK_SET) in binary %s: %m", (long long) *offset, file->path); return FALSE; @@ -576,11 +594,11 @@ static bool _file_lazy_read while (insize > 0) { if ( (ret=read(file->fd, indata, insize)) <= 0 ) { if ( ret == 0 ) - sieve_sys_error( + sieve_sys_error(svinst, "binary read: binary %s is truncated (more data expected)", file->path); else - sieve_sys_error( + sieve_sys_error(svinst, "binary read: failed to read from binary %s: %m", file->path); break; } @@ -626,7 +644,7 @@ static buffer_t *_file_lazy_load_buffer } static struct sieve_binary_file *_file_lazy_open -(const char *path, enum sieve_error *error_r) +(struct sieve_instance *svinst, const char *path, enum sieve_error *error_r) { pool_t pool; struct sieve_binary_file *file; @@ -638,7 +656,7 @@ static struct sieve_binary_file *_file_lazy_open file->load_data = _file_lazy_load_data; file->load_buffer = _file_lazy_load_buffer; - if ( !sieve_binary_file_open(file, path, error_r) ) { + if ( !sieve_binary_file_open(file, svinst, path, error_r) ) { pool_unref(&pool); return NULL; } @@ -663,14 +681,14 @@ bool sieve_binary_load_block LOAD_HEADER(sbin, &offset, const struct sieve_binary_block_header); if ( header == NULL ) { - sieve_sys_error( + sieve_sys_error(sbin->svinst, "binary load: binary %s is corrupt: " "failed to read header of block %d", sbin->path, id); return FALSE; } if ( header->id != id ) { - sieve_sys_error( + sieve_sys_error(sbin->svinst, "binary load: binary %s is corrupt: " "header of block %d has non-matching id %d", sbin->path, id, header->id); @@ -679,7 +697,7 @@ bool sieve_binary_load_block sblock->data = sbin->file->load_buffer(sbin->file, &offset, header->size); if ( sblock->data == NULL ) { - sieve_sys_error( + sieve_sys_error(sbin->svinst, "binary load: failed to read block %d of binary %s (size=%d)", id, sbin->path, header->size); return FALSE; @@ -696,14 +714,14 @@ static bool _read_block_index_record struct sieve_binary_block *block; if ( record == NULL ) { - sieve_sys_error( + sieve_sys_error(sbin->svinst, "binary open: binary %s is corrupt: " "failed to load block index record %d", sbin->path, id); return FALSE; } if ( record->id != id ) { - sieve_sys_error( + sieve_sys_error(sbin->svinst, "binary open: binary %s is corrupt: " "block index record %d has unexpected id %d", sbin->path, id, record->id); return FALSE; @@ -735,7 +753,7 @@ static bool _read_extensions(struct sieve_binary_block *sblock) ext = sieve_extension_get_by_name(sbin->svinst, str_c(extension)); if ( ext == NULL ) { - sieve_sys_error( + sieve_sys_error(sbin->svinst, "binary open: binary %s requires unknown extension '%s'", sbin->path, str_sanitize(str_c(extension), 128)); result = FALSE; @@ -768,18 +786,20 @@ static bool _sieve_binary_open(struct sieve_binary *sbin) header = LOAD_HEADER(sbin, &offset, const struct sieve_binary_header); /* Check header presence */ if ( header == NULL ) { - sieve_sys_error("binary_open: file %s is not large enough " - "to contain the header.", sbin->path); + sieve_sys_error(sbin->svinst, + "binary_open: file %s is not large enough to contain the header.", + sbin->path); result = FALSE; /* Check header validity */ } else if ( header->magic != SIEVE_BINARY_MAGIC ) { if ( header->magic != SIEVE_BINARY_MAGIC_OTHER_ENDIAN ) - sieve_sys_error("binary_open: binary %s has corrupted header " + sieve_sys_error(sbin->svinst, + "binary_open: binary %s has corrupted header " "(0x%08x) or it is not a Sieve binary", sbin->path, header->magic); else if ( sbin->svinst->debug ) - sieve_sys_debug("binary open: binary %s stored " - "with in different endian format " + sieve_sys_debug(sbin->svinst, + "binary open: binary %s stored with in different endian format " "(automatically fixed when re-compiled)", sbin->path); result = FALSE; @@ -792,8 +812,8 @@ static bool _sieve_binary_open(struct sieve_binary *sbin) /* Binary is of different version. Caller will have to recompile */ if ( sbin->svinst->debug ) { - sieve_sys_debug("binary open: binary %s stored " - "with different binary version %d.%d " + sieve_sys_debug(sbin->svinst, + "binary open: binary %s stored with different binary version %d.%d " "(!= %d.%d; automatically fixed when re-compiled)", sbin->path, (int) header->version_major, header->version_minor, SIEVE_BINARY_VERSION_MAJOR, SIEVE_BINARY_VERSION_MINOR); @@ -802,7 +822,7 @@ static bool _sieve_binary_open(struct sieve_binary *sbin) /* Check block content */ } else if ( result && header->blocks == 0 ) { - sieve_sys_error( + sieve_sys_error(sbin->svinst, "binary open: binary %s is corrupt: it contains no blocks", sbin->path); result = FALSE; @@ -835,8 +855,8 @@ static bool _sieve_binary_open(struct sieve_binary *sbin) result = FALSE; } else { if ( !_read_extensions(ext_block) ) { - sieve_sys_error("binary open: binary %s is corrupt: " - "failed to load extension block", + sieve_sys_error(sbin->svinst, + "binary open: binary %s is corrupt: failed to load extension block", sbin->path); result = FALSE; } @@ -858,7 +878,7 @@ struct sieve_binary *sieve_binary_open i_assert( script == NULL || sieve_script_svinst(script) == svinst ); //file = _file_memory_open(path); - if ( (file=_file_lazy_open(path, error_r)) == NULL ) + if ( (file=_file_lazy_open(svinst, path, error_r)) == NULL ) return NULL; /* Create binary object */ diff --git a/src/lib-sieve/sieve-binary-private.h b/src/lib-sieve/sieve-binary-private.h index e241247dfac7b556bdc84ae3793e2d70527f4f48..4c38265bee0419342523a05f0dc547db08a43721 100644 --- a/src/lib-sieve/sieve-binary-private.h +++ b/src/lib-sieve/sieve-binary-private.h @@ -17,6 +17,7 @@ struct sieve_binary_file { pool_t pool; const char *path; + struct sieve_instance *svinst; struct stat st; int fd; @@ -29,7 +30,8 @@ struct sieve_binary_file { }; bool sieve_binary_file_open - (struct sieve_binary_file *file, const char *path, enum sieve_error *error_r); + (struct sieve_binary_file *file, struct sieve_instance *svinst, + const char *path, enum sieve_error *error_r); void sieve_binary_file_close(struct sieve_binary_file **file); /* diff --git a/src/lib-sieve/sieve-common.h b/src/lib-sieve/sieve-common.h index 5c03e08716204916a6618a7349d9068aaef43e0a..086c082bb81ad870b9679b637e32ce9a3f119fc0 100644 --- a/src/lib-sieve/sieve-common.h +++ b/src/lib-sieve/sieve-common.h @@ -165,6 +165,9 @@ struct sieve_instance { /* Extension registry */ struct sieve_extension_registry *ext_reg; + /* System error handler */ + struct sieve_error_handler *system_ehandler; + /* Plugin modules */ struct sieve_plugin *plugins; diff --git a/src/lib-sieve/sieve-error-private.h b/src/lib-sieve/sieve-error-private.h index 62368f1d6dbbb1300286f2e3e8a5b6b305fa4938..d4f844b121df107d86415dc973a61e560979facd 100644 --- a/src/lib-sieve/sieve-error-private.h +++ b/src/lib-sieve/sieve-error-private.h @@ -6,6 +6,13 @@ #include "sieve-error.h" +/* + * Initialization + */ + +void sieve_errors_init(struct sieve_instance *svinst); +void sieve_errors_deinit(struct sieve_instance *svinst); + /* * Error handler object */ @@ -14,6 +21,8 @@ struct sieve_error_handler { pool_t pool; int refcount; + struct sieve_instance *svinst; + struct sieve_error_handler *parent; unsigned int max_errors; @@ -40,7 +49,8 @@ struct sieve_error_handler { }; void sieve_error_handler_init - (struct sieve_error_handler *ehandler, pool_t pool, unsigned int max_errors); + (struct sieve_error_handler *ehandler, struct sieve_instance *svinst, + pool_t pool, unsigned int max_errors); void sieve_error_handler_init_from_parent (struct sieve_error_handler *ehandler, pool_t pool, diff --git a/src/lib-sieve/sieve-error.c b/src/lib-sieve/sieve-error.c index e3a52614357d8739971a0de396c8d5cbd0f2020b..f13f1c5c0b912dbb95bded6a7fc2765913bf3b57 100644 --- a/src/lib-sieve/sieve-error.c +++ b/src/lib-sieve/sieve-error.c @@ -47,20 +47,95 @@ const char *sieve_error_script_location return t_strdup_printf("%s: line %d", sname, source_line); } +/* + * Initialization + */ + +void sieve_errors_init(struct sieve_instance *svinst) +{ + svinst->system_ehandler = sieve_master_ehandler_create(svinst, 0); +} + +void sieve_errors_deinit(struct sieve_instance *svinst) +{ + sieve_error_handler_unref(&svinst->system_ehandler); +} + +/* + * System errors + */ + +void sieve_sys_error(struct sieve_instance *svinst, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + + T_BEGIN { + sieve_verror(svinst->system_ehandler, NULL, fmt, args); + } T_END; + + va_end(args); +} + +void sieve_sys_warning(struct sieve_instance *svinst, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + + T_BEGIN { + sieve_vwarning(svinst->system_ehandler, NULL, fmt, args); + } T_END; + + va_end(args); +} + +void sieve_sys_info(struct sieve_instance *svinst, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + + T_BEGIN { + sieve_vinfo(svinst->system_ehandler, NULL, fmt, args); + } T_END; + + va_end(args); +} + +void sieve_sys_debug(struct sieve_instance *svinst, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + + T_BEGIN { + sieve_vdebug(svinst->system_ehandler, NULL, fmt, args); + } T_END; + + va_end(args); +} + +void sieve_system_ehandler_set +(struct sieve_error_handler *ehandler) +{ + struct sieve_instance *svinst = ehandler->svinst; + + sieve_error_handler_unref(&svinst->system_ehandler); + svinst->system_ehandler = ehandler; + sieve_error_handler_ref(ehandler); +} /* * Main error functions */ static void sieve_vcopy_master -(const char *location, sieve_error_vfunc_t error_vfunc, - const char *fmt, va_list args) +(struct sieve_instance *svinst, const char *location, + sieve_error_vfunc_t error_vfunc, const char *fmt, va_list args) { va_list args_copy; VA_COPY(args_copy, args); - error_vfunc(_sieve_system_ehandler, location, fmt, args_copy); + error_vfunc(svinst->system_ehandler, location, fmt, args_copy); } void sieve_verror @@ -70,7 +145,7 @@ void sieve_verror if ( ehandler == NULL ) return; if ( ehandler->parent == NULL && ehandler->log_master ) - sieve_vcopy_master(location, sieve_verror, fmt, args); + sieve_vcopy_master(ehandler->svinst, location, sieve_verror, fmt, args); sieve_direct_verror(ehandler, location, fmt, args); } @@ -82,7 +157,7 @@ void sieve_vwarning if ( ehandler == NULL ) return; if ( ehandler->parent == NULL && ehandler->log_master ) - sieve_vcopy_master(location, sieve_vwarning, fmt, args); + sieve_vcopy_master(ehandler->svinst, location, sieve_vwarning, fmt, args); sieve_direct_vwarning(ehandler, location, fmt, args); } @@ -94,7 +169,7 @@ void sieve_vinfo if ( ehandler == NULL ) return; if ( ehandler->parent == NULL && ehandler->log_master ) - sieve_vcopy_master(location, sieve_vinfo, fmt, args); + sieve_vcopy_master(ehandler->svinst, location, sieve_vinfo, fmt, args); sieve_direct_vinfo(ehandler, location, fmt, args); } @@ -106,7 +181,7 @@ void sieve_vdebug if ( ehandler == NULL ) return; if ( ehandler->parent == NULL && ehandler->log_master ) - sieve_vcopy_master(location, sieve_vdebug, fmt, args); + sieve_vcopy_master(ehandler->svinst, location, sieve_vdebug, fmt, args); sieve_direct_vdebug(ehandler, location, fmt, args); } @@ -120,11 +195,14 @@ void sieve_vcritical tm = localtime(&ioloop_time); - if ( location == NULL || *location == '\0' ) - sieve_sys_error("%s", t_strdup_vprintf(fmt, args)); - else - sieve_sys_error("%s: %s", location, t_strdup_vprintf(fmt, args)); - + if ( location == NULL || *location == '\0' ) { + sieve_sys_error + (ehandler->svinst, "%s", t_strdup_vprintf(fmt, args)); + } else { + sieve_sys_error + (ehandler->svinst, "%s: %s", location, t_strdup_vprintf(fmt, args)); + } + if ( ehandler == NULL ) return; sieve_error(ehandler, location, "%s", @@ -254,9 +332,11 @@ void sieve_error_handler_copy_masterlog */ void sieve_error_handler_init -(struct sieve_error_handler *ehandler, pool_t pool, unsigned int max_errors) +(struct sieve_error_handler *ehandler, struct sieve_instance *svinst, + pool_t pool, unsigned int max_errors) { ehandler->pool = pool; + ehandler->svinst = svinst; ehandler->refcount = 1; ehandler->max_errors = max_errors; @@ -269,7 +349,7 @@ void sieve_error_handler_init_from_parent { i_assert( parent != NULL ); - sieve_error_handler_init(ehandler, pool, parent->max_errors); + sieve_error_handler_init(ehandler, parent->svinst, pool, parent->max_errors); ehandler->parent = parent; sieve_error_handler_ref(parent); @@ -369,7 +449,7 @@ static void sieve_master_vdebug } struct sieve_error_handler *sieve_master_ehandler_create -(unsigned int max_errors) +(struct sieve_instance *svinst, unsigned int max_errors) { pool_t pool; struct sieve_error_handler *ehandler; @@ -380,7 +460,7 @@ struct sieve_error_handler *sieve_master_ehandler_create pool = pool_alloconly_create ("master_error_handler", sizeof(struct sieve_error_handler)); ehandler = p_new(pool, struct sieve_error_handler, 1); - sieve_error_handler_init(ehandler, pool, max_errors); + sieve_error_handler_init(ehandler, svinst, pool, max_errors); ehandler->verror = sieve_master_verror; ehandler->vwarning = sieve_master_vwarning; @@ -390,33 +470,6 @@ struct sieve_error_handler *sieve_master_ehandler_create return ehandler; } -struct sieve_error_handler _sieve_system_ehandler_object = { - NULL, 0, NULL, 0, 0, 0, - FALSE, - TRUE, - TRUE, - sieve_master_verror, - sieve_master_vwarning, - sieve_master_vinfo, - sieve_master_vdebug, - NULL -}; - -struct sieve_error_handler *_sieve_system_ehandler = &_sieve_system_ehandler_object; - -void sieve_system_ehandler_set(struct sieve_error_handler *ehandler) -{ - sieve_error_handler_unref(&_sieve_system_ehandler); - _sieve_system_ehandler = ehandler; - sieve_error_handler_ref(_sieve_system_ehandler); -} - -void sieve_system_ehandler_reset(void) -{ - sieve_error_handler_unref(&_sieve_system_ehandler); - _sieve_system_ehandler = &_sieve_system_ehandler_object; -} - /* * STDERR error handler * @@ -462,7 +515,7 @@ static void sieve_stderr_vdebug } struct sieve_error_handler *sieve_stderr_ehandler_create -(unsigned int max_errors) +(struct sieve_instance *svinst, unsigned int max_errors) { pool_t pool; struct sieve_error_handler *ehandler; @@ -473,7 +526,7 @@ struct sieve_error_handler *sieve_stderr_ehandler_create pool = pool_alloconly_create ("stderr_error_handler", sizeof(struct sieve_error_handler)); ehandler = p_new(pool, struct sieve_error_handler, 1); - sieve_error_handler_init(ehandler, pool, max_errors); + sieve_error_handler_init(ehandler, svinst, pool, max_errors); ehandler->verror = sieve_stderr_verror; ehandler->vwarning = sieve_stderr_vwarning; @@ -542,7 +595,8 @@ static void sieve_strbuf_vdebug } struct sieve_error_handler *sieve_strbuf_ehandler_create -(string_t *strbuf, bool crlf, unsigned int max_errors) +(struct sieve_instance *svinst, string_t *strbuf, bool crlf, + unsigned int max_errors) { pool_t pool; struct sieve_strbuf_ehandler *ehandler; @@ -551,7 +605,7 @@ struct sieve_error_handler *sieve_strbuf_ehandler_create ehandler = p_new(pool, struct sieve_strbuf_ehandler, 1); ehandler->errors = strbuf; - sieve_error_handler_init(&ehandler->handler, pool, max_errors); + sieve_error_handler_init(&ehandler->handler, svinst, pool, max_errors); ehandler->handler.verror = sieve_strbuf_verror; ehandler->handler.vwarning = sieve_strbuf_vwarning; @@ -609,14 +663,14 @@ static void sieve_logfile_vprintf } T_END; if ( ret < 0 ) { - sieve_sys_error( + sieve_sys_error(ehandler->handler.svinst, "o_stream_send() failed on logfile %s: %m", ehandler->logfile); } } inline static void sieve_logfile_printf -(struct sieve_logfile_ehandler *ehandler, const char *location, const char *prefix, - const char *fmt, ...) +(struct sieve_logfile_ehandler *ehandler, const char *location, + const char *prefix, const char *fmt, ...) { va_list args; va_start(args, fmt); @@ -628,22 +682,23 @@ inline static void sieve_logfile_printf static void sieve_logfile_start(struct sieve_logfile_ehandler *ehandler) { - int fd; + struct sieve_instance *svinst = ehandler->handler.svinst; struct ostream *ostream = NULL; struct stat st; struct tm *tm; char buf[256]; time_t now; + int fd; /* Open the logfile */ fd = open(ehandler->logfile, O_CREAT | O_APPEND | O_WRONLY, 0600); if (fd == -1) { if ( errno == EACCES ) { - sieve_sys_error("failed to open logfile (LOGGING TO STDERR): %s", + sieve_sys_error(svinst, "failed to open logfile (LOGGING TO STDERR): %s", eacces_error_get_creating("open", ehandler->logfile)); } else { - sieve_sys_error("failed to open logfile (LOGGING TO STDERR): " + sieve_sys_error(svinst, "failed to open logfile (LOGGING TO STDERR): " "open(%s) failed: %m", ehandler->logfile); } fd = STDERR_FILENO; @@ -652,11 +707,11 @@ static void sieve_logfile_start(struct sieve_logfile_ehandler *ehandler) /* Stat the log file to obtain size information */ if ( fstat(fd, &st) != 0 ) { - sieve_sys_error("failed to stat logfile (logging to STDERR): " + sieve_sys_error(svinst, "failed to stat logfile (logging to STDERR): " "fstat(fd=%s) failed: %m", ehandler->logfile); if ( close(fd) < 0 ) { - sieve_sys_error("failed to close logfile after error: " + sieve_sys_error(svinst, "failed to close logfile after error: " "close(fd=%s) failed: %m", ehandler->logfile); } @@ -669,14 +724,15 @@ static void sieve_logfile_start(struct sieve_logfile_ehandler *ehandler) /* Close open file */ if ( close(fd) < 0 ) { - sieve_sys_error("failed to close logfile: close(fd=%s) failed: %m", - ehandler->logfile); + sieve_sys_error(svinst, + "failed to close logfile: close(fd=%s) failed: %m", ehandler->logfile); } /* Rotate logfile */ rotated = t_strconcat(ehandler->logfile, ".0", NULL); if ( rename(ehandler->logfile, rotated) < 0 ) { - sieve_sys_error("failed to rotate logfile: rename(%s, %s) failed: %m", + sieve_sys_error(svinst, + "failed to rotate logfile: rename(%s, %s) failed: %m", ehandler->logfile, rotated); } @@ -684,11 +740,13 @@ static void sieve_logfile_start(struct sieve_logfile_ehandler *ehandler) fd = open(ehandler->logfile, O_CREAT | O_WRONLY | O_TRUNC, 0600); if (fd == -1) { if ( errno == EACCES ) { - sieve_sys_error("failed to open logfile (LOGGING TO STDERR): %s", + sieve_sys_error(svinst, + "failed to open logfile (LOGGING TO STDERR): %s", eacces_error_get_creating("open", ehandler->logfile)); } else { - sieve_sys_error("failed to open logfile (LOGGING TO STDERR): " - "open(%s) failed: %m", ehandler->logfile); + sieve_sys_error(svinst, + "failed to open logfile (LOGGING TO STDERR): open(%s) failed: %m", + ehandler->logfile); } fd = STDERR_FILENO; } @@ -698,7 +756,7 @@ 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? */ - sieve_sys_error("failed to open log stream on open file: " + sieve_sys_error(svinst, "failed to open log stream on open file: " "o_stream_create_fd(fd=%s) failed " "(non-critical messages are not logged!)", ehandler->logfile); } @@ -776,7 +834,7 @@ static void sieve_logfile_free o_stream_destroy(&(handler->stream)); if ( handler->fd != STDERR_FILENO ){ if ( close(handler->fd) < 0 ) { - sieve_sys_error("failed to close logfile: " + sieve_sys_error(ehandler->svinst, "failed to close logfile: " "close(fd=%s) failed: %m", handler->logfile); } } @@ -784,14 +842,14 @@ static void sieve_logfile_free } struct sieve_error_handler *sieve_logfile_ehandler_create -(const char *logfile, unsigned int max_errors) +(struct sieve_instance *svinst, const char *logfile, unsigned int max_errors) { pool_t pool; struct sieve_logfile_ehandler *ehandler; pool = pool_alloconly_create("logfile_error_handler", 512); ehandler = p_new(pool, struct sieve_logfile_ehandler, 1); - sieve_error_handler_init(&ehandler->handler, pool, max_errors); + sieve_error_handler_init(&ehandler->handler, svinst, pool, max_errors); ehandler->handler.verror = sieve_logfile_verror; ehandler->handler.vwarning = sieve_logfile_vwarning; diff --git a/src/lib-sieve/sieve-error.h b/src/lib-sieve/sieve-error.h index fd7d743b2024ca3237c7b33173ef928db19d070c..5fb8c8f44cc86209dbc52e481e1e956553c630f9 100644 --- a/src/lib-sieve/sieve-error.h +++ b/src/lib-sieve/sieve-error.h @@ -15,6 +15,7 @@ struct var_expand_table; +struct sieve_instance; struct sieve_script; struct sieve_error_handler; @@ -33,15 +34,17 @@ typedef void (*sieve_error_func_t) * System errors */ -extern struct sieve_error_handler *_sieve_system_ehandler; +void sieve_sys_error + (struct sieve_instance *svinst, const char *fmt, ...) ATTR_FORMAT(2, 3); +void sieve_sys_warning + (struct sieve_instance *svinst, const char *fmt, ...) ATTR_FORMAT(2, 3); +void sieve_sys_info + (struct sieve_instance *svinst, const char *fmt, ...) ATTR_FORMAT(2, 3); +void sieve_sys_debug + (struct sieve_instance *svinst, const char *fmt, ...) ATTR_FORMAT(2, 3); -#define sieve_sys_error(...) sieve_error(_sieve_system_ehandler, NULL, __VA_ARGS__ ) -#define sieve_sys_warning(...) sieve_warning(_sieve_system_ehandler, NULL, __VA_ARGS__ ) -#define sieve_sys_info(...) sieve_info(_sieve_system_ehandler, NULL, __VA_ARGS__ ) -#define sieve_sys_debug(...) sieve_debug(_sieve_system_ehandler, NULL, __VA_ARGS__ ) - -void sieve_system_ehandler_set(struct sieve_error_handler *ehandler); -void sieve_system_ehandler_reset(void); +void sieve_system_ehandler_set + (struct sieve_error_handler *ehandler); /* * Main error functions @@ -121,19 +124,20 @@ void sieve_error_handler_reset(struct sieve_error_handler *ehandler); /* Write errors to dovecot master log */ struct sieve_error_handler *sieve_master_ehandler_create - (unsigned int max_errors); + (struct sieve_instance *svinst, unsigned int max_errors); /* Write errors to stderr */ struct sieve_error_handler *sieve_stderr_ehandler_create - (unsigned int max_errors); + (struct sieve_instance *svinst, unsigned int max_errors); /* Write errors into a string buffer */ struct sieve_error_handler *sieve_strbuf_ehandler_create - (string_t *strbuf, bool crlf, unsigned int max_errors); + (struct sieve_instance *svinst, string_t *strbuf, bool crlf, + unsigned int max_errors); /* Write errors to a logfile */ struct sieve_error_handler *sieve_logfile_ehandler_create - (const char *logfile, unsigned int max_errors); + (struct sieve_instance *svinst, const char *logfile, unsigned int max_errors); /* Wrapper: prefix all log messages */ struct sieve_error_handler *sieve_prefix_ehandler_create diff --git a/src/lib-sieve/sieve-extensions.c b/src/lib-sieve/sieve-extensions.c index c4ac848d005c4e75288fc405b8e4e16091d52d05..9086264a7acd2beae9ca81bf97243d86ce345182 100644 --- a/src/lib-sieve/sieve-extensions.c +++ b/src/lib-sieve/sieve-extensions.c @@ -268,7 +268,8 @@ static bool _sieve_extension_load(struct sieve_extension *ext) /* Call load handler */ if ( ext->def != NULL && ext->def->load != NULL && !ext->def->load(ext, &ext->context) ) { - sieve_sys_error("failed to load '%s' extension support.", ext->def->name); + sieve_sys_error(ext->svinst, + "failed to load '%s' extension support.", ext->def->name); return FALSE; } @@ -277,9 +278,9 @@ static bool _sieve_extension_load(struct sieve_extension *ext) static void _sieve_extension_unload(struct sieve_extension *ext) { - /* Call unload handler */ - if ( ext->def != NULL && ext->def->unload != NULL ) - ext->def->unload(ext); + /* Call unload handler */ + if ( ext->def != NULL && ext->def->unload != NULL ) + ext->def->unload(ext); } static void sieve_extension_registry_init(struct sieve_instance *svinst) @@ -544,7 +545,7 @@ void sieve_extensions_set_string hash_table_lookup(ext_reg->extension_index, name); if ( ext == NULL || ext->def == NULL ) { - sieve_sys_warning( + sieve_sys_warning(ext->svinst, "ignored unknown extension '%s' while configuring " "available extensions", name); continue; diff --git a/src/lib-sieve/sieve-message.c b/src/lib-sieve/sieve-message.c index 005dadc8c8985d13f301e4042afe012a9fbe901f..1ff42a197713b6f3562ea3155c726719635a9a0f 100644 --- a/src/lib-sieve/sieve-message.c +++ b/src/lib-sieve/sieve-message.c @@ -142,21 +142,31 @@ const void *sieve_message_context_extension_get static void sieve_message_envelope_parse(struct sieve_message_context *msgctx) { + struct sieve_instance *svinst = msgctx->svinst; + /* FIXME: log parse problems properly; logs only 'failure' now */ msgctx->envelope_recipient = sieve_address_parse_envelope_path (msgctx->pool, msgctx->msgdata->to_address); - if ( msgctx->envelope_recipient == NULL ) - sieve_sys_error("envelope recipient address '%s' is unparsable", msgctx->msgdata->to_address); - else if ( msgctx->envelope_recipient->local_part == NULL ) - sieve_sys_error("envelope recipient address '%s' is a null path", msgctx->msgdata->to_address); + if ( msgctx->envelope_recipient == NULL ) { + sieve_sys_error(svinst, + "envelope recipient address '%s' is unparsable", + msgctx->msgdata->to_address); + } else if ( msgctx->envelope_recipient->local_part == NULL ) { + sieve_sys_error(svinst, + "envelope recipient address '%s' is a null path", + msgctx->msgdata->to_address); + } msgctx->envelope_sender = sieve_address_parse_envelope_path (msgctx->pool, msgctx->msgdata->return_path); - if ( msgctx->envelope_sender == NULL ) - sieve_sys_error("envelope sender address '%s' is unparsable", msgctx->msgdata->return_path); + if ( msgctx->envelope_sender == NULL ) { + sieve_sys_error(svinst, + "envelope sender address '%s' is unparsable", + msgctx->msgdata->return_path); + } msgctx->envelope_parsed = TRUE; } diff --git a/src/lib-sieve/sieve-script.c b/src/lib-sieve/sieve-script.c index e0010b2a87f36ff73c9cf618b909e419dd9c904a..9f8765a53f5aebf131d451a1faf54d8aed1d81bc 100644 --- a/src/lib-sieve/sieve-script.c +++ b/src/lib-sieve/sieve-script.c @@ -142,7 +142,7 @@ static void sieve_script_handle_file_error sieve_error(ehandler, name, "sieve script does not exist"); else { if ( svinst->debug ) - sieve_sys_debug("script file %s not found", t_abspath(path)); + sieve_sys_debug(svinst, "script file %s not found", t_abspath(path)); *error_r = SIEVE_ERROR_NOT_FOUND; } break; @@ -403,7 +403,7 @@ struct istream *sieve_script_open if ( result == NULL ) { /* Something went wrong, close the fd */ if ( close(fd) != 0 ) { - sieve_sys_error( + sieve_sys_error(script->svinst, "failed to close sieve script: close(fd=%s) failed: %m", script->path); } diff --git a/src/lib-sieve/sieve-settings.c b/src/lib-sieve/sieve-settings.c index 9c318b2147fbce87785c63e59e488b9036f3d73a..cd0ed8e1cf767639b49b2484ef331d8fb6ace4ab 100644 --- a/src/lib-sieve/sieve-settings.c +++ b/src/lib-sieve/sieve-settings.c @@ -25,7 +25,8 @@ bool sieve_setting_get_uint_value *value_r = strtoull(str_value, &endp, 10); if ( *endp != '\0' ) { - sieve_sys_warning("invalid unsigned integer value for setting '%s': '%s'", + sieve_sys_warning(svinst, + "invalid unsigned integer value for setting '%s': '%s'", setting, str_value); return FALSE; } @@ -48,7 +49,7 @@ bool sieve_setting_get_int_value *value_r = strtoll(str_value, &endp, 10); if ( *endp != '\0' ) { - sieve_sys_warning("invalid integer value for setting '%s': '%s'", + sieve_sys_warning(svinst, "invalid integer value for setting '%s': '%s'", setting, str_value); return FALSE; @@ -92,7 +93,8 @@ bool sieve_setting_get_size_value multiply = 1024ULL*1024*1024*1024; break; default: - sieve_sys_warning("invalid unsigned integer value for setting '%s': '%s'", + sieve_sys_warning(svinst, + "invalid unsigned integer value for setting '%s': '%s'", setting, str_value); return FALSE; } @@ -124,7 +126,7 @@ bool sieve_setting_get_bool_value return TRUE; } - sieve_sys_warning("invalid boolean value for setting '%s': '%s'", + sieve_sys_warning(svinst, "invalid boolean value for setting '%s': '%s'", setting, str_value); return FALSE; } diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c index fd1e98a9c63daefe48b92b8185eb46fde7083ad6..3c0caef11344b4824724877f7ae56b75ecb0724e 100644 --- a/src/lib-sieve/sieve.c +++ b/src/lib-sieve/sieve.c @@ -26,6 +26,7 @@ #include "sieve.h" #include "sieve-common.h" +#include "sieve-error-private.h" #include <sys/types.h> #include <sys/stat.h> @@ -55,6 +56,8 @@ struct sieve_instance *sieve_init svinst->context = context; svinst->debug = debug; + sieve_errors_init(svinst); + /* Read limits from configuration */ svinst->max_script_size = SIEVE_DEFAULT_MAX_SCRIPT_SIZE; @@ -93,6 +96,8 @@ void sieve_deinit(struct sieve_instance **svinst) sieve_extensions_deinit(*svinst); + sieve_errors_deinit(*svinst); + pool_unref(&(*svinst)->pool); *svinst = NULL; @@ -247,7 +252,8 @@ struct sieve_binary *sieve_compile sieve_script_unref(&script); if ( svinst->debug && sbin != NULL ) { - sieve_sys_debug("script file %s successfully compiled", script_path); + sieve_sys_debug(svinst, "script file %s successfully compiled", + script_path); } return sbin; @@ -329,7 +335,8 @@ struct sieve_binary *sieve_open if ( !sieve_binary_up_to_date(sbin) ) { /* Not up to date */ if ( svinst->debug ) - sieve_sys_debug("script binary %s is not up-to-date", bin_path); + sieve_sys_debug(svinst, "script binary %s is not up-to-date", + bin_path); sieve_binary_unref(&sbin); sbin = NULL; @@ -341,7 +348,8 @@ struct sieve_binary *sieve_open */ if ( sbin != NULL ) { if ( svinst->debug ) - sieve_sys_debug("script binary %s successfully loaded", bin_path); + sieve_sys_debug(svinst, "script binary %s successfully loaded", + bin_path); } else { sbin = sieve_compile_script(script, ehandler, error_r); @@ -349,7 +357,8 @@ struct sieve_binary *sieve_open /* Save the binary if compile was successful */ if ( sbin != NULL ) { if ( svinst->debug ) - sieve_sys_debug("script %s successfully compiled", script_path); + sieve_sys_debug(svinst, "script %s successfully compiled", + script_path); } } } T_END; @@ -640,13 +649,14 @@ size_t sieve_max_script_size(struct sieve_instance *svinst) */ struct sieve_directory { + struct sieve_instance *svinst; DIR *dirp; const char *path; }; struct sieve_directory *sieve_directory_open -(const char *path, enum sieve_error *error_r) +(struct sieve_instance *svinst, const char *path, enum sieve_error *error_r) { struct sieve_directory *sdir = NULL; DIR *dirp; @@ -663,14 +673,14 @@ struct sieve_directory *sieve_directory_open *error_r = SIEVE_ERROR_NOT_FOUND; break; case EACCES: - sieve_sys_error("failed to open sieve dir: %s", + sieve_sys_error(svinst, "failed to open sieve dir: %s", eacces_error_get("stat", path)); if ( error_r != NULL ) *error_r = SIEVE_ERROR_NO_PERM; break; default: - sieve_sys_error("failed to open sieve dir: " - "stat(%s) failed: %m", path); + sieve_sys_error(svinst, "failed to open sieve dir: stat(%s) failed: %m", + path); if ( error_r != NULL ) *error_r = SIEVE_ERROR_TEMP_FAIL; break; @@ -688,14 +698,14 @@ struct sieve_directory *sieve_directory_open *error_r = SIEVE_ERROR_NOT_FOUND; break; case EACCES: - sieve_sys_error("failed to open sieve dir: %s", + sieve_sys_error(svinst, "failed to open sieve dir: %s", eacces_error_get("opendir", path)); if ( error_r != NULL ) *error_r = SIEVE_ERROR_NO_PERM; break; default: - sieve_sys_error("failed to open sieve dir: " - "opendir(%s) failed: %m", path); + sieve_sys_error(svinst, "failed to open sieve dir: opendir(%s) failed: " + "%m", path); if ( error_r != NULL ) *error_r = SIEVE_ERROR_TEMP_FAIL; break; @@ -713,6 +723,8 @@ struct sieve_directory *sieve_directory_open sdir->dirp = NULL; } + sdir->svinst = svinst; + return sdir; } @@ -729,7 +741,7 @@ const char *sieve_directory_get_scriptfile(struct sieve_directory *sdir) errno = 0; if ( (dp = readdir(sdir->dirp)) == NULL ) { if ( errno != 0 ) { - sieve_sys_error("failed to read sieve dir: " + sieve_sys_error(sdir->svinst, "failed to read sieve dir: " "readdir(%s) failed: %m", sdir->path); } @@ -761,7 +773,7 @@ void sieve_directory_close(struct sieve_directory **sdir) { /* Close the directory */ if ( (*sdir)->dirp != NULL && closedir((*sdir)->dirp) < 0 ) - sieve_sys_error("failed to close sieve dir: " + sieve_sys_error((*sdir)->svinst, "failed to close sieve dir: " "closedir(%s) failed: %m", (*sdir)->path); *sdir = NULL; diff --git a/src/lib-sieve/sieve.h b/src/lib-sieve/sieve.h index 082e95acc51d520977e69c78ada2433807d4fa82..ac58cf77ba98a1634d0fc8f51676d913725d16e9 100644 --- a/src/lib-sieve/sieve.h +++ b/src/lib-sieve/sieve.h @@ -181,7 +181,7 @@ size_t sieve_max_script_size(struct sieve_instance *svinst); struct sieve_directory; struct sieve_directory *sieve_directory_open - (const char *path, enum sieve_error *error_r); + (struct sieve_instance *svinst, const char *path, enum sieve_error *error_r); const char *sieve_directory_get_scriptfile(struct sieve_directory *sdir); void sieve_directory_close(struct sieve_directory **sdir); diff --git a/src/lib-sieve/tst-size.c b/src/lib-sieve/tst-size.c index c4759decf4d6a53799a23e9c4f38c8e0dd6a88ac..2e3aa19d737b27f1d899c4f2a0e8011afefef847 100644 --- a/src/lib-sieve/tst-size.c +++ b/src/lib-sieve/tst-size.c @@ -263,7 +263,7 @@ static int tst_size_operation_execute /* Get the size of the message */ if ( !tst_size_get(renv, &mail_size) ) { /* FIXME: improve this error */ - sieve_sys_error("failed to assess message size"); + sieve_sys_error(renv->svinst, "failed to assess message size"); return SIEVE_EXEC_FAILURE; } diff --git a/src/lib-sievestorage/sieve-storage.c b/src/lib-sievestorage/sieve-storage.c index 2e0a1c791bfe6e5629c4de2d7b2d9d6beb29b82e..e5478835edc1182111ab6cd9cc9bb7bfe1a8fe42 100644 --- a/src/lib-sievestorage/sieve-storage.c +++ b/src/lib-sievestorage/sieve-storage.c @@ -399,7 +399,7 @@ struct sieve_error_handler *sieve_storage_get_error_handler if ( storage->ehandler == NULL ) { pool_t pool = pool_alloconly_create("sieve_storage_ehandler", 512); ehandler = p_new(pool, struct sieve_storage_ehandler,1); - sieve_error_handler_init(&ehandler->handler, pool, 1); + sieve_error_handler_init(&ehandler->handler, storage->svinst, pool, 1); ehandler->handler.verror = sieve_storage_verror; ehandler->storage = storage; diff --git a/src/managesieve/cmd-putscript.c b/src/managesieve/cmd-putscript.c index 10d4f31a19ae7a1dc9f936f5c43c2f9a6140fe6e..a52d88257ed8e45a49b118e6d069b3f85bb9200c 100644 --- a/src/managesieve/cmd-putscript.c +++ b/src/managesieve/cmd-putscript.c @@ -199,8 +199,8 @@ static bool cmd_putscript_finish_parsing(struct client_command_context *cmd) /* Prepare error handler */ errors = str_new(default_pool, 1024); - ehandler = sieve_strbuf_ehandler_create - (errors, TRUE, client->set->managesieve_max_compile_errors); + ehandler = sieve_strbuf_ehandler_create(client->svinst, errors, TRUE, + client->set->managesieve_max_compile_errors); /* Compile */ if ( (sbin=sieve_compile_script(script, ehandler, NULL)) == NULL ) { diff --git a/src/plugins/lda-sieve/lda-sieve-log.c b/src/plugins/lda-sieve/lda-sieve-log.c index 4d9d545c5b291b8c3e002eb9d37ff9ff0a531096..1b12809c7c5a94ca4ae096a17447094fa5a4f7c6 100644 --- a/src/plugins/lda-sieve/lda-sieve-log.c +++ b/src/plugins/lda-sieve/lda-sieve-log.c @@ -76,7 +76,8 @@ static void lda_sieve_log_vdebug } struct sieve_error_handler *lda_sieve_log_ehandler_create -(struct mail_deliver_context *mdctx, unsigned int max_errors) +(struct sieve_instance *svinst, struct mail_deliver_context *mdctx, + unsigned int max_errors) { pool_t pool; struct lda_sieve_log_ehandler *ehandler; @@ -85,7 +86,7 @@ struct sieve_error_handler *lda_sieve_log_ehandler_create ehandler = p_new(pool, struct lda_sieve_log_ehandler, 1); ehandler->mdctx = mdctx; - sieve_error_handler_init(&ehandler->handler, pool, max_errors); + sieve_error_handler_init(&ehandler->handler, svinst, pool, max_errors); ehandler->handler.verror = lda_sieve_log_verror; ehandler->handler.vwarning = lda_sieve_log_vwarning; diff --git a/src/plugins/lda-sieve/lda-sieve-log.h b/src/plugins/lda-sieve/lda-sieve-log.h index 1c549ac8309302b7b13eb7be2d0148eaed2fde8c..4523b82f64e8bb71ec4fbdb6cf288c2a05e72f40 100644 --- a/src/plugins/lda-sieve/lda-sieve-log.h +++ b/src/plugins/lda-sieve/lda-sieve-log.h @@ -8,6 +8,7 @@ #include "mail-deliver.h" struct sieve_error_handler *lda_sieve_log_ehandler_create - (struct mail_deliver_context *mdctx, unsigned int max_errors); + (struct sieve_instance *svinst, struct mail_deliver_context *mdctx, + unsigned int max_errors); #endif /* __LDA_SIEVE_LOG */ diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c index 44ea0f9ae5d8c64dc07a4c4ed0b802b969364533..3fa7a9d8dc7bae2609051e020bdd3724ba45de38 100644 --- a/src/plugins/lda-sieve/lda-sieve-plugin.c +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c @@ -136,7 +136,8 @@ struct lda_sieve_run_context { const char *userlog; }; -static const char *lda_sieve_get_personal_path(struct mail_user *user) +static const char *lda_sieve_get_personal_path +(struct sieve_instance *svinst, struct mail_user *user) { const char *script_path, *home; @@ -150,7 +151,7 @@ static const char *lda_sieve_get_personal_path(struct mail_user *user) if (*script_path == '\0') { /* disabled */ if ( user->mail_debug ) - sieve_sys_debug("empty script path, disabled"); + sieve_sys_debug(svinst, "empty script path, disabled"); return NULL; } @@ -161,7 +162,7 @@ static const char *lda_sieve_get_personal_path(struct mail_user *user) if ( home == NULL || *home == '\0' ) { if ( user->mail_debug ) - sieve_sys_debug("relative script path, but empty home dir"); + sieve_sys_debug(svinst, "relative script path, but empty home dir"); return NULL; } @@ -169,7 +170,7 @@ static const char *lda_sieve_get_personal_path(struct mail_user *user) } } else { if ( home == NULL || *home == '\0' ) { - sieve_sys_error( + sieve_sys_error(svinst, "path to user's main active personal script is unknown. " "See http://wiki.dovecot.org/LDA/Sieve/Dovecot#configuration"); return NULL; @@ -181,7 +182,8 @@ static const char *lda_sieve_get_personal_path(struct mail_user *user) return script_path; } -static const char *lda_sieve_get_default_path(struct mail_user *user) +static const char *lda_sieve_get_default_path +(struct mail_user *user) { const char *script_path; @@ -196,13 +198,14 @@ static const char *lda_sieve_get_default_path(struct mail_user *user) } static int lda_sieve_multiscript_get_scriptfiles -(const char *script_path, ARRAY_TYPE(const_string) *scriptfiles) +(struct sieve_instance *svinst, const char *script_path, + ARRAY_TYPE(const_string) *scriptfiles) { struct sieve_directory *sdir; enum sieve_error error; const char *file; - if ( (sdir=sieve_directory_open(script_path, &error)) == NULL ) + if ( (sdir=sieve_directory_open(svinst, script_path, &error)) == NULL ) return ( error == SIEVE_ERROR_NOT_FOUND ? 0 : -1 ); while ( (file=sieve_directory_get_scriptfile(sdir)) != NULL ) { @@ -238,7 +241,7 @@ static void lda_sieve_binary_save if ( sieve_save(sbin, NULL, FALSE, &error) < 0 && error == SIEVE_ERROR_NO_PERM && script_path != srctx->user_script ) { /* Cannot save binary for global script */ - sieve_sys_error( + sieve_sys_error(srctx->svinst, "the lda sieve plugin does not have permission " "to save global sieve script binaries; " "global sieve scripts like %s need to be " @@ -264,26 +267,25 @@ static struct sieve_binary *lda_sieve_open ehandler = srctx->master_ehandler; if ( debug ) - sieve_sys_debug("opening script %s", script_path); + sieve_sys_debug(svinst, "opening script %s", script_path); sieve_error_handler_reset(ehandler); /* Open the sieve script */ - if ( (sbin=sieve_open(svinst, script_path, script_name, ehandler, error_r)) + if ( (sbin=sieve_open(svinst, script_path, script_name, ehandler, error_r)) == NULL ) { if ( *error_r == SIEVE_ERROR_NOT_FOUND ) { if ( debug ) - sieve_sys_debug("script file %s is missing", script_path); + sieve_sys_debug(svinst, "script file %s is missing", script_path); } else { if ( script_path == srctx->user_script && srctx->userlog != NULL ) { - sieve_sys_error - ("failed to open script %s " - "(view logfile %s for more information)", - script_path, srctx->userlog); + sieve_sys_error(svinst, + "failed to open script %s " + "(view logfile %s for more information)", + script_path, srctx->userlog); } else { - sieve_sys_error - ("failed to open script %s", - script_path); + sieve_sys_error(svinst, + "failed to open script %s", script_path); } } @@ -307,10 +309,10 @@ static struct sieve_binary *lda_sieve_recompile /* Warn */ - sieve_sys_warning("encountered corrupt binary: re-compiling script %s", + sieve_sys_warning(svinst, "encountered corrupt binary: re-compiling script %s", script_path); - /* Recompile */ + /* Recompile */ if ( script_path == srctx->user_script ) ehandler = srctx->user_ehandler; @@ -321,13 +323,13 @@ static struct sieve_binary *lda_sieve_recompile (svinst, script_path, script_name, ehandler, error_r)) == NULL ) { if ( script_path == srctx->user_script && srctx->userlog != NULL ) { - sieve_sys_error - ("failed to re-compile script %s " - "(view logfile %s for more information)", - script_path, srctx->userlog); + sieve_sys_error(svinst, + "failed to re-compile script %s " + "(view logfile %s for more information)", + script_path, srctx->userlog); } else { - sieve_sys_error - ("failed to re-compile script %s", script_path); + sieve_sys_error(svinst, + "failed to re-compile script %s", script_path); } return NULL; @@ -336,27 +338,29 @@ static struct sieve_binary *lda_sieve_recompile return sbin; } -static int lda_sieve_handle_exec_status(const char *script_path, int status) +static int lda_sieve_handle_exec_status +(struct lda_sieve_run_context *srctx, const char *script_path, int status) { + struct sieve_instance *svinst = srctx->svinst; int ret; switch ( status ) { case SIEVE_EXEC_FAILURE: - sieve_sys_error - ("execution of script %s failed, but implicit keep was successful", + sieve_sys_error(svinst, + "execution of script %s failed, but implicit keep was successful", script_path); ret = 1; break; case SIEVE_EXEC_BIN_CORRUPT: - sieve_sys_error - ("!!BUG!!: binary compiled from %s is still corrupt; " + sieve_sys_error(svinst, + "!!BUG!!: binary compiled from %s is still corrupt; " "bailing out and reverting to default delivery", script_path); ret = -1; break; case SIEVE_EXEC_KEEP_FAILED: - sieve_sys_error - ("script %s failed with unsuccessful implicit keep", script_path); + sieve_sys_error(svinst, + "script %s failed with unsuccessful implicit keep", script_path); ret = -1; break; default: @@ -370,6 +374,7 @@ static int lda_sieve_handle_exec_status(const char *script_path, int status) static int lda_sieve_singlescript_execute (struct lda_sieve_run_context *srctx) { + struct sieve_instance *svinst = srctx->svinst; const char *script_file = srctx->script_files[0]; bool user_script = ( script_file == srctx->user_script ); struct sieve_error_handler *ehandler; @@ -386,18 +391,18 @@ static int lda_sieve_singlescript_execute /* Execute */ if ( debug ) - sieve_sys_debug("executing script from %s", sieve_get_source(sbin)); + sieve_sys_debug(svinst, "executing script from %s", sieve_get_source(sbin)); if ( user_script ) { ehandler = srctx->user_ehandler; - sieve_error_handler_copy_masterlog(ehandler, TRUE); + sieve_error_handler_copy_masterlog(ehandler, TRUE); } else { ehandler = srctx->master_ehandler; } ret = sieve_execute(sbin, srctx->msgdata, srctx->scriptenv, ehandler, NULL); - sieve_error_handler_copy_masterlog(ehandler, FALSE); + sieve_error_handler_copy_masterlog(ehandler, FALSE); /* Recompile if corrupt binary */ @@ -414,7 +419,7 @@ static int lda_sieve_singlescript_execute /* Execute again */ if ( debug ) - sieve_sys_debug("executing script from %s", sieve_get_source(sbin)); + sieve_sys_debug(svinst, "executing script from %s", sieve_get_source(sbin)); if ( user_script ) sieve_error_handler_copy_masterlog(ehandler, TRUE); @@ -432,7 +437,7 @@ static int lda_sieve_singlescript_execute sieve_close(&sbin); /* Report status */ - return lda_sieve_handle_exec_status(script_file, ret); + return lda_sieve_handle_exec_status(srctx, script_file, ret); } static int lda_sieve_multiscript_execute @@ -484,7 +489,7 @@ static int lda_sieve_multiscript_execute sieve_error_handler_copy_masterlog(ehandler, TRUE); if ( debug ) - sieve_sys_debug("executing script from %s", sieve_get_source(sbin)); + sieve_sys_debug(svinst, "executing script from %s", sieve_get_source(sbin)); more = sieve_multiscript_run(mscript, sbin, ehandler, final); @@ -533,30 +538,25 @@ static int lda_sieve_multiscript_execute sieve_error_handler_copy_masterlog(ehandler, FALSE); - return lda_sieve_handle_exec_status(last_script, ret); + return lda_sieve_handle_exec_status(srctx, last_script, ret); } static int lda_sieve_run -(struct mail_deliver_context *mdctx, +(struct mail_deliver_context *mdctx, struct sieve_instance *svinst, const char *user_script, const char *default_script, const ARRAY_TYPE (const_string) *scripts_before, const ARRAY_TYPE (const_string) *scripts_after, struct mail_storage **storage_r) { - struct sieve_instance *svinst; ARRAY_TYPE (const_string) scripts; struct lda_sieve_run_context srctx; struct sieve_message_data msgdata; struct sieve_script_env scriptenv; struct sieve_exec_status estatus; - bool debug = mdctx->dest_user->mail_debug; int ret = 0; *storage_r = NULL; - /* Initialize Sieve engine */ - svinst = sieve_init(&lda_sieve_env, mdctx->dest_user, debug); - /* Initialize */ memset(&srctx, 0, sizeof(srctx)); @@ -589,11 +589,11 @@ static int lda_sieve_run if ( user_script != NULL ) { srctx.userlog = t_strconcat(user_script, ".log", NULL); srctx.user_ehandler = sieve_logfile_ehandler_create - (srctx.userlog, LDA_SIEVE_MAX_USER_ERRORS); + (svinst, srctx.userlog, LDA_SIEVE_MAX_USER_ERRORS); } srctx.master_ehandler = lda_sieve_log_ehandler_create - (mdctx, LDA_SIEVE_MAX_SYSTEM_ERRORS); + (svinst, mdctx, LDA_SIEVE_MAX_SYSTEM_ERRORS); sieve_system_ehandler_set(srctx.master_ehandler); sieve_error_handler_accept_infolog(srctx.master_ehandler, TRUE); @@ -653,7 +653,6 @@ static int lda_sieve_run if ( srctx.user_ehandler != NULL ) sieve_error_handler_unref(&srctx.user_ehandler); - sieve_system_ehandler_reset(); sieve_error_handler_unref(&srctx.master_ehandler); /* Deinitialize Sieve engine */ @@ -665,12 +664,17 @@ static int lda_sieve_run static int lda_sieve_deliver_mail (struct mail_deliver_context *mdctx, struct mail_storage **storage_r) { + struct sieve_instance *svinst; const char *user_script, *default_script, *sieve_before, *sieve_after; ARRAY_TYPE (const_string) scripts_before; ARRAY_TYPE (const_string) scripts_after; bool debug = mdctx->dest_user->mail_debug; int ret = 0; + /* Initialize Sieve engine */ + + svinst = sieve_init(&lda_sieve_env, mdctx->dest_user, debug); + *storage_r = NULL; T_BEGIN { @@ -678,7 +682,7 @@ static int lda_sieve_deliver_mail /* Find the personal script to execute */ - user_script = lda_sieve_get_personal_path(mdctx->dest_user); + user_script = lda_sieve_get_personal_path(svinst, mdctx->dest_user); default_script = lda_sieve_get_default_path(mdctx->dest_user); if ( user_script != NULL && stat(user_script, &st) < 0 ) { @@ -686,16 +690,16 @@ static int lda_sieve_deliver_mail switch ( errno ) { case ENOENT: if ( debug ) - sieve_sys_debug("user's script path %s doesn't exist " + sieve_sys_debug(svinst, "user's script path %s doesn't exist " "(using global script path in stead)", user_script); break; case EACCES: - sieve_sys_error("failed to stat user's sieve script: %s " + sieve_sys_error(svinst, "failed to stat user's sieve script: %s " "(using global script path in stead)", eacces_error_get("stat", user_script)); break; default: - sieve_sys_error("failed to stat user's sieve script: " + sieve_sys_error(svinst, "failed to stat user's sieve script: " "stat(%s) failed: %m (using global script path in stead)", user_script); break; @@ -708,9 +712,9 @@ static int lda_sieve_deliver_mail const char *script = user_script == NULL ? default_script : user_script; if ( script == NULL ) - sieve_sys_debug("user has no valid personal script"); + sieve_sys_debug(svinst, "user has no valid personal script"); else - sieve_sys_debug("using sieve path for user's script: %s", script); + sieve_sys_debug(svinst, "using sieve path for user's script: %s", script); } /* Check for multiscript */ @@ -723,15 +727,15 @@ static int lda_sieve_deliver_mail if ( sieve_before != NULL && *sieve_before != '\0' ) { if ( lda_sieve_multiscript_get_scriptfiles - (sieve_before, &scripts_before) == 0 && debug ) { - sieve_sys_debug("sieve_before path not found: %s", sieve_before); + (svinst, sieve_before, &scripts_before) == 0 && debug ) { + sieve_sys_debug(svinst, "sieve_before path not found: %s", sieve_before); } } if ( sieve_after != NULL && *sieve_after != '\0' ) { if ( lda_sieve_multiscript_get_scriptfiles - (sieve_after, &scripts_after) == 0 && debug ) { - sieve_sys_debug("sieve_after path not found: %s", sieve_after); + (svinst, sieve_after, &scripts_after) == 0 && debug ) { + sieve_sys_debug(svinst, "sieve_after path not found: %s", sieve_after); } } @@ -741,13 +745,13 @@ static int lda_sieve_deliver_mail scriptfiles = array_get(&scripts_before, &count); for ( i = 0; i < count; i ++ ) { - sieve_sys_debug("executed before user's script(%d): %s", + sieve_sys_debug(svinst, "executed before user's script(%d): %s", i+1, scriptfiles[i]); } scriptfiles = array_get(&scripts_after, &count); for ( i = 0; i < count; i ++ ) { - sieve_sys_debug("executed after user's script(%d): %s", + sieve_sys_debug(svinst, "executed after user's script(%d): %s", i+1, scriptfiles[i]); } } @@ -757,7 +761,7 @@ static int lda_sieve_deliver_mail if ( array_count(&scripts_before) == 0 && array_count(&scripts_after) == 0 && user_script == NULL && default_script == NULL ) { if ( debug ) - sieve_sys_debug("no scripts to execute: reverting to default delivery."); + sieve_sys_debug(svinst, "no scripts to execute: reverting to default delivery."); /* No error, but no delivery by this plugin either. A return value of <= 0 for a * deliver plugin is is considered a failure. In deliver itself, saved_mail and @@ -769,8 +773,8 @@ static int lda_sieve_deliver_mail /* Run the script(s) */ ret = lda_sieve_run - (mdctx, user_script, default_script, &scripts_before, &scripts_after, - storage_r); + (mdctx, svinst, user_script, default_script, &scripts_before, + &scripts_after, storage_r); } } T_END; diff --git a/src/sieve-tools/sieve-test.c b/src/sieve-tools/sieve-test.c index 87739e0adcfec45bcbb3ee65cafcc4aef226f120..fdf8a89756311b001e86a8473bf5fb1990a86de7 100644 --- a/src/sieve-tools/sieve-test.c +++ b/src/sieve-tools/sieve-test.c @@ -207,7 +207,7 @@ int main(int argc, char **argv) (void) sieve_extension_register(svinst, &debug_extension, TRUE); /* Create error handler */ - ehandler = sieve_stderr_ehandler_create(0); + ehandler = sieve_stderr_ehandler_create(svinst, 0); sieve_system_ehandler_set(ehandler); sieve_error_handler_accept_infolog(ehandler, TRUE); @@ -225,7 +225,7 @@ int main(int argc, char **argv) } else { /* Dump script */ sieve_tool_dump_binary_to(main_sbin, dumpfile); - + /* Obtain mail namespaces from -l argument */ if ( mailloc != NULL ) { sieve_tool_init_mail_user(sieve_tool, mailloc); @@ -380,12 +380,11 @@ int main(int argc, char **argv) if ( main_sbin != NULL ) sieve_close(&main_sbin); } - + /* Cleanup error handler */ sieve_error_handler_unref(&ehandler); - sieve_system_ehandler_reset(); sieve_tool_deinit(&sieve_tool); - + return exit_status; } diff --git a/src/testsuite/cmd-test-binary.c b/src/testsuite/cmd-test-binary.c index 7bb076ca3612ab18c974c775a386df8e4e66dbe7..349b9f295791daf5a99a0b9f30c4d0f3f0dbbe0e 100644 --- a/src/testsuite/cmd-test-binary.c +++ b/src/testsuite/cmd-test-binary.c @@ -178,7 +178,8 @@ static int cmd_test_binary_operation_execute sieve_binary_unref(&sbin); } else { - sieve_sys_error("failed to load binary %s", str_c(binary_name)); + sieve_sys_error(testsuite_sieve_instance, + "failed to load binary %s", str_c(binary_name)); return SIEVE_EXEC_FAILURE; } @@ -194,7 +195,8 @@ static int cmd_test_binary_operation_execute if ( sbin != NULL ) testsuite_binary_save(sbin, str_c(binary_name)); else { - sieve_sys_error("no compiled binary to save as %s", str_c(binary_name)); + sieve_sys_error(testsuite_sieve_instance, + "no compiled binary to save as %s", str_c(binary_name)); return SIEVE_EXEC_FAILURE; } } else { diff --git a/src/testsuite/testsuite-log.c b/src/testsuite/testsuite-log.c index b43a30de9c277d46ed5a03f98252ceac8e1661b6..d713d49c8967bb7a63dd3c53469be1e73d94949e 100644 --- a/src/testsuite/testsuite-log.c +++ b/src/testsuite/testsuite-log.c @@ -9,6 +9,7 @@ #include "sieve-stringlist.h" #include "sieve-error-private.h" +#include "testsuite-common.h" #include "testsuite-log.h" /* @@ -40,8 +41,7 @@ static void _testsuite_log_verror pool_t pool = _testsuite_logmsg_pool; struct _testsuite_log_message msg; - if ( _testsuite_log_stdout ) - { + if ( _testsuite_log_stdout ) { va_list args_copy; VA_COPY(args_copy, args); @@ -52,7 +52,7 @@ static void _testsuite_log_verror fprintf(stdout, "LOG: error: %s: %s.\n", location, t_strdup_vprintf(fmt, args_copy)); } - + msg.location = p_strdup(pool, location); msg.message = p_strdup_vprintf(pool, fmt, args); @@ -78,8 +78,7 @@ static void _testsuite_log_vwarning pool_t pool = _testsuite_logmsg_pool; struct _testsuite_log_message msg; - if ( _testsuite_log_stdout ) - { + if ( _testsuite_log_stdout ) { va_list args_copy; VA_COPY(args_copy, args); @@ -90,11 +89,11 @@ static void _testsuite_log_vwarning fprintf(stdout, "LOG: warning: %s: %s.\n", location, t_strdup_vprintf(fmt, args_copy)); } - + msg.location = p_strdup(pool, location); msg.message = p_strdup_vprintf(pool, fmt, args); - array_append(&_testsuite_log_warnings, &msg, 1); + array_append(&_testsuite_log_warnings, &msg, 1); } static struct sieve_error_handler *_testsuite_log_ehandler_create(void) @@ -105,7 +104,7 @@ static struct sieve_error_handler *_testsuite_log_ehandler_create(void) pool = pool_alloconly_create ("testsuite_log_ehandler", sizeof(struct sieve_error_handler)); ehandler = p_new(pool, struct sieve_error_handler, 1); - sieve_error_handler_init(ehandler, pool, 0); + sieve_error_handler_init(ehandler, testsuite_sieve_instance, pool, 0); ehandler->verror = _testsuite_log_verror; ehandler->vwarning = _testsuite_log_vwarning; @@ -121,7 +120,7 @@ static struct sieve_error_handler *_testsuite_log_main_ehandler_create(void) pool = pool_alloconly_create ("testsuite_log_main_ehandler", sizeof(struct sieve_error_handler)); ehandler = p_new(pool, struct sieve_error_handler, 1); - sieve_error_handler_init(ehandler, pool, 0); + sieve_error_handler_init(ehandler, testsuite_sieve_instance, pool, 0); ehandler->verror = _testsuite_log_main_verror; ehandler->vwarning = _testsuite_log_vwarning; @@ -143,9 +142,9 @@ void testsuite_log_clear_messages(void) _testsuite_logmsg_pool = pool_alloconly_create ("testsuite_log_messages", 8192); - - p_array_init(&_testsuite_log_errors, _testsuite_logmsg_pool, 128); - p_array_init(&_testsuite_log_warnings, _testsuite_logmsg_pool, 128); + + p_array_init(&_testsuite_log_errors, _testsuite_logmsg_pool, 128); + p_array_init(&_testsuite_log_warnings, _testsuite_logmsg_pool, 128); sieve_error_handler_reset(testsuite_log_ehandler); } @@ -158,10 +157,10 @@ void testsuite_log_init(bool log_stdout) { _testsuite_log_stdout = log_stdout; - testsuite_log_ehandler = _testsuite_log_ehandler_create(); + testsuite_log_ehandler = _testsuite_log_ehandler_create(); sieve_error_handler_accept_infolog(testsuite_log_ehandler, TRUE); - testsuite_log_main_ehandler = _testsuite_log_main_ehandler_create(); + testsuite_log_main_ehandler = _testsuite_log_main_ehandler_create(); sieve_system_ehandler_set(testsuite_log_ehandler); @@ -170,8 +169,6 @@ void testsuite_log_init(bool log_stdout) void testsuite_log_deinit(void) { - sieve_system_ehandler_reset(); - sieve_error_handler_unref(&testsuite_log_ehandler); sieve_error_handler_unref(&testsuite_log_main_ehandler); diff --git a/src/testsuite/testsuite-mailstore.c b/src/testsuite/testsuite-mailstore.c index c298d0f5e02700b979d37093e513720e88e1d9a0..49d423cda5f2cb6ac44d68b20db558531eb0b37a 100644 --- a/src/testsuite/testsuite-mailstore.c +++ b/src/testsuite/testsuite-mailstore.c @@ -134,7 +134,8 @@ static struct mail *testsuite_mailstore_open(const char *folder) box = mailbox_alloc(ns->list, folder, flags); if ( mailbox_open(box) < 0 ) { - sieve_sys_error("testsuite: failed to open mailbox '%s'", folder); + sieve_sys_error(testsuite_sieve_instance, + "testsuite: failed to open mailbox '%s'", folder); mailbox_free(&box); return NULL; } @@ -142,7 +143,8 @@ static struct mail *testsuite_mailstore_open(const char *folder) /* Sync mailbox */ if ( mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0 ) { - sieve_sys_error("testsuite: failed to sync mailbox '%s'", folder); + sieve_sys_error(testsuite_sieve_instance, + "testsuite: failed to sync mailbox '%s'", folder); mailbox_free(&box); return NULL; }