check_y2k.c revision 1.1.1.1.6.1 1 1.1.1.1.6.1 yamt /* $NetBSD: check_y2k.c,v 1.1.1.1.6.1 2014/05/22 15:50:09 yamt Exp $ */
2 1.1 kardel
3 1.1 kardel /* check_y2k.c -- test ntp code constructs for Y2K correctness Y2KFixes [*/
4 1.1 kardel
5 1.1 kardel /*
6 1.1 kardel Code invoked by `make check`. Not part of ntpd and not to be
7 1.1 kardel installed.
8 1.1 kardel
9 1.1 kardel On any code I even wonder about, I've cut and pasted the code
10 1.1 kardel here and ran it as a test case just to be sure.
11 1.1 kardel
12 1.1 kardel For code not in "ntpd" proper, we have tried to call most
13 1.1 kardel repaired functions from herein to properly test them
14 1.1 kardel (something never done before!). This has found several bugs,
15 1.1 kardel not normal Y2K bugs, that will strike in Y2K so repair them
16 1.1 kardel we did.
17 1.1 kardel
18 1.1 kardel Program exits with 0 on success, 1 on Y2K failure (stdout messages).
19 1.1 kardel Exit of 2 indicates internal logic bug detected OR failure of
20 1.1 kardel what should be our correct formulas.
21 1.1 kardel
22 1.1 kardel While "make check" should only check logic for source within that
23 1.1 kardel specific directory, this check goes outside the scope of the local
24 1.1 kardel directory. It's not a perfect world (besides, there is a lot of
25 1.1 kardel interdependence here, and it really needs to be tested in
26 1.1 kardel a controled order).
27 1.1 kardel */
28 1.1 kardel
29 1.1 kardel /* { definitions lifted from ntpd.c to allow us to complie with
30 1.1 kardel "#include ntp.h". I have not taken the time to reduce the clutter. */
31 1.1 kardel
32 1.1 kardel #ifdef HAVE_CONFIG_H
33 1.1 kardel # include <config.h>
34 1.1 kardel #endif
35 1.1 kardel
36 1.1 kardel #include "ntpd.h"
37 1.1 kardel
38 1.1 kardel #ifdef HAVE_UNISTD_H
39 1.1 kardel # include <unistd.h>
40 1.1 kardel #endif
41 1.1 kardel #ifdef HAVE_SYS_STAT_H
42 1.1 kardel # include <sys/stat.h>
43 1.1 kardel #endif
44 1.1 kardel #include <stdio.h>
45 1.1 kardel #include <errno.h>
46 1.1 kardel #ifndef SYS_WINNT
47 1.1 kardel # if !defined(VMS) /*wjm*/
48 1.1 kardel # include <sys/param.h>
49 1.1 kardel # endif /* VMS */
50 1.1 kardel # if HAVE_SYS_SIGNAL_H
51 1.1 kardel # include <sys/signal.h>
52 1.1 kardel # endif /* HAVE_SYS_SIGNAL_H */
53 1.1 kardel # include <sys/signal.h>
54 1.1 kardel # ifdef HAVE_SYS_IOCTL_H
55 1.1 kardel # include <sys/ioctl.h>
56 1.1 kardel # endif /* HAVE_SYS_IOCTL_H */
57 1.1 kardel # if !defined(VMS) /*wjm*/
58 1.1 kardel # include <sys/resource.h>
59 1.1 kardel # endif /* VMS */
60 1.1 kardel #else
61 1.1 kardel # include <signal.h>
62 1.1 kardel # include <process.h>
63 1.1 kardel # include <io.h>
64 1.1 kardel # include "../libntp/log.h"
65 1.1 kardel #endif /* SYS_WINNT */
66 1.1 kardel #if defined(HAVE_RTPRIO)
67 1.1 kardel # ifdef HAVE_SYS_RESOURCE_H
68 1.1 kardel # include <sys/resource.h>
69 1.1 kardel # endif
70 1.1 kardel # ifdef HAVE_SYS_LOCK_H
71 1.1 kardel # include <sys/lock.h>
72 1.1 kardel # endif
73 1.1 kardel # include <sys/rtprio.h>
74 1.1 kardel #else
75 1.1 kardel # ifdef HAVE_PLOCK
76 1.1 kardel # ifdef HAVE_SYS_LOCK_H
77 1.1 kardel # include <sys/lock.h>
78 1.1 kardel # endif
79 1.1 kardel # endif
80 1.1 kardel #endif
81 1.1 kardel #if defined(HAVE_SCHED_SETSCHEDULER)
82 1.1 kardel # ifdef HAVE_SCHED_H
83 1.1 kardel # include <sched.h>
84 1.1 kardel # else
85 1.1 kardel # ifdef HAVE_SYS_SCHED_H
86 1.1 kardel # include <sys/sched.h>
87 1.1 kardel # endif
88 1.1 kardel # endif
89 1.1 kardel #endif
90 1.1 kardel #if defined(HAVE_SYS_MMAN_H)
91 1.1 kardel # include <sys/mman.h>
92 1.1 kardel #endif
93 1.1 kardel
94 1.1 kardel #ifdef HAVE_TERMIOS_H
95 1.1 kardel # include <termios.h>
96 1.1 kardel #endif
97 1.1 kardel
98 1.1 kardel #ifdef SYS_DOMAINOS
99 1.1 kardel # include <apollo/base.h>
100 1.1 kardel #endif /* SYS_DOMAINOS */
101 1.1 kardel
102 1.1 kardel /* } end definitions lifted from ntpd.c */
103 1.1 kardel
104 1.1 kardel #include "ntp_calendar.h"
105 1.1 kardel #include "parse.h"
106 1.1 kardel
107 1.1 kardel #define GoodLeap(Year) (((Year)%4 || (!((Year)%100) && (Year)%400)) ? 0 : 13 )
108 1.1 kardel
109 1.1 kardel char const *progname = "check_y2k";
110 1.1 kardel
111 1.1 kardel long
112 1.1 kardel Days ( int Year ) /* return number of days since year "0" */
113 1.1 kardel {
114 1.1 kardel long Return;
115 1.1 kardel /* this is a known to be good algorithm */
116 1.1 kardel Return = Year * 365; /* first aproximation to the value */
117 1.1 kardel if ( Year >= 1 )
118 1.1 kardel { /* see notes in libparse/parse.c if you want a PROPER
119 1.1 kardel * **generic algorithm. */
120 1.1 kardel Return += (Year+3) / 4; /* add in (too many) leap days */
121 1.1 kardel Return -= (Year-1) / 100; /* reduce by (too many) centurys */
122 1.1 kardel Return += (Year-1) / 400; /* get final answer */
123 1.1 kardel }
124 1.1 kardel
125 1.1 kardel return Return;
126 1.1 kardel }
127 1.1 kardel
128 1.1 kardel static int year0 = 1900; /* sarting year for NTP time */
129 1.1 kardel static int yearend; /* ending year we test for NTP time.
130 1.1 kardel * 32-bit systems: through 2036, the
131 1.1 kardel **year in which NTP time overflows.
132 1.1 kardel * 64-bit systems: a reasonable upper
133 1.1 kardel **limit (well, maybe somewhat beyond
134 1.1 kardel **reasonable, but well before the
135 1.1 kardel **max time, by which time the earth
136 1.1 kardel **will be dead.) */
137 1.1 kardel static time_t Time;
138 1.1 kardel static struct tm LocalTime;
139 1.1 kardel
140 1.1 kardel #define Error(year) if ( (year)>=2036 && LocalTime.tm_year < 110 ) \
141 1.1 kardel Warnings++; else Fatals++
142 1.1 kardel
143 1.1 kardel int
144 1.1 kardel main( void )
145 1.1 kardel {
146 1.1 kardel int Fatals;
147 1.1 kardel int Warnings;
148 1.1 kardel int year;
149 1.1 kardel
150 1.1 kardel Time = time( (time_t *)NULL )
151 1.1 kardel #ifdef TESTTIMEOFFSET
152 1.1 kardel + test_time_offset
153 1.1 kardel #endif
154 1.1 kardel ;
155 1.1 kardel LocalTime = *localtime( &Time );
156 1.1 kardel
157 1.1 kardel year = ( sizeof( u_long ) > 4 ) /* save max span using year as temp */
158 1.1 kardel ? ( 400 * 3 ) /* three greater gregorian cycles */
159 1.1 kardel : ((int)(0x7FFFFFFF / 365.242 / 24/60/60)* 2 ); /*32-bit limit*/
160 1.1 kardel /* NOTE: will automacially expand test years on
161 1.1 kardel * 64 bit machines.... this may cause some of the
162 1.1 kardel * existing ntp logic to fail for years beyond
163 1.1 kardel * 2036 (the current 32-bit limit). If all checks
164 1.1 kardel * fail ONLY beyond year 2036 you may ignore such
165 1.1 kardel * errors, at least for a decade or so. */
166 1.1 kardel yearend = year0 + year;
167 1.1 kardel
168 1.1 kardel puts( " internal self check" );
169 1.1 kardel { /* verify our own logic used to verify repairs */
170 1.1 kardel unsigned long days;
171 1.1 kardel
172 1.1 kardel if ( year0 >= yearend )
173 1.1 kardel {
174 1.1 kardel fprintf( stdout, "year0=%d NOT LESS THAN yearend=%d (span=%d)\n",
175 1.1 kardel (int)year0, (int)yearend, (int)year );
176 1.1 kardel exit(2);
177 1.1 kardel }
178 1.1 kardel
179 1.1 kardel {
180 1.1 kardel int save_year;
181 1.1 kardel
182 1.1 kardel save_year = LocalTime.tm_year; /* save current year */
183 1.1 kardel
184 1.1 kardel year = 1980;
185 1.1 kardel LocalTime.tm_year = year - 1900;
186 1.1 kardel Fatals = Warnings = 0;
187 1.1 kardel Error(year); /* should increment Fatals */
188 1.1 kardel if ( Fatals == 0 )
189 1.1 kardel {
190 1.1 kardel fprintf( stdout,
191 1.1 kardel "%4d: %s(%d): FATAL DID NOT INCREMENT (Fatals=%d Warnings=%d)\n",
192 1.1 kardel (int)year, __FILE__, __LINE__, (int)Fatals, (int)Warnings );
193 1.1 kardel exit(2);
194 1.1 kardel }
195 1.1 kardel
196 1.1 kardel year = 2100; /* test year > limit but CURRENT year < limit */
197 1.1 kardel Fatals = Warnings = 0;
198 1.1 kardel Error(year); /* should increment Fatals */
199 1.1 kardel if ( Warnings == 0 )
200 1.1 kardel {
201 1.1 kardel fprintf( stdout,
202 1.1 kardel "%4d: %s(%d): WARNING DID NOT INCREMENT (Fatals=%d Warnings=%d)\n",
203 1.1 kardel (int)year, __FILE__, __LINE__, (int)Fatals, (int)Warnings );
204 1.1 kardel exit(2);
205 1.1 kardel }
206 1.1 kardel Fatals = Warnings = 0;
207 1.1 kardel LocalTime.tm_year = year - 1900; /* everything > limit */
208 1.1 kardel Error(1980); /* should increment Fatals */
209 1.1 kardel if ( Fatals == 0 )
210 1.1 kardel {
211 1.1 kardel fprintf( stdout,
212 1.1 kardel "%4d: %s(%d): FATALS DID NOT INCREMENT (Fatals=%d Warnings=%d)\n",
213 1.1 kardel (int)year, __FILE__, __LINE__, (int)Fatals, (int)Warnings );
214 1.1 kardel exit(2);
215 1.1 kardel }
216 1.1 kardel
217 1.1 kardel LocalTime.tm_year = save_year;
218 1.1 kardel }
219 1.1 kardel
220 1.1 kardel days = 365+1; /* days in year 0 + 1 more day */
221 1.1 kardel for ( year = 1; year <= 2500; year++ )
222 1.1 kardel {
223 1.1 kardel long Test;
224 1.1 kardel Test = Days( year );
225 1.1 kardel if ( days != Test )
226 1.1 kardel {
227 1.1 kardel fprintf( stdout, "%04d: Days() DAY COUNT ERROR: s/b=%ld was=%ld\n",
228 1.1 kardel year, (long)days, (long)Test );
229 1.1 kardel exit(2); /* would throw off many other tests */
230 1.1 kardel }
231 1.1 kardel
232 1.1 kardel Test = julian0(year); /* compare with julian0() macro */
233 1.1 kardel if ( days != Test )
234 1.1 kardel {
235 1.1 kardel fprintf( stdout, "%04d: julian0() DAY COUNT ERROR: s/b=%ld was=%ld\n",
236 1.1 kardel year, (long)days, (long)Test );
237 1.1 kardel exit(2); /* would throw off many other tests */
238 1.1 kardel }
239 1.1 kardel
240 1.1 kardel days += 365;
241 1.1 kardel if ( isleap_4(year) ) days++;
242 1.1 kardel }
243 1.1 kardel
244 1.1 kardel if ( isleap_4(1999) )
245 1.1 kardel {
246 1.1 kardel fprintf( stdout, "isleap_4(1999) REPORTED TRUE\n" );
247 1.1 kardel exit(2);
248 1.1 kardel }
249 1.1 kardel if ( !isleap_4(2000) )
250 1.1 kardel {
251 1.1 kardel fprintf( stdout, "isleap_4(2000) REPORTED FALSE\n" );
252 1.1 kardel exit(2);
253 1.1 kardel }
254 1.1 kardel if ( isleap_4(2001) )
255 1.1 kardel {
256 1.1 kardel fprintf( stdout, "isleap_4(1999) REPORTED TRUE\n" );
257 1.1 kardel exit(2);
258 1.1 kardel }
259 1.1 kardel
260 1.1 kardel if ( !isleap_tm(2000-1900) )
261 1.1 kardel {
262 1.1 kardel fprintf( stdout, "isleap_tm(100) REPORTED FALSE\n" );
263 1.1 kardel exit(2);
264 1.1 kardel }
265 1.1 kardel }
266 1.1 kardel
267 1.1 kardel Fatals = Warnings = 0;
268 1.1 kardel
269 1.1 kardel puts( " include/ntp.h" );
270 1.1 kardel { /* test our new isleap_*() #define "functions" */
271 1.1 kardel
272 1.1 kardel for ( year = 1400; year <= 2200; year++ )
273 1.1 kardel {
274 1.1 kardel int LeapSw;
275 1.1 kardel int IsLeapSw;
276 1.1 kardel
277 1.1 kardel LeapSw = GoodLeap(year);
278 1.1 kardel IsLeapSw = isleap_4(year);
279 1.1 kardel
280 1.1 kardel if ( !!LeapSw != !!IsLeapSw )
281 1.1 kardel {
282 1.1 kardel Error(year);
283 1.1 kardel fprintf( stdout,
284 1.1 kardel " %4d %2d %3d *** ERROR\n", year, LeapSw, IsLeapSw );
285 1.1 kardel break;
286 1.1 kardel }
287 1.1 kardel
288 1.1 kardel IsLeapSw = isleap_tm(year-1900);
289 1.1 kardel
290 1.1 kardel if ( !!LeapSw != !!IsLeapSw )
291 1.1 kardel {
292 1.1 kardel Error(year);
293 1.1 kardel fprintf( stdout,
294 1.1 kardel " %4d %2d %3d *** ERROR\n", year, LeapSw, IsLeapSw );
295 1.1 kardel break;
296 1.1 kardel }
297 1.1 kardel }
298 1.1 kardel }
299 1.1 kardel
300 1.1 kardel puts( " include/ntp_calendar.h" );
301 1.1 kardel { /* I belive this is good, but just to be sure... */
302 1.1 kardel
303 1.1 kardel /* we are testing this #define */
304 1.1 kardel #define is_leapyear(y) (y%4 == 0 && !(y%100 == 0 && !(y%400 == 0)))
305 1.1 kardel
306 1.1 kardel for ( year = 1400; year <= 2200; year++ )
307 1.1 kardel {
308 1.1 kardel int LeapSw;
309 1.1 kardel
310 1.1 kardel LeapSw = GoodLeap(year);
311 1.1 kardel
312 1.1 kardel if ( !(!LeapSw) != !(!is_leapyear(year)) )
313 1.1 kardel {
314 1.1 kardel Error(year);
315 1.1 kardel fprintf( stdout,
316 1.1 kardel " %4d %2d *** ERROR\n", year, LeapSw );
317 1.1 kardel break;
318 1.1 kardel }
319 1.1 kardel }
320 1.1 kardel }
321 1.1 kardel
322 1.1 kardel
323 1.1 kardel puts( " libparse/parse.c" );
324 1.1 kardel {
325 1.1 kardel long Days1970; /* days from 1900 to 1970 */
326 1.1 kardel
327 1.1 kardel struct ParseTime /* womp up a test structure to all cut/paste code */
328 1.1 kardel {
329 1.1 kardel int year;
330 1.1 kardel } Clock_Time, *clock_time;
331 1.1 kardel
332 1.1 kardel clock_time = &Clock_Time;
333 1.1 kardel
334 1.1 kardel /* first test this #define */
335 1.1 kardel #define days_per_year(x) ((x) % 4 ? 365 : ((x % 400) ? ((x % 100) ? 366 : 365) : 366))
336 1.1 kardel
337 1.1 kardel for ( year = 1400; year <= 2200; year++ )
338 1.1 kardel {
339 1.1 kardel int LeapSw;
340 1.1 kardel int DayCnt;
341 1.1 kardel
342 1.1 kardel LeapSw = GoodLeap(year);
343 1.1 kardel DayCnt = (int)days_per_year(year);
344 1.1 kardel
345 1.1 kardel if ( ( LeapSw ? 366 : 365 ) != DayCnt )
346 1.1 kardel {
347 1.1 kardel Error(year);
348 1.1 kardel fprintf( stdout,
349 1.1 kardel " days_per_year() %4d %2d %3d *** ERROR\n",
350 1.1 kardel year, LeapSw, DayCnt );
351 1.1 kardel break;
352 1.1 kardel }
353 1.1 kardel }
354 1.1 kardel
355 1.1 kardel /* test (what is now julian0) calculations */
356 1.1 kardel
357 1.1 kardel Days1970 = Days( 1970 ); /* get days since 1970 using a known good */
358 1.1 kardel
359 1.1 kardel for ( year = 1970; year < yearend; year++ )
360 1.1 kardel {
361 1.1 kardel unsigned long t;
362 1.1 kardel long DaysYear ;
363 1.1 kardel
364 1.1 kardel clock_time->year = year;
365 1.1 kardel
366 1.1 kardel /* here is the code we are testing, cut and pasted out of the source */
367 1.1 kardel #if 0 /* old BUGGY code that has Y2K (and many other) failures */
368 1.1 kardel /* ghealton: this logic FAILED with great frequency when run
369 1.1 kardel * over a period of time, including for year 2000. True, it
370 1.1 kardel * had more successes than failures, but that's not really good
371 1.1 kardel * enough for critical time distribution software.
372 1.1 kardel * It is so awful I wonder if it has had a history of failure
373 1.1 kardel * and fixes? */
374 1.1 kardel t = (clock_time->year - 1970) * 365;
375 1.1 kardel t += (clock_time->year >> 2) - (1970 >> 2);
376 1.1 kardel t -= clock_time->year / 100 - 1970 / 100;
377 1.1 kardel t += clock_time->year / 400 - 1970 / 400;
378 1.1 kardel
379 1.1 kardel /* (immediate feare of rounding errors on integer
380 1.1 kardel * **divisions proved well founded) */
381 1.1 kardel
382 1.1 kardel #else
383 1.1 kardel /* my replacement, based on Days() above */
384 1.1 kardel t = julian0(year) - julian0(1970);
385 1.1 kardel #endif
386 1.1 kardel
387 1.1 kardel /* compare result in t against trusted calculations */
388 1.1 kardel DaysYear = Days( year ); /* get days to this year */
389 1.1 kardel if ( t != DaysYear - Days1970 )
390 1.1 kardel {
391 1.1 kardel Error(year);
392 1.1 kardel fprintf( stdout,
393 1.1 kardel " %4d 1970=%-8ld %4d=%-8ld %-3ld t=%-8ld *** ERROR ***\n",
394 1.1 kardel year, (long)Days1970,
395 1.1 kardel year,
396 1.1 kardel (long)DaysYear,
397 1.1 kardel (long)(DaysYear - Days1970),
398 1.1 kardel (long)t );
399 1.1 kardel }
400 1.1 kardel }
401 1.1 kardel
402 1.1 kardel #if 1 /* { */
403 1.1 kardel {
404 1.1 kardel debug = 1; /* enable debugging */
405 1.1 kardel for ( year = 1970; year < yearend; year++ )
406 1.1 kardel { /* (limited by theory unix 2038 related bug lives by, but
407 1.1 kardel * ends in yearend) */
408 1.1 kardel clocktime_t ct;
409 1.1 kardel time_t Observed;
410 1.1 kardel time_t Expected;
411 1.1 kardel u_long Flag;
412 1.1 kardel unsigned long t;
413 1.1 kardel
414 1.1 kardel ct.day = 1;
415 1.1 kardel ct.month = 1;
416 1.1 kardel ct.year = year;
417 1.1 kardel ct.hour = ct.minute = ct.second = ct.usecond = 0;
418 1.1 kardel ct.utcoffset = 0;
419 1.1 kardel ct.utctime = 0;
420 1.1 kardel ct.flags = 0;
421 1.1 kardel
422 1.1 kardel Flag = 0;
423 1.1 kardel Observed = parse_to_unixtime( &ct, &Flag );
424 1.1 kardel if ( ct.year != year )
425 1.1 kardel {
426 1.1 kardel fprintf( stdout,
427 1.1 kardel "%04d: parse_to_unixtime(,%d) CORRUPTED ct.year: was %d\n",
428 1.1 kardel (int)year, (int)Flag, (int)ct.year );
429 1.1 kardel Error(year);
430 1.1 kardel break;
431 1.1 kardel }
432 1.1 kardel t = julian0(year) - julian0(1970); /* Julian day from 1970 */
433 1.1 kardel Expected = t * 24 * 60 * 60;
434 1.1 kardel if ( Observed != Expected || Flag )
435 1.1 kardel { /* time difference */
436 1.1 kardel fprintf( stdout,
437 1.1 kardel "%04d: parse_to_unixtime(,%d) FAILURE: was=%lu s/b=%lu (%ld)\n",
438 1.1 kardel year, (int)Flag,
439 1.1 kardel (unsigned long)Observed, (unsigned long)Expected,
440 1.1 kardel ((long)Observed - (long)Expected) );
441 1.1 kardel Error(year);
442 1.1 kardel break;
443 1.1 kardel }
444 1.1 kardel
445 1.1 kardel if ( year >= YEAR_PIVOT+1900 )
446 1.1 kardel {
447 1.1 kardel /* check year % 100 code we put into parse_to_unixtime() */
448 1.1 kardel ct.utctime = 0;
449 1.1 kardel ct.year = year % 100;
450 1.1 kardel Flag = 0;
451 1.1 kardel
452 1.1 kardel Observed = parse_to_unixtime( &ct, &Flag );
453 1.1 kardel
454 1.1 kardel if ( Observed != Expected || Flag )
455 1.1 kardel { /* time difference */
456 1.1 kardel fprintf( stdout,
457 1.1 kardel "%04d: parse_to_unixtime(%d,%d) FAILURE: was=%lu s/b=%lu (%ld)\n",
458 1.1 kardel year, (int)ct.year, (int)Flag,
459 1.1 kardel (unsigned long)Observed, (unsigned long)Expected,
460 1.1 kardel ((long)Observed - (long)Expected) );
461 1.1 kardel Error(year);
462 1.1 kardel break;
463 1.1 kardel }
464 1.1 kardel
465 1.1 kardel /* check year - 1900 code we put into parse_to_unixtime() */
466 1.1 kardel ct.utctime = 0;
467 1.1 kardel ct.year = year - 1900;
468 1.1 kardel Flag = 0;
469 1.1 kardel
470 1.1 kardel Observed = parse_to_unixtime( &ct, &Flag );
471 1.1 kardel
472 1.1 kardel if ( Observed != Expected || Flag )
473 1.1 kardel { /* time difference */
474 1.1 kardel fprintf( stdout,
475 1.1 kardel "%04d: parse_to_unixtime(%d,%d) FAILURE: was=%lu s/b=%lu (%ld)\n",
476 1.1 kardel year, (int)ct.year, (int)Flag,
477 1.1 kardel (unsigned long)Observed, (unsigned long)Expected,
478 1.1 kardel ((long)Observed - (long)Expected) );
479 1.1 kardel Error(year);
480 1.1 kardel break;
481 1.1 kardel }
482 1.1 kardel
483 1.1 kardel
484 1.1 kardel }
485 1.1 kardel }
486 1.1 kardel #endif /* } */
487 1.1 kardel }
488 1.1 kardel }
489 1.1 kardel
490 1.1 kardel puts( " libntp/caljulian.c" );
491 1.1 kardel { /* test caljulian() */
492 1.1 kardel struct calendar ot;
493 1.1 kardel u_long ntp_time; /* NTP time */
494 1.1 kardel
495 1.1 kardel year = year0; /* calculate the basic year */
496 1.1 kardel printf( " starting year %04d\n", (int)year0 );
497 1.1 kardel printf( " ending year %04d\n", (int)yearend );
498 1.1 kardel
499 1.1 kardel
500 1.1 kardel ntp_time = julian0( year0 ); /* NTP starts in 1900-01-01 */
501 1.1 kardel #if DAY_NTP_STARTS == 693596
502 1.1 kardel ntp_time -= 365; /* BIAS required for successful test */
503 1.1 kardel #endif
504 1.1 kardel if ( DAY_NTP_STARTS != ntp_time )
505 1.1 kardel {
506 1.1 kardel Error(year);
507 1.1 kardel fprintf( stdout,
508 1.1 kardel "%04d: DAY_NTP_STARTS (%ld) NOT TRUE VALUE OF %ld (%ld)\n",
509 1.1 kardel (int)year0,
510 1.1 kardel (long)DAY_NTP_STARTS, (long)ntp_time,
511 1.1 kardel (long)DAY_NTP_STARTS - (long)ntp_time );
512 1.1 kardel }
513 1.1 kardel
514 1.1 kardel for ( ; year < yearend; year++ )
515 1.1 kardel {
516 1.1 kardel
517 1.1 kardel /* 01-01 for the current year */
518 1.1 kardel ntp_time = Days( year ) - Days( year0 ); /* days into NTP time */
519 1.1 kardel ntp_time *= 24 * 60 * 60; /* convert into seconds */
520 1.1 kardel caljulian( ntp_time, &ot ); /* convert January 1 */
521 1.1 kardel if ( ot.year != year
522 1.1 kardel || ot.month != 1
523 1.1 kardel || ot.monthday != 1 )
524 1.1 kardel {
525 1.1 kardel Error(year);
526 1.1 kardel fprintf( stdout, "%lu: EXPECTED %04d-01-01: FOUND %04d-%02d-%02d\n",
527 1.1 kardel (unsigned long)ntp_time,
528 1.1 kardel year,
529 1.1 kardel (int)ot.year, (int)ot.month, (int)ot.monthday );
530 1.1 kardel break;
531 1.1 kardel }
532 1.1 kardel
533 1.1 kardel ntp_time += (31 + 28-1) * ( 24 * 60 * 60 ); /* advance to 02-28 */
534 1.1 kardel caljulian( ntp_time, &ot ); /* convert Feb 28 */
535 1.1 kardel if ( ot.year != year
536 1.1 kardel || ot.month != 2
537 1.1 kardel || ot.monthday != 28 )
538 1.1 kardel {
539 1.1 kardel Error(year);
540 1.1 kardel fprintf( stdout, "%lu: EXPECTED %04d-02-28: FOUND %04d-%02d-%02d\n",
541 1.1 kardel (unsigned long)ntp_time,
542 1.1 kardel year,
543 1.1 kardel (int)ot.year, (int)ot.month, (int)ot.monthday );
544 1.1 kardel break;
545 1.1 kardel }
546 1.1 kardel
547 1.1 kardel {
548 1.1 kardel int m; /* expected month */
549 1.1 kardel int d; /* expected day */
550 1.1 kardel
551 1.1 kardel m = isleap_4(year) ? 2 : 3;
552 1.1 kardel d = isleap_4(year) ? 29 : 1;
553 1.1 kardel
554 1.1 kardel ntp_time += ( 24 * 60 * 60 ); /* advance to the next day */
555 1.1 kardel caljulian( ntp_time, &ot ); /* convert this day */
556 1.1 kardel if ( ot.year != year
557 1.1 kardel || ot.month != m
558 1.1 kardel || ot.monthday != d )
559 1.1 kardel {
560 1.1 kardel Error(year);
561 1.1 kardel fprintf( stdout, "%lu: EXPECTED %04d-%02d-%02d: FOUND %04d-%02d-%02d\n",
562 1.1 kardel (unsigned long)ntp_time,
563 1.1 kardel year, m, d,
564 1.1 kardel (int)ot.year, (int)ot.month, (int)ot.monthday );
565 1.1 kardel break;
566 1.1 kardel }
567 1.1 kardel
568 1.1 kardel }
569 1.1 kardel }
570 1.1 kardel }
571 1.1 kardel
572 1.1 kardel puts( " libntp/caltontp.c" );
573 1.1 kardel { /* test caltontp() */
574 1.1 kardel struct calendar ot;
575 1.1 kardel u_long ntp_time; /* NTP time */
576 1.1 kardel
577 1.1 kardel year = year0; /* calculate the basic year */
578 1.1 kardel printf( " starting year %04d\n", (int)year0 );
579 1.1 kardel printf( " ending year %04d\n", (int)yearend );
580 1.1 kardel
581 1.1 kardel
582 1.1 kardel for ( ; year < yearend; year++ )
583 1.1 kardel {
584 1.1 kardel u_long ObservedNtp;
585 1.1 kardel
586 1.1 kardel /* 01-01 for the current year */
587 1.1 kardel ot.year = year;
588 1.1 kardel ot.month = ot.monthday = 1; /* unused, but set anyway JIC */
589 1.1 kardel ot.yearday = 1; /* this is the magic value used by caltontp() */
590 1.1 kardel ot.hour = ot.minute = ot.second = 0;
591 1.1 kardel
592 1.1 kardel ntp_time = Days( year ) - Days( year0 ); /* days into NTP time */
593 1.1 kardel ntp_time *= 24 * 60 * 60; /* convert into seconds */
594 1.1 kardel ObservedNtp = caltontp( &ot );
595 1.1 kardel if ( ntp_time != ObservedNtp )
596 1.1 kardel {
597 1.1 kardel Error(year);
598 1.1 kardel fprintf( stdout, "%d: EXPECTED %lu: FOUND %lu (%ld)\n",
599 1.1 kardel (int)year,
600 1.1 kardel (unsigned long)ntp_time, (unsigned long)ObservedNtp ,
601 1.1 kardel (long)ntp_time - (long)ObservedNtp );
602 1.1 kardel
603 1.1 kardel break;
604 1.1 kardel }
605 1.1 kardel
606 1.1 kardel /* now call caljulian as a type of failsafe supercheck */
607 1.1 kardel caljulian( ObservedNtp, &ot ); /* convert January 1 */
608 1.1 kardel if ( ot.year != year
609 1.1 kardel || ot.month != 1
610 1.1 kardel || ot.monthday != 1 )
611 1.1 kardel {
612 1.1 kardel Error(year);
613 1.1 kardel fprintf( stdout, "%lu: caljulian FAILSAFE EXPECTED %04d-01-01: FOUND %04d-%02d-%02d\n",
614 1.1 kardel (unsigned long)ObservedNtp,
615 1.1 kardel year,
616 1.1 kardel (int)ot.year, (int)ot.month, (int)ot.monthday );
617 1.1 kardel break;
618 1.1 kardel }
619 1.1 kardel }
620 1.1 kardel }
621 1.1 kardel
622 1.1 kardel if ( Warnings > 0 )
623 1.1 kardel fprintf( stdout, "%d WARNINGS\n", Warnings );
624 1.1 kardel if ( Fatals > 0 )
625 1.1 kardel fprintf( stdout, "%d FATAL ERRORS\n", Fatals );
626 1.1 kardel return Fatals ? 1 : 0;
627 1.1 kardel }
628 1.1 kardel /* Y2KFixes ] */
629