Ejemplo n.º 1
0
bool cmd_getscript(struct client_command_context *cmd)
{
	struct client *client = cmd->client;
	struct cmd_getscript_context *ctx;
	const char *scriptname;
	enum sieve_error error;

	/* <scriptname> */
	if ( !client_read_string_args(cmd, TRUE, 1, &scriptname) )
		return FALSE;

	ctx = p_new(cmd->pool, struct cmd_getscript_context, 1);
	ctx->cmd = cmd;
	ctx->client = client;
	ctx->storage = client->storage;
	ctx->failed = FALSE;

	ctx->script = sieve_storage_open_script
		(client->storage, scriptname, NULL);
	if (ctx->script == NULL) {
		ctx->failed = TRUE;
		return cmd_getscript_finish(ctx);
	}

	if ( sieve_script_get_stream
		(ctx->script, &ctx->script_stream, &error) < 0 ) {
		if ( error == SIEVE_ERROR_NOT_FOUND )
			sieve_storage_set_error(client->storage, error, "Script does not exist.");
		ctx->failed = TRUE;
		return cmd_getscript_finish(ctx);
	}

	if ( sieve_script_get_size(ctx->script, &ctx->script_size) <= 0 ) {
		sieve_storage_set_critical(ctx->storage,
			"failed to obtain script size for script `%s' from %s",
			sieve_script_name(ctx->script), sieve_script_location(ctx->script));
		ctx->failed = TRUE;
		return cmd_getscript_finish(ctx);
	}

	i_assert(ctx->script_stream->v_offset == 0);

	client_send_line
		(client, t_strdup_printf("{%"PRIuUOFF_T"}", ctx->script_size));

	client->command_pending = TRUE;
	cmd->func = cmd_getscript_continue;
	cmd->context = ctx;

	return cmd_getscript_continue(cmd);
}
Ejemplo n.º 2
0
bool cmd_getscript(struct client_command_context *cmd)
{
	struct client *client = cmd->client;
	struct cmd_getscript_context *ctx;
	const char *scriptname;
	enum sieve_error error;

	/* <scriptname> */
	if ( !client_read_string_args(cmd, 1, TRUE, &scriptname) )
		return FALSE;

	ctx = p_new(cmd->pool, struct cmd_getscript_context, 1);
	ctx->cmd = cmd;
	ctx->client = client;
	ctx->storage = client->storage;
	ctx->failed = FALSE;
	ctx->script = sieve_storage_script_init(client->storage, scriptname);

	if (ctx->script == NULL) {
		ctx->failed = TRUE;
		return cmd_getscript_finish(ctx);
	}
			
	ctx->script_stream = sieve_script_open(ctx->script, &error);

	if ( ctx->script_stream == NULL ) {
		ctx->failed = TRUE;
		if ( error == SIEVE_ERROR_NOT_FOUND )
			sieve_storage_set_error(client->storage, error, "Script does not exist.");		
		return cmd_getscript_finish(ctx);
	}

	ctx->script_size = sieve_script_get_size(ctx->script);
	ctx->script_offset = 0;	

	client_send_line
		(client, t_strdup_printf("{%"PRIuUOFF_T"}", ctx->script_size));

	client->command_pending = TRUE;
	cmd->func = cmd_getscript_continue;
	cmd->context = ctx;

	return cmd_getscript_continue(cmd);
}
Ejemplo n.º 3
0
static bool cmd_putscript_finish_parsing(struct client_command_context *cmd)
{
	struct client *client = cmd->client;
	struct cmd_putscript_context *ctx = cmd->context;
	const struct managesieve_arg *args;
	int ret;

	/* if error occurs, the CRLF is already read. */
	client->input_skip_line = FALSE;

	/* <script literal> */
	ret = managesieve_parser_read_args(ctx->save_parser, 0, 0, &args);
	if (ret == -1 || client->output->closed) {
		if (ctx->storage != NULL)
			client_send_command_error(cmd, NULL);
		cmd_putscript_finish(ctx);
		return TRUE;
	}
	if (ret < 0) {
		/* need more data */
		return FALSE;
	}

	if ( MANAGESIEVE_ARG_IS_EOL(&args[0]) ) {
		struct sieve_script *script;
		bool success = TRUE;

		/* Eat away the trailing CRLF */
		client->input_skip_line = TRUE;

		/* Obtain script object for uploaded script */
		script = sieve_storage_save_get_tempscript(ctx->save_ctx);

		/* Check result */
		if ( script == NULL ) {
			client_send_storage_error(client, ctx->storage);
			cmd_putscript_finish(ctx);
			return TRUE;
		}

		/* If quoted string, the size was not known until now */
		if ( ctx->script_size == 0 ) {
			if (sieve_script_get_size(script, &ctx->script_size) < 0) {
				client_send_storage_error(client, ctx->storage);
				cmd_putscript_finish(ctx);
				return TRUE;
			}
			/* Check quota; max size is already checked */
			if ( ctx->scriptname != NULL && !managesieve_quota_check_all
					(client, ctx->scriptname, ctx->script_size) ) {
				cmd_putscript_finish(ctx);
				return TRUE;
			}
		}

		/* Try to compile script */
		T_BEGIN {
			struct sieve_error_handler *ehandler;
			enum sieve_compile_flags cpflags =
				SIEVE_COMPILE_FLAG_NOGLOBAL | SIEVE_COMPILE_FLAG_UPLOADED;
			struct sieve_binary *sbin;
			enum sieve_error error;
			string_t *errors;

			/* Mark this as an activation when we are replacing the active script */
			if ( sieve_storage_save_will_activate(ctx->save_ctx) ) {
				cpflags |= SIEVE_COMPILE_FLAG_ACTIVATED;
			}

			/* Prepare error handler */
			errors = str_new(default_pool, 1024);
			ehandler = sieve_strbuf_ehandler_create(client->svinst, errors, TRUE,
				client->set->managesieve_max_compile_errors);

			/* Compile */
			if ( (sbin=sieve_compile_script
				(script, ehandler, cpflags, &error)) == NULL ) {
				if ( error != SIEVE_ERROR_NOT_VALID ) {
					const char *errormsg =
						sieve_script_get_last_error(script, &error);
					if ( error != SIEVE_ERROR_NONE )
						client_send_no(client, errormsg);
					else
						client_send_no(client, str_c(errors));
				} else {
					client_send_no(client, str_c(errors));
				}
				success = FALSE;
			} else {
				sieve_close(&sbin);

				/* Commit to save only when this is a putscript command */
				if ( ctx->scriptname != NULL ) {
					ret = sieve_storage_save_commit(&ctx->save_ctx);

					/* Check commit */
					if (ret < 0) {
						client_send_storage_error(client, ctx->storage);
						success = FALSE;
					}
				}
			}

			/* Finish up */
			cmd_putscript_finish(ctx);

			/* Report result to user */
			if ( success ) {
				if ( ctx->scriptname != NULL ) {
					client->put_count++;
					client->put_bytes += ctx->script_size;
				} else {
					client->check_count++;
					client->check_bytes += ctx->script_size;
				}

				if ( sieve_get_warnings(ehandler) > 0 )
					client_send_okresp(client, "WARNINGS", str_c(errors));
				else {
					if ( ctx->scriptname != NULL )
						client_send_ok(client, "PUTSCRIPT completed.");
					else
						client_send_ok(client, "Script checked successfully.");
				}
			}

			sieve_error_handler_unref(&ehandler);
			str_free(&errors);
		} T_END;

		return TRUE;
	}

	client_send_command_error(cmd, "Too many command arguments.");
	cmd_putscript_finish(ctx);
	return TRUE;
}