aboutsummaryrefslogtreecommitdiff
path: root/src/config.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2020-02-28 10:07:54 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2020-02-28 10:07:54 +0200
commit73bfc3bdfac590266ad67c48de5e866bb5d5fa4d (patch)
tree2488c3b3b009c0c49f56a63f10df7340432588c4 /src/config.c
parent7e8ff0ed908913de7467daa28feb25164abc7ad9 (diff)
downloadping903-73bfc3bdfac590266ad67c48de5e866bb5d5fa4d.tar.gz
ping903-73bfc3bdfac590266ad67c48de5e866bb5d5fa4d.tar.bz2
Implement here-document syntax in configuration file.
Here-document is supported for ip-list and trusted-ip statements. * doc/ping903.conf.5: Document the here-document syntax. * NEWS: Likewise. * examples/inspect: Mention that the created output is a valid configuration file. * src/config.c: Support for here-document. * src/defs.h: Mark printf-like functions as such. * src/ping903.h (CF_HEREDOC_OPCODE): New data type. (cf_callback_arg): Add heredoc member. (STMT_T_HEREDOC): New statement type. * src/remoteip.c (cf_trusted_ip_heredoc): New function. * src/ping903.c: Fix format strings and unused variables. * src/ping903q.c: Likewise. * src/pinger.c: Likewise.
Diffstat (limited to 'src/config.c')
-rw-r--r--src/config.c109
1 files changed, 105 insertions, 4 deletions
diff --git a/src/config.c b/src/config.c
index a04423f..58841c9 100644
--- a/src/config.c
+++ b/src/config.c
@@ -118,7 +118,7 @@ file_read_ip_list(FILE *fp, char const *fname)
rc = pinger_host_add(p, res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);
if (rc) {
- error("%s:%d: out of memory");
+ error("%s:%d: out of memory", fname, ln);
ret = CF_RET_FAIL;
break;
}
@@ -143,7 +143,45 @@ cf_ip_list(int mode, union cf_callback_arg *arg, void *data)
case CF_SERIALIZE:
return cf_ip_list_serialize(arg, data);
}
+ abort();
}
+
+static int
+cf_ip_list_heredoc(int mode, union cf_callback_arg *arg, void *data)
+{
+ struct addrinfo hints, *res;
+ int rc;
+
+ if (mode == CF_SERIALIZE)
+ return CF_RET_IGNORE;
+
+ switch (arg->heredoc.op) {
+ case CF_HEREDOC_START:
+ case CF_HEREDOC_STOP:
+ break;
+
+ case CF_HEREDOC_NEXT:
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_protocol = IPPROTO_TCP;
+ rc = getaddrinfo(arg->heredoc.val, NULL, &hints, &res);
+ if (rc) {
+ error("%s:%d: invalid IP address",
+ arg->heredoc.file, arg->heredoc.line);
+ return CF_RET_FAIL;
+ }
+ rc = pinger_host_add(arg->heredoc.val, res->ai_addr,
+ res->ai_addrlen);
+ freeaddrinfo(res);
+ if (rc) {
+ error("%s:%d: out of memory", arg->heredoc.file,
+ arg->heredoc.line);
+ return CF_RET_FAIL;
+ }
+ }
+ return CF_RET_OK;
+}
+
struct cf_stmt {
char const *kw;
@@ -156,11 +194,13 @@ struct cf_stmt statements[] = {
{ "listen", STMT_T_STRING, &httpd_addr },
{ "pidfile", STMT_T_STRING, &pidfile },
{ "trusted-ip", STMT_T_CALLBACK, NULL, cf_trusted_ip },
+ { "trusted-ip", STMT_T_HEREDOC, NULL, cf_trusted_ip_heredoc },
{ "probe-interval", STMT_T_ULONG, &probe_interval },
{ "ping-interval", STMT_T_ULONG, &ping_interval },
{ "ping-count", STMT_T_ULONG, &ping_count },
{ "tolerance", STMT_T_ULONG, &ping_tolerance },
{ "ip-list", STMT_T_CALLBACK, NULL, cf_ip_list },
+ { "ip-list", STMT_T_HEREDOC, NULL, cf_ip_list_heredoc },
{ "data-length", STMT_T_ULONG, &data_length },
{ "syslog-facility", STMT_T_CALLBACK, NULL, cf_syslog_facility },
{ "access-log", STMT_T_BOOL, &httpd_access_log },
@@ -171,11 +211,13 @@ struct cf_stmt statements[] = {
};
static struct cf_stmt *
-find_stmt(char const *kw)
+find_stmt(char const *kw, int heredoc)
{
struct cf_stmt *cf;
for (cf = statements; cf->kw; cf++) {
- if (strcmp(cf->kw, kw) == 0)
+ if (((heredoc && cf->type == STMT_T_HEREDOC)
+ || (!heredoc && cf->type != STMT_T_HEREDOC))
+ && strcmp(cf->kw, kw) == 0)
return cf;
}
return NULL;
@@ -184,7 +226,7 @@ find_stmt(char const *kw)
static int
stmt_parse(char const *kw, char const *val, char const *file, unsigned line)
{
- struct cf_stmt *cf = find_stmt(kw);
+ struct cf_stmt *cf = find_stmt(kw, 0);
union cf_callback_arg arg;
if (!cf) {
@@ -240,6 +282,12 @@ readconfig(char const *file)
unsigned ln = 0;
int skip_to_eol = 0;
int ec = 0;
+ struct {
+ char *eot;
+ CF_CALLBACK callback;
+ void *data;
+ unsigned line;
+ } heredoc = { .eot = NULL };
fp = fopen(file, "r");
if (!fp) {
@@ -281,6 +329,29 @@ readconfig(char const *file)
;
if (*p == 0 || *p == '#')
continue;
+
+ if (heredoc.eot) {
+ union cf_callback_arg arg;
+ arg.heredoc.file = file;
+ arg.heredoc.line = ln;
+
+ if (strcmp(heredoc.eot, p) == 0) {
+ arg.heredoc.op = CF_HEREDOC_STOP;
+ if (heredoc.callback(CF_PARSE, &arg,
+ heredoc.data))
+ ec = 1;
+ free(heredoc.eot);
+ heredoc.eot = NULL;
+ } else {
+ arg.heredoc.op = CF_HEREDOC_NEXT;
+ arg.heredoc.val = p;
+ if (heredoc.callback(CF_PARSE, &arg,
+ heredoc.data))
+ ec = 1;
+ }
+ continue;
+ }
+
kw = p;
while (*p && isascii(*p) && (isalnum(*p) || *p == '_' || *p == '-'))
@@ -296,12 +367,41 @@ readconfig(char const *file)
continue;
}
+ if (p[0] == '<' && p[1] == '<') {
+ p += 2;
+ struct cf_stmt *cf = find_stmt(kw, 1);
+ if (cf) {
+ union cf_callback_arg arg;
+
+ arg.heredoc.op = CF_HEREDOC_START;
+ arg.heredoc.file = file;
+ arg.heredoc.line = ln;
+
+ heredoc.callback = cf->callback;
+ heredoc.data = cf->data;
+ heredoc.line = ln;
+ heredoc.eot = estrdup(p);
+ if (heredoc.callback(CF_PARSE, &arg,
+ heredoc.data))
+ ec = 1;
+ } else {
+ error("%s:%d: unknown heredoc statement",
+ file, ln);
+ ec = 1;
+ }
+ continue;
+ }
+
if (stmt_parse(kw, p, file, ln)) {
ec = 1;
}
}
fclose(fp);
+ if (heredoc.eot) {
+ error("%s:%d: heredoc not closed", file, heredoc.line);
+ ec = 1;
+ }
if ((double) ping_count * ping_interval >= probe_interval) {
error("configuration error: ping_count * ping_interval >= probe_interval");
ec = 1;
@@ -339,6 +439,7 @@ config_to_json(void)
break;
case STMT_T_CALLBACK:
+ case STMT_T_HEREDOC:
arg.output = NULL;
switch (cf->callback(CF_SERIALIZE, &arg, cf->data)) {
case CF_RET_OK:

Return to:

Send suggestions and report system problems to the System administrator.