From 7cac6770e0b380d6e5f37b9fad71c9f7f15952ba Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 11 Apr 2014 18:56:47 +0200 Subject: Add support for async commands --- src/config.y | 44 ++++++++++++++++++++++++++++++-------------- src/lex.c | 2 ++ src/options.c | 14 +++++++------- src/peer.c | 5 ++++- src/shell.c | 37 ++++++++++++++++++++++++++----------- src/shell.h | 4 +++- 6 files changed, 72 insertions(+), 34 deletions(-) diff --git a/src/config.y b/src/config.y index 70ee4a2..2bdd5d3 100644 --- a/src/config.y +++ b/src/config.y @@ -69,6 +69,7 @@ %token TOK_ADDRESSES %token TOK_ANY %token TOK_AS +%token TOK_ASYNC %token TOK_AUTO %token TOK_BIND %token TOK_CAPABILITIES @@ -118,6 +119,7 @@ %token TOK_SECRET %token TOK_SECURE %token TOK_STDERR +%token TOK_SYNC %token TOK_SYSLOG %token TOK_TAP %token TOK_TO @@ -155,6 +157,9 @@ %type bind_default %type drop_capabilities_enabled %type autobool +%type sync +%type sync_def_sync +%type sync_def_async %% start: START_CONFIG config @@ -373,38 +378,38 @@ method: TOK_STRING { secret: TOK_STRING { free(conf->secret); conf->secret = strdup($1->str); } ; -on_pre_up: TOK_STRING { - fastd_shell_command_set(&conf->on_pre_up, $1->str); +on_pre_up: sync_def_sync TOK_STRING { + fastd_shell_command_set(&conf->on_pre_up, $2->str, $1); } ; -on_up: TOK_STRING { - fastd_shell_command_set(&conf->on_up, $1->str); +on_up: sync_def_sync TOK_STRING { + fastd_shell_command_set(&conf->on_up, $2->str, $1); } ; -on_down: TOK_STRING { - fastd_shell_command_set(&conf->on_down, $1->str); +on_down: sync_def_sync TOK_STRING { + fastd_shell_command_set(&conf->on_down, $2->str, $1); } ; -on_post_down: TOK_STRING { - fastd_shell_command_set(&conf->on_post_down, $1->str); +on_post_down: sync_def_sync TOK_STRING { + fastd_shell_command_set(&conf->on_post_down, $2->str, $1); } ; -on_establish: TOK_STRING { - fastd_shell_command_set(&conf->on_establish, $1->str); +on_establish: sync_def_async TOK_STRING { + fastd_shell_command_set(&conf->on_establish, $2->str, $1); } ; -on_disestablish: TOK_STRING { - fastd_shell_command_set(&conf->on_disestablish, $1->str); +on_disestablish: sync_def_async TOK_STRING { + fastd_shell_command_set(&conf->on_disestablish, $2->str, $1); } ; -on_verify: TOK_STRING { - fastd_shell_command_set(&conf->on_verify, $1->str); +on_verify: sync_def_async TOK_STRING { + fastd_shell_command_set(&conf->on_verify, $2->str, $1); } ; @@ -565,6 +570,17 @@ maybe_float: TOK_FLOAT { $$ = true; } | { $$ = false; } ; +sync_def_sync: sync { $$ = $1; } + | { $$ = true; } + ; + +sync_def_async: sync { $$ = $1; } + | { $$ = false; } + ; + +sync: TOK_SYNC { $$ = true; } + | TOK_ASYNC { $$ = false; } + boolean: TOK_YES { $$ = true; } | TOK_NO { $$ = false; } ; diff --git a/src/lex.c b/src/lex.c index 991a136..d5f4c4f 100644 --- a/src/lex.c +++ b/src/lex.c @@ -51,6 +51,7 @@ static const keyword_t keywords[] = { { "addresses", TOK_ADDRESSES }, { "any", TOK_ANY }, { "as", TOK_AS }, + { "async", TOK_ASYNC }, { "auto", TOK_AUTO }, { "bind", TOK_BIND }, { "capabilities", TOK_CAPABILITIES }, @@ -100,6 +101,7 @@ static const keyword_t keywords[] = { { "secret", TOK_SECRET }, { "secure", TOK_SECURE }, { "stderr", TOK_STDERR }, + { "sync", TOK_SYNC }, { "syslog", TOK_SYSLOG }, { "tap", TOK_TAP }, { "to", TOK_TO }, diff --git a/src/options.c b/src/options.c index 03f50ae..a4c334f 100644 --- a/src/options.c +++ b/src/options.c @@ -270,31 +270,31 @@ static void option_forward(fastd_context_t *ctx UNUSED, fastd_config_t *conf) { #ifdef WITH_CMDLINE_COMMANDS static void option_on_pre_up(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) { - fastd_shell_command_set(&conf->on_pre_up, arg); + fastd_shell_command_set(&conf->on_pre_up, arg, true); } static void option_on_up(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) { - fastd_shell_command_set(&conf->on_up, arg); + fastd_shell_command_set(&conf->on_up, arg, true); } static void option_on_down(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) { - fastd_shell_command_set(&conf->on_down, arg); + fastd_shell_command_set(&conf->on_down, arg, true); } static void option_on_post_down(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) { - fastd_shell_command_set(&conf->on_post_down, arg); + fastd_shell_command_set(&conf->on_post_down, arg, true); } static void option_on_establish(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) { - fastd_shell_command_set(&conf->on_establish, arg); + fastd_shell_command_set(&conf->on_establish, arg, false); } static void option_on_disestablish(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) { - fastd_shell_command_set(&conf->on_disestablish, arg); + fastd_shell_command_set(&conf->on_disestablish, arg, false); } static void option_on_verify(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) { - fastd_shell_command_set(&conf->on_verify, arg); + fastd_shell_command_set(&conf->on_verify, arg, false); } #endif diff --git a/src/peer.c b/src/peer.c index 07354df..9aeb81e 100644 --- a/src/peer.c +++ b/src/peer.c @@ -574,8 +574,11 @@ bool fastd_peer_verify_temporary(fastd_context_t *ctx, fastd_peer_t *peer, const if (!fastd_shell_command_isset(&ctx->conf->on_verify)) exit_bug(ctx, "tried to verify temporary peer without on-verify command"); + fastd_shell_command_t cmd = ctx->conf->on_verify; + cmd.sync = true; /* TODO: async not supported yet */ + int ret; - if (!fastd_shell_command_exec(ctx, &ctx->conf->on_verify, peer, local_addr, peer_addr, &ret)) + if (!fastd_shell_command_exec(ctx, &cmd, peer, local_addr, peer_addr, &ret)) return false; if (WIFSIGNALED(ret)) { diff --git a/src/shell.c b/src/shell.c index 6d60a07..e1161d4 100644 --- a/src/shell.c +++ b/src/shell.c @@ -36,12 +36,11 @@ bool fastd_shell_command_exec(fastd_context_t *ctx, const fastd_shell_command_t if (!fastd_shell_command_isset(command)) return true; - int result = -1; bool ok = false; char *cwd = get_current_dir_name(); - if(!chdir(command->dir)) { + if (!chdir(command->dir)) { /* both INET6_ADDRSTRLEN and IFNAMESIZE already include space for the zero termination, so there is no need to add space for the '%' here. */ char buf[INET6_ADDRSTRLEN+IF_NAMESIZE]; @@ -133,19 +132,35 @@ bool fastd_shell_command_exec(fastd_context_t *ctx, const fastd_shell_command_t ctx->conf->protocol->set_shell_env(ctx, peer); - result = system(command->command); + if (command->sync) { + int result = system(command->command); + + if (ret) { + *ret = result; + ok = true; + } + else { + if (WIFSIGNALED(result)) + pr_error(ctx, "command exited with signal %i", WTERMSIG(result)); + else if (WEXITSTATUS(result)) + pr_warn(ctx, "command exited with status %i", WEXITSTATUS(result)); + else + ok = true; + } - if (ret) { - *ret = result; - ok = true; } else { - if (WIFSIGNALED(result)) - pr_error(ctx, "command exited with signal %i", WTERMSIG(result)); - else if (WEXITSTATUS(result)) - pr_warn(ctx, "command exited with status %i", WEXITSTATUS(result)); - else + pid_t pid = fork(); + if (pid == 0) { + execl("/bin/sh", "sh", "-c", command->command, (char*)NULL); + _exit(127); + } + else if (pid > 0) { ok = true; + } + else { + pr_error_errno(ctx, "fastd_shell_exec_command: fork"); + } } if(chdir(cwd)) diff --git a/src/shell.h b/src/shell.h index 18ceb2a..e6c3618 100644 --- a/src/shell.h +++ b/src/shell.h @@ -35,6 +35,7 @@ struct fastd_shell_command { char *command; char *dir; + bool sync; }; static inline void fastd_shell_command_unset(fastd_shell_command_t *command) { @@ -45,11 +46,12 @@ static inline void fastd_shell_command_unset(fastd_shell_command_t *command) { command->dir = NULL; } -static inline void fastd_shell_command_set(fastd_shell_command_t *command, const char *val) { +static inline void fastd_shell_command_set(fastd_shell_command_t *command, const char *val, bool sync) { fastd_shell_command_unset(command); command->command = strdup(val); command->dir = get_current_dir_name(); + command->sync = sync; } static inline bool fastd_shell_command_isset(const fastd_shell_command_t *command) { -- cgit v1.2.3