Obfuscate RCS ID matching so that CVS doesn't expand it.
[netbsd-mini2440.git] / dist / ntp / libntp / clocktime.c
blobc40ab84137f7ce0eb80a41d4065bb26ae4c1bcd3
1 /* $NetBSD$ */
3 /*
4 * clocktime - compute the NTP date from a day of year, hour, minute
5 * and second.
6 */
7 #include "ntp_fp.h"
8 #include "ntp_unixtime.h"
9 #include "ntp_stdlib.h"
12 * Hacks to avoid excercising the multiplier. I have no pride.
14 #define MULBY10(x) (((x)<<3) + ((x)<<1))
15 #define MULBY60(x) (((x)<<6) - ((x)<<2)) /* watch overflow */
16 #define MULBY24(x) (((x)<<4) + ((x)<<3))
19 * Two days, in seconds.
21 #define TWODAYS (2*24*60*60)
24 * We demand that the time be within CLOSETIME seconds of the receive
25 * time stamp. This is about 4 hours, which hopefully should be
26 * wide enough to collect most data, while close enough to keep things
27 * from getting confused.
29 #define CLOSETIME (4*60*60)
32 int
33 clocktime(
34 int yday,
35 int hour,
36 int minute,
37 int second,
38 int tzoff,
39 u_long rec_ui,
40 u_long *yearstart,
41 u_int32 *ts_ui
44 register long tmp;
45 register u_long date;
46 register u_long yst;
49 * Compute the offset into the year in seconds. Note that
50 * this could come out to be a negative number.
52 tmp = (long)(MULBY24((yday-1)) + hour + tzoff);
53 tmp = MULBY60(tmp) + (long)minute;
54 tmp = MULBY60(tmp) + (long)second;
57 * Initialize yearstart, if necessary.
59 yst = *yearstart;
60 if (yst == 0) {
61 yst = calyearstart(rec_ui);
62 *yearstart = yst;
66 * Now the fun begins. We demand that the received clock time
67 * be within CLOSETIME of the receive timestamp, but
68 * there is uncertainty about the year the timestamp is in.
69 * Use the current year start for the first check, this should
70 * work most of the time.
72 date = (u_long)(tmp + (long)yst);
73 if (date < (rec_ui + CLOSETIME) &&
74 date > (rec_ui - CLOSETIME)) {
75 *ts_ui = date;
76 return 1;
80 * Trouble. Next check is to see if the year rolled over and, if
81 * so, try again with the new year's start.
83 yst = calyearstart(rec_ui);
84 if (yst != *yearstart) {
85 date = (u_long)((long)yst + tmp);
86 *ts_ui = date;
87 if (date < (rec_ui + CLOSETIME) &&
88 date > (rec_ui - CLOSETIME)) {
89 *yearstart = yst;
90 return 1;
95 * Here we know the year start matches the current system
96 * time. One remaining possibility is that the time code
97 * is in the year previous to that of the system time. This
98 * is only worth checking if the receive timestamp is less
99 * than a couple of days into the new year.
101 if ((rec_ui - yst) < TWODAYS) {
102 yst = calyearstart(yst - TWODAYS);
103 if (yst != *yearstart) {
104 date = (u_long)(tmp + (long)yst);
105 if (date < (rec_ui + CLOSETIME) &&
106 date > (rec_ui - CLOSETIME)) {
107 *yearstart = yst;
108 *ts_ui = date;
109 return 1;
115 * One last possibility is that the time stamp is in the year
116 * following the year the system is in. Try this one before
117 * giving up.
119 yst = calyearstart(rec_ui + TWODAYS);
120 if (yst != *yearstart) {
121 date = (u_long)((long)yst + tmp);
122 if (date < (rec_ui + CLOSETIME) &&
123 date > (rec_ui - CLOSETIME)) {
124 *yearstart = yst;
125 *ts_ui = date;
126 return 1;
131 * Give it up.
133 return 0;