struct sieve_binary *sieve_binary_open
(struct sieve_instance *svinst, const char *path, struct sieve_script *script,
	enum sieve_error *error_r)
{
	struct sieve_binary_extension_reg *const *regs;
	unsigned int ext_count, i;
	struct sieve_binary *sbin;
	struct sieve_binary_file *file;

	i_assert( script == NULL || sieve_script_svinst(script) == svinst );

	//file = _file_memory_open(path);
	if ( (file=_file_lazy_open(svinst, path, error_r)) == NULL )
		return NULL;

	/* Create binary object */
	sbin = sieve_binary_create(svinst, script);
	sbin->path = p_strdup(sbin->pool, path);
	sbin->file = file;

	if ( !_sieve_binary_open(sbin) ) {
		sieve_binary_unref(&sbin);
		if ( error_r != NULL )
			*error_r = SIEVE_ERROR_NOT_VALID;
		return NULL;
	}

	sieve_binary_activate(sbin);

	/* Signal open event to extensions */
	regs = array_get(&sbin->extensions, &ext_count);
	for ( i = 0; i < ext_count; i++ ) {
		const struct sieve_binary_extension *binext = regs[i]->binext;

		if ( binext != NULL && binext->binary_open != NULL &&
			!binext->binary_open(regs[i]->extension, sbin, regs[i]->context) ) {
			/* Extension thinks its corrupt */

			if ( error_r != NULL )
				*error_r = SIEVE_ERROR_NOT_VALID;

			sieve_binary_unref(&sbin);
			return NULL;
		}
	}

	return sbin;
}
Пример #2
0
void sieve_generator_free(struct sieve_generator **gentr)
{
	sieve_ast_unref(&(*gentr)->genenv.ast);

	sieve_error_handler_unref(&(*gentr)->ehandler);
	sieve_binary_debug_writer_deinit(&(*gentr)->dwriter);

	if ( (*gentr)->genenv.sbin != NULL )
		sieve_binary_unref(&(*gentr)->genenv.sbin);

	pool_unref(&((*gentr)->pool));

	*gentr = NULL;
}
Пример #3
0
struct sieve_binary *sieve_open_script
(struct sieve_script *script, struct sieve_error_handler *ehandler,
	enum sieve_compile_flags flags, enum sieve_error *error_r)
{
	struct sieve_instance *svinst = sieve_script_svinst(script);
	struct sieve_binary *sbin;

	T_BEGIN {
		/* Then try to open the matching binary */
		sbin = sieve_script_binary_load(script, error_r);

		if (sbin != NULL) {
			/* Ok, it exists; now let's see if it is up to date */
			if ( !sieve_binary_up_to_date(sbin, flags) ) {
				/* Not up to date */
				if ( svinst->debug ) {
					sieve_sys_debug(svinst, "Script binary %s is not up-to-date",
						sieve_binary_path(sbin));
				}

				sieve_binary_unref(&sbin);
				sbin = NULL;
			}
		}

		/* If the binary does not exist or is not up-to-date, we need
		 * to (re-)compile.
		 */
		if ( sbin != NULL ) {
			if ( svinst->debug ) {
				sieve_sys_debug(svinst,
					"Script binary %s successfully loaded",
					sieve_binary_path(sbin));
			}

		} else {
			sbin = sieve_compile_script(script, ehandler, flags, error_r);

			if ( sbin != NULL ) {
				if ( svinst->debug ) {
					sieve_sys_debug(svinst,
						"Script `%s' from %s successfully compiled",
						sieve_script_name(script), sieve_script_location(script));
				}
			}
		}
	} T_END;

