]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 2326] Notice when a new leapfile has been installed
authorHarlan Stenn <stenn@ntp.org>
Mon, 28 Jan 2013 00:20:35 +0000 (00:20 +0000)
committerHarlan Stenn <stenn@ntp.org>
Mon, 28 Jan 2013 00:20:35 +0000 (00:20 +0000)
bk: 5105c453SLbPo9EURLRlmZkHmq4RKw

ChangeLog
include/ntpd.h
ntpd/ntp_config.c
ntpd/ntp_io.c
ntpd/ntp_util.c

index 9a548356dd71cc655664d980830fd080963dfb68..113fc3981bb7e24f23a15cd9714a7946032738c9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,4 @@
+* [Bug 2326] Notice when a new leapfile has been installed.
 (4.2.7p351) 2013/01/24 Released by Harlan Stenn <stenn@ntp.org>
 * [Bug 2328] Don't apply small time adjustments on Windows versions
   which don't support this.
index 3c435836eaece3555707d2b92eed224befbb00bb..f224b981e7d39d1defda762cf5e66943a8262a0d 100644 (file)
@@ -288,6 +288,7 @@ extern      void    record_clock_stats (sockaddr_u *, const char *);
 extern int     mprintf_clock_stats(sockaddr_u *, const char *, ...)
                        __attribute__((__format__(__printf__, 2, 3)));
 extern void    record_raw_stats (sockaddr_u *srcadr, sockaddr_u *dstadr, l_fp *t1, l_fp *t2, l_fp *t3, l_fp *t4, int leap, int version, int mode, int stratum, int poll, int precision, double root_delay, double root_dispersion, u_int32 refid);
+extern void    check_leap_file (void);
 extern u_long  leap_month(u_long);
 extern void    record_crypto_stats (sockaddr_u *, const char *);
 #ifdef DEBUG
index e9098fdc8201d717f6e0616e3b97bb55c6f9130a..ca3fa6aac4747103a1748b961d19793ac7400686 100644 (file)
@@ -188,7 +188,7 @@ int cryptosw;               /* crypto command called */
 
 extern int sys_maxclock;
 extern char *stats_drift_file; /* name of the driftfile */
-extern char *leapseconds_file_name; /*name of the leapseconds file */
+extern char *leapseconds_file; /*name of the leapseconds file */
 
 #ifdef BC_LIST_FRAMEWORK_NOT_YET_USED
 /*
index 58e4c85bb60a53dc00a04297227e5c3c261de28b..c304c1ec9de4145e59ebb807451c4dff64f019c2 100644 (file)
@@ -151,6 +151,9 @@ volatile u_long handler_calls;      /* number of calls to interrupt handler */
 volatile u_long handler_pkts;  /* number of pkts received by handler */
 u_long io_timereset;           /* time counters were reset */
 
+time_t check_leapfile;
+#define CHECK_LEAP_EVERY       86400
+
 /*
  * Interface stuff
  */
