1 /* $OpenBSD: src/usr.sbin/rdate/ntpleaps.c,v 1.7 2004/05/05 20:29:54 jakob Exp $ */
2 /* $DragonFly: src/usr.sbin/rdate/ntpleaps.c,v 1.1 2004/12/01 15:04:43 joerg Exp $ */
5 * Copyright (c) 2002 Thorsten Glaser. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 /* Leap second support for NTP clients (generic) */
36 * I could include tzfile.h, but this would make the code unportable
37 * at no real benefit. Read tzfile.h for why.
40 #include <sys/types.h>
41 #include <netinet/in.h>
51 static uint32_t read_be_dword(uint8_t *ptr
);
53 static uint64_t *leapsecs
= NULL
;
54 static unsigned int leapsecs_num
= 0;
55 static int flaginit
= -1;
56 static int flagwarn
= 0;
64 if (!ntpleaps_read()) {
69 /* This does not really hurt, but users will complain about
70 * off-by-22-seconds (at time of coding) errors if we don't warn.
73 fputs("Warning: error reading tzfile. You will NOT be\n"
74 "able to get legal time or posix compliance!\n", stderr
);
75 flagwarn
= 1; /* put it only once */
82 ntpleaps_sub(uint64_t *t
)
88 if ((flaginit
? ntpleaps_init() : 0) == -1)
93 while (i
< leapsecs_num
) {
96 if (u
== leapsecs
[i
++])
107 read_be_dword(uint8_t *ptr
)
111 memcpy(&res
, ptr
, 4);
125 fd
= open("/usr/share/zoneinfo/Etc/UTC", O_RDONLY
| O_NDELAY
);
129 /* Check signature */
132 if (strcmp((const char *)buf
, "TZif")) {
137 /* Pre-initalize buf[24..27] so we need not check read(2) result */
143 /* Skip uninteresting parts of header */
146 /* Read number of leap second entries */
147 r
= read_be_dword(&buf
[24]);
148 /* Check for plausibility - arbitrary values */
149 if ((r
< 20) || (r
> 60000)) {
153 if ((l
= (uint64_t *)malloc(r
<< 3)) == NULL
) {
158 /* Skip further uninteresting stuff */
160 m1
= read_be_dword(buf
);
161 m2
= read_be_dword(&buf
[4]);
162 m3
= read_be_dword(&buf
[8]);
163 m3
+= (m1
<< 2) + m1
+ (m2
<< 2) + (m2
<< 1);
164 lseek(fd
, (off_t
)m3
, SEEK_CUR
);
166 /* Now go parse the tzfile leap second info */
167 for (m1
= 0; m1
< r
; m1
++) {
168 if (read(fd
, buf
, 8) != 8) {
173 s
= SEC_TO_TAI64(read_be_dword(buf
));
175 * Assume just _one_ leap second on each entry, and compensate
176 * the lacking error checking by validating the first entry
177 * against the known value
179 if (!m1
&& s
!= 0x4000000004B2580AULL
)
184 /* Clean up and activate the table */
186 if (leapsecs
!= NULL
)