Beispiel #1
0
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;
}
Beispiel #2
0
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;
}