@@ -423,6 +426,8 @@ collect_timing(struct recvbuf *rb, const char *tag, int count, l_fp *dts)
 void
 init_io(void)
 {
+       check_leapfile = time(NULL) + CHECK_LEAP_EVERY;
+
        /* Init buffer free list and stat counters */
        init_recvbuff(RECV_INIT);
        /* update interface every 5 minutes as default */
@@ -3516,7 +3521,7 @@ input_handler(
                                maxactivefd + 1,
                                fdbits(maxactivefd, &activefds));
                if (err != EBADF)
-                       return;
+                       goto ih_return;
                for (j = 0, prior = 0; j <= maxactivefd; j++) {
                        if (FD_ISSET(j, &activefds)) {
                                if (-1 != read(j, &b, 0)) {
@@ -3531,10 +3536,10 @@ input_handler(
                                        maxactivefd = prior;
                        }
                }
-               return;
+               goto ih_return;
        }
        else if (n == 0)
-               return;
+               goto ih_return;
 
        ++handler_pkts;
 
@@ -3644,7 +3649,7 @@ input_handler(
                if (debug)
                        msyslog(LOG_DEBUG, "input_handler: select() returned 0");
 #endif
-               return;
+               goto ih_return;
        }
        /* We've done our work */
 #ifdef DEBUG_TIMING
@@ -3661,7 +3666,12 @@ input_handler(
                        "input_handler: Processed a gob of fd's in %s msec",
                        lfptoms(&ts_e, 6));
 #endif
-       /* just bail. */
+       /* We're done... */
+    ih_return:
+       if (check_leapfile < time(NULL)) {
+               check_leapfile += CHECK_LEAP_EVERY;
+               check_leap_file();
+       }
        return;
 }
 #endif
index 83040aeef59e14b0111a5fe439e7d5351e58810d..49f41af6a96727acd3305ba9ea1766670f832588 100644 (file)
@@ -23,6 +23,7 @@
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif
+#include <sys/stat.h>
 
 #ifdef HAVE_IEEEFP_H
 # include <ieeefp.h>
@@ -53,7 +54,9 @@
  * File names
  */
 static char *key_file_name;            /* keys file name */
-char   *leapseconds_file_name;         /* leapseconds file name */
+char   *leapseconds_file;              /* leapseconds file name */
+struct stat leapseconds_file_sb1;      /* leapseconds file stat() buffer */
+struct stat leapseconds_file_sb2;      /* leapseconds file stat() buffer */
 char   *stats_drift_file;              /* frequency file name */
 static char *stats_temp_file;          /* temp frequency file name */
 static double wander_resid;            /* last frequency update */
@@ -470,16 +473,26 @@ stats_config(
         * Read leapseconds file.
         */
        case STATS_LEAP_FILE:
-               if ((fp = fopen(value, "r")) == NULL) {
+               if (!value || (len = strlen(value)) == 0)
+                       break;
+
+               leapseconds_file = erealloc(leapseconds_file, len + 1);
+               memcpy(leapseconds_file, value, len + 1);
+
+               if ((fp = fopen(leapseconds_file, "r")) == NULL) {
                        msyslog(LOG_ERR, "leapseconds file %s: %m",
-                           value);
+                           leapseconds_file);
                        break;
                }
 
-               if (leap_file(fp) < 0) {
+               if (-1 == fstat(fileno(fp), &leapseconds_file_sb1)) {
+                       msyslog(LOG_ERR,
+                           "leapseconds: stat(%s) failed: %m",
+                           leapseconds_file);
+               } else if (leap_file(fp) < 0) {
                        msyslog(LOG_ERR,
                            "format error leapseconds file %s",
-                           value);
+                           leapseconds_file);
                } else {
                        get_systime(&now);
                        mprintf_event(EVNT_TAI, NULL,
@@ -843,6 +856,48 @@ record_timing_stats(
 #endif
 
 
+/*
+ *
+ */
+void
+check_leap_file(
+       void
+       )
+{
+       struct stat *sp1 = &leapseconds_file_sb1;
+       struct stat *sp2 = &leapseconds_file_sb2;
+
+       if (leapseconds_file) {
+               if (stat(leapseconds_file, &leapseconds_file_sb2)) {
+                       msyslog(LOG_ERR,
+                           "check_leap_file: stat(%s): %m",
+                           leapseconds_file);
+                       return;
+               }
+               if (   (sp1->st_mtime != sp2->st_mtime)
+                   || (sp1->st_ctime != sp2->st_ctime)) {
+                       FILE *fp;
+
+                       if ((fp = fopen(leapseconds_file, "r")) == NULL) {
+                               msyslog(LOG_ERR,
+                                   "check_leap_file: fopen(%s): %m",
+                                   leapseconds_file);
+                       } else {
+                               leapseconds_file_sb1 = leapseconds_file_sb2;
+                               if (leap_file(fp) < 0) {
+                                       msyslog(LOG_ERR,
+                                           "format error leapseconds file %s",
+                                           leapseconds_file);
+                               }
+                               fclose(fp);
+                       }
+               }
+       }
+
+       return;
+}
+
+
 /*
  * leap_file - read leapseconds file
  *