diff options
Diffstat (limited to 'usr.sbin/xntpd/lib/clocktime.c')
-rw-r--r-- | usr.sbin/xntpd/lib/clocktime.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/usr.sbin/xntpd/lib/clocktime.c b/usr.sbin/xntpd/lib/clocktime.c new file mode 100644 index 0000000..36b967e --- /dev/null +++ b/usr.sbin/xntpd/lib/clocktime.c @@ -0,0 +1,131 @@ +/* clocktime.c,v 3.1 1993/07/06 01:08:07 jbj Exp + * clocktime - compute the NTP date from a day of year, hour, minute + * and second. + */ +#include "ntp_fp.h" +#include "ntp_unixtime.h" +#include "ntp_stdlib.h" + +/* + * Hacks to avoid excercising the multiplier. I have no pride. + */ +#define MULBY10(x) (((x)<<3) + ((x)<<1)) +#define MULBY60(x) (((x)<<6) - ((x)<<2)) /* watch overflow */ +#define MULBY24(x) (((x)<<4) + ((x)<<3)) + +/* + * Two days, in seconds. + */ +#define TWODAYS (2*24*60*60) + +/* + * We demand that the time be within CLOSETIME seconds of the receive + * time stamp. This is about 4 hours, which hopefully should be + * wide enough to collect most data, while close enough to keep things + * from getting confused. + */ +#define CLOSETIME (4*60*60) + + +int +clocktime(yday, hour, minute, second, tzoff, rec_ui, yearstart, ts_ui) + int yday; + int hour; + int minute; + int second; + int tzoff; + U_LONG rec_ui; + U_LONG *yearstart; + U_LONG *ts_ui; +{ + register LONG tmp; + register U_LONG date; + register U_LONG yst; + + /* + * Compute the offset into the year in seconds. Note that + * this could come out to be a negative number. + */ + tmp = (LONG)(MULBY24((yday-1)) + hour + tzoff); + tmp = MULBY60(tmp) + (LONG)minute; + tmp = MULBY60(tmp) + (LONG)second; + + /* + * Initialize yearstart, if necessary. + */ + yst = *yearstart; + if (yst == 0) { + yst = calyearstart(rec_ui); + *yearstart = yst; + } + + /* + * Now the fun begins. We demand that the received clock time + * be within CLOSETIME of the receive timestamp, but + * there is uncertainty about the year the timestamp is in. + * Use the current year start for the first check, this should + * work most of the time. + */ + date = (U_LONG)(tmp + (LONG)yst); + if (date < (rec_ui + CLOSETIME) && + date > (rec_ui - CLOSETIME)) { + *ts_ui = date; + return 1; + } + + /* + * Trouble. Next check is to see if the year rolled over and, if + * so, try again with the new year's start. + */ + yst = calyearstart(rec_ui); + if (yst != *yearstart) { + date = (U_LONG)((LONG)yst + tmp); + *ts_ui = date; + if (date < (rec_ui + CLOSETIME) && + date > (rec_ui - CLOSETIME)) { + *yearstart = yst; + return 1; + } + } + + /* + * Here we know the year start matches the current system + * time. One remaining possibility is that the time code + * is in the year previous to that of the system time. This + * is only worth checking if the receive timestamp is less + * than a couple of days into the new year. + */ + if ((rec_ui - yst) < TWODAYS) { + yst = calyearstart(yst - TWODAYS); + if (yst != *yearstart) { + date = (U_LONG)(tmp + (LONG)yst); + if (date < (rec_ui + CLOSETIME) && + date > (rec_ui - CLOSETIME)) { + *yearstart = yst; + *ts_ui = date; + return 1; + } + } + } + + /* + * One last possibility is that the time stamp is in the year + * following the year the system is in. Try this one before + * giving up. + */ + yst = calyearstart(rec_ui + TWODAYS); + if (yst != *yearstart) { + date = (U_LONG)((LONG)yst + tmp); + if (date < (rec_ui + CLOSETIME) && + date > (rec_ui - CLOSETIME)) { + *yearstart = yst; + *ts_ui = date; + return 1; + } + } + + /* + * Give it up. + */ + return 0; +} |