FILE *str; /* file handle */
char buf[NTP_MAXSTRLEN]; /* file line buffer */
u_int32 leapsec[MAX_LEAP]; /* NTP time at leaps */
+ u_long expire; /* NTP time when file expires */
int offset; /* offset at leap (s) */
char filename[MAXFILENAME]; /* name of leapseconds file */
char linkname[MAXFILENAME]; /* file link (for filestamp) */
* must equal the initial insertion of ten seconds on 1 January
* 1972 plus one second for each succeeding insertion.
*/
- i = 0;
+ i = TAI_1972;
+ expire = 0;
while (i < MAX_LEAP) {
dp = fgets(buf, NTP_MAXSTRLEN - 1, str);
if (dp == NULL)
if (strlen(buf) < 1)
continue;
- if (*buf == '#')
- continue;
+ if (buf[0] == '#') {
+ if (buf[1] == '@') {
+ if (sscanf(&buf[2], "%lu", &expire) !=
+ 1)
+ break;
+ }
+ }
+ continue;
if (sscanf(buf, "%u %d", &leapsec[i], &offset) != 2)
continue;
- if (i != offset - TAI_1972)
+ if (i != offset)
break;
i++;
tai_leap.ptr = (u_char *)ptr;
for (j = 0; j < i; j++)
*ptr++ = htonl(leapsec[j]);
+ sys_tai = offset;
+ leap_ins = leapsec[--j];
+ leap_expire = expire;
crypto_flags |= CRYPTO_FLAG_TAI;
- sprintf(statstr, "%s fs %u leap %u len %u", cp, fstamp,
- leapsec[--j], len);
+ sprintf(statstr,
+ "%s fs %u leap %lu tai %d expire %lu len %u", cp,
+ fstamp, leap_ins, sys_tai, leap_expire, len);
record_crypto_stats(NULL, statstr);
#ifdef DEBUG
if (debug)
static int sys_hopper; /* anticlockhop counter */
static int sys_maxhop = MAXHOP; /* anticlockhop counter threshold */
u_long leap_ins; /* seconds at next leap */
+u_long leap_expire; /* seconds leapfile expires */
u_long leap_sec; /* leap countdown */
static int leap_next; /* leap consensus */
static int leap_sw; /* leap is from file */
* Clock was slewed. Update the system stratum, leap bits, root
* delay, root dispersion, reference ID and reference time.
* Except for reference clocks, the minimum dispersion increment
- * is not less than sys_mindisp. If a leap is anticipated, read
- * the system clock because the time now might not be the time
- * at the last offset measurement.
+ * is not less than sys_mindisp.
*/
case 1:
sys_stratum = min(sys_peer->stratum + 1,
sys_reftime = sys_peer->rec;
/*
- * If no leap is scheduled and the leap is triggered
- * from the leapseconds file, schedule a leap for the
- * last entry in the file, but only if it is in the
- * future. If triggered by upstream server leap bits and
- * the number of bits is at least the sanity threshold,
- * schedule a leap for the end of the current month.
- *
- * If the kernel code is available and enabled, pass the
- * current TAI offset to the kernel. Note, if the leap
- * hasn't been taken yet, decrement the offset.
+ * If a leapseconds file is not present or expired and
+ * the number of upstream server leap bits is at least
+ * the sanity threshold, schedule a leap for the end of
+ * the current month.
*/
get_systime(&now);
- if (leap_sec == 0) {
- if (leap_ins > now.l_ui) {
- if (leap_sw == 0) {
+ if (now.l_ui > leap_expire) {
+ if (leap_next >= sys_minsane) {
+ if (!leap_sw) {
leap_sw++;
- sys_tai--;
+ leap_sec = leap_month(now.l_ui);
msyslog(LOG_NOTICE,
- "TAI offset %d s", sys_tai);
-#ifdef KERNEL_PLL
- if (pll_control && kern_enable)
- loop_config(LOOP_LEAP,
- 0);
-#endif /* KERNEL_PLL */
+ "leap second armed %lu s",
+ leap_sec);
}
- if (leap_ins - now.l_ui < 28 * 86400)
- leap_sec = leap_ins - now.l_ui;
- } else if (leap_next >= sys_minsane) {
- leap_sec = leap_month(now.l_ui);
+ } else {
+ leap_sw = 0;
+ leap_sec = 0;
}
- if (leap_sec > 0)
- msyslog(LOG_NOTICE,
- "leap second armed %lu s",
- leap_sec);
-
/*
- * If the leap was not triggered from the leapsecond
- * file, cancel the leap if the server leap bits grow
- * dim.
+ * If a leapseconds file is present and not expired and
+ * a future leap is scheduled, decrement the TAI offset.
+ * If the kernel code is available and enabled, pass the
+ * TAI offset to the kernel. If less than 28 days remain
+ * to the leap, schedule a leap when the leapseconds
+ * counter expires.
*/
- } else if (!leap_sw && leap_next < sys_minsane) {
- leap_sec = 0;
+ } else if (leap_sec == 0) {
+ if (leap_ins > now.l_ui) {
+ if (leap_ins - now.l_ui < 28 * 86400) {
+ leap_sec = leap_ins - now.l_ui;
+ msyslog(LOG_NOTICE,
+ "leap second armed %lu s",
+ leap_sec);
+ }
+ if (!leap_sw)
+ sys_tai--;
+ }
+ if (!leap_sw) {
+ leap_sw++;
+ msyslog(LOG_NOTICE,
+ "TAI offset %d s", sys_tai);
+#ifdef KERNEL_PLL
+ if (pll_control && kern_enable)
+ loop_config(LOOP_LEAP, 0);
+#endif /* KERNEL_PLL */
+ }
}
/*
FILE *str; /* file handle */
char buf[NTP_MAXSTRLEN]; /* file line buffer */
u_long leapsec; /* NTP time at leap */
+ u_long expire; /* NTP time when file expires */
int offset; /* TAI offset at leap (s) */
char filename[MAXFILENAME]; /* name of leapseconds file */
char *dp;
int i;
NTP_REQUIRE(cp != NULL);
+
/*
* Open the file and discard comment lines. If the first
* character of the file name is not '/', prepend the keys
* insertion.
*/
i = TAI_1972;
+ expire = 0;
while (i < MAX_TAI) {
dp = fgets(buf, NTP_MAXSTRLEN - 1, str);
if (dp == NULL)
if (strlen(buf) < 1)
continue;
- if (*buf == '#')
- continue;
+ if (buf[0] == '#') {
+ if (buf[1] == '@') {
+ if (sscanf(&buf[2], "%lu", &expire) !=
+ 1)
+ break;
+ }
+ }
+ continue;
if (sscanf(buf, "%lu %d", &leapsec, &offset) != 2)
continue;
}
fclose(str);
if (dp != NULL) {
- msyslog(LOG_INFO, "leapseconds format error from %s",
- cp);
+ msyslog(LOG_INFO, "leapseconds %s error", cp);
} else {
sys_tai = offset;
leap_ins = leapsec;
- msyslog(LOG_INFO, "TAI offset %d s at %lu from %s",
- sys_tai, leap_ins, cp);
+ leap_expire = expire;
+ msyslog(LOG_INFO,
+ "TAI offset %d s at %lu file %s expire %lu",
+ sys_tai, leap_ins, cp, leap_expire);
}
}