Exemple #1
0
/* ------------------------------------------------------------------ */
int32_t
leapsec_daystolive(
	uint32_t       when,
	const time_t * tpiv)
{
	const leap_table_t * pt;
	vint64 limit;

	pt = leapsec_get_table(FALSE);
	limit = ntpcal_ntp_to_ntp(when, tpiv);
	limit = subv64(&pt->head.expire, &limit);
	return ntpcal_daysplit(&limit).hi;
}
Exemple #2
0
/* ------------------------------------------------------------------ */
int32_t
leapsec_daystolive(
	uint32_t       when,
	const time_t * tpiv)
{
	const leap_table_t * pt;
	time64_t limit;

	pt = leapsec_get_table(false);
	limit = ntpcal_ntp_to_ntp(when, tpiv);
	limit = pt->head.expire - limit;
	return ntpcal_daysplit(limit).hi;
}
Exemple #3
0
/*
 * calweekstart - get NTP time at midnight of the last monday on or
 * before the current date.
 */
u_int32
calweekstart(u_int32 ntptime, const time_t *pivot)
{
	u_int32      ndays; /* elapsed days since NTP starts */
	vint64       vlong;
	ntpcal_split split;

	vlong = ntpcal_ntp_to_ntp(ntptime, pivot);
	split = ntpcal_daysplit(&vlong);
	ndays = ntpcal_weekday_le(split.hi + DAY_NTP_STARTS, CAL_MONDAY)
	      - DAY_NTP_STARTS;

	return (u_int32)(ndays * SECSPERDAY);
}
/* ------------------------------------------------------------------ */
int/*BOOL*/
leapsec_add_dyn(
	int            insert,
	uint32_t       ntpnow,
	const time_t * pivot )
{
	leap_table_t * pt;
	vint64         now64;

	pt = leapsec_get_table(TRUE);
	now64 = ntpcal_ntp_to_ntp(ntpnow, pivot);
	return (   leapsec_add(pt, &now64, (insert != 0))
		&& leapsec_set_table(pt));
}
Exemple #5
0
/* ------------------------------------------------------------------ */
int/*BOOL*/
leapsec_query_era(
	leap_era_t *   qr   ,
	uint32_t       ntpts,
	const time_t * pivot)
{
	const leap_table_t * pt;
	vint64               ts64;

	pt   = leapsec_get_table(FALSE);
	ts64 = ntpcal_ntp_to_ntp(ntpts, pivot);
	fetch_leap_era(qr, pt, &ts64);
	return TRUE;
}
Exemple #6
0
/* ------------------------------------------------------------------ */
bool
leapsec_add_dyn(
	bool           insert,
	uint32_t       ntpnow,
	const time_t * pivot )
{
	leap_table_t * pt;
	time64_t         now64;

	pt = leapsec_get_table(true);
	now64 = ntpcal_ntp_to_ntp(ntpnow, pivot);
	return (   leapsec_add(pt, now64, insert)
		&& leapsec_set_table(pt));
}
Exemple #7
0
void
caljulian(
	uint32_t		ntp,
	struct calendar *	jt
	)
{
	vint64		vlong;
	ntpcal_split	split;
	
	
	NTP_INSIST(NULL != jt);

	/*
	 * Unfold ntp time around current time into NTP domain. Split
	 * into days and seconds, shift days into CE domain and
	 * process the parts.
	 */
	vlong = ntpcal_ntp_to_ntp(ntp, NULL);
	split = ntpcal_daysplit(&vlong);
	ntpcal_daysplit_to_date(jt, &split, DAY_NTP_STARTS);
}
int/*BOOL*/
leapsec_query(
	leap_result_t * qr   ,
	uint32_t        ts32 ,
	const time_t *  pivot)
{
	leap_table_t *   pt;
	vint64           ts64, last, next;
	uint32_t         due32;
	int              fired;

	/* preset things we use later on... */
	fired = FALSE;
	ts64  = ntpcal_ntp_to_ntp(ts32, pivot);
	pt    = leapsec_get_table(FALSE);
	memset(qr, 0, sizeof(leap_result_t));

	if (ucmpv64(&ts64, &pt->head.ebase) < 0) {
		/* Most likely after leap frame reset. Could also be a
		 * backstep of the system clock. Anyway, get the new
		 * leap era frame.
		 */
		reload_limits(pt, &ts64);
	} else if (ucmpv64(&ts64, &pt->head.dtime) >= 0)	{
		/* Boundary crossed in forward direction. This might
		 * indicate a leap transition, so we prepare for that
		 * case.
		 *
		 * Some operations below are actually NOPs in electric
		 * mode, but having only one code path that works for
		 * both modes is easier to maintain.
		 */
		last = pt->head.ttime;
		qr->warped = (int16_t)(last.D_s.lo -
				       pt->head.dtime.D_s.lo);
		next = addv64i32(&ts64, qr->warped);
		reload_limits(pt, &next);
		fired = ucmpv64(&pt->head.ebase, &last) == 0;
		if (fired) {
			ts64 = next;
			ts32 = next.D_s.lo;
		} else {
			qr->warped = 0;
		}
	}

	qr->tai_offs = pt->head.this_tai;

	/* If before the next scheduling alert, we're done. */
	if (ucmpv64(&ts64, &pt->head.stime) < 0)
		return fired;

	/* now start to collect the remaing data */
	due32 = pt->head.dtime.D_s.lo;

	qr->tai_diff  = pt->head.next_tai - pt->head.this_tai;
	qr->ttime     = pt->head.ttime;
	qr->ddist     = due32 - ts32;
	qr->dynamic   = pt->head.dynls;
	qr->proximity = LSPROX_SCHEDULE;

	/* if not in the last day before transition, we're done. */
	if (!betweenu32(due32 - SECSPERDAY, ts32, due32))
		return fired;
	
	qr->proximity = LSPROX_ANNOUNCE;
	if (!betweenu32(due32 - 10, ts32, due32))
		return fired;

	/* The last 10s before the transition. Prepare for action! */
	qr->proximity = LSPROX_ALERT;
	return fired;
}
Exemple #9
0
/* ------------------------------------------------------------------ */
int/*BOOL*/
leapsec_autokey_tai(
	int            tai_offset,
	uint32_t       ntpnow    ,
	const time_t * pivot     )
{
	leap_table_t * pt;
	leap_era_t     era;
	vint64         now64;
	int            idx;

	(void)tai_offset;
	pt = leapsec_get_table(FALSE);

	/* Bail out if the basic offset is not zero and the putative
	 * offset is bigger than 10s. That was in 1972 -- we don't want
	 * to go back that far!
	 */
	if (pt->head.base_tai != 0 || tai_offset < 10)
		return FALSE;

	/* If there's already data in the table, check if an update is
	 * possible. Update is impossible if there are static entries
	 * (since this indicates a valid leapsecond file) or if we're
	 * too close to a leapsecond transition: We do not know on what
	 * side the transition the sender might have been, so we use a
	 * dead zone around the transition.
	 */

	/* Check for static entries */
	for (idx = 0; idx != pt->head.size; idx++)
		if ( ! pt->info[idx].dynls)
			return FALSE;

	/* get the fulll time stamp and leap era for it */
	now64 = ntpcal_ntp_to_ntp(ntpnow, pivot);
	fetch_leap_era(&era, pt, &now64);

	/* check the limits with 20s dead band */
	era.ebase = addv64i32(&era.ebase,  20);
	if (ucmpv64(&now64, &era.ebase) < 0)
		return FALSE;

	era.ttime = addv64i32(&era.ttime, -20);
	if (ucmpv64(&now64, &era.ttime) > 0)
		return FALSE;

	/* Here we can proceed. Calculate the delta update. */
	tai_offset -= era.taiof;

	/* Shift the header info offsets. */
	pt->head.base_tai += tai_offset;
	pt->head.this_tai += tai_offset;
	pt->head.next_tai += tai_offset;

	/* Shift table entry offsets (if any) */
	for (idx = 0; idx != pt->head.size; idx++)
		pt->info[idx].taiof += tai_offset;

	/* claim success... */
	return TRUE;
}