From: Harlan Stenn Date: Mon, 28 Jan 2013 00:20:35 +0000 (+0000) Subject: [Bug 2326] Notice when a new leapfile has been installed X-Git-Tag: NTP_4_2_7P352~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=43ce30207546a2674bcad292ea73ab606b5a2d84;p=thirdparty%2Fntp.git [Bug 2326] Notice when a new leapfile has been installed bk: 5105c453SLbPo9EURLRlmZkHmq4RKw --- diff --git a/ChangeLog b/ChangeLog index 9a548356d..113fc3981 100644 --- 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 * [Bug 2328] Don't apply small time adjustments on Windows versions which don't support this. diff --git a/include/ntpd.h b/include/ntpd.h index 3c435836e..f224b981e 100644 --- a/include/ntpd.h +++ b/include/ntpd.h @@ -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 diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index e9098fdc8..ca3fa6aac 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -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 /* diff --git a/ntpd/ntp_io.c b/ntpd/ntp_io.c index 58e4c85bb..c304c1ec9 100644 --- a/ntpd/ntp_io.c +++ b/ntpd/ntp_io.c @@ -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 diff --git a/ntpd/ntp_util.c b/ntpd/ntp_util.c index 83040aeef..49f41af6a 100644 --- a/ntpd/ntp_util.c +++ b/ntpd/ntp_util.c @@ -23,6 +23,7 @@ #ifdef HAVE_UNISTD_H # include #endif +#include #ifdef HAVE_IEEEFP_H # include @@ -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 *