diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2020-02-28 10:07:54 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2020-02-28 10:07:54 +0200 |
commit | 73bfc3bdfac590266ad67c48de5e866bb5d5fa4d (patch) | |
tree | 2488c3b3b009c0c49f56a63f10df7340432588c4 /src | |
parent | 7e8ff0ed908913de7467daa28feb25164abc7ad9 (diff) | |
download | ping903-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.c | 109 | ||||
-rw-r--r-- | src/defs.h | 9 | ||||
-rw-r--r-- | src/ping903.c | 7 | ||||
-rw-r--r-- | src/ping903.h | 16 | ||||
-rw-r--r-- | src/ping903q.c | 8 | ||||
-rw-r--r-- | src/pinger.c | 27 | ||||
-rw-r--r-- | src/remoteip.c | 21 |
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: @@ -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) { |