From 88bd9dab5fce9e85972818400a827701caacd467 Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Tue, 9 Jun 2020 12:11:06 +0200 Subject: Add config parameters for stop and start methods --- cfgdir.c | 49 +++++++++++++++++++++++++++++++++++++++++++ server.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- server.h | 25 ++++++++++++++++++++++ utils.h | 7 +++++++ 4 files changed, 144 insertions(+), 9 deletions(-) diff --git a/cfgdir.c b/cfgdir.c index a43988e..6f01189 100644 --- a/cfgdir.c +++ b/cfgdir.c @@ -26,6 +26,15 @@ enum scfg_keys { SCFG_KEY_LOCAL, SCFG_KEY_REMOTE, SCFG_KEY_IDLE_TIMEOUT, + SCFG_KEY_STOP_METHOD, + SCFG_KEY_START_METHOD, + SCFG_KEY_STOP_EXEC, + SCFG_KEY_START_EXEC, + /* + SCFG_KEY_SYSTEMD_SERVICE, + SCFG_KEY_RCON, + SCFG_KEY_RCON_PASSWORD, + */ }; struct cfg_key_value_map scfg_key_map[] = { @@ -53,6 +62,22 @@ struct cfg_key_value_map scfg_key_map[] = { .key_name = "idle_timeout", .key_value = SCFG_KEY_IDLE_TIMEOUT, .value_type = CFG_VAL_TYPE_UINT16, + }, { + .key_name = "stop_method", + .key_value = SCFG_KEY_STOP_METHOD, + .value_type = CFG_VAL_TYPE_STRING, + }, { + .key_name = "start_method", + .key_value = SCFG_KEY_START_METHOD, + .value_type = CFG_VAL_TYPE_STRING, + }, { + .key_name = "stop_exec", + .key_value = SCFG_KEY_STOP_EXEC, + .value_type = CFG_VAL_TYPE_STRING, + }, { + .key_name = "start_exec", + .key_value = SCFG_KEY_START_EXEC, + .value_type = CFG_VAL_TYPE_STRING, }, { .key_name = NULL, .key_value = SCFG_KEY_INVALID, @@ -126,6 +151,30 @@ scfg_parse(struct cfg *cfg, struct server *scfg) return; break; + case SCFG_KEY_STOP_METHOD: + if (!strcmp(value.str, "exec")) { + if (server_set_stop_method(cfg, scfg, SERVER_STOP_METHOD_EXEC)) + break; + } + return; + + case SCFG_KEY_START_METHOD: + if (!strcmp(value.str, "exec")) { + if (server_set_start_method(cfg, scfg, SERVER_START_METHOD_EXEC)) + break; + } + return; + + case SCFG_KEY_STOP_EXEC: + if (!server_set_stop_exec(cfg, scfg, value.str)) + return; + break; + + case SCFG_KEY_START_EXEC: + if (!server_set_start_exec(cfg, scfg, value.str)) + return; + break; + case SCFG_KEY_INVALID: default: break; diff --git a/server.c b/server.c index 3ea6d77..44779eb 100644 --- a/server.c +++ b/server.c @@ -19,6 +19,21 @@ struct server_local { struct list_head list; }; +static bool +set_property(struct cfg *cfg, struct server *scfg, char **property, const char *value) +{ + if (!cfg || !scfg || empty_str(value) || *property) + return false; + + *property = strdup(value); + if (!*property) { + perror("strdup"); + return false; + } + + return true; +} + void server_refdump(struct server *server) { @@ -42,6 +57,8 @@ server_free(struct uring_task *task) fprintf(stderr, "Freeing scfg %s\n", scfg->name); list_del(&scfg->list); free(scfg->pretty_name); + free(scfg->start_exec); + free(scfg->stop_exec); free(scfg->name); free(scfg); } @@ -222,7 +239,10 @@ server_commit(struct cfg *cfg, struct server *scfg) case SERVER_TYPE_ANNOUNCE: if (scfg->announce_port < 1) return false; - if (scfg->idle_timeout > 0) + if (scfg->idle_timeout > 0 && + scfg->stop_method == SERVER_STOP_METHOD_UNDEFINED) + return false; + if (scfg->start_method != SERVER_START_METHOD_UNDEFINED) return false; if (!list_empty(&scfg->locals)) return false; @@ -233,6 +253,9 @@ server_commit(struct cfg *cfg, struct server *scfg) case SERVER_TYPE_PROXY: if (scfg->announce_port >= 1) return false; + if (scfg->idle_timeout > 0 && + scfg->stop_method == SERVER_STOP_METHOD_UNDEFINED) + return false; if (list_empty(&scfg->locals)) return false; if (list_empty(&scfg->remotes)) @@ -318,6 +341,42 @@ server_add_local(struct cfg *cfg, struct server *scfg, struct sockaddr_in46 *add return true; } +bool +server_set_stop_method(struct cfg *cfg, struct server *scfg, + enum server_stop_method stop_method) +{ + if (scfg->stop_method != SERVER_STOP_METHOD_UNDEFINED || + stop_method == SERVER_STOP_METHOD_UNDEFINED) + return false; + + scfg->stop_method = stop_method; + return true; +} + +bool +server_set_start_method(struct cfg *cfg, struct server *scfg, + enum server_start_method start_method) +{ + if (scfg->start_method != SERVER_START_METHOD_UNDEFINED || + start_method == SERVER_START_METHOD_UNDEFINED) + return false; + + scfg->start_method = start_method; + return true; +} + +bool +server_set_stop_exec(struct cfg *cfg, struct server *scfg, const char *cmd) +{ + return set_property(cfg, scfg, &scfg->stop_exec, cmd); +} + +bool +server_set_start_exec(struct cfg *cfg, struct server *scfg, const char *cmd) +{ + return set_property(cfg, scfg, &scfg->start_exec, cmd); +} + bool server_set_idle_timeout(struct cfg *cfg, struct server *scfg, uint16_t timeout) { @@ -361,14 +420,7 @@ server_set_type(struct cfg *cfg, struct server *scfg, enum server_type type) bool server_set_pretty_name(struct cfg *cfg, struct server *scfg, const char *pretty_name) { - if (!pretty_name || pretty_name[0] == '\0' || !scfg || scfg->pretty_name) - return false; - - scfg->pretty_name = strdup(pretty_name); - if (!scfg->pretty_name) - return false; - - return true; + return set_property(cfg, scfg, &scfg->pretty_name, pretty_name); } struct server * @@ -393,6 +445,8 @@ server_new(struct cfg *cfg, const char *name) scfg->type = SERVER_TYPE_UNDEFINED; scfg->name = strdup(name); scfg->running = false; + scfg->stop_method = SERVER_STOP_METHOD_UNDEFINED; + scfg->start_method = SERVER_START_METHOD_UNDEFINED; uring_task_init(&scfg->task, "scfg", uring_parent(cfg), server_free); list_init(&scfg->remotes); list_init(&scfg->locals); diff --git a/server.h b/server.h index 3c32844..e8e6ba8 100644 --- a/server.h +++ b/server.h @@ -7,6 +7,16 @@ enum server_type { SERVER_TYPE_PROXY }; +enum server_stop_method { + SERVER_STOP_METHOD_UNDEFINED, + SERVER_STOP_METHOD_EXEC +}; + +enum server_start_method { + SERVER_START_METHOD_UNDEFINED, + SERVER_START_METHOD_EXEC +}; + struct server { enum server_type type; char *name; @@ -17,6 +27,11 @@ struct server { struct list_head proxys; bool running; + enum server_stop_method stop_method; + enum server_start_method start_method; + char *stop_exec; + char *start_exec; + /* For config files */ char buf[4096]; size_t len; @@ -49,6 +64,16 @@ bool server_add_remote(struct cfg *cfg, struct server *scfg, bool server_add_local(struct cfg *cfg, struct server *scfg, struct sockaddr_in46 *local); +bool server_set_stop_method(struct cfg *cfg, struct server *scfg, + enum server_stop_method stop_method); + +bool server_set_start_method(struct cfg *cfg, struct server *scfg, + enum server_start_method start_method); + +bool server_set_stop_exec(struct cfg *cfg, struct server *scfg, const char *cmd); + +bool server_set_start_exec(struct cfg *cfg, struct server *scfg, const char *cmd); + bool server_set_idle_timeout(struct cfg *cfg, struct server *scfg, uint16_t timeout); bool server_set_port(struct cfg *cfg, struct server *scfg, uint16_t port); diff --git a/utils.h b/utils.h index 7110265..81ffdb8 100644 --- a/utils.h +++ b/utils.h @@ -101,6 +101,13 @@ char *sockaddr_to_str(struct sockaddr_in46 *addr, char *buf, size_t buflen); int strtou16_strict(const char *str, uint16_t *result); +static inline bool empty_str(const char *str) +{ + if (!str || str[0] == '\0') + return true; + else + return false; +} /* #define _cleanup_(x) __attribute__((cleanup(x))) -- cgit v1.2.3