]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
Fixes for ntpdate as discussed in bug #3442.
authorMartin Burnicki <burnicki@ntp.org>
Tue, 19 Jun 2018 11:00:54 +0000 (13:00 +0200)
committerMartin Burnicki <burnicki@ntp.org>
Tue, 19 Jun 2018 11:00:54 +0000 (13:00 +0200)
bk: 5b28e266Iv8CnIp2uGuMQqZG3fp3OA

ChangeLog
ntpdate/ntpdate.c

index 61e886ebddf19b16fe4221f371c9f07c92acdd4c..6a8bbce3e58fadfb93d5c57ac116df705e803d6c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,5 @@
+* [Bug 3442] Fixes for ntpdate as suggested by Gerry Garvey,
+  with modifications
   New macro REFID_ISTEXT() which is also used in ntpd/ntp_control.c.
 
 ---
index 8d80767b9670476e7c843c8f91b4e0d9cd6dfbed..03d9552dd4b4b6070712172abdd24ee0311973b7 100644 (file)
@@ -154,7 +154,7 @@ char const *progname;
 /*
  * Systemwide parameters and flags
  */
-int sys_samples = DEFSAMPLES;  /* number of samples/server */
+int sys_samples = 0;           /* number of samples/server, will be modified later */
 u_long sys_timeout = DEFTIMEOUT; /* timeout time, in TIMER_HZ units */
 struct server *sys_servers;    /* the server list */
 int sys_numservers = 0;        /* number of servers to poll */
@@ -220,7 +220,7 @@ void        input_handler   (void);
 static int l_adj_systime       (l_fp *);
 static int l_step_systime      (l_fp *);
 
-static void    printserver (struct server *, FILE *);
+static void    print_server (struct server *, FILE *);
 
 #ifdef SYS_WINNT
 int    on = 1;
@@ -437,6 +437,14 @@ ntpdatemain (
                exit(2);
        }
 
