From 0f8def4ca4237495f13a93384ded9245495e3c8f Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Thu, 9 May 2013 17:29:37 +0200 Subject: [PATCH] Refactor command parsing - normalize command line before parsing - compare whole words - check for missing/extra arguments in config parsing - use strdup for string allocation - share code for reporting syntax errors - avoid using function pointers - cleanup the code a bit --- client.c | 349 +++++++++++----------- cmdmon.c | 3 - cmdparse.c | 118 +++++--- cmdparse.h | 6 +- conf.c | 856 ++++++++++++++++++++++++++++------------------------- main.c | 2 +- 6 files changed, 706 insertions(+), 628 deletions(-) diff --git a/client.c b/client.c index eadc430..64be42a 100644 --- a/client.c +++ b/client.c @@ -239,7 +239,6 @@ read_mask_address(char *line, IPAddr *mask, IPAddr *address) char *p, *q; p = line; - while (*p && isspace((unsigned char)*p)) p++; if (!*p) { mask->family = address->family = IPADDR_UNSPEC; return 1; @@ -249,8 +248,6 @@ read_mask_address(char *line, IPAddr *mask, IPAddr *address) *q++ = 0; if (UTI_StringToIP(p, mask)) { p = q; - while (*q && !isspace((unsigned char)*q)) q++; - *q = 0; if (UTI_StringToIP(p, address)) { if (address->family == mask->family) return 1; @@ -320,10 +317,13 @@ process_cmd_online(CMD_Request *msg, char *line) static int read_address_integer(char *line, IPAddr *address, int *value) { - char hostname[2048]; + char *hostname; int ok = 0; - if (sscanf(line, "%2047s %d", hostname, value) != 2) { + hostname = line; + line = CPS_SplitWord(line); + + if (sscanf(line, "%d", value) != 1) { fprintf(stderr, "Invalid syntax for address value\n"); ok = 0; } else { @@ -345,10 +345,13 @@ read_address_integer(char *line, IPAddr *address, int *value) static int read_address_double(char *line, IPAddr *address, double *value) { - char hostname[2048]; + char *hostname; int ok = 0; - if (sscanf(line, "%2047s %lf", hostname, value) != 2) { + hostname = line; + line = CPS_SplitWord(line); + + if (sscanf(line, "%lf", value) != 1) { fprintf(stderr, "Invalid syntax for address value\n"); ok = 0; } else { @@ -578,11 +581,18 @@ static int process_cmd_burst(CMD_Request *msg, char *line) { int n_good_samples, n_total_samples; - int n_parsed; - char s[101]; + char *s1, *s2; IPAddr address, mask; - n_parsed = sscanf(line, "%d/%d %100s", &n_good_samples, &n_total_samples, s); + s1 = line; + s2 = CPS_SplitWord(s1); + CPS_SplitWord(s2); + + if (sscanf(s1, "%d/%d", &n_good_samples, &n_total_samples) != 2 || + (*s2 && !read_mask_address(s2, &mask, &address))) { + fprintf(stderr, "Invalid syntax for burst command\n"); + return 0; + } msg->command = htons(REQ_BURST); msg->data.burst.n_good_samples = ntohl(n_good_samples); @@ -590,11 +600,6 @@ process_cmd_burst(CMD_Request *msg, char *line) mask.family = address.family = IPADDR_UNSPEC; - if (n_parsed < 2 || (n_parsed == 3 && !read_mask_address(s, &mask, &address))) { - fprintf(stderr, "Invalid syntax for burst command\n"); - return 0; - } - UTI_IPHostToNetwork(&mask, &msg->data.burst.mask); UTI_IPHostToNetwork(&address, &msg->data.burst.address); @@ -610,11 +615,10 @@ process_cmd_local(CMD_Request *msg, const char *line) int stratum; p = line; - while (*p && isspace((unsigned char)*p)) p++; if (!*p) { return 0; - } else if (!strncmp(p, "off", 3)) { + } else if (!strcmp(p, "off")) { msg->data.local.on_off = htonl(0); msg->data.local.stratum = htonl(0); } else if (sscanf(p, "stratum%d", &stratum) == 1) { @@ -637,15 +641,14 @@ process_cmd_manual(CMD_Request *msg, const char *line) const char *p; p = line; - while (*p && isspace((unsigned char)*p)) p++; if (!*p) { return 0; - } else if (!strncmp(p, "off", 3)) { + } else if (!strcmp(p, "off")) { msg->data.manual.option = htonl(0); - } else if (!strncmp(p, "on", 2)) { + } else if (!strcmp(p, "on")) { msg->data.manual.option = htonl(1); - } else if (!strncmp(p, "reset", 5)) { + } else if (!strcmp(p, "reset")) { msg->data.manual.option = htonl(2); } else { return 0; @@ -662,10 +665,9 @@ parse_allow_deny(CMD_Request *msg, char *line) { unsigned long a, b, c, d, n; IPAddr ip; - char *p, *q; + char *p; p = line; - while (*p && isspace((unsigned char)*p)) p++; if (!*p) { /* blank line - applies to all addresses */ ip.family = IPADDR_UNSPEC; @@ -681,11 +683,6 @@ parse_allow_deny(CMD_Request *msg, char *line) (n = sscanf(p, "%lu.%lu.%lu.%lu", &a, &b, &c, &d)) == 0) { /* Try to parse as the name of a machine */ - q = p; - while (*q) { - if (*q == '\n') *q = 0; - q++; - } if (DNS_Name2IPAddress(p, &ip) != DNS_Success) { fprintf(stderr, "Could not read address\n"); return 0; @@ -844,9 +841,8 @@ accheck_getaddr(char *line, IPAddr *addr) { unsigned long a, b, c, d; IPAddr ip; - char *p, *q; + char *p; p = line; - while (*p && isspace(*p)) p++; if (!*p) { return 0; } else { @@ -855,11 +851,6 @@ accheck_getaddr(char *line, IPAddr *addr) addr->addr.in4 = (a<<24) | (b<<16) | (c<<8) | d; return 1; } else { - q = p; - while (*q) { - if (*q == '\n') *q = 0; - q++; - } if (DNS_Name2IPAddress(p, &ip) != DNS_Success) { return 0; } else { @@ -1071,13 +1062,15 @@ process_cmd_add_peer(CMD_Request *msg, char *line) static int process_cmd_delete(CMD_Request *msg, char *line) { - char hostname[2048]; + char *hostname; int ok = 0; IPAddr address; msg->command = htons(REQ_DEL_SOURCE); + hostname = line; + CPS_SplitWord(line); - if (sscanf(line, "%2047s", hostname) != 1) { + if (!*hostname) { fprintf(stderr, "Invalid syntax for address\n"); ok = 0; } else { @@ -1105,7 +1098,7 @@ static int auth_hash_id; static int process_cmd_password(CMD_Request *msg, char *line) { - char *p, *q; + char *p; struct timeval now; int i, len; @@ -1118,13 +1111,6 @@ process_cmd_password(CMD_Request *msg, char *line) } p = line; - while (*p && isspace((unsigned char)*p)) - p++; - - /* Get rid of trailing newline */ - for (q=p; *q; q++) { - if (isspace((unsigned char)*q)) *q = 0; - } if (!*p) { /* blank line, prompt for password */ @@ -1671,8 +1657,7 @@ static int check_for_verbose_flag(char *line) { char *p = line; - while (*p && isspace((unsigned char)*p)) p++; - if (!strncmp(p, "-v", 2)) { + if (!strcmp(p, "-v")) { return 1; } else { return 0; @@ -2507,15 +2492,15 @@ process_cmd_waitsync(char *line) static int process_cmd_dns(const char *line) { - if (!strncmp(line, "-46", 3)) { + if (!strcmp(line, "-46")) { DNS_SetAddressFamily(IPADDR_UNSPEC); - } else if (!strncmp(line, "-4", 2)) { + } else if (!strcmp(line, "-4")) { DNS_SetAddressFamily(IPADDR_INET4); - } else if (!strncmp(line, "-6", 2)) { + } else if (!strcmp(line, "-6")) { DNS_SetAddressFamily(IPADDR_INET6); - } else if (!strncmp(line, "-n", 2)) { + } else if (!strcmp(line, "-n")) { no_dns = 1; - } else if (!strncmp(line, "+n", 2)) { + } else if (!strcmp(line, "+n")) { no_dns = 0; } else { fprintf(stderr, "Unrecognized dns command\n"); @@ -2527,14 +2512,15 @@ process_cmd_dns(const char *line) /* ================================================== */ static int -process_cmd_authhash(const char *line) +process_cmd_authhash(char *line) { - char hash_name[50]; + char *hash_name; int new_hash_id; assert(auth_hash_id >= 0); + hash_name = line; - if (sscanf(line, "%49s", hash_name) != 1) { + if (!*hash_name) { fprintf(stderr, "Could not parse hash name\n"); return 0; } @@ -2587,7 +2573,7 @@ process_cmd_retries(const char *line) static int process_line(char *line, int *quit) { - char *p; + char *command; int do_normal_submit; int ret; CMD_Request tx_message; @@ -2598,142 +2584,155 @@ process_line(char *line, int *quit) do_normal_submit = 1; - /* Check for line being blank */ - p = line; - while (*p && isspace((unsigned char)*p)) p++; - if (!*p) { + CPS_NormalizeLine(line); + + if (!*line) { fflush(stderr); fflush(stdout); return 1; }; - if (!strncmp(p, "offline", 7)) { - do_normal_submit = process_cmd_offline(&tx_message, p+7); - } else if (!strncmp(p, "online", 6)) { - do_normal_submit = process_cmd_online(&tx_message, p+6); - } else if (!strncmp(p, "burst", 5)) { - do_normal_submit = process_cmd_burst(&tx_message, p+5); - } else if (!strncmp(p, "password", 8)) { - do_normal_submit = process_cmd_password(&tx_message, p+8); - } else if (!strncmp(p, "minpoll", 7)) { - do_normal_submit = process_cmd_minpoll(&tx_message, p+7); - } else if (!strncmp(p, "maxpoll", 7)) { - do_normal_submit = process_cmd_maxpoll(&tx_message, p+7); - } else if (!strncmp(p, "dump", 4)) { - process_cmd_dump(&tx_message, p+4); - } else if (!strncmp(p, "maxdelaydevratio", 16)) { - do_normal_submit = process_cmd_maxdelaydevratio(&tx_message, p+16); - } else if (!strncmp(p, "maxdelayratio", 13)) { - do_normal_submit = process_cmd_maxdelayratio(&tx_message, p+13); - } else if (!strncmp(p, "maxdelay", 8)) { - do_normal_submit = process_cmd_maxdelay(&tx_message, p+8); - } else if (!strncmp(p, "maxupdateskew", 13)) { - do_normal_submit = process_cmd_maxupdateskew(&tx_message, p+13); - } else if (!strncmp(p, "minstratum", 10)) { - do_normal_submit = process_cmd_minstratum(&tx_message, p+10); - } else if (!strncmp(p, "polltarget", 10)) { - do_normal_submit = process_cmd_polltarget(&tx_message, p+10); - } else if (!strncmp(p, "settime", 7)) { + command = line; + line = CPS_SplitWord(line); + + if (!strcmp(command, "accheck")) { + do_normal_submit = process_cmd_accheck(&tx_message, line); + } else if (!strcmp(command, "activity")) { do_normal_submit = 0; - ret = process_cmd_settime(p+7); - } else if (!strncmp(p, "local", 5)) { - do_normal_submit = process_cmd_local(&tx_message, p+5); - } else if (!strncmp(p, "manual list", 11)) { + ret = process_cmd_activity(line); + } else if (!strcmp(command, "add") && !strncmp(line, "peer", 4)) { + do_normal_submit = process_cmd_add_peer(&tx_message, CPS_SplitWord(line)); + } else if (!strcmp(command, "add") && !strncmp(line, "server", 6)) { + do_normal_submit = process_cmd_add_server(&tx_message, CPS_SplitWord(line)); + } else if (!strcmp(command, "allow")) { + if (!strncmp(line, "all", 3)) { + do_normal_submit = process_cmd_allowall(&tx_message, CPS_SplitWord(line)); + } else { + do_normal_submit = process_cmd_allow(&tx_message, line); + } + } else if (!strcmp(command, "authhash")) { + ret = process_cmd_authhash(line); do_normal_submit = 0; - ret = process_cmd_manual_list(p+11); - } else if (!strncmp(p, "manual delete", 13)) { - do_normal_submit = process_cmd_manual_delete(&tx_message, p+13); - } else if (!strncmp(p, "manual", 6)) { - do_normal_submit = process_cmd_manual(&tx_message, p+6); - } else if (!strncmp(p, "sourcestats", 11)) { + } else if (!strcmp(command, "burst")) { + do_normal_submit = process_cmd_burst(&tx_message, line); + } else if (!strcmp(command, "clients")) { + ret = process_cmd_clients(line); do_normal_submit = 0; - ret = process_cmd_sourcestats(p+11); - } else if (!strncmp(p, "sources", 7)) { + } else if (!strcmp(command, "cmdaccheck")) { + do_normal_submit = process_cmd_cmdaccheck(&tx_message, line); + } else if (!strcmp(command, "cmdallow")) { + if (!strncmp(line, "all", 3)) { + do_normal_submit = process_cmd_cmdallowall(&tx_message, CPS_SplitWord(line)); + } else { + do_normal_submit = process_cmd_cmdallow(&tx_message, line); + } + } else if (!strcmp(command, "cmddeny")) { + if (!strncmp(line, "all", 3)) { + line = CPS_SplitWord(line); + do_normal_submit = process_cmd_cmddenyall(&tx_message, line); + } else { + do_normal_submit = process_cmd_cmddeny(&tx_message, line); + } + } else if (!strcmp(command, "cyclelogs")) { + process_cmd_cyclelogs(&tx_message, line); + } else if (!strcmp(command, "delete")) { + do_normal_submit = process_cmd_delete(&tx_message, line); + } else if (!strcmp(command, "deny")) { + if (!strncmp(line, "all", 3)) { + do_normal_submit = process_cmd_denyall(&tx_message, CPS_SplitWord(line)); + } else { + do_normal_submit = process_cmd_deny(&tx_message, line); + } + } else if (!strcmp(command, "dfreq")) { + process_cmd_dfreq(&tx_message, line); + } else if (!strcmp(command, "dns")) { + ret = process_cmd_dns(line); do_normal_submit = 0; - ret = process_cmd_sources(p+7); - } else if (!strncmp(p, "rekey", 5)) { - process_cmd_rekey(&tx_message, p+5); - } else if (!strncmp(p, "allow all", 9)) { - do_normal_submit = process_cmd_allowall(&tx_message, p+9); - } else if (!strncmp(p, "allow", 5)) { - do_normal_submit = process_cmd_allow(&tx_message, p+5); - } else if (!strncmp(p, "deny all", 8)) { - do_normal_submit = process_cmd_denyall(&tx_message, p+8); - } else if (!strncmp(p, "deny", 4)) { - do_normal_submit = process_cmd_deny(&tx_message, p+4); - } else if (!strncmp(p, "cmdallow all", 12)) { - do_normal_submit = process_cmd_cmdallowall(&tx_message, p+12); - } else if (!strncmp(p, "cmdallow", 8)) { - do_normal_submit = process_cmd_cmdallow(&tx_message, p+8); - } else if (!strncmp(p, "cmddeny all", 11)) { - do_normal_submit = process_cmd_cmddenyall(&tx_message, p+11); - } else if (!strncmp(p, "cmddeny", 7)) { - do_normal_submit = process_cmd_cmddeny(&tx_message, p+7); - } else if (!strncmp(p, "accheck", 7)) { - do_normal_submit = process_cmd_accheck(&tx_message, p+7); - } else if (!strncmp(p, "cmdaccheck", 10)) { - do_normal_submit = process_cmd_cmdaccheck(&tx_message, p+10); - } else if (!strncmp(p, "add server", 10)) { - do_normal_submit = process_cmd_add_server(&tx_message, p+10); - } else if (!strncmp(p, "add peer", 8)) { - do_normal_submit = process_cmd_add_peer(&tx_message, p+8); - } else if (!strncmp(p, "delete", 6)) { - do_normal_submit = process_cmd_delete(&tx_message, p+6); - } else if (!strncmp(p, "writertc", 7)) { - process_cmd_writertc(&tx_message, p+7); - } else if (!strncmp(p, "rtcdata", 7)) { + } else if (!strcmp(command, "doffset")) { + process_cmd_doffset(&tx_message, line); + } else if (!strcmp(command, "dump")) { + process_cmd_dump(&tx_message, line); + } else if (!strcmp(command, "exit")) { do_normal_submit = 0; - ret = process_cmd_rtcreport(p); - } else if (!strncmp(p, "trimrtc", 7)) { - process_cmd_trimrtc(&tx_message, p); - } else if (!strncmp(p, "cyclelogs", 9)) { - process_cmd_cyclelogs(&tx_message, p); - } else if (!strncmp(p, "dfreq", 5)) { - process_cmd_dfreq(&tx_message, p+5); - } else if (!strncmp(p, "doffset", 7)) { - process_cmd_doffset(&tx_message, p+7); - } else if (!strncmp(p, "tracking", 8)) { - ret = process_cmd_tracking(p+8); - do_normal_submit = 0; - } else if (!strncmp(p, "clients", 7)) { - ret = process_cmd_clients(p+7); - do_normal_submit = 0; - } else if (!strncmp(p, "makestep", 8)) { - process_cmd_makestep(&tx_message, p+8); - } else if (!strncmp(p, "activity", 8)) { - ret = process_cmd_activity(p+8); - do_normal_submit = 0; - } else if (!strncmp(p, "reselectdist", 12)) { - do_normal_submit = process_cmd_reselectdist(&tx_message, p+12); - } else if (!strncmp(p, "reselect", 8)) { - process_cmd_reselect(&tx_message, p+8); - } else if (!strncmp(p, "waitsync", 8)) { - ret = process_cmd_waitsync(p+8); - do_normal_submit = 0; - } else if (!strncmp(p, "authhash", 8)) { - ret = process_cmd_authhash(p+8); - do_normal_submit = 0; - } else if (!strncmp(p, "dns ", 4)) { - ret = process_cmd_dns(p+4); - do_normal_submit = 0; - } else if (!strncmp(p, "timeout", 7)) { - ret = process_cmd_timeout(p+7); - do_normal_submit = 0; - } else if (!strncmp(p, "retries", 7)) { - ret = process_cmd_retries(p+7); - do_normal_submit = 0; - } else if (!strncmp(p, "help", 4)) { + *quit = 1; + ret = 1; + } else if (!strcmp(command, "help")) { do_normal_submit = 0; give_help(); ret = 1; - } else if (!strncmp(p, "quit", 4)) { + } else if (!strcmp(command, "local")) { + do_normal_submit = process_cmd_local(&tx_message, line); + } else if (!strcmp(command, "makestep")) { + process_cmd_makestep(&tx_message, line); + } else if (!strcmp(command, "manual")) { + if (!strncmp(line, "list", 4)) { + do_normal_submit = 0; + ret = process_cmd_manual_list(CPS_SplitWord(line)); + } else if (!strncmp(line, "delete", 6)) { + do_normal_submit = process_cmd_manual_delete(&tx_message, CPS_SplitWord(line)); + } else { + do_normal_submit = process_cmd_manual(&tx_message, line); + } + } else if (!strcmp(command, "maxdelay")) { + do_normal_submit = process_cmd_maxdelay(&tx_message, line); + } else if (!strcmp(command, "maxdelaydevratio")) { + do_normal_submit = process_cmd_maxdelaydevratio(&tx_message, line); + } else if (!strcmp(command, "maxdelayratio")) { + do_normal_submit = process_cmd_maxdelayratio(&tx_message, line); + } else if (!strcmp(command, "maxpoll")) { + do_normal_submit = process_cmd_maxpoll(&tx_message, line); + } else if (!strcmp(command, "maxupdateskew")) { + do_normal_submit = process_cmd_maxupdateskew(&tx_message, line); + } else if (!strcmp(command, "minpoll")) { + do_normal_submit = process_cmd_minpoll(&tx_message, line); + } else if (!strcmp(command, "minstratum")) { + do_normal_submit = process_cmd_minstratum(&tx_message, line); + } else if (!strcmp(command, "offline")) { + do_normal_submit = process_cmd_offline(&tx_message, line); + } else if (!strcmp(command, "online")) { + do_normal_submit = process_cmd_online(&tx_message, line); + } else if (!strcmp(command, "password")) { + do_normal_submit = process_cmd_password(&tx_message, line); + } else if (!strcmp(command, "polltarget")) { + do_normal_submit = process_cmd_polltarget(&tx_message, line); + } else if (!strcmp(command, "quit")) { do_normal_submit = 0; *quit = 1; ret = 1; - } else if (!strncmp(p, "exit", 4)) { + } else if (!strcmp(command, "rekey")) { + process_cmd_rekey(&tx_message, line); + } else if (!strcmp(command, "reselect")) { + process_cmd_reselect(&tx_message, line); + } else if (!strcmp(command, "reselectdist")) { + do_normal_submit = process_cmd_reselectdist(&tx_message, line); + } else if (!strcmp(command, "retries")) { + ret = process_cmd_retries(line); do_normal_submit = 0; - *quit = 1; - ret = 1; + } else if (!strcmp(command, "rtcdata")) { + do_normal_submit = 0; + ret = process_cmd_rtcreport(line); + } else if (!strcmp(command, "settime")) { + do_normal_submit = 0; + ret = process_cmd_settime(line); + } else if (!strcmp(command, "sources")) { + do_normal_submit = 0; + ret = process_cmd_sources(line); + } else if (!strcmp(command, "sourcestats")) { + do_normal_submit = 0; + ret = process_cmd_sourcestats(line); + } else if (!strcmp(command, "timeout")) { + ret = process_cmd_timeout(line); + do_normal_submit = 0; + } else if (!strcmp(command, "tracking")) { + ret = process_cmd_tracking(line); + do_normal_submit = 0; + } else if (!strcmp(command, "trimrtc")) { + process_cmd_trimrtc(&tx_message, line); + } else if (!strcmp(command, "waitsync")) { + ret = process_cmd_waitsync(line); + do_normal_submit = 0; + } else if (!strcmp(command, "writertc")) { + process_cmd_writertc(&tx_message, line); } else { fprintf(stderr, "Unrecognized command\n"); do_normal_submit = 0; diff --git a/cmdmon.c b/cmdmon.c index 964d518..d58e0f1 100644 --- a/cmdmon.c +++ b/cmdmon.c @@ -187,9 +187,6 @@ prepare_socket(int family) int on_off = 1; port_number = CNF_GetCommandPort(); - if (port_number < 0) { - port_number = DEFAULT_CANDM_PORT; - } sock_fd = socket(family, SOCK_DGRAM, 0); if (sock_fd < 0) { diff --git a/cmdparse.c b/cmdparse.c index 4b878e8..80fd09c 100644 --- a/cmdparse.c +++ b/cmdparse.c @@ -33,17 +33,15 @@ #include "cmdparse.h" #include "memory.h" #include "nameserv.h" - -#define MAXLEN 2047 -#define SMAXLEN "2047" +#include "util.h" /* ================================================== */ CPS_Status -CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src) +CPS_ParseNTPSourceAdd(char *line, CPS_NTP_Source *src) { + char *hostname, *cmd; int ok, n, done; - char cmd[MAXLEN+1], hostname[MAXLEN+1]; CPS_Status result; src->port = SRC_DEFAULT_PORT; @@ -63,26 +61,22 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src) result = CPS_Success; - ok = 0; - if (sscanf(line, "%" SMAXLEN "s%n", hostname, &n) == 1) { - ok = 1; - } + hostname = line; + line = CPS_SplitWord(line); - if (!ok) { + if (!*hostname) { result = CPS_BadHost; + ok = 0; } else { - - line += n; - /* Parse subfields */ ok = 1; done = 0; do { - if (sscanf(line, "%" SMAXLEN "s%n", cmd, &n) == 1) { - - line += n; - - if (!strncasecmp(cmd, "port", 4)) { + cmd = line; + line = CPS_SplitWord(line); + + if (*cmd) { + if (!strcasecmp(cmd, "port")) { if (sscanf(line, "%hu%n", &src->port, &n) != 1) { result = CPS_BadPort; ok = 0; @@ -90,7 +84,7 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src) } else { line += n; } - } else if (!strncasecmp(cmd, "minpoll", 7)) { + } else if (!strcasecmp(cmd, "minpoll")) { if (sscanf(line, "%d%n", &src->params.minpoll, &n) != 1) { result = CPS_BadMinpoll; ok = 0; @@ -98,7 +92,7 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src) } else { line += n; } - } else if (!strncasecmp(cmd, "maxpoll", 7)) { + } else if (!strcasecmp(cmd, "maxpoll")) { if (sscanf(line, "%d%n", &src->params.maxpoll, &n) != 1) { result = CPS_BadMaxpoll; ok = 0; @@ -106,7 +100,7 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src) } else { line += n; } - } else if (!strncasecmp(cmd, "presend", 7)) { + } else if (!strcasecmp(cmd, "presend")) { if (sscanf(line, "%d%n", &src->params.presend_minpoll, &n) != 1) { result = CPS_BadPresend; ok = 0; @@ -114,7 +108,7 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src) } else { line += n; } - } else if (!strncasecmp(cmd, "maxdelaydevratio", 16)) { + } else if (!strcasecmp(cmd, "maxdelaydevratio")) { if (sscanf(line, "%lf%n", &src->params.max_delay_dev_ratio, &n) != 1) { result = CPS_BadMaxdelaydevratio; ok = 0; @@ -122,8 +116,7 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src) } else { line += n; } - /* This MUST come before the following one ! */ - } else if (!strncasecmp(cmd, "maxdelayratio", 13)) { + } else if (!strcasecmp(cmd, "maxdelayratio")) { if (sscanf(line, "%lf%n", &src->params.max_delay_ratio, &n) != 1) { result = CPS_BadMaxdelayratio; ok = 0; @@ -131,7 +124,7 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src) } else { line += n; } - } else if (!strncasecmp(cmd, "maxdelay", 8)) { + } else if (!strcasecmp(cmd, "maxdelay")) { if (sscanf(line, "%lf%n", &src->params.max_delay, &n) != 1) { result = CPS_BadMaxdelay; ok = 0; @@ -139,7 +132,7 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src) } else { line += n; } - } else if (!strncasecmp(cmd, "key", 3)) { + } else if (!strcasecmp(cmd, "key")) { if (sscanf(line, "%lu%n", &src->params.authkey, &n) != 1) { result = CPS_BadKey; ok = 0; @@ -147,16 +140,16 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src) } else { line += n; } - } else if (!strncasecmp(cmd, "offline", 7)) { + } else if (!strcasecmp(cmd, "offline")) { src->params.online = 0; - } else if (!strncasecmp(cmd, "auto_offline", 12)) { + } else if (!strcasecmp(cmd, "auto_offline")) { src->params.auto_offline = 1; - } else if (!strncasecmp(cmd, "iburst", 6)) { + } else if (!strcasecmp(cmd, "iburst")) { src->params.iburst = 1; - } else if (!strncasecmp(cmd, "minstratum", 10)) { + } else if (!strcasecmp(cmd, "minstratum")) { if (sscanf(line, "%d%n", &src->params.min_stratum, &n) != 1) { result = CPS_BadMinstratum; ok = 0; @@ -165,7 +158,7 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src) line += n; } - } else if (!strncasecmp(cmd, "polltarget", 10)) { + } else if (!strcasecmp(cmd, "polltarget")) { if (sscanf(line, "%d%n", &src->params.poll_target, &n) != 1) { result = CPS_BadPolltarget; ok = 0; @@ -174,10 +167,10 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src) line += n; } - } else if (!strncasecmp(cmd, "noselect", 8)) { + } else if (!strcasecmp(cmd, "noselect")) { src->params.sel_option = SRC_SelectNoselect; - } else if (!strncasecmp(cmd, "prefer", 6)) { + } else if (!strcasecmp(cmd, "prefer")) { src->params.sel_option = SRC_SelectPrefer; } else { @@ -192,10 +185,7 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src) } if (ok) { - n = strlen(hostname); - src->name = MallocArray(char, n + 1); - strncpy(src->name, hostname, n); - src->name[n] = '\0'; + src->name = strdup(hostname); } return result; @@ -204,3 +194,57 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src) /* ================================================== */ +void +CPS_NormalizeLine(char *line) +{ + char *p, *q; + int space = 1, first = 1; + + /* Remove white-space at beginning and replace white-spaces with space char */ + for (p = q = line; *p; p++) { + if (isspace(*p)) { + if (!space) + *q++ = ' '; + space = 1; + continue; + } + + /* Discard comment lines */ + if (first && strchr("!;#%", *p)) + break; + + *q++ = *p; + space = first = 0; + } + + /* Strip trailing space */ + if (q > line && q[-1] == ' ') + q--; + + *q = '\0'; +} + +/* ================================================== */ + +char * +CPS_SplitWord(char *line) +{ + char *p = line, *q = line; + + /* Skip white-space before the word */ + while (*q && isspace(*q)) + q++; + + /* Move the word to the beginning */ + while (*q && !isspace(*q)) + *p++ = *q++; + + /* Find the next word */ + while (*q && isspace(*q)) + q++; + + *p = '\0'; + + /* Return pointer to the next word or NUL */ + return q; +} diff --git a/cmdparse.h b/cmdparse.h index 4b0b9ce..3c0a256 100644 --- a/cmdparse.h +++ b/cmdparse.h @@ -53,8 +53,12 @@ typedef struct { } CPS_NTP_Source; /* Parse a command to add an NTP server or peer */ -extern CPS_Status CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src); +extern CPS_Status CPS_ParseNTPSourceAdd(char *line, CPS_NTP_Source *src); +/* Remove extra white-space and comments */ +extern void CPS_NormalizeLine(char *line); +/* Terminate first word and return pointer to the next word */ +extern char *CPS_SplitWord(char *line); #endif /* GOT_CMDPARSE_H */ diff --git a/conf.c b/conf.c index 3bbc2b6..87529db 100644 --- a/conf.c +++ b/conf.c @@ -57,55 +57,55 @@ /* ================================================== */ /* Forward prototypes */ -static void parse_commandkey(const char *); -static void parse_driftfile(const char *); -static void parse_dumpdir(const char *); -static void parse_dumponexit(const char *); -static void parse_keyfile(const char *); -static void parse_rtcfile(const char *); -static void parse_log(const char *); -static void parse_logbanner(const char *); -static void parse_logdir(const char *); -static void parse_maxupdateskew(const char *); -static void parse_maxclockerror(const char *); -static void parse_corrtimeratio(const char *); -static void parse_reselectdist(const char *); -static void parse_stratumweight(const char *); -static void parse_peer(const char *); -static void parse_acquisitionport(const char *); -static void parse_port(const char *); -static void parse_server(const char *); -static void parse_refclock(const char *); -static void parse_local(const char *); -static void parse_manual(const char *); -static void parse_initstepslew(const char *); -static void parse_allow(const char *); -static void parse_deny(const char *); -static void parse_cmdallow(const char *); -static void parse_cmddeny(const char *); -static void parse_cmdport(const char *); -static void parse_rtconutc(const char *); -static void parse_rtcsync(const char *); -static void parse_noclientlog(const char *); -static void parse_clientloglimit(const char *); -static void parse_fallbackdrift(const char *); -static void parse_makestep(const char *); -static void parse_maxchange(const char *); -static void parse_logchange(const char *); -static void parse_mailonchange(const char *); -static void parse_bindaddress(const char *); -static void parse_bindcmdaddress(const char *); -static void parse_rtcdevice(const char *); -static void parse_pidfile(const char *); -static void parse_broadcast(const char *); -static void parse_linux_hz(const char *); -static void parse_linux_freq_scale(const char *); -static void parse_sched_priority(const char *); -static void parse_lockall(const char *); -static void parse_tempcomp(const char *); -static void parse_include(const char *); -static void parse_leapsectz(const char *); -static void parse_user(const char *); +static void parse_acquisitionport(char *); +static void parse_allow(char *); +static void parse_bindaddress(char *); +static void parse_bindcmdaddress(char *); +static void parse_broadcast(char *); +static void parse_clientloglimit(char *); +static void parse_cmdallow(char *); +static void parse_cmddeny(char *); +static void parse_cmdport(char *); +static void parse_commandkey(char *); +static void parse_corrtimeratio(char *); +static void parse_deny(char *); +static void parse_driftfile(char *); +static void parse_dumpdir(char *); +static void parse_dumponexit(char *); +static void parse_fallbackdrift(char *); +static void parse_include(char *); +static void parse_initstepslew(char *); +static void parse_keyfile(char *); +static void parse_leapsectz(char *); +static void parse_linux_freq_scale(char *); +static void parse_linux_hz(char *); +static void parse_local(char *); +static void parse_lockall(char *); +static void parse_log(char *); +static void parse_logbanner(char *); +static void parse_logchange(char *); +static void parse_logdir(char *); +static void parse_mailonchange(char *); +static void parse_makestep(char *); +static void parse_manual(char *); +static void parse_maxchange(char *); +static void parse_maxclockerror(char *); +static void parse_maxupdateskew(char *); +static void parse_noclientlog(char *); +static void parse_peer(char *); +static void parse_pidfile(char *); +static void parse_port(char *); +static void parse_refclock(char *); +static void parse_reselectdist(char *); +static void parse_rtcdevice(char *); +static void parse_rtcfile(char *); +static void parse_rtconutc(char *); +static void parse_rtcsync(char *); +static void parse_sched_priority(char *); +static void parse_server(char *); +static void parse_stratumweight(char *); +static void parse_tempcomp(char *); +static void parse_user(char *); /* ================================================== */ /* Configuration variables */ @@ -125,7 +125,7 @@ static double max_clock_error = 1.0; /* in ppm */ static double reselect_distance = 1e-4; static double stratum_weight = 1.0; -static int cmd_port = -1; +static int cmd_port = DEFAULT_CANDM_PORT; static int do_log_measurements = 0; static int do_log_statistics = 0; @@ -139,7 +139,6 @@ static char *logdir = "."; static char *dumpdir = "."; static int enable_local=0; -#define DEFAULT_LOCAL_STRATUM 8 static int local_stratum; static int do_init_stepslew = 0; @@ -225,73 +224,6 @@ static char *leapsec_tz = NULL; /* Name of the user to which will be dropped root privileges. */ static char *user = NULL; -/* ================================================== */ - -typedef struct { - const char *keyword; - int len; - void (*handler)(const char *); -} Command; - -static const Command commands[] = { - {"server", 6, parse_server}, - {"peer", 4, parse_peer}, - {"refclock", 8, parse_refclock}, - {"acquisitionport", 15, parse_acquisitionport}, - {"port", 4, parse_port}, - {"driftfile", 9, parse_driftfile}, - {"keyfile", 7, parse_keyfile}, - {"rtcfile", 7, parse_rtcfile}, - {"logbanner", 9, parse_logbanner}, - {"logdir", 6, parse_logdir}, - {"log", 3, parse_log}, - {"dumponexit", 10, parse_dumponexit}, - {"dumpdir", 7, parse_dumpdir}, - {"maxupdateskew", 13, parse_maxupdateskew}, - {"maxclockerror", 13, parse_maxclockerror}, - {"corrtimeratio", 13, parse_corrtimeratio}, - {"commandkey", 10, parse_commandkey}, - {"initstepslew", 12, parse_initstepslew}, - {"local", 5, parse_local}, - {"manual", 6, parse_manual}, - {"allow", 5, parse_allow}, - {"deny", 4, parse_deny}, - {"cmdallow", 8, parse_cmdallow}, - {"cmddeny", 7, parse_cmddeny}, - {"cmdport", 7, parse_cmdport}, - {"rtconutc", 8, parse_rtconutc}, - {"rtcsync", 7, parse_rtcsync}, - {"noclientlog", 11, parse_noclientlog}, - {"clientloglimit", 14, parse_clientloglimit}, - {"fallbackdrift", 13, parse_fallbackdrift}, - {"makestep", 8, parse_makestep}, - {"maxchange", 9, parse_maxchange}, - {"logchange", 9, parse_logchange}, - {"mailonchange", 12, parse_mailonchange}, - {"bindaddress", 11, parse_bindaddress}, - {"bindcmdaddress", 14, parse_bindcmdaddress}, - {"rtcdevice", 9, parse_rtcdevice}, - {"pidfile", 7, parse_pidfile}, - {"broadcast", 9, parse_broadcast}, - {"tempcomp", 8, parse_tempcomp}, - {"reselectdist", 12, parse_reselectdist}, - {"stratumweight", 13, parse_stratumweight}, - {"include", 7, parse_include}, - {"leapsectz", 9, parse_leapsectz}, - {"linux_hz", 8, parse_linux_hz}, - {"linux_freq_scale", 16, parse_linux_freq_scale}, - {"user", 4, parse_user}, - {"sched_priority", 14, parse_sched_priority}, - {"lock_all", 8, parse_lockall} -}; - -static int n_commands = (sizeof(commands) / sizeof(commands[0])); - -/* The line number in the configuration file being processed */ -static int line_number; - -/* ================================================== */ - typedef struct { NTP_Source_Type type; CPS_NTP_Source params; @@ -307,8 +239,6 @@ static int n_ntp_sources = 0; static RefclockParameters refclock_sources[MAX_RCL_SOURCES]; static int n_refclock_sources = 0; -/* ================================================== */ - typedef struct _AllowDeny { struct _AllowDeny *next; struct _AllowDeny *prev; @@ -321,6 +251,63 @@ typedef struct _AllowDeny { static AllowDeny ntp_auth_list = {&ntp_auth_list, &ntp_auth_list}; static AllowDeny cmd_auth_list = {&cmd_auth_list, &cmd_auth_list}; +typedef struct { + /* Both in host (not necessarily network) order */ + IPAddr addr; + unsigned short port; + int interval; +} NTP_Broadcast_Destination; + +static NTP_Broadcast_Destination *broadcasts = NULL; +static int max_broadcasts = 0; +static int n_broadcasts = 0; + +/* ================================================== */ + +/* The line number in the configuration file being processed */ +static int line_number; +static const char *processed_file; +static const char *processed_command; + +/* ================================================== */ + +static void +command_parse_error(void) +{ + LOG_FATAL(LOGF_Configure, "Could not parse %s directive at line %d in file %s", + processed_command, line_number, processed_file); +} + +/* ================================================== */ + +static void +other_parse_error(const char *message) +{ + LOG_FATAL(LOGF_Configure, "%s at line %d in file %s", + message, line_number, processed_file); +} + +/* ================================================== */ + +static void +check_number_of_args(char *line, int num) +{ + /* The line is normalized, between arguments is just one space */ + if (*line == ' ') + line++; + if (*line) + num--; + for (; *line; line++) { + if (*line == ' ') + num--; + } + if (num) { + LOG_FATAL(LOGF_Configure, "%s arguments for %s directive at line %d in file %s", + num > 0 ? "Missing" : "Too many", + processed_command, line_number, processed_file); + } +} + /* ================================================== */ void @@ -337,67 +324,149 @@ CNF_ReadFile(const char *filename) { FILE *in; char line[2048]; - char *p; - int i, ok; + char *p, *command; + const char *prev_processed_file; int prev_line_number; - if (filename == NULL) { - filename = DEFAULT_CONF_FILE; - } - in = fopen(filename, "r"); if (!in) { - LOG(LOGS_ERR, LOGF_Configure, "Could not open configuration file [%s]", filename); + LOG_FATAL(LOGF_Configure, "Could not open configuration file %s", filename); } else { - /* Save current line number in case this is an included file */ prev_line_number = line_number; + prev_processed_file = processed_file; line_number = 0; + processed_file = filename; /* Success */ while (fgets(line, sizeof(line), in)) { - line_number++; - /* Strip trailing newline */ - line[strlen(line) - 1] = 0; + /* Remove extra white-space and comments */ + CPS_NormalizeLine(line); - /* Discard comment lines, blank lines etc */ - p = line; - while(*p && (isspace((unsigned char)*p))) - p++; - - if (!*p || (strchr("!;#%", *p) != NULL)) + /* Skip blank lines */ + if (!*line) continue; /* We have a real line, now try to match commands */ - ok = 0; - for (i=0; i= MAX_INIT_SRCS) { - break; + other_parse_error("Too many initstepslew servers"); } - - } else { - /* If we get invalid trailing syntax, forget it ... */ - break; } - p += n; } if (n_init_srcs > 0) { do_init_stepslew = 1; - } else { - LOG(LOGS_WARN, LOGF_Configure, "No usable initstepslew servers at line %d\n", line_number); } } /* ================================================== */ static void -parse_manual(const char *line) +parse_manual(char *line) { + check_number_of_args(line, 0); enable_manual = 1; } /* ================================================== */ static void -parse_rtconutc(const char *line) +parse_rtconutc(char *line) { + check_number_of_args(line, 0); rtc_on_utc = 1; } /* ================================================== */ static void -parse_rtcsync(const char *line) +parse_rtcsync(char *line) { + check_number_of_args(line, 0); rtc_sync = 1; } /* ================================================== */ static void -parse_noclientlog(const char *line) +parse_noclientlog(char *line) { + check_number_of_args(line, 0); no_client_log = 1; } /* ================================================== */ static void -parse_clientloglimit(const char *line) +parse_clientloglimit(char *line) { + check_number_of_args(line, 1); if (sscanf(line, "%lu", &client_log_limit) != 1) { - LOG_FATAL(LOGF_Configure, "Could not read clientlog memory limit at line %d", line_number); + command_parse_error(); } if (client_log_limit == 0) { @@ -946,23 +989,23 @@ parse_clientloglimit(const char *line) /* ================================================== */ static void -parse_fallbackdrift(const char *line) +parse_fallbackdrift(char *line) { + check_number_of_args(line, 2); if (sscanf(line, "%d %d", &fb_drift_min, &fb_drift_max) != 2) { - LOG_FATAL(LOGF_Configure, "Could not read fallback drift intervals at line %d", line_number); + command_parse_error(); } } /* ================================================== */ static void -parse_makestep(const char *line) +parse_makestep(char *line) { + check_number_of_args(line, 2); if (sscanf(line, "%lf %d", &make_step_threshold, &make_step_limit) != 2) { make_step_limit = 0; - LOG_FATAL(LOGF_Configure, - "Could not read threshold or update limit for stepping clock at line %d\n", - line_number); + command_parse_error(); } /* Disable limited makestep if chronyd was started with -R. */ @@ -974,58 +1017,53 @@ parse_makestep(const char *line) /* ================================================== */ static void -parse_maxchange(const char *line) +parse_maxchange(char *line) { + check_number_of_args(line, 3); if (sscanf(line, "%lf %d %d", &max_offset, &max_offset_delay, &max_offset_ignore) != 3) { max_offset_delay = -1; - LOG_FATAL(LOGF_Configure, - "Could not read offset, check delay or ignore limit for maximum change at line %d\n", - line_number); + command_parse_error(); } } /* ================================================== */ static void -parse_logchange(const char *line) +parse_logchange(char *line) { + check_number_of_args(line, 1); if (sscanf(line, "%lf", &log_change_threshold) == 1) { do_log_change = 1; } else { do_log_change = 0; - LOG_FATAL(LOGF_Configure, - "Could not read threshold for logging clock changes at line %d\n", - line_number); + command_parse_error(); } } /* ================================================== */ -#define BUFLEN 2047 -#define SBUFLEN "2047" - static void -parse_mailonchange(const char *line) +parse_mailonchange(char *line) { - char buffer[BUFLEN+1]; - if (sscanf(line, "%" SBUFLEN "s%lf", buffer, &mail_change_threshold) == 2) { - mail_user_on_change = MallocArray(char, strlen(buffer)+1); - strcpy(mail_user_on_change, buffer); + char *address; + check_number_of_args(line, 2); + address = line; + line = CPS_SplitWord(line); + if (sscanf(line, "%lf", &mail_change_threshold) == 1) { + mail_user_on_change = strdup(address); } else { mail_user_on_change = NULL; - LOG_FATAL(LOGF_Configure, - "Could not read user or threshold for clock change mail notify at line %d\n", - line_number); + command_parse_error(); } } /* ================================================== */ static void -parse_allow_deny(const char *line, AllowDeny *list, int allow) +parse_allow_deny(char *line, AllowDeny *list, int allow) { - const char *p; + char *p; unsigned long a, b, c, d, n; int all = 0; AllowDeny *new_node = NULL; @@ -1033,14 +1071,11 @@ parse_allow_deny(const char *line, AllowDeny *list, int allow) p = line; - while (*p && isspace((unsigned char)*p)) p++; - if (!strncmp(p, "all", 3)) { all = 1; - p += 3; + p = CPS_SplitWord(line); } - while (*p && isspace((unsigned char)*p)) p++; if (!*p) { /* Empty line applies to all addresses */ new_node = MallocNew(AllowDeny); @@ -1053,6 +1088,7 @@ parse_allow_deny(const char *line, AllowDeny *list, int allow) slashpos = strchr(p, '/'); if (slashpos) *slashpos = 0; + check_number_of_args(p, 1); n = 0; if (UTI_StringToIP(p, &ip_addr) || (n = sscanf(p, "%lu.%lu.%lu.%lu", &a, &b, &c, &d)) >= 1) { @@ -1102,7 +1138,7 @@ parse_allow_deny(const char *line, AllowDeny *list, int allow) if (n == 1) { new_node->subnet_bits = specified_subnet_bits; } else { - LOG_FATAL(LOGF_Configure, "Could not read subnet size at line %d", line_number); + command_parse_error(); } } @@ -1117,7 +1153,7 @@ parse_allow_deny(const char *line, AllowDeny *list, int allow) else new_node->subnet_bits = 32; } else { - LOG_FATAL(LOGF_Configure, "Could not read address at line %d", line_number); + command_parse_error(); } } } @@ -1135,7 +1171,7 @@ parse_allow_deny(const char *line, AllowDeny *list, int allow) /* ================================================== */ static void -parse_allow(const char *line) +parse_allow(char *line) { parse_allow_deny(line, &ntp_auth_list, 1); } @@ -1144,7 +1180,7 @@ parse_allow(const char *line) /* ================================================== */ static void -parse_deny(const char *line) +parse_deny(char *line) { parse_allow_deny(line, &ntp_auth_list, 0); } @@ -1152,7 +1188,7 @@ parse_deny(const char *line) /* ================================================== */ static void -parse_cmdallow(const char *line) +parse_cmdallow(char *line) { parse_allow_deny(line, &cmd_auth_list, 1); } @@ -1161,7 +1197,7 @@ parse_cmdallow(const char *line) /* ================================================== */ static void -parse_cmddeny(const char *line) +parse_cmddeny(char *line) { parse_allow_deny(line, &cmd_auth_list, 0); } @@ -1169,83 +1205,86 @@ parse_cmddeny(const char *line) /* ================================================== */ static void -parse_bindaddress(const char *line) +parse_bindaddress(char *line) { IPAddr ip; - char addr[51]; - if (sscanf(line, "%50s", addr) == 1 && UTI_StringToIP(addr, &ip)) { + check_number_of_args(line, 1); + if (UTI_StringToIP(line, &ip)) { if (ip.family == IPADDR_INET4) bind_address4 = ip; else if (ip.family == IPADDR_INET6) bind_address6 = ip; } else { - LOG_FATAL(LOGF_Configure, "Could not read bind address at line %d\n", line_number); + command_parse_error(); } } /* ================================================== */ static void -parse_bindcmdaddress(const char *line) +parse_bindcmdaddress(char *line) { IPAddr ip; - char addr[51]; - if (sscanf(line, "%50s", addr) == 1 && UTI_StringToIP(addr, &ip)) { + check_number_of_args(line, 1); + if (UTI_StringToIP(line, &ip)) { if (ip.family == IPADDR_INET4) bind_cmd_address4 = ip; else if (ip.family == IPADDR_INET6) bind_cmd_address6 = ip; } else { - LOG_FATAL(LOGF_Configure, "Could not read bind command address at line %d\n", line_number); + command_parse_error(); } } /* ================================================== */ static void -parse_pidfile(const char *line) +parse_pidfile(char *line) { - pidfile = MallocArray(char, 1 + strlen(line)); - sscanf(line, "%s", pidfile); - strip_trailing_spaces(pidfile); + check_number_of_args(line, 1); + pidfile = strdup(line); } /* ================================================== */ -typedef struct { - /* Both in host (not necessarily network) order */ - IPAddr addr; - unsigned short port; - int interval; -} NTP_Broadcast_Destination; - -static NTP_Broadcast_Destination *broadcasts = NULL; -static int max_broadcasts = 0; -static int n_broadcasts = 0; - -/* ================================================== */ - static void -parse_broadcast(const char *line) +parse_broadcast(char *line) { /* Syntax : broadcast [] */ int port; - int n; int interval; - char addr[51]; + char *p; IPAddr ip; - n = sscanf(line, "%d %50s %d", &interval, addr, &port); - if (n < 2 || !UTI_StringToIP(addr, &ip)) { - LOG_FATAL(LOGF_Configure, "Could not parse broadcast directive at line %d", line_number); + p = line; + line = CPS_SplitWord(line); + + if (sscanf(p, "%d", &interval) != 1) { + command_parse_error(); return; - } else if (n == 2) { + } + + p = line; + line = CPS_SplitWord(line); + + if (!UTI_StringToIP(p, &ip)) { + command_parse_error(); + return; + } + + p = line; + line = CPS_SplitWord(line); + + if (*p) { + if (sscanf(p, "%d", &port) != 1 || *line) { + command_parse_error(); + return; + } + } else { /* default port */ port = 123; - } else if (n > 3) { - LOG_FATAL(LOGF_Configure, "Too many fields in broadcast directive at line %d", line_number); } if (max_broadcasts == n_broadcasts) { @@ -1267,83 +1306,78 @@ parse_broadcast(const char *line) /* ================================================== */ static void -parse_tempcomp(const char *line) +parse_tempcomp(char *line) { - const char *tmp; + char *p; - while (isspace(line[0])) - line++; - tmp = line; - while (line[0] != '\0' && !isspace(line[0])) - line++; + check_number_of_args(line, 6); + p = line; + line = CPS_SplitWord(line); - if (line == tmp) { - LOG_FATAL(LOGF_Configure, "Could not read tempcomp filename at line %d", line_number); + if (!*p) { + command_parse_error(); return; } if (sscanf(line, "%lf %lf %lf %lf %lf", &tempcomp_interval, &tempcomp_T0, &tempcomp_k0, &tempcomp_k1, &tempcomp_k2) != 5) { - LOG_FATAL(LOGF_Configure, "Could not read tempcomp interval or coefficients at line %d", line_number); + command_parse_error(); return; } - tempcomp_file = MallocArray(char, 1 + line - tmp); - strncpy(tempcomp_file, tmp, line - tmp); - tempcomp_file[line - tmp] = '\0'; + tempcomp_file = strdup(p); } /* ================================================== */ static void -parse_include(const char *line) +parse_include(char *line) { - while (isspace(line[0])) - line++; + check_number_of_args(line, 1); CNF_ReadFile(line); } /* ================================================== */ static void -parse_leapsectz(const char *line) +parse_leapsectz(char *line) { - /* This must allocate enough space! */ - leapsec_tz = MallocArray(char, 1 + strlen(line)); - sscanf(line, "%s", leapsec_tz); + check_number_of_args(line, 1); + leapsec_tz = strdup(line); } /* ================================================== */ static void -parse_linux_hz(const char *line) +parse_linux_hz(char *line) { + check_number_of_args(line, 1); if (1 == sscanf(line, "%d", &linux_hz)) { set_linux_hz = 1; } else { - LOG_FATAL(LOGF_Configure, "Could not parse linux_hz directive at line %d", line_number); + command_parse_error(); } } /* ================================================== */ static void -parse_linux_freq_scale(const char *line) +parse_linux_freq_scale(char *line) { + check_number_of_args(line, 1); if (1 == sscanf(line, "%lf", &linux_freq_scale)) { set_linux_freq_scale = 1; } else { - LOG_FATAL(LOGF_Configure, "Could not parse linux_freq_scale directive at line %d", line_number); + command_parse_error(); } } /* ================================================== */ static void -parse_user(const char *line) +parse_user(char *line) { - /* This must allocate enough space! */ - user = MallocArray(char, 1 + strlen(line)); - sscanf(line, "%s", user); + check_number_of_args(line, 1); + user = strdup(line); } /* ================================================== */ diff --git a/main.c b/main.c index dd08ca2..59c3be5 100644 --- a/main.c +++ b/main.c @@ -284,7 +284,7 @@ go_daemon(void) int main (int argc, char **argv) { - char *conf_file = NULL; + const char *conf_file = DEFAULT_CONF_FILE; char *user = NULL; int debug = 0, nofork = 0; int do_init_rtc = 0, restarted = 0;