summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2020-09-23 11:33:05 -0400
committerDrew DeVault <sir@cmpwn.com>2020-09-23 11:33:05 -0400
commit9adc6f34c7497cf2fde21cd1dfdf87ba3296b559 (patch)
tree3a7c92e11f68742a15377175f177ec91377fa2d3 /src
parent58500c8e530cc9b0807afbe8b068fe7b00db0131 (diff)
downloadgmnisrv-9adc6f34c7497cf2fde21cd1dfdf87ba3296b559.tar.gz
gmnisrv-9adc6f34c7497cf2fde21cd1dfdf87ba3296b559.tar.xz
gmnisrv-9adc6f34c7497cf2fde21cd1dfdf87ba3296b559.zip
config: parse listen directives
Diffstat (limited to 'src')
-rw-r--r--src/config.c61
1 files changed, 58 insertions, 3 deletions
diff --git a/src/config.c b/src/config.c
index 847af6e..9bc251c 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1,3 +1,4 @@
+#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -21,9 +22,63 @@ gmnisrv_config_get_host(struct gmnisrv_config *conf, const char *hostname)
static int
parse_listen(struct gmnisrv_config *conf, const char *value)
{
- // TODO
- (void)conf;
- (void)value;
+ char listen[4096];
+ assert(strlen(value) < sizeof(listen) - 1);
+ strcpy(listen, value);
+
+ char *tok = strtok(listen, " ");
+ while (tok) {
+ char *port = tok;
+ struct gmnisrv_bind *bind =
+ calloc(1, sizeof(struct gmnisrv_bind));
+ bind->port = 1965;
+
+ if (tok[0] == '[') {
+ bind->family = AF_INET6;
+ char *e = strchr(tok, ']');
+ if (!e) {
+ fprintf(stderr,
+ "Error: invalid address specification %s\n",
+ tok);
+ return 0;
+ }
+ *e = '\0';
+ port = e + 1;
+ ++tok;
+ } else {
+ bind->family = AF_INET;
+ }
+
+ port = strchr(port, ':');
+ if (port) {
+ *port = '\0';
+ ++port;
+
+ char *endptr;
+ bind->port = strtoul(port, &endptr, 10);
+ if (*endptr) {
+ fprintf(stderr, "Error: invalid port %s\n", port);
+ return 0;
+ }
+ if (bind->port == 0 || bind->port > 65535) {
+ fprintf(stderr, "Error: invalid port %s\n", port);
+ return 0;
+ }
+ }
+
+ int r = inet_pton(bind->family, tok, bind->addr);
+ if (r != 1) {
+ fprintf(stderr,
+ "Error: invalid address specification %s\n",
+ tok);
+ return 0;
+ }
+
+ bind->next = conf->binds;
+ conf->binds = bind;
+ tok = strtok(NULL, " ");
+ }
+
return 1;
}