From: Juergen Perlinger Date: Wed, 17 Feb 2016 17:36:10 +0000 (+0100) Subject: [Bug 3015] ntpq: config-from-file: "request contains an unprintable character" X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=90f26ba97f414545f804a35c5ae54cd62c20387f;p=thirdparty%2Fntp.git [Bug 3015] ntpq: config-from-file: "request contains an unprintable character" bk: 56c4af8aFVDScwAS3F58jvJvV5VUFQ --- diff --git a/ChangeLog b/ChangeLog index c70fe8fc5..7e99e843b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,9 @@ * [Bug 2994] Systems with HAVE_SIGNALED_IO fail to compile. perlinger@ntp.org * [Bug 2995] Fixes to compile on Windows +* [Bug 3015] ntpq: config-from-file: "request contains an unprintable character" + - A change related [Bug 2853] forbids trailing white space in + remote config command. perlinger@ntp.org --- (4.2.8p6) 2016/01/20 Released by Harlan Stenn diff --git a/ntpq/ntpq-subs.c b/ntpq/ntpq-subs.c index 8e7047776..09f5d8559 100644 --- a/ntpq/ntpq-subs.c +++ b/ntpq/ntpq-subs.c @@ -2244,6 +2244,10 @@ config ( * Longer lines will lead to unpredictable results. * 3. Since this function is sending a line at a time, we can't update * the control key through the configuration file (YUCK!!) + * + * Pearly: There are a few places where 'size_t' is cast to 'int' based + * on the assumption that 'int' can hold the size of the involved + * buffers without overflow. */ static void config_from_file ( @@ -2254,6 +2258,7 @@ config_from_file ( u_short rstatus; size_t rsize; const char *rdata; + char * cp; int res; FILE *config_fd; char config_cmd[MAXLINE]; @@ -2278,33 +2283,47 @@ config_from_file ( printf("Sending configuration file, one line at a time.\n"); i = 0; while (fgets(config_cmd, MAXLINE, config_fd) != NULL) { - config_len = strlen(config_cmd); - /* ensure even the last line has newline, if possible */ - if (config_len > 0 && - config_len + 2 < sizeof(config_cmd) && - '\n' != config_cmd[config_len - 1]) - config_cmd[config_len++] = '\n'; + /* Eliminate comments first. */ + cp = strchr(config_cmd, '#'); + config_len = (NULL != cp) + ? (size_t)(cp - config_cmd) + : strlen(config_cmd); + + /* [Bug 3015] make sure there's no trailing whitespace; + * the fix for [Bug 2853] on the server side forbids + * those. And don't transmit empty lines, as this would + * just be waste. + */ + while (config_len != 0 && + (u_char)config_cmd[config_len-1] <= ' ') + --config_len; + config_cmd[config_len] = '\0'; + ++i; + if (0 == config_len) + continue; + retry_limit = 2; do res = doquery(CTL_OP_CONFIGURE, 0, 1, - strlen(config_cmd), config_cmd, + config_len, config_cmd, &rstatus, &rsize, &rdata); while (res != 0 && retry_limit--); if (res != 0) { - printf("Line No: %d query failed: %s", i, - config_cmd); - printf("Subsequent lines not sent.\n"); + printf("Line No: %d query failed: %.*s\n" + "Subsequent lines not sent.\n", + i, (int)config_len, config_cmd); fclose(config_fd); return; } - if (rsize > 0 && '\n' == rdata[rsize - 1]) - rsize--; - if (rsize > 0 && '\r' == rdata[rsize - 1]) - rsize--; - printf("Line No: %d %.*s: %s", i, (int)rsize, rdata, /* cast is wobbly */ - config_cmd); + /* Right-strip the result code string, then output the + * last line executed, with result code. */ + while (rsize != 0 && (u_char)rdata[rsize - 1] <= ' ') + --rsize; + printf("Line No: %d %.*s: %.*s\n", i, + (int)rsize, rdata, + (int)config_len, config_cmd); } printf("Done sending file\n"); fclose(config_fd);