+* [Bug 2597] leap file loose ends (follow-up)
+ - uniform expiration check messages for config and timer triggered
+ leap file loads
+ - timer triggered loads log messages only once per day
(4.2.7p449) 2014/07/16 Released by Harlan Stenn <stenn@ntp.org>
* [Bug 2547] Automate update of "Last Update" datestamps in .html files.
* [Bug 2623] Missing {} in refclock_oncore.c.
int/*BOOL*/
leapsec_load_stream(
FILE * ifp ,
- const char * fname)
+ const char * fname,
+ int/*BOOL*/ logall)
{
leap_table_t *pt;
int rcheck;
fname = "<unknown>";
rcheck = leapsec_validate((leapsec_reader)getc, ifp);
- switch (rcheck)
- {
- case LSVALID_GOODHASH:
- msyslog(LOG_NOTICE, "%s ('%s'): good hash signature",
- logPrefix, fname);
- break;
-
- case LSVALID_NOHASH:
- msyslog(LOG_NOTICE, "%s ('%s'): no hash signature",
- logPrefix, fname);
- break;
- case LSVALID_BADHASH:
- msyslog(LOG_ERR, "%s ('%s'): signature mismatch",
- logPrefix, fname);
- break;
- case LSVALID_BADFORMAT:
- msyslog(LOG_ERR, "%s ('%s'): malformed hash signature",
- logPrefix, fname);
- break;
- default:
- msyslog(LOG_ERR, "%s ('%s'): unknown error code %d",
- logPrefix, fname, rcheck);
- break;
- }
+ if (logall)
+ switch (rcheck)
+ {
+ case LSVALID_GOODHASH:
+ msyslog(LOG_NOTICE, "%s ('%s'): good hash signature",
+ logPrefix, fname);
+ break;
+
+ case LSVALID_NOHASH:
+ msyslog(LOG_ERR, "%s ('%s'): no hash signature",
+ logPrefix, fname);
+ break;
+ case LSVALID_BADHASH:
+ msyslog(LOG_ERR, "%s ('%s'): signature mismatch",
+ logPrefix, fname);
+ break;
+ case LSVALID_BADFORMAT:
+ msyslog(LOG_ERR, "%s ('%s'): malformed hash signature",
+ logPrefix, fname);
+ break;
+ default:
+ msyslog(LOG_ERR, "%s ('%s'): unknown error code %d",
+ logPrefix, fname, rcheck);
+ break;
+ }
if (rcheck < 0)
return FALSE;
leapsec_load_file(
const char * fname,
struct stat * sb_old,
- int/*BOOL*/ force)
+ int/*BOOL*/ force,
+ int/*BOOL*/ logall)
{
FILE * fp;
struct stat sb_new;
/* try to stat the leapfile */
if (0 != stat(fname, &sb_new)) {
- msyslog(LOG_ERR, "%s ('%s'): stat failed: %m",
- logPrefix, fname);
+ if (logall)
+ msyslog(LOG_ERR, "%s ('%s'): stat failed: %m",
+ logPrefix, fname);
return FALSE;
}
*/
/* coverity[toctou] */
if ((fp = fopen(fname, "r")) == NULL) {
- msyslog(LOG_ERR,
- "%s ('%s'): open failed: %m",
- logPrefix, fname);
+ if (logall)
+ msyslog(LOG_ERR,
+ "%s ('%s'): open failed: %m",
+ logPrefix, fname);
return FALSE;
}
- rc = leapsec_load_stream(fp, fname);
+ rc = leapsec_load_stream(fp, fname, logall);
fclose(fp);
return rc;
}
/* Read a leap second file from stream. This is a convenience wrapper
* around the generic load function, 'leapsec_load()'.
*/
-extern int/*BOOL*/ leapsec_load_stream(FILE * fp, const char * fname);
+extern int/*BOOL*/ leapsec_load_stream(FILE * fp, const char * fname,
+ int/*BOOL*/logall);
/* Read a leap second file from file. It checks that the file exists and
* (if 'force' is not applied) the ctime/mtime has changed since the
* otherwise. Uses 'leapsec_load_stream()' internally.
*/
extern int/*BOOL*/ leapsec_load_file(const char * fname, struct stat * sb,
- int/*BOOL*/force);
+ int/*BOOL*/force, int/*BOOL*/logall);
/* Get the current leap data signature. This consists of the last
* ransition, the table expiration, and the total TAI difference at the
static u_long interface_timer; /* interface update timer */
static u_long adjust_timer; /* second timer */
static u_long stats_timer; /* stats timer */
-static u_long check_leapfile; /* Report leapfile problems once/day */
+static u_long leapf_timer; /* Report leapfile problems once/day */
static u_long huffpuff_timer; /* huff-n'-puff timer */
static u_long worker_idle_timer;/* next check for idle intres */
u_long leapsec; /* seconds to next leap (proximity class) */
alarm_overflow = 0;
adjust_timer = 1;
stats_timer = SECSPERHR;
- check_leapfile = 0;
+ leapf_timer = SECSPERDAY;
huffpuff_timer = 0;
interface_timer = 0;
current_time = 0;
if (stats_timer <= current_time) {
stats_timer += SECSPERHR;
write_stats();
- if (check_leapfile < current_time) {
- check_leapfile += SECSPERDAY;
+ if (leapf_timer <= current_time) {
+ leapf_timer += SECSPERDAY;
check_leap_file(TRUE, now.l_ui, &tnow);
} else {
check_leap_file(FALSE, now.l_ui, &tnow);
*/
static void record_sys_stats(void);
void ntpd_time_stepped(void);
+static void check_leap_expiration(int, uint32_t, const time_t*);
/*
* Prototypes
void uninit_util(void);
#endif
-
/*
* uninit_util - free memory allocated by init_util
*/
int len;
double old_drift;
l_fp now;
+ time_t ttnow;
#ifndef VMS
const char temp_ext[] = ".TEMP";
#else
leapfile_name = erealloc(leapfile_name, len + 1);
memcpy(leapfile_name, value, len + 1);
- if (leapsec_load_file(leapfile_name, &leapfile_stat, TRUE)) {
+ if (leapsec_load_file(
+ leapfile_name, &leapfile_stat, TRUE, TRUE))
+ {
leap_signature_t lsig;
- leapsec_getsig(&lsig);
get_systime(&now);
+ time(&ttnow);
+ leapsec_getsig(&lsig);
mprintf_event(EVNT_TAI, NULL,
"%d leap %s %s %s",
lsig.taiof,
? "expired"
: "expires",
fstostr(lsig.etime));
+
have_leapfile = TRUE;
+
+ /* force an immediate daily expiration check of
+ * the leap seconds table
+ */
+ check_leap_expiration(TRUE, now.l_ui, &ttnow);
}
break;
/*
* check_leap_file - See if the leapseconds file has been updated.
*
- * Returns:
- * -1 if there was a problem,
- * 0 if the leapfile has expired or less than 24hrs remaining TTL
- * >0 # of full days until the leapfile expires
+ * Returns: n/a
*
* Note: This loads a new leapfile on the fly. Currently a leap file
* without SHA1 signature is accepted, but if there is a signature line,
const time_t *systime
)
{
- static const char * const logPrefix = "leapsecond file";
- int rc;
-
/* just do nothing if there is no leap file */
if ( ! (leapfile_name && *leapfile_name))
return;
/* try to load leapfile, force it if no leapfile loaded yet */
if (leapsec_load_file(
- leapfile_name, &leapfile_stat, !have_leapfile))
+ leapfile_name, &leapfile_stat,
+ !have_leapfile, is_daily_check))
have_leapfile = TRUE;
else if (!have_leapfile)
return;
+ check_leap_expiration(is_daily_check, ntptime, systime);
+}
+
+/*
+ * check expiration of a loaded leap table
+ */
+static void
+check_leap_expiration(
+ int is_daily_check,
+ uint32_t ntptime ,
+ const time_t *systime
+ )
+{
+ static const char * const logPrefix = "leapsecond file";
+ int rc;
+
/* test the expiration of the leap data and log with proper
* level and frequency (once/hour or once/day, depending on the
* state.