summaryrefslogtreecommitdiff
path: root/libparse
diff options
context:
space:
mode:
authorCy Schubert <cy@FreeBSD.org>2020-03-04 13:59:29 +0000
committerCy Schubert <cy@FreeBSD.org>2020-03-04 13:59:29 +0000
commit5171bc9b11192d9ad273db7854787eaa65eb9997 (patch)
treeb872a53605ef14ae76de1104afb4be189d1a958a /libparse
parent360c01464aee3bc4c520898a675f35967db09ac2 (diff)
Diffstat (limited to 'libparse')
-rw-r--r--libparse/Makefile.am4
-rw-r--r--libparse/Makefile.in4
-rw-r--r--libparse/clk_rawdcf.c55
3 files changed, 61 insertions, 2 deletions
diff --git a/libparse/Makefile.am b/libparse/Makefile.am
index 41528a76bd79..8fb089f7717f 100644
--- a/libparse/Makefile.am
+++ b/libparse/Makefile.am
@@ -164,9 +164,11 @@ parse: $(parsesolaris_OBJECTS) libparse_kernel.a ../libntp/libntp.a
parsesolaris.o: sys/systm.h
+# [Bug3608] Solaris has inconsistent definitions of ffs() and fls(). Drop the
+# ones from 'systm.h'.
sys/systm.h:
-mkdir sys
- sed -e '/ffs(.*)/d' < /usr/include/sys/systm.h > sys/systm.h
+ sed -e '/f[fl]s(.*)/d' < /usr/include/sys/systm.h > sys/systm.h
## check-libparse is invoked by ntpd/Makefile.am
check-libparse: $(noinst_LIBRARIES)
diff --git a/libparse/Makefile.in b/libparse/Makefile.in
index b034ee142dd6..3d1686d678ee 100644
--- a/libparse/Makefile.in
+++ b/libparse/Makefile.in
@@ -1000,9 +1000,11 @@ parse: $(parsesolaris_OBJECTS) libparse_kernel.a ../libntp/libntp.a
parsesolaris.o: sys/systm.h
+# [Bug3608] Solaris has inconsistent definitions of ffs() and fls(). Drop the
+# ones from 'systm.h'.
sys/systm.h:
-mkdir sys
- sed -e '/ffs(.*)/d' < /usr/include/sys/systm.h > sys/systm.h
+ sed -e '/f[fl]s(.*)/d' < /usr/include/sys/systm.h > sys/systm.h
check-libparse: $(noinst_LIBRARIES)
@: do-nothing action to avoid default SCCS get
diff --git a/libparse/clk_rawdcf.c b/libparse/clk_rawdcf.c
index e22ebb0a4808..3fa74997c9bf 100644
--- a/libparse/clk_rawdcf.c
+++ b/libparse/clk_rawdcf.c
@@ -220,6 +220,58 @@ pcheck(
return psum;
}
+static int/*BOOL*/
+zeller_expand(
+ clocktime_t *clock_time,
+ unsigned int wd
+ )
+{
+ unsigned int y = (unsigned int)clock_time->year;
+ unsigned int m = (unsigned int)clock_time->month - 1u;
+ unsigned int d = (unsigned int)clock_time->day - 1u;
+ unsigned int c;
+
+ /* Check basic constraints first. */
+ if ((y >= 100u) || (m >= 12u) || (d >= 31u) || (--wd >= 7u))
+ return FALSE;
+
+ /* Get weekday of date in 1st century by a variation on Zeller's
+ * congruence. All operands are non-negative, and the month
+ * formula is adjusted to use a divider of 32, so we can do a
+ * shift instead of a 'true' division:
+ */
+ if ((m += 10u) >= 12u) /* shift base to 0000-03-01 */
+ m -= 12u;
+ else if (--y >= 100u)
+ y += 100;
+ d += y + (y >> 2) + 2u; /* year-related share */
+ d += (m * 83u + 16u) >> 5; /* month-related share */
+
+ /* The next step combines the exact division by modular inverse
+ * with the (mod 7) step in such way that no true division and
+ * only one multiplication is needed. The multiplier is
+ * M <- ceil((3*8)/7 * 2**29)
+ * and combines multiplication by invmod(5, 7) -> 3 and modulus
+ * by 7 transformation to (mod 8) in one step.
+ * Note that 252 == 0 (mod 7) and that 'd' is less than 185,
+ * so the number to invert and reduce is strictly positive. In
+ * the end, 'c' is number of centuries since start of a great
+ * cycle and must be in [0..3] or we had bad input.
+ */
+ c = (((252u + wd - d) * 0x6db6db6eU) >> 29) & 7u;
+ if (c >= 4)
+ return FALSE;
+ /* undo calendar base shift now */
+ if ((m > 9u) && (++y >= 100u)) {
+ y -= 100u;
+ c = (c + 1u) & 3u;
+ }
+ /* combine year with centuries & map to [1970..2369] */
+ y += (c * 100u);
+ clock_time->year = (int)y + ((y < 370u) ? 2000 : 1600);
+ return TRUE;
+}
+
static u_long
convert_rawdcf(
unsigned char *buffer,
@@ -288,6 +340,9 @@ convert_rawdcf(
clock_time->year = ext_bf(buffer, DCF_Y10, dcfprm->zerobits);
clock_time->year = TIMES10(clock_time->year) + ext_bf(buffer, DCF_Y1, dcfprm->zerobits);
+ if (!zeller_expand(clock_time, ext_bf(buffer, DCF_DW, dcfprm->zerobits)))
+ return CVT_FAIL|CVT_BADFMT;
+
switch (ext_bf(buffer, DCF_Z, dcfprm->zerobits))
{
case DCF_Z_MET: