1: /*
2: * clocktime - compute the NTP date from a day of year, hour, minute
3: * and second.
4: */
5: #include "ntp_fp.h"
6: #include "ntp_unixtime.h"
7: #include "ntp_stdlib.h"
8:
9: /*
10: * Hacks to avoid excercising the multiplier. I have no pride.
11: */
12: #define MULBY10(x) (((x)<<3) + ((x)<<1))
13: #define MULBY60(x) (((x)<<6) - ((x)<<2)) /* watch overflow */
14: #define MULBY24(x) (((x)<<4) + ((x)<<3))
15:
16: /*
17: * Two days, in seconds.
18: */
19: #define TWODAYS (2*24*60*60)
20:
21: /*
22: * We demand that the time be within CLOSETIME seconds of the receive
23: * time stamp. This is about 4 hours, which hopefully should be
24: * wide enough to collect most data, while close enough to keep things
25: * from getting confused.
26: */
27: #define CLOSETIME (4*60*60)
28:
29:
30: int
31: clocktime(
32: int yday,
33: int hour,
34: int minute,
35: int second,
36: int tzoff,
37: u_long rec_ui,
38: u_long *yearstart,
39: u_int32 *ts_ui
40: )
41: {
42: register long tmp;
43: register u_long date;
44: register u_long yst;
45:
46: /*
47: * Compute the offset into the year in seconds. Note that
48: * this could come out to be a negative number.
49: */
50: tmp = (long)(MULBY24((yday-1)) + hour + tzoff);
51: tmp = MULBY60(tmp) + (long)minute;
52: tmp = MULBY60(tmp) + (long)second;
53:
54: /*
55: * Initialize yearstart, if necessary.
56: */
57: yst = *yearstart;
58: if (yst == 0) {
59: yst = calyearstart(rec_ui);
60: *yearstart = yst;
61: }
62:
63: /*
64: * Now the fun begins. We demand that the received clock time
65: * be within CLOSETIME of the receive timestamp, but
66: * there is uncertainty about the year the timestamp is in.
67: * Use the current year start for the first check, this should
68: * work most of the time.
69: */
70: date = (u_long)(tmp + (long)yst);
71: if (date < (rec_ui + CLOSETIME) &&
72: date > (rec_ui - CLOSETIME)) {
73: *ts_ui = date;
74: return 1;
75: }
76:
77: /*
78: * Trouble. Next check is to see if the year rolled over and, if
79: * so, try again with the new year's start.
80: */
81: yst = calyearstart(rec_ui);
82: if (yst != *yearstart) {
83: date = (u_long)((long)yst + tmp);
84: *ts_ui = date;
85: if (date < (rec_ui + CLOSETIME) &&
86: date > (rec_ui - CLOSETIME)) {
87: *yearstart = yst;
88: return 1;
89: }
90: }
91:
92: /*
93: * Here we know the year start matches the current system
94: * time. One remaining possibility is that the time code
95: * is in the year previous to that of the system time. This
96: * is only worth checking if the receive timestamp is less
97: * than a couple of days into the new year.
98: */
99: if ((rec_ui - yst) < TWODAYS) {
100: yst = calyearstart(yst - TWODAYS);
101: if (yst != *yearstart) {
102: date = (u_long)(tmp + (long)yst);
103: if (date < (rec_ui + CLOSETIME) &&
104: date > (rec_ui - CLOSETIME)) {
105: *yearstart = yst;
106: *ts_ui = date;
107: return 1;
108: }
109: }
110: }
111:
112: /*
113: * One last possibility is that the time stamp is in the year
114: * following the year the system is in. Try this one before
115: * giving up.
116: */
117: yst = calyearstart(rec_ui + TWODAYS);
118: if (yst != *yearstart) {
119: date = (u_long)((long)yst + tmp);
120: if (date < (rec_ui + CLOSETIME) &&
121: date > (rec_ui - CLOSETIME)) {
122: *yearstart = yst;
123: *ts_ui = date;
124: return 1;
125: }
126: }
127:
128: /*
129: * Give it up.
130: */
131: return 0;
132: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>