+       /*
+        * If number of Samples (-p) not specified by user:
+        * - if a simple_query (-q) just ONE will do
+        * - otherwise the normal is DEFSAMPLES
+        */
+       if (sys_samples == 0)
+                sys_samples = (simple_query ? 1 : DEFSAMPLES);
+
        if (debug || simple_query) {
 #ifdef HAVE_SETVBUF
                static char buf[BUFSIZ];
@@ -651,9 +659,6 @@ transmit(
 {
        struct pkt xpkt;
 
-       if (debug)
-               printf("transmit(%s)\n", stoa(&server->srcadr));
-
        if (server->filter_nextpt < server->xmtcnt) {
                l_fp ts;
                /*
@@ -674,6 +679,9 @@ transmit(
                return;
        }
 
+       if (debug)
+               printf("transmit(%s)\n", stoa(&server->srcadr));
+
        /*
         * If we're here, send another message to the server.  Fill in
         * the packet and let 'er rip.
@@ -849,7 +857,7 @@ receive(
        NTOHL_FP(&rpkt->xmt, &server->org);
 
        /*
-        * Make sure the server is at least somewhat sane.      If not, try
+        * Make sure the server is at least somewhat sane. If not, try
         * again.
         */
        if (L_ISZERO(&rec) || !L_ISHIS(&server->org, &rec)) {
@@ -1042,15 +1050,15 @@ clock_select(void)
        /*
         * This first chunk of code is supposed to go through all
         * servers we know about to find the NTP_MAXLIST servers which
-        * are most likely to succeed.  We run through the list
+        * are most likely to succeed. We run through the list
         * doing the sanity checks and trying to insert anyone who
-        * looks okay.  We are at all times aware that we should
+        * looks okay. We are at all times aware that we should
         * only keep samples from the top two strata and we only need
         * NTP_MAXLIST of them.
         */
        nlist = 0;      /* none yet */
        for (server = sys_servers; server != NULL; server = server->next_server) {
-               if (server->delay == 0) {
+               if (server->stratum == 0) {
                        if (debug)
                                printf("%s: Server dropped: no data\n", ntoa(&server->srcadr));
                        continue;       /* no data */
@@ -1068,7 +1076,7 @@ clock_select(void)
                }
                if (server->leap == LEAP_NOTINSYNC) {
                        if (debug)
-                               printf("%s: Server dropped: Leap not in sync\n", ntoa(&server->srcadr));
+                               printf("%s: Server dropped: leap not in sync\n", ntoa(&server->srcadr));
                        continue;       /* he's in trouble */
                }
                if (!L_ISHIS(&server->org, &server->reftime)) {
@@ -1080,7 +1088,7 @@ clock_select(void)
                if ((server->org.l_ui - server->reftime.l_ui)
                    >= NTP_MAXAGE) {
                        if (debug)
-                               printf("%s: Server dropped: Server has gone too long without sync\n",
+                               printf("%s: Server dropped: server has gone too long without sync\n",
                                       ntoa(&server->srcadr));
                        continue;       /* too long without sync */
                }
@@ -1256,8 +1264,10 @@ clock_adjust(void)
        server = clock_select();
 
        if (debug || simple_query) {
+               if (debug)
+                       printf ("\n");
                for (sp = sys_servers; sp != NULL; sp = sp->next_server)
-                       printserver(sp, stdout);
+                       print_server(sp, stdout);
        }
 
        if (server == 0) {
@@ -1283,31 +1293,17 @@ clock_adjust(void)
        }
 
        if (dostep) {
-               if (simple_query || debug || l_step_systime(&server->offset)){
+               if (simple_query || l_step_systime(&server->offset)){
                        msyslog(LOG_NOTICE, "step time server %s offset %s sec",
                                stoa(&server->srcadr),
                                lfptoa(&server->offset, 6));
                }
        } else {
-#ifndef SYS_WINNT
                if (simple_query || l_adj_systime(&server->offset)) {
                        msyslog(LOG_NOTICE, "adjust time server %s offset %s sec",
                                stoa(&server->srcadr),
                                lfptoa(&server->offset, 6));
                }
-#else
-               /* The NT SetSystemTimeAdjustment() call achieves slewing by
-                * changing the clock frequency. This means that we cannot specify
-                * it to slew the clock by a definite amount and then stop like
-                * the Unix adjtime() routine. We can technically adjust the clock
-                * frequency, have ntpdate sleep for a while, and then wake
-                * up and reset the clock frequency, but this might cause some
-                * grief if the user attempts to run ntpd immediately after
-                * ntpdate and the socket is in use.
-                */
-               printf("\nThe -b option is required by ntpdate on Windows NT platforms\n");
-               exit(1);
-#endif /* SYS_WINNT */
        }
        return(0);
 }
@@ -1605,24 +1601,26 @@ init_alarm(void)
 #else  /* SYS_WINNT follows */
        _tzset();
 
-       /*
-        * Get privileges needed for fiddling with the clock
-        */
+       if (!simple_query && !debug) {
+               /*
+                * Get privileges needed for fiddling with the clock
+                */
 
-       /* get the current process token handle */
-       if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
-               msyslog(LOG_ERR, "OpenProcessToken failed: %m");
-               exit(1);
+               /* get the current process token handle */
+               if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
+                       msyslog(LOG_ERR, "OpenProcessToken failed: %m");
+                       exit(1);
+               }
+               /* get the LUID for system-time privilege. */
+               LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid);
+               tkp.PrivilegeCount = 1;         /* one privilege to set */
+               tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+               /* get set-time privilege for this process. */
+               AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0);
+               /* cannot test return value of AdjustTokenPrivileges. */
+               if (GetLastError() != ERROR_SUCCESS)
+                       msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m");
        }
-       /* get the LUID for system-time privilege. */
-       LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid);
-       tkp.PrivilegeCount = 1;         /* one privilege to set */
-       tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
-       /* get set-time privilege for this process. */
-       AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0);
-       /* cannot test return value of AdjustTokenPrivileges. */
-       if (GetLastError() != ERROR_SUCCESS)
-               msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m");
 
        /*
         * Set up timer interrupts for every 2**EVENT_TIMEOUT seconds
@@ -1996,7 +1994,6 @@ input_handler(void)
 }
 
 
-#if !defined SYS_WINNT && !defined SYS_CYGWIN32
 /*
  * adj_systime - do a big long slew of the system time
  */
@@ -2041,15 +2038,30 @@ l_adj_systime(
                adjtv.tv_usec = -adjtv.tv_usec;
        }
 
-       if (adjtv.tv_usec != 0 && !debug) {
+       if (!debug && (adjtv.tv_usec != 0)) {
+               /* A time correction needs to be applied. */
+#if !defined SYS_WINNT && !defined SYS_CYGWIN32
+               /* Slew the time on systems that support this. */
                if (adjtime(&adjtv, &oadjtv) < 0) {
                        msyslog(LOG_ERR, "Can't adjust the time of day: %m");
                        exit(1);
                }
+#else  /* SYS_WINNT or SYS_CYGWIN32 is defined */
+               /*
+                * The NT SetSystemTimeAdjustment() call achieves slewing by
+                * changing the clock frequency. This means that we cannot specify
+                * it to slew the clock by a definite amount and then stop like
+                * the Unix adjtime() routine. We can technically adjust the clock
+                * frequency, have ntpdate sleep for a while, and then wake
+                * up and reset the clock frequency, but this might cause some
+                * grief if the user attempts to run ntpd immediately after
+                * ntpdate and the socket is in use.
+                */
+               printf("\nSlewing the system time is not supported on Windows. Use the -b option to step the time.\n");
+#endif /* defined SYS_WINNT || defined SYS_CYGWIN32 */
        }
        return 1;
 }
-#endif /* SYS_WINNT */
 
 
 /*
@@ -2068,11 +2080,14 @@ l_step_systime(
        int isneg;
        int n;
 
-       if (debug) return 1;
+       if (debug)
+               return 1;
+
        /*
         * Take the absolute value of the offset
         */
        ftmp = *ts;
+
        if (L_ISNEG(&ftmp)) {
                L_NEG(&ftmp);
                isneg = 1;
@@ -2082,9 +2097,9 @@ l_step_systime(
        if (ftmp.l_ui >= 3) {           /* Step it and slew - we might win */
                LFPTOD(ts, dtemp);
                n = step_systime(dtemp);
-               if (!n)
-                       return n;
-               if (isneg)
+               if (n == 0)
+                       return 0;
+               if (isneg)              /* WTF! */
                        ts->l_ui = ~0;
                else
                        ts->l_ui = ~0;
@@ -2113,12 +2128,12 @@ l_step_systime(
 }
 
 
-/* XXX ELIMINATE printserver similar in ntptrace.c, ntpdate.c */
+/* XXX ELIMINATE print_server similar in ntptrace.c, ntpdate.c */
 /*
- * printserver - print detail information for a server
+ * print_server - print detail information for a server
  */
 static void
-printserver(
+print_server(
        register struct server *pp,
        FILE *fp
        )
@@ -2127,6 +2142,9 @@ printserver(
        char junk[5];
        const char *str;
 
+       if (pp->stratum == 0)           /* Nothing received => nothing to print */
+               return;
+
        if (!debug) {
                (void) fprintf(fp, "server %s, stratum %d, offset %s, delay %s\n",
                                   stoa(&pp->srcadr), pp->stratum,
@@ -2143,17 +2161,20 @@ printserver(
                           pp->leap & 0x1 ? '1' : '0',
                           pp->trust);
 
-       if (pp->stratum == 1) {
-               junk[4] = 0;
-               memmove(junk, (char *)&pp->refid, 4);
+       if (REFID_ISTEXT(pp->stratum)) {
+               str = (char *) &pp->refid;
+               for (i=0; i<4 && str[i]; i++) {
+                       junk[i] = (isprint(str[i]) ? str[i] : '.');
+               }
+               junk[i] = 0; // force terminating 0
                str = junk;
        } else {
-               str = stoa(&pp->srcadr);
+               str = numtoa(pp->refid);
        }
        (void) fprintf(fp,
-                          "refid [%s], delay %s, dispersion %s\n",
-                          str, fptoa((s_fp)pp->delay, 5),
-                          ufptoa(pp->dispersion, 5));
+                       "refid [%s], root delay %s, root dispersion %s\n",
+                       str, fptoa((s_fp)pp->rootdelay, 6),
+                       ufptoa(pp->rootdisp, 6));
 
        (void) fprintf(fp, "transmitted %d, in filter %d\n",
                           pp->xmtcnt, pp->filter_nextpt);
@@ -2165,21 +2186,23 @@ printserver(
        (void) fprintf(fp, "transmit timestamp:  %s\n",
                           prettydate(&pp->xmt));
 
-       (void) fprintf(fp, "filter delay: ");
-       for (i = 0; i < NTP_SHIFT; i++) {
-               (void) fprintf(fp, " %-8.8s", fptoa(pp->filter_delay[i], 5));
-               if (i == (NTP_SHIFT>>1)-1)
-                       (void) fprintf(fp, "\n        ");
-       }
-       (void) fprintf(fp, "\n");
+       if (sys_samples > 1) {
+               (void) fprintf(fp, "filter delay: ");
+               for (i = 0; i < NTP_SHIFT; i++) {
+                       (void) fprintf(fp, " %-8.8s", fptoa(pp->filter_delay[i], 5));
+                       if (i == (NTP_SHIFT>>1)-1)
+                               (void) fprintf(fp, "\n        ");
+               }
+               (void) fprintf(fp, "\n");
 
-       (void) fprintf(fp, "filter offset:");
-       for (i = 0; i < PEER_SHIFT; i++) {
-               (void) fprintf(fp, " %-8.8s", lfptoa(&pp->filter_offset[i], 6));
-               if (i == (PEER_SHIFT>>1)-1)
-                       (void) fprintf(fp, "\n        ");
+               (void) fprintf(fp, "filter offset:");
+               for (i = 0; i < PEER_SHIFT; i++) {
+                       (void) fprintf(fp, " %-8.8s", lfptoa(&pp->filter_offset[i], 6));
+                       if (i == (PEER_SHIFT>>1)-1)
+                               (void) fprintf(fp, "\n        ");
+               }
+               (void) fprintf(fp, "\n");
        }
-       (void) fprintf(fp, "\n");
 
        (void) fprintf(fp, "delay %s, dispersion %s\n",
                           fptoa((s_fp)pp->delay, 5), ufptoa(pp->dispersion, 5));