bool cmd_setactive(struct client_command_context *cmd) { struct client *client = cmd->client; struct sieve_storage *storage = client->storage; const char *scriptname; struct sieve_script *script; int ret; /* <scriptname> */ if ( !client_read_string_args(cmd, TRUE, 1, &scriptname) ) return FALSE; /* Activate, or .. */ if ( *scriptname != '\0' ) { string_t *errors = NULL; const char *errormsg = NULL; bool warnings = FALSE; bool success = TRUE; script = sieve_storage_open_script (storage, scriptname, NULL); if ( script == NULL ) { client_send_storage_error(client, storage); return TRUE; } if ( sieve_script_is_active(script) <= 0 ) { /* Script is first being activated; compile it again without the UPLOAD * flag. */ T_BEGIN { struct sieve_error_handler *ehandler; enum sieve_compile_flags cpflags = SIEVE_COMPILE_FLAG_NOGLOBAL | SIEVE_COMPILE_FLAG_ACTIVATED; struct sieve_binary *sbin; enum sieve_error error; /* 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) { errormsg = sieve_script_get_last_error(script, &error); if ( error == SIEVE_ERROR_NONE ) errormsg = NULL; } success = FALSE; } else { sieve_close(&sbin); } warnings = ( sieve_get_warnings(ehandler) > 0 ); sieve_error_handler_unref(&ehandler); } T_END; }
static int cmd_sieve_activate_run(struct doveadm_sieve_cmd_context *_ctx) { struct doveadm_sieve_activate_cmd_context *ctx = (struct doveadm_sieve_activate_cmd_context *)_ctx; struct sieve_storage *storage = _ctx->storage; struct sieve_script *script; enum sieve_error error; int ret = 0; script = sieve_storage_open_script (storage, ctx->scriptname, NULL); if ( script == NULL ) { i_error("Failed to activate Sieve script: %s", sieve_storage_get_last_error(storage, &error)); doveadm_sieve_cmd_failed_error(_ctx, error); return -1; } if ( sieve_script_is_active(script) <= 0 ) { /* Script is first being activated; compile it again without the UPLOAD * flag. */ struct sieve_error_handler *ehandler; enum sieve_compile_flags cpflags = SIEVE_COMPILE_FLAG_NOGLOBAL | SIEVE_COMPILE_FLAG_ACTIVATED; struct sieve_binary *sbin; enum sieve_error error; /* Compile */ ehandler = sieve_master_ehandler_create(ctx->ctx.svinst, NULL, 0); if ( (sbin=sieve_compile_script (script, ehandler, cpflags, &error)) == NULL ) { doveadm_sieve_cmd_failed_error(_ctx, error); ret = -1; } else { sieve_close(&sbin); } sieve_error_handler_unref(&ehandler); } /* Activate only when script is valid (or already active) */ if ( ret == 0 ) { /* Refresh activation no matter what; this can also resolve some erroneous * situations. */ ret = sieve_script_activate(script, (time_t)-1); if ( ret < 0 ) { i_error("Failed to activate Sieve script: %s", sieve_storage_get_last_error(storage, &error)); doveadm_sieve_cmd_failed_error(_ctx, error); ret = -1; } } sieve_script_unref(&script); return ret; }
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; }
int main(int argc, char **argv) { struct sieve_instance *svinst; const char *scriptfile, *dumpfile, *tracefile; struct sieve_trace_config tr_config; struct sieve_binary *sbin; const char *sieve_dir; bool log_stdout = FALSE; int ret, c; sieve_tool = sieve_tool_init ("testsuite", &argc, &argv, "d:t:T:EDP:", TRUE); /* Parse arguments */ scriptfile = dumpfile = tracefile = NULL; memset(&tr_config, 0, sizeof(tr_config)); tr_config.level = SIEVE_TRLVL_ACTIONS; while ((c = sieve_tool_getopt(sieve_tool)) > 0) { switch (c) { case 'd': /* destination address */ dumpfile = optarg; break; case 't': /* trace file */ tracefile = optarg; break; case 'T': sieve_tool_parse_trace_option(&tr_config, optarg); break; case 'E': log_stdout = TRUE; break; default: print_help(); i_fatal_status(EX_USAGE, "Unknown argument: %c", c); break; } } if ( optind < argc ) { scriptfile = t_strdup(argv[optind++]); } else { print_help(); i_fatal_status(EX_USAGE, "Missing <scriptfile> argument"); } if (optind != argc) { print_help(); i_fatal_status(EX_USAGE, "Unknown argument: %s", argv[optind]); } /* Initialize mail user */ sieve_tool_set_homedir(sieve_tool, t_abspath("")); /* Initialize settings environment */ testsuite_settings_init(); /* Currently needed for include (FIXME) */ sieve_dir = strrchr(scriptfile, '/'); if ( sieve_dir == NULL ) sieve_dir= "./"; else { sieve_dir = t_strdup_until(scriptfile, sieve_dir+1); } testsuite_setting_set ("sieve_dir", t_strconcat(sieve_dir, "included", NULL)); testsuite_setting_set ("sieve_global_dir", t_strconcat(sieve_dir, "included-global", NULL)); /* Finish testsuite initialization */ svinst = sieve_tool_init_finish(sieve_tool, FALSE); testsuite_init(svinst, log_stdout); printf("Test case: %s:\n\n", scriptfile); /* Compile sieve script */ if ( (sbin = sieve_compile (svinst, scriptfile, NULL, testsuite_log_main_ehandler, NULL)) != NULL ) { struct ostream *tracestream = NULL; struct sieve_script_env scriptenv; /* Dump script */ sieve_tool_dump_binary_to(sbin, dumpfile, FALSE); if ( tracefile != NULL ) tracestream = sieve_tool_open_output_stream(tracefile); testsuite_mailstore_init(); testsuite_message_init(); memset(&scriptenv, 0, sizeof(scriptenv)); scriptenv.user = sieve_tool_get_mail_user(sieve_tool); scriptenv.default_mailbox = "INBOX"; scriptenv.hostname = "testsuite.example.com"; scriptenv.postmaster_address = "*****@*****.**"; scriptenv.username = sieve_tool_get_username(sieve_tool); scriptenv.smtp_open = testsuite_smtp_open; scriptenv.smtp_close = testsuite_smtp_close; scriptenv.trace_stream = tracestream; scriptenv.trace_config = tr_config; testsuite_scriptenv = &scriptenv; testsuite_result_init(); /* Run the test */ ret = testsuite_run (sbin, &testsuite_msgdata, &scriptenv, testsuite_log_main_ehandler); switch ( ret ) { case SIEVE_EXEC_OK: break; case SIEVE_EXEC_FAILURE: case SIEVE_EXEC_KEEP_FAILED: testsuite_testcase_fail("test script execution aborted due to error"); break; case SIEVE_EXEC_BIN_CORRUPT: testsuite_testcase_fail("compiled test script binary is corrupt"); break; default: testsuite_testcase_fail("unknown execution exit code"); } sieve_close(&sbin); /* De-initialize message environment */ testsuite_message_deinit(); testsuite_mailstore_deinit(); testsuite_result_deinit(); if ( tracestream != NULL ) o_stream_unref(&tracestream); } else { testsuite_testcase_fail("failed to compile testcase script"); } /* De-initialize testsuite */ testsuite_deinit(); testsuite_settings_deinit(); sieve_tool_deinit(&sieve_tool); if ( !testsuite_testcase_result() ) return EXIT_FAILURE; return EXIT_SUCCESS; }