reference: move leap second source into leapdb

Separate out source of leap second data into a new module in preparation
for supporting more sources such as leap-seconds.list.
This commit is contained in:
Patrick Oppenlander
2024-02-08 14:36:25 +11:00
committed by Miroslav Lichvar
parent eb26d13140
commit 017d6f8f56
5 changed files with 194 additions and 94 deletions

View File

@@ -33,6 +33,7 @@
#include "reference.h"
#include "util.h"
#include "conf.h"
#include "leapdb.h"
#include "logging.h"
#include "local.h"
#include "sched.h"
@@ -122,9 +123,6 @@ static int leap_in_progress;
/* Timer for the leap second handler */
static SCH_TimeoutID leap_timeout_id;
/* Name of a system timezone containing leap seconds occuring at midnight */
static char *leap_tzname;
/* ================================================== */
static LOG_FileID logfileid;
@@ -155,7 +153,6 @@ static int ref_adjustments;
/* ================================================== */
static NTP_Leap get_tz_leap(time_t when, int *tai_offset);
static void update_leap_status(NTP_Leap leap, time_t now, int reset);
/* ================================================== */
@@ -195,7 +192,6 @@ REF_Initialise(void)
FILE *in;
double file_freq_ppm, file_skew_ppm;
double our_frequency_ppm;
int tai_offset;
mode = REF_ModeNormal;
are_we_synchronised = 0;
@@ -260,18 +256,6 @@ REF_Initialise(void)
if (leap_mode == REF_LeapModeSystem && !LCL_CanSystemLeap())
leap_mode = REF_LeapModeStep;
leap_tzname = CNF_GetLeapSecTimezone();
if (leap_tzname) {
/* Check that the timezone has good data for Jun 30 2012 and Dec 31 2012 */
if (get_tz_leap(1341014400, &tai_offset) == LEAP_InsertSecond && tai_offset == 34 &&
get_tz_leap(1356912000, &tai_offset) == LEAP_Normal && tai_offset == 35) {
LOG(LOGS_INFO, "Using %s timezone to obtain leap second data", leap_tzname);
} else {
LOG(LOGS_WARN, "Timezone %s failed leap second check, ignoring", leap_tzname);
leap_tzname = NULL;
}
}
CNF_GetMakeStep(&make_step_limit, &make_step_threshold);
CNF_GetMaxChange(&max_offset_delay, &max_offset_ignore, &max_offset);
CNF_GetMailOnChange(&do_mail_change, &mail_change_threshold, &mail_change_user);
@@ -593,77 +577,6 @@ is_leap_second_day(time_t when)
/* ================================================== */
static NTP_Leap
get_tz_leap(time_t when, int *tai_offset)
{
static time_t last_tz_leap_check;
static NTP_Leap tz_leap;
static int tz_tai_offset;
struct tm stm, *tm;
time_t t;
char *tz_env, tz_orig[128];
*tai_offset = tz_tai_offset;
/* Do this check at most twice a day */
when = when / (12 * 3600) * (12 * 3600);
if (last_tz_leap_check == when)
return tz_leap;
last_tz_leap_check = when;
tz_leap = LEAP_Normal;
tz_tai_offset = 0;
tm = gmtime(&when);
if (!tm)
return tz_leap;
stm = *tm;
/* Temporarily switch to the timezone containing leap seconds */
tz_env = getenv("TZ");
if (tz_env) {
if (strlen(tz_env) >= sizeof (tz_orig))
return tz_leap;
strcpy(tz_orig, tz_env);
}
setenv("TZ", leap_tzname, 1);
tzset();
/* Get the TAI-UTC offset, which started at the epoch at 10 seconds */
t = mktime(&stm);
if (t != -1)
tz_tai_offset = t - when + 10;
/* Set the time to 23:59:60 and see how it overflows in mktime() */
stm.tm_sec = 60;
stm.tm_min = 59;
stm.tm_hour = 23;
t = mktime(&stm);
if (tz_env)
setenv("TZ", tz_orig, 1);
else
unsetenv("TZ");
tzset();
if (t == -1)
return tz_leap;
if (stm.tm_sec == 60)
tz_leap = LEAP_InsertSecond;
else if (stm.tm_sec == 1)
tz_leap = LEAP_DeleteSecond;
*tai_offset = tz_tai_offset;
return tz_leap;
}
/* ================================================== */
static void
leap_end_timeout(void *arg)
{
@@ -751,16 +664,16 @@ set_leap_timeout(time_t now)
static void
update_leap_status(NTP_Leap leap, time_t now, int reset)
{
NTP_Leap tz_leap;
NTP_Leap ldb_leap;
int leap_sec, tai_offset;
leap_sec = 0;
tai_offset = 0;
if (leap_tzname && now) {
tz_leap = get_tz_leap(now, &tai_offset);
if (now) {
ldb_leap = LDB_GetLeap(now, &tai_offset);
if (leap == LEAP_Normal)
leap = tz_leap;
leap = ldb_leap;
}
if (leap == LEAP_InsertSecond || leap == LEAP_DeleteSecond) {
@@ -1398,7 +1311,7 @@ REF_GetTaiOffset(struct timespec *ts)
{
int tai_offset;
get_tz_leap(ts->tv_sec, &tai_offset);
LDB_GetLeap(ts->tv_sec, &tai_offset);
return tai_offset;
}