diff options
| author | David Härdeman <david@hardeman.nu> | 2020-06-09 12:11:06 +0200 | 
|---|---|---|
| committer | David Härdeman <david@hardeman.nu> | 2020-06-09 12:11:06 +0200 | 
| commit | 88bd9dab5fce9e85972818400a827701caacd467 (patch) | |
| tree | 9738a7aaed2b9a213923df7418dc85e92960746d | |
| parent | 8fb2a95981deb64065a8593c9c33b3f930aadc3c (diff) | |
Add config parameters for stop and start methods
| -rw-r--r-- | cfgdir.c | 49 | ||||
| -rw-r--r-- | server.c | 72 | ||||
| -rw-r--r-- | server.h | 25 | ||||
| -rw-r--r-- | utils.h | 7 | 
4 files changed, 144 insertions, 9 deletions
@@ -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[] = { @@ -54,6 +63,22 @@ struct cfg_key_value_map scfg_key_map[] = {  		.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,  		.value_type = CFG_VAL_TYPE_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; @@ -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)) @@ -319,6 +342,42 @@ server_add_local(struct cfg *cfg, struct server *scfg, struct sockaddr_in46 *add  }  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)  {  	if (!scfg || scfg->idle_timeout != 0) @@ -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); @@ -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); @@ -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)))  | 
