]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 3015] ntpq: config-from-file: "request contains an unprintable character"
authorJuergen Perlinger <perlinger@ntp.org>
Wed, 17 Feb 2016 17:36:10 +0000 (18:36 +0100)
committerJuergen Perlinger <perlinger@ntp.org>
Wed, 17 Feb 2016 17:36:10 +0000 (18:36 +0100)
bk: 56c4af8aFVDScwAS3F58jvJvV5VUFQ

ChangeLog
ntpq/ntpq-subs.c

index c70fe8fc563cf0a16def01a652b989e8bc667f06..7e99e843b1fe15ae51dc57a8f681f03f98042512 100644 (file)
--- 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 <stenn@ntp.org>
index 8e7047776cf8bd9675ae6ab0b31ee13a2822975e..09f5d8559be5fffb45ca8cb0bf52576217751f19 100644 (file)
@@ -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);