aboutsummaryrefslogtreecommitdiff
path: root/src
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
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')
-rw-r--r--src/config.c109
-rw-r--r--src/defs.h9
-rw-r--r--src/ping903.c7
-rw-r--r--src/ping903.h16
-rw-r--r--src/ping903q.c8
-rw-r--r--src/pinger.c27
-rw-r--r--src/remoteip.c21
7 files changed, 160 insertions, 37 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:
diff --git a/src/defs.h b/src/defs.h
index 85918ef..1f7c7f3 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -51,10 +51,13 @@ void *e2nrealloc(void *p, size_t *pn, size_t s);
extern char *progname;
+#define ATTR_PRINTFLIKE(fmt,narg) \
+ __attribute__ ((__format__ (__printf__, fmt, narg)))
+
void vlogger(int prio, char const *fmt, va_list ap);
-void fatal(char const *fmt, ...);
-void error(char const *fmt, ...);
-void info(char const *fmt, ...);
+void fatal(char const *fmt, ...) ATTR_PRINTFLIKE(1,2);
+void error(char const *fmt, ...) ATTR_PRINTFLIKE(1,2);
+void info(char const *fmt, ...) ATTR_PRINTFLIKE(1,2);
void syslog_enable(void);
void set_progname(char const *arg);
int set_log_facility(char const *arg);
diff --git a/src/ping903.c b/src/ping903.c
index 3e5aadd..7bc0f1c 100644
--- a/src/ping903.c
+++ b/src/ping903.c
@@ -369,8 +369,6 @@ ept_ip_put(struct MHD_Connection *conn,
const char *url, const char *method, const char *suffix,
struct json_value *unused)
{
- int ret;
-
while (*suffix == '/')
suffix++;
if (!*suffix)
@@ -886,8 +884,9 @@ p903_httpd_handler(void *cls,
}
rc = json_parse_string(pb->base, &jv, &endp);
if (rc != JSON_E_NOERR) {
- error("%s: %s near #%d", url,
- json_strerror(rc), endp - pb->base);
+ error("%s: %s near #%ld", url,
+ json_strerror(rc),
+ endp - pb->base);
return http_response(conn, method, url,
MHD_HTTP_BAD_REQUEST);
}
diff --git a/src/ping903.h b/src/ping903.h
index 26851ad..1390152 100644
--- a/src/ping903.h
+++ b/src/ping903.h
@@ -30,6 +30,12 @@ enum {
CF_SERIALIZE /* serialize configuration setting */
};
+typedef enum {
+ CF_HEREDOC_START,
+ CF_HEREDOC_NEXT,
+ CF_HEREDOC_STOP
+} CF_HEREDOC_OPCODE;
+
union cf_callback_arg {
struct json_value *output; /* Output value */
struct cf_line {
@@ -37,6 +43,12 @@ union cf_callback_arg {
char const *file; /* Statement location: file name */
unsigned line; /* ... and input line number */
} input;
+ struct cf_heredoc {
+ CF_HEREDOC_OPCODE op;
+ char const *val; /* Statement value (after keyword) */
+ char const *file; /* Statement location: file name */
+ unsigned line; /* ... and input line number */
+ } heredoc;
};
enum {
@@ -53,11 +65,13 @@ enum {
STMT_T_STRING,
STMT_T_ULONG,
STMT_T_BOOL,
- STMT_T_CALLBACK
+ STMT_T_CALLBACK,
+ STMT_T_HEREDOC
};
int readconfig(char const *file);
int cf_trusted_ip(int mode, union cf_callback_arg *arg, void *data);
+int cf_trusted_ip_heredoc(int mode, union cf_callback_arg *arg, void *data);
int cf_syslog_facility(int mode, union cf_callback_arg *arg, void *data);
int cf_auth(int mode, union cf_callback_arg *arg, void *data);
diff --git a/src/ping903q.c b/src/ping903q.c
index e9070ab..8323f44 100644
--- a/src/ping903q.c
+++ b/src/ping903q.c
@@ -469,8 +469,6 @@ nodecmp(char const *a, char const *b)
static int
machinecmp(char const *pat)
{
- size_t slen;
-
if (strcmp(pat, "*") == 0)
return 0;
if (pat[0] == '*' && pat[1] == ':') {
@@ -505,7 +503,6 @@ machinecmp(char const *pat)
static int
get_realm_creds(char const *realm, char **retval)
{
- char *p;
size_t len;
char const *cfname;
FILE *fp;
@@ -592,7 +589,8 @@ get_realm_creds(char const *realm, char **retval)
strcat(plaintext, av[3]);
/* Encode it to base64 */
- if (base64_encode(plaintext, len, &b64, &b64_len))
+ if (base64_encode((unsigned char const *)plaintext,
+ len, &b64, &b64_len))
emalloc_die();
free(plaintext);
@@ -602,7 +600,7 @@ get_realm_creds(char const *realm, char **retval)
+ b64_len
+ 1);
strcpy(hdr, HTTP_AUTHORIZATION);
- strcat(hdr, b64);
+ strcat(hdr, (char*) b64);
free(b64);
/* Return it */
diff --git a/src/pinger.c b/src/pinger.c
index 96a55ae..825c814 100644
--- a/src/pinger.c
+++ b/src/pinger.c
@@ -211,17 +211,6 @@ hostlist_concat(HOSTLIST *a, HOSTLIST *b)
b->head = b->tail = NULL;
b->count = 0;
}
-
-static HOSTPING *
-hostlist_locate(HOSTLIST *list, char const *name)
-{
- HOSTPING *hp;
- for (hp = list->head; hp; hp++) {
- if (strcmp(hp->name, name) == 0)
- break;
- }
- return hp;
-}
static HOSTLIST *hostlist;
static HOSTPING *conf_hostping_tail;
@@ -604,7 +593,6 @@ err:
int
pinger_host_delete_by_name(char const *name)
{
- HOSTPING *hp;
int rc;
pthread_mutex_lock(&update_mutex);
@@ -1101,7 +1089,7 @@ send_echo(HOSTPING *host, unsigned char *ping_buffer)
}
if (verbose > 2)
- info("sending %d bytes to %s, icmp_seq=%d", buflen, host->name,
+ info("sending %zu bytes to %s, icmp_seq=%d", buflen, host->name,
seqno);
icmp_generic_encode(ping_buffer, buflen, ICMP_ECHO, ping_ident, seqno);
@@ -1117,7 +1105,7 @@ send_echo(HOSTPING *host, unsigned char *ping_buffer)
hostping_unlock(host);
xmit_total++;
if (n != buflen)
- error("ping: wrote %s %d chars, ret=%d\n",
+ error("ping: wrote %s %zu chars, ret=%ld\n",
host->name, buflen, n);
}
}
@@ -1127,7 +1115,6 @@ static void hostping_commit(HOSTPING *host);
void *
p903_sender(void *p)
{
- size_t i;
unsigned char *ping_buffer;
struct pollfd pfd;
int n;
@@ -1166,10 +1153,11 @@ p903_sender(void *p)
fatal("poll: %s", strerror(errno));
exit(1);
}
- if (i < hostlist->count - 1)
+ if (hp->next)
clock_nanosleep(CLOCK_MONOTONIC,
TIMER_ABSTIME, &nts,
NULL);
+
}
send_count++;
if (send_count == ping_count)
@@ -1197,7 +1185,7 @@ log_echo(struct sockaddr *addr, socklen_t addrlen,
strcpy(hbuf, "UNKNOWN");
}
- info("%d bytes from %s: icmp_seq=%u ttl=%d time=%.3f ms", datalen,
+ info("%zu bytes from %s: icmp_seq=%u ttl=%d time=%.3f ms", datalen,
hbuf, icmp->icmp_seq, ip->ip_ttl, rtt);
}
@@ -1232,9 +1220,9 @@ p903_receiver(void *p)
addrlen,
hbuf, sizeof(hbuf),
NULL, 0, NI_NUMERICHOST)) {
- error("packet too short (%d bytes)", n);
+ error("packet too short (%zu bytes)", n);
} else {
- error("packet too short (%d bytes), from %s",
+ error("packet too short (%zu bytes), from %s",
n, hbuf);
}
continue;
@@ -1351,7 +1339,6 @@ save_local_ip_list(void)
{
FILE *fp;
HOSTPING *hp;
- size_t i;
info("saving mutable IP address list");
fp = fopen(LOCAL_IP_LIST_FILE, "w");
diff --git a/src/remoteip.c b/src/remoteip.c
index 5146efb..573b69d 100644
--- a/src/remoteip.c
+++ b/src/remoteip.c
@@ -289,6 +289,27 @@ cf_trusted_ip(int mode, union cf_callback_arg *arg, void *data)
return CF_RET_OK;
}
+int
+cf_trusted_ip_heredoc(int mode, union cf_callback_arg *arg, void *data)
+{
+ struct cidr *cidr;
+
+ if (mode == CF_SERIALIZE)
+ return CF_RET_IGNORE;
+
+ cidr = emalloc(sizeof(cidr[0]));
+
+ if (str_to_cidr(arg->heredoc.val, cidr,
+ arg->heredoc.file, arg->heredoc.line)) {
+ free(cidr);
+ return CF_RET_FAIL;
+ }
+ cidr->next = trusted_ip_list;
+ trusted_ip_list = cidr;
+
+ return CF_RET_OK;
+}
+
static int
is_trusted_ip(char const *ipstr)
{

Return to:

Send suggestions and report system problems to the System administrator.