/* ------------------------------------------------------------------ */ int/*BOOL*/ leapsec_add_fix( int total, uint32_t ttime, uint32_t etime, const time_t * pivot) { time_t tpiv; leap_table_t * pt; vint64 tt64, et64; if (pivot == NULL) { time(&tpiv); pivot = &tpiv; } et64 = ntpcal_ntp_to_ntp(etime, pivot); tt64 = ntpcal_ntp_to_ntp(ttime, pivot); pt = leapsec_get_table(TRUE); if ( ucmpv64(&et64, &pt->head.expire) <= 0 || !leapsec_raw(pt, &tt64, total, FALSE) ) return FALSE; pt->lsig.etime = etime; pt->lsig.ttime = ttime; pt->lsig.taiof = (int16_t)total; pt->head.expire = et64; return leapsec_set_table(pt); }
/* ------------------------------------------------------------------ */ bool leapsec_add_fix( int total, uint32_t ttime, uint32_t etime, const time_t * pivot) { time_t tpiv; leap_table_t * pt; time64_t tt64, et64; if (pivot == NULL) { time(&tpiv); pivot = &tpiv; } et64 = ntpcal_ntp_to_ntp(etime, pivot); tt64 = ntpcal_ntp_to_ntp(ttime, pivot); pt = leapsec_get_table(true); if ((et64 <= pt->head.expire) || !leapsec_raw(pt, tt64, total, false) ) return false; pt->lsig.etime = etime; pt->lsig.ttime = ttime; pt->lsig.taiof = (int16_t)total; pt->head.expire = et64; return leapsec_set_table(pt); }
/* --------------------------------------------------------------------- * Load a leap second file and check expiration on the go */ int/*BOOL*/ leapsec_load( leap_table_t * pt , leapsec_reader func, void * farg, int use_build_limit) { char *cp, *ep, linebuf[50]; vint64 ttime, limit; long taiof; struct calendar build; leapsec_clear(pt); if (use_build_limit && ntpcal_get_build_date(&build)) limit = ntpcal_date_to_ntp64(&build); else memset(&limit, 0, sizeof(limit)); while (get_line(func, farg, linebuf, sizeof(linebuf))) { cp = linebuf; if (*cp == '#') { cp++; if (*cp == '@') { cp = skipws(cp+1); pt->head.expire = strtouv64(cp, &ep, 10); if (parsefail(cp, ep)) goto fail_read; pt->lsig.etime = pt->head.expire.D_s.lo; } else if (*cp == '$') { cp = skipws(cp+1); pt->head.update = strtouv64(cp, &ep, 10); if (parsefail(cp, ep)) goto fail_read; } } else if (isdigit((u_char)*cp)) { ttime = strtouv64(cp, &ep, 10); if (parsefail(cp, ep)) goto fail_read; cp = skipws(ep); taiof = strtol(cp, &ep, 10); if ( parsefail(cp, ep) || taiof > SHRT_MAX || taiof < SHRT_MIN) goto fail_read; if (ucmpv64(&ttime, &limit) >= 0) { if (!leapsec_raw(pt, &ttime, taiof, FALSE)) goto fail_insn; } else { pt->head.base_tai = (int16_t)taiof; } pt->lsig.ttime = ttime.D_s.lo; pt->lsig.taiof = (int16_t)taiof; } } return TRUE; fail_read: errno = EILSEQ; fail_insn: leapsec_clear(pt); return FALSE; }
/* --------------------------------------------------------------------- * Load a leap second file and check expiration on the go */ bool leapsec_load( leap_table_t * pt , leapsec_reader func, void * farg, int use_build_limit) { char *cp, *ep, linebuf[50]; time64_t ttime, limit; long taiof; struct calendar build; leapsec_clear(pt); if (use_build_limit && ntpcal_get_build_date(&build)) limit = ntpcal_date_to_ntp64(&build); else memset(&limit, 0, sizeof(limit)); while (get_line(func, farg, linebuf, sizeof(linebuf))) { cp = linebuf; if (*cp == '#') { cp++; if (*cp == '@') { cp = skipws(cp+1); settime64u(pt->head.expire, strtoull(cp, &ep, 10)); if (parsefail(cp, ep)) goto fail_read; pt->lsig.etime = time64lo(pt->head.expire); } else if (*cp == '$') { cp = skipws(cp+1); settime64u(pt->head.update, strtoull(cp, &ep, 10)); if (parsefail(cp, ep)) goto fail_read; } } else if (isdigit((uint8_t)*cp)) { settime64u(ttime, strtoull(cp, &ep, 10)); if (parsefail(cp, ep)) goto fail_read; cp = skipws(ep); taiof = strtol(cp, &ep, 10); if ( parsefail(cp, ep) || taiof > SHRT_MAX || taiof < SHRT_MIN) goto fail_read; if (ttime >= limit) { if (!leapsec_raw(pt, ttime, taiof, false)) goto fail_insn; } else { pt->head.base_tai = (int16_t)taiof; } pt->lsig.ttime = time64lo(ttime); pt->lsig.taiof = (int16_t)taiof; } } return true; fail_read: errno = EILSEQ; fail_insn: leapsec_clear(pt); return false; }