summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2013-02-25 04:48:11 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2013-02-25 04:48:11 +0100
commit698ede3ce4ab7ff88e5c69b3910544094c7f9814 (patch)
treed3a7bd1835ecf25e16c35ab658e7d56cc2c69ad2 /src
parentb3ba14d47370e156ef7366954c1160e088e92b49 (diff)
downloadfastd-698ede3ce4ab7ff88e5c69b3910544094c7f9814.tar
fastd-698ede3ce4ab7ff88e5c69b3910544094c7f9814.zip
Get rid of some duplicate code for calling shell commands
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/fastd.c46
-rw-r--r--src/fastd.h2
-rw-r--r--src/peer.c110
-rw-r--r--src/shell.c98
5 files changed, 110 insertions, 147 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ccee0d9..916a726 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -26,6 +26,7 @@ add_executable(fastd
queue.c
random.c
resolve.c
+ shell.c
task.c
protocol_ec25519_fhmqvc.c
${FLEX_fastd_config_lex_OUTPUTS}
diff --git a/src/fastd.c b/src/fastd.c
index 8b6ea94..ce297f7 100644
--- a/src/fastd.c
+++ b/src/fastd.c
@@ -563,56 +563,18 @@ void fastd_handle_receive(fastd_context_t *ctx, fastd_peer_t *peer, fastd_buffer
}
}
-static void on_up(fastd_context_t *ctx) {
+static inline void on_up(fastd_context_t *ctx) {
if (!ctx->conf->on_up)
return;
- char *cwd = get_current_dir_name();
-
- if (!chdir(ctx->conf->on_up_dir)) {
- setenv("INTERFACE", ctx->ifname, 1);
-
- int ret = system(ctx->conf->on_up);
-
- if (WIFSIGNALED(ret))
- pr_error(ctx, "on-up command exited with signal %i", WTERMSIG(ret));
- else if(ret)
- pr_warn(ctx, "on-up command exited with status %i", WEXITSTATUS(ret));
-
- if (chdir(cwd))
- pr_error(ctx, "can't chdir to `%s': %s", cwd, strerror(errno));
- }
- else {
- pr_error(ctx, "can't chdir to `%s': %s", ctx->conf->on_up_dir, strerror(errno));
- }
-
- free(cwd);
+ fastd_shell_exec(ctx, NULL, ctx->conf->on_up, ctx->conf->on_up_dir, NULL);
}
-static void on_down(fastd_context_t *ctx) {
+static inline void on_down(fastd_context_t *ctx) {
if (!ctx->conf->on_down)
return;
- char *cwd = get_current_dir_name();
-
- if(!chdir(ctx->conf->on_down_dir)) {
- setenv("INTERFACE", ctx->ifname, 1);
-
- int ret = system(ctx->conf->on_down);
-
- if (WIFSIGNALED(ret))
- pr_error(ctx, "on-down command exited with signal %i", WTERMSIG(ret));
- else if(ret)
- pr_warn(ctx, "on-down command exited with status %i", WEXITSTATUS(ret));
-
- if (chdir(cwd))
- pr_error(ctx, "can't chdir to `%s': %s", cwd, strerror(errno));
- }
- else {
- pr_error(ctx, "can't chdir to `%s': %s", ctx->conf->on_down_dir, strerror(errno));
- }
-
- free(cwd);
+ fastd_shell_exec(ctx, NULL, ctx->conf->on_down, ctx->conf->on_down_dir, NULL);
}
static fastd_peer_group_t* init_peer_group(const fastd_peer_group_config_t *config, fastd_peer_group_t *parent) {
diff --git a/src/fastd.h b/src/fastd.h
index 8b6eb7e..731ee8c 100644
--- a/src/fastd.h
+++ b/src/fastd.h
@@ -327,6 +327,8 @@ void fastd_reconfigure(fastd_context_t *ctx, fastd_config_t *conf);
void fastd_cap_init(fastd_context_t *ctx);
void fastd_cap_drop(fastd_context_t *ctx);
+bool fastd_shell_exec(fastd_context_t *ctx, const fastd_peer_t *peer, const char *command, const char *dir, int *ret);
+
void fastd_random_bytes(fastd_context_t *ctx, void *buffer, size_t len, bool secure);
static inline int fastd_rand(fastd_context_t *ctx, int min, int max) {
diff --git a/src/peer.c b/src/peer.c
index 9e1b097..3eeb261 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -32,118 +32,18 @@
#include <arpa/inet.h>
-static void on_establish(fastd_context_t *ctx, fastd_peer_t *peer) {
+static inline void on_establish(fastd_context_t *ctx, const fastd_peer_t *peer) {
if (!ctx->conf->on_establish)
return;
- char *cwd = get_current_dir_name();
-
- if(!chdir(ctx->conf->on_establish_dir)) {
- setenv("INTERFACE", ctx->ifname, 1);
-
- char buf[INET6_ADDRSTRLEN];
-
- if (peer->config && peer->config->name)
- setenv("PEER_NAME", peer->config->name, 1);
- else
- unsetenv("PEER_NAME");
-
- switch(peer->address.sa.sa_family) {
- case AF_INET:
- inet_ntop(AF_INET, &peer->address.in.sin_addr, buf, sizeof(buf));
- setenv("PEER_ADDRESS", buf, 1);
-
- snprintf(buf, sizeof(buf), "%u", ntohs(peer->address.in.sin_port));
- setenv("PEER_PORT", buf, 1);
-
- break;
-
- case AF_INET6:
- inet_ntop(AF_INET6, &peer->address.in6.sin6_addr, buf, sizeof(buf));
- setenv("PEER_ADDRESS", buf, 1);
-
- snprintf(buf, sizeof(buf), "%u", ntohs(peer->address.in6.sin6_port));
- setenv("PEER_PORT", buf, 1);
-
- break;
-
- default:
- unsetenv("PEER_ADDRESS");
- unsetenv("PEER_PORT");
- }
-
- int ret = system(ctx->conf->on_establish);
-
- if (WIFSIGNALED(ret))
- pr_error(ctx, "on-establish command exited with signal %i", WTERMSIG(ret));
- else if(ret)
- pr_warn(ctx, "on-establish command exited with status %i", WEXITSTATUS(ret));
-
- if(chdir(cwd))
- pr_error(ctx, "can't chdir to `%s': %s", cwd, strerror(errno));
- }
- else {
- pr_error(ctx, "can't chdir to `%s': %s", ctx->conf->on_establish_dir, strerror(errno));
- }
-
- free(cwd);
+ fastd_shell_exec(ctx, peer, ctx->conf->on_establish, ctx->conf->on_establish_dir, NULL);
}
-static void on_disestablish(fastd_context_t *ctx, fastd_peer_t *peer) {
+static inline void on_disestablish(fastd_context_t *ctx, const fastd_peer_t *peer) {
if (!ctx->conf->on_disestablish)
return;
- char *cwd = get_current_dir_name();
-
- if(!chdir(ctx->conf->on_disestablish_dir)) {
- setenv("INTERFACE", ctx->ifname, 1);
-
- char buf[INET6_ADDRSTRLEN];
-
- if (peer->config && peer->config->name)
- setenv("PEER_NAME", peer->config->name, 1);
- else
- unsetenv("PEER_NAME");
-
- switch(peer->address.sa.sa_family) {
- case AF_INET:
- inet_ntop(AF_INET, &peer->address.in.sin_addr, buf, sizeof(buf));
- setenv("PEER_ADDRESS", buf, 1);
-
- snprintf(buf, sizeof(buf), "%u", ntohs(peer->address.in.sin_port));
- setenv("PEER_PORT", buf, 1);
-
- break;
-
- case AF_INET6:
- inet_ntop(AF_INET6, &peer->address.in6.sin6_addr, buf, sizeof(buf));
- setenv("PEER_ADDRESS", buf, 1);
-
- snprintf(buf, sizeof(buf), "%u", ntohs(peer->address.in6.sin6_port));
- setenv("PEER_PORT", buf, 1);
-
- break;
-
- default:
- unsetenv("PEER_ADDRESS");
- unsetenv("PEER_PORT");
- }
-
- int ret = system(ctx->conf->on_disestablish);
-
- if (WIFSIGNALED(ret))
- pr_error(ctx, "on-disestablish command exited with signal %i", WTERMSIG(ret));
- else if(ret)
- pr_warn(ctx, "on-disestablish command exited with status %i", WEXITSTATUS(ret));
-
- if(chdir(cwd))
- pr_error(ctx, "can't chdir to `%s': %s", cwd, strerror(errno));
- }
- else {
- pr_error(ctx, "can't chdir to `%s': %s", ctx->conf->on_disestablish_dir, strerror(errno));
- }
-
- free(cwd);
+ fastd_shell_exec(ctx, peer, ctx->conf->on_disestablish, ctx->conf->on_disestablish_dir, NULL);
}
static inline void free_socket(fastd_context_t *ctx, fastd_peer_t *peer) {
@@ -159,7 +59,7 @@ static inline void free_socket(fastd_context_t *ctx, fastd_peer_t *peer) {
}
}
-static bool has_group_config_constraints(const fastd_peer_group_config_t *group) {
+static inline bool has_group_config_constraints(const fastd_peer_group_config_t *group) {
for (; group; group = group->parent) {
if (group->max_connections)
return true;
diff --git a/src/shell.c b/src/shell.c
new file mode 100644
index 0000000..c80a32a
--- /dev/null
+++ b/src/shell.c
@@ -0,0 +1,98 @@
+/*
+ Copyright (c) 2012-2013, Matthias Schiffer <mschiffer@universe-factory.net>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#define _GNU_SOURCE
+
+#include "peer.h"
+
+#include <arpa/inet.h>
+
+
+bool fastd_shell_exec(fastd_context_t *ctx, const fastd_peer_t *peer, const char *command, const char *dir, int *ret) {
+ int result = -1;
+ bool ok = false;
+ char *cwd = get_current_dir_name();
+
+ if(!chdir(dir)) {
+ setenv("INTERFACE", ctx->ifname, 1);
+
+ char buf[INET6_ADDRSTRLEN];
+
+ if (peer && peer->config && peer->config->name)
+ setenv("PEER_NAME", peer->config->name, 1);
+ else
+ unsetenv("PEER_NAME");
+
+ switch(peer ? peer->address.sa.sa_family : AF_UNSPEC) {
+ case AF_INET:
+ inet_ntop(AF_INET, &peer->address.in.sin_addr, buf, sizeof(buf));
+ setenv("PEER_ADDRESS", buf, 1);
+
+ snprintf(buf, sizeof(buf), "%u", ntohs(peer->address.in.sin_port));
+ setenv("PEER_PORT", buf, 1);
+
+ break;
+
+ case AF_INET6:
+ inet_ntop(AF_INET6, &peer->address.in6.sin6_addr, buf, sizeof(buf));
+ setenv("PEER_ADDRESS", buf, 1);
+
+ snprintf(buf, sizeof(buf), "%u", ntohs(peer->address.in6.sin6_port));
+ setenv("PEER_PORT", buf, 1);
+
+ break;
+
+ default:
+ unsetenv("PEER_ADDRESS");
+ unsetenv("PEER_PORT");
+ }
+
+ result = system(command);
+
+ if (ret) {
+ *ret = result;
+ ok = true;
+ }
+ else {
+ if (WIFSIGNALED(result))
+ pr_error(ctx, "command exited with signal %i", WTERMSIG(result));
+ else if (result)
+ pr_warn(ctx, "command exited with status %i", WEXITSTATUS(ret));
+ else
+ ok = true;
+ }
+
+ if(chdir(cwd))
+ pr_error(ctx, "can't chdir to `%s': %s", cwd, strerror(errno));
+ }
+ else {
+ pr_error(ctx, "can't chdir to `%s': %s", dir, strerror(errno));
+ }
+
+ free(cwd);
+
+ return ok;
+}