static bool opc_global_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { const struct sieve_extension *this_ext = denv->oprtn->ext; unsigned int count, i, var_count; struct sieve_variable_scope_binary *global_vars; struct sieve_variable_scope *global_scope; struct sieve_variable * const *vars; if ( !sieve_binary_read_unsigned(denv->sblock, address, &count) ) return FALSE; sieve_code_dumpf(denv, "GLOBAL (count: %u):", count); global_vars = ext_include_binary_get_global_scope(this_ext, denv->sbin); global_scope = sieve_variable_scope_binary_get(global_vars); vars = sieve_variable_scope_get_variables(global_scope, &var_count); sieve_code_descend(denv); for ( i = 0; i < count; i++ ) { unsigned int index; sieve_code_mark(denv); if ( !sieve_binary_read_unsigned(denv->sblock, address, &index) || index >= var_count ) return FALSE; sieve_code_dumpf(denv, "%d: VAR[%d]: '%s'", i, index, vars[index]->identifier); } return TRUE; }
static int opc_global_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_extension *this_ext = renv->oprtn->ext; struct sieve_variable_scope_binary *global_vars; struct sieve_variable_scope *global_scope; struct sieve_variable_storage *storage; struct sieve_variable * const *vars; unsigned int var_count, count, i; if ( !sieve_binary_read_unsigned(renv->sblock, address, &count) ) { sieve_runtime_trace_error(renv, "global: count operand invalid"); return SIEVE_EXEC_BIN_CORRUPT; } global_vars = ext_include_binary_get_global_scope(this_ext, renv->sbin); global_scope = sieve_variable_scope_binary_get(global_vars); vars = sieve_variable_scope_get_variables(global_scope, &var_count); storage = ext_include_interpreter_get_global_variables (this_ext, renv->interp); for ( i = 0; i < count; i++ ) { unsigned int index; if ( !sieve_binary_read_unsigned(renv->sblock, address, &index) ) { sieve_runtime_trace_error(renv, "global: variable index operand invalid"); return SIEVE_EXEC_BIN_CORRUPT; } if ( index >= var_count ) { sieve_runtime_trace_error(renv, "global: variable index %u is invalid in global storage (> %u)", index, var_count); return SIEVE_EXEC_BIN_CORRUPT; } sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "global: exporting variable '%s' [gvid: %u, vid: %u]", vars[index]->identifier, i, index); /* Make sure variable is initialized (export) */ (void)sieve_variable_get_modifiable(storage, index, NULL); } return SIEVE_EXEC_OK; }
static int _read_extensions(struct sieve_binary_block *sblock) { struct sieve_binary *sbin = sblock->sbin; sieve_size_t offset = 0; unsigned int i, count; bool result = 1; if ( !sieve_binary_read_unsigned(sblock, &offset, &count) ) return -1; for ( i = 0; result > 0 && i < count; i++ ) { T_BEGIN { string_t *extension; const struct sieve_extension *ext; unsigned int version; if ( sieve_binary_read_string(sblock, &offset, &extension) ) { ext = sieve_extension_get_by_name(sbin->svinst, str_c(extension)); if ( ext == NULL ) { sieve_sys_error(sbin->svinst, "binary open: binary %s requires unknown extension `%s'", sbin->path, str_sanitize(str_c(extension), 128)); result = 0; } else { struct sieve_binary_extension_reg *ereg = NULL; (void) sieve_binary_extension_register(sbin, ext, &ereg); if ( !sieve_binary_read_unsigned(sblock, &offset, &version) || !sieve_binary_read_unsigned(sblock, &offset, &ereg->block_id) ) { result = -1; } else if ( !sieve_extension_version_is(ext, version) ) { sieve_sys_debug(sbin->svinst, "binary open: binary %s was compiled with different version " "of the `%s' extension (compiled v%d, expected v%d;" "automatically fixed when re-compiled)", sbin->path, sieve_extension_name(ext), version, sieve_extension_version(ext)); result = 0; } } } else result = -1; } T_END; } return result; }
static bool ext_ihave_binary_open (const struct sieve_extension *ext, struct sieve_binary *sbin, void *context) { struct sieve_instance *svinst = ext->svinst; struct ext_ihave_binary_context *binctx = (struct ext_ihave_binary_context *) context; struct sieve_binary_block *sblock; unsigned int i, count, block_id; sieve_size_t offset; sblock = sieve_binary_extension_get_block(sbin, ext); if ( sblock != NULL ) { binctx->block = sblock; block_id = sieve_binary_block_get_id(sblock); offset = 0; /* Read number of missing extensions to read subsequently */ if ( !sieve_binary_read_unsigned(sblock, &offset, &count) ) { sieve_sys_error(svinst, "ihave: failed to read missing extension count " "from block %d of binary %s", block_id, sieve_binary_path(sbin)); return FALSE; } /* Read dependencies */ for ( i = 0; i < count; i++ ) { string_t *ext_name; const char *name; if ( !sieve_binary_read_string(sblock, &offset, &ext_name) ) { /* Binary is corrupt, recompile */ sieve_sys_error(svinst, "ihave: failed to read missing extension name " "from block %d of binary %s", block_id, sieve_binary_path(sbin)); return FALSE; } name = str_c(ext_name); array_append(&binctx->missing_extensions, &name, 1); } } return TRUE; }