	return sbin;
}
Пример #4
0
static int cmd_test_binary_operation_execute
(const struct sieve_runtime_env *renv, sieve_size_t *address)
{
	const struct sieve_operation *oprtn = renv->oprtn;
	string_t *binary_name = NULL;
	int ret;

	/* 
	 * Read operands 
	 */

	/* Binary Name */

	if ( (ret=sieve_opr_string_read(renv, address, "binary-name", &binary_name))
		<= 0 )
		return ret;

	/*
	 * Perform operation
	 */

	if ( sieve_operation_is(oprtn, test_binary_load_operation) ) {
		struct sieve_binary *sbin = testsuite_binary_load(str_c(binary_name));

		if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) {
			sieve_runtime_trace(renv, 0, "testsuite: test_binary_load command");
			sieve_runtime_trace_descend(renv);
			sieve_runtime_trace(renv, 0, "load binary `%s'", str_c(binary_name));
		}

		if ( sbin != NULL ) {
			testsuite_script_set_binary(sbin);

			sieve_binary_unref(&sbin);
		} else {
			sieve_sys_error(testsuite_sieve_instance,
				"failed to load binary %s", str_c(binary_name));
			return SIEVE_EXEC_FAILURE;
		}

	} else if ( sieve_operation_is(oprtn, test_binary_save_operation) ) {
		struct sieve_binary *sbin = testsuite_script_get_binary();

		if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) {
			sieve_runtime_trace(renv, 0, "testsuite: test_binary_save command");
			sieve_runtime_trace_descend(renv);
			sieve_runtime_trace(renv, 0, "save binary `%s'", str_c(binary_name));
		}

		if ( sbin != NULL ) 
			testsuite_binary_save(sbin, str_c(binary_name));
		else {
			sieve_sys_error(testsuite_sieve_instance,
				"no compiled binary to save as %s", str_c(binary_name));
			return SIEVE_EXEC_FAILURE;
		}
	} else {
		i_unreached();
	}

	return SIEVE_EXEC_OK;
}
Пример #5
0
struct sieve_binary *sieve_generator_run
(struct sieve_generator *gentr, struct sieve_binary_block **sblock_r)
{
	bool topmost = ( sblock_r == NULL || *sblock_r == NULL );
	struct sieve_binary *sbin;
	struct sieve_binary_block *sblock, *debug_block;
	const struct sieve_extension *const *extensions;
	unsigned int i, ext_count;
	bool result = TRUE;

	/* Initialize */

	if ( topmost ) {
		sbin = sieve_binary_create_new(sieve_ast_script(gentr->genenv.ast));
		sblock = sieve_binary_block_get(sbin, SBIN_SYSBLOCK_MAIN_PROGRAM);
	} else {
		sblock = *sblock_r;
		sbin = sieve_binary_block_get_binary(sblock);
	}

	i_assert(sbin != NULL);

	sieve_binary_ref(sbin);
	gentr->genenv.sbin = sbin;
	gentr->genenv.sblock = sblock;

	/* Create debug block */
	debug_block = sieve_binary_block_create(sbin);
	gentr->dwriter = sieve_binary_debug_writer_init(debug_block);
	(void)sieve_binary_emit_unsigned
		(sblock, sieve_binary_block_get_id(debug_block));

	/* Load extensions linked to the AST and emit a list in code */
	extensions = sieve_ast_extensions_get(gentr->genenv.ast, &ext_count);
	(void) sieve_binary_emit_unsigned(sblock, ext_count);
	for ( i = 0; i < ext_count; i++ ) {
		const struct sieve_extension *ext = extensions[i];

		/* Link to binary */
		(void)sieve_binary_extension_link(sbin, ext);

		/* Emit */
		sieve_binary_emit_extension(sblock, ext, 0);

		/* Load */
		if ( ext->def != NULL && ext->def->generator_load != NULL &&
			!ext->def->generator_load(ext, &gentr->genenv) )
			result = FALSE;
	}

	/* Generate code */

	if ( result ) {
		if ( !sieve_generate_block
			(&gentr->genenv, sieve_ast_root(gentr->genenv.ast)))
			result = FALSE;
		else if ( topmost )
			sieve_binary_activate(sbin);
	}

	/* Cleanup */

	gentr->genenv.sbin = NULL;
	gentr->genenv.sblock = NULL;
	sieve_binary_unref(&sbin);

	if ( !result ) {
		if ( topmost ) {
			sieve_binary_unref(&sbin);
			if ( sblock_r != NULL )
				*sblock_r = NULL;
		}
		sbin = NULL;
	} else {
		if ( sblock_r != NULL )
			*sblock_r = sblock;
	}

	return sbin;
}
Пример #6
0
void sieve_close(struct sieve_binary **sbin)
{
	sieve_binary_unref(sbin);
}