summaryrefslogtreecommitdiff
path: root/parseutil
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-12-02 09:01:21 +0000
committer <>2014-12-04 16:11:25 +0000
commitbdab5265fcbf3f472545073a23f8999749a9f2b9 (patch)
treec6018dd03dea906f8f1fb5f105f05b71a7dc250a /parseutil
downloadntp-bdab5265fcbf3f472545073a23f8999749a9f2b9.tar.gz
Imported from /home/lorry/working-area/delta_ntp/ntp-dev-4.2.7p482.tar.gz.ntp-dev-4.2.7p482
Diffstat (limited to 'parseutil')
-rw-r--r--parseutil/Makefile.am24
-rw-r--r--parseutil/Makefile.in752
-rw-r--r--parseutil/README16
-rw-r--r--parseutil/dcfd.c1872
-rw-r--r--parseutil/testdcf.c541
5 files changed, 3205 insertions, 0 deletions
diff --git a/parseutil/Makefile.am b/parseutil/Makefile.am
new file mode 100644
index 0000000..99fb3d1
--- /dev/null
+++ b/parseutil/Makefile.am
@@ -0,0 +1,24 @@
+NULL=
+
+BUILT_SOURCES =
+CLEANFILES =
+noinst_PROGRAMS = @TESTDCF@ @DCFD@
+EXTRA_PROGRAMS = testdcf dcfd
+
+AM_CFLAGS = $(CFLAGS_NTP)
+
+AM_CPPFLAGS = $(NTP_INCS)
+AM_CPPFLAGS += $(CPPFLAGS_NTP)
+
+LDADD = ../libntp/libntp.a $(LDADD_LIBNTP) $(LIBM)
+
+ETAGS_ARGS = Makefile.am
+DISTCLEANFILES = $(EXTRA_PROGRAMS)
+
+check-local: @DCFD@
+ case "$(noinst_PROGRAMS)" in \
+ *dcfd*) ./dcfd -Y ;; \
+ esac
+
+include $(top_srcdir)/depsver.mf
+include $(top_srcdir)/includes.mf
diff --git a/parseutil/Makefile.in b/parseutil/Makefile.in
new file mode 100644
index 0000000..963fd08
--- /dev/null
+++ b/parseutil/Makefile.in
@@ -0,0 +1,752 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+EXTRA_PROGRAMS = testdcf$(EXEEXT) dcfd$(EXEEXT)
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(top_srcdir)/depsver.mf $(top_srcdir)/includes.mf
+subdir = parseutil
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/sntp/libopts/m4/libopts.m4 \
+ $(top_srcdir)/sntp/libopts/m4/stdnoreturn.m4 \
+ $(top_srcdir)/sntp/libevent/m4/openldap-thread-check.m4 \
+ $(top_srcdir)/sntp/libevent/m4/openldap.m4 \
+ $(top_srcdir)/sntp/m4/define_dir.m4 \
+ $(top_srcdir)/sntp/m4/hms_search_lib.m4 \
+ $(top_srcdir)/sntp/m4/libtool.m4 \
+ $(top_srcdir)/sntp/m4/ltoptions.m4 \
+ $(top_srcdir)/sntp/m4/ltsugar.m4 \
+ $(top_srcdir)/sntp/m4/ltversion.m4 \
+ $(top_srcdir)/sntp/m4/lt~obsolete.m4 \
+ $(top_srcdir)/sntp/m4/ntp_cacheversion.m4 \
+ $(top_srcdir)/sntp/m4/ntp_compiler.m4 \
+ $(top_srcdir)/sntp/m4/ntp_crosscompile.m4 \
+ $(top_srcdir)/sntp/m4/ntp_debug.m4 \
+ $(top_srcdir)/sntp/m4/ntp_dir_sep.m4 \
+ $(top_srcdir)/sntp/m4/ntp_facilitynames.m4 \
+ $(top_srcdir)/sntp/m4/ntp_googletest.m4 \
+ $(top_srcdir)/sntp/m4/ntp_ipv6.m4 \
+ $(top_srcdir)/sntp/m4/ntp_lib_m.m4 \
+ $(top_srcdir)/sntp/m4/ntp_libevent.m4 \
+ $(top_srcdir)/sntp/m4/ntp_libntp.m4 \
+ $(top_srcdir)/sntp/m4/ntp_lineeditlibs.m4 \
+ $(top_srcdir)/sntp/m4/ntp_locinfo.m4 \
+ $(top_srcdir)/sntp/m4/ntp_openssl.m4 \
+ $(top_srcdir)/sntp/m4/ntp_pkg_config.m4 \
+ $(top_srcdir)/sntp/m4/ntp_prog_cc.m4 \
+ $(top_srcdir)/sntp/m4/ntp_rlimit.m4 \
+ $(top_srcdir)/sntp/m4/ntp_sntp.m4 \
+ $(top_srcdir)/sntp/m4/ntp_ver_suffix.m4 \
+ $(top_srcdir)/sntp/m4/ntp_vpathhack.m4 \
+ $(top_srcdir)/sntp/m4/os_cflags.m4 \
+ $(top_srcdir)/sntp/m4/snprintf.m4 \
+ $(top_srcdir)/sntp/m4/version.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+PROGRAMS = $(noinst_PROGRAMS)
+dcfd_SOURCES = dcfd.c
+dcfd_OBJECTS = dcfd.$(OBJEXT)
+dcfd_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+dcfd_DEPENDENCIES = ../libntp/libntp.a $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+testdcf_SOURCES = testdcf.c
+testdcf_OBJECTS = testdcf.$(OBJEXT)
+testdcf_LDADD = $(LDADD)
+testdcf_DEPENDENCIES = ../libntp/libntp.a $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/sntp/libevent/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = dcfd.c testdcf.c
+DIST_SOURCES = dcfd.c testdcf.c
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CALC_TICKADJ_DB = @CALC_TICKADJ_DB@
+CALC_TICKADJ_DL = @CALC_TICKADJ_DL@
+CALC_TICKADJ_DS = @CALC_TICKADJ_DS@
+CALC_TICKADJ_MS = @CALC_TICKADJ_MS@
+CALC_TICKADJ_NI = @CALC_TICKADJ_NI@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CFLAGS_NTP = @CFLAGS_NTP@
+CHUTEST = @CHUTEST@
+CONFIG_SHELL = @CONFIG_SHELL@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPFLAGS_NTP = @CPPFLAGS_NTP@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DCFD = @DCFD@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EDITLINE_LIBS = @EDITLINE_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GTEST_CONFIG = @GTEST_CONFIG@
+GTEST_CPPFLAGS = @GTEST_CPPFLAGS@
+GTEST_CXXFLAGS = @GTEST_CXXFLAGS@
+GTEST_LDFLAGS = @GTEST_LDFLAGS@
+GTEST_LIBS = @GTEST_LIBS@
+HAVE_INLINE = @HAVE_INLINE@
+HAVE_RLIMIT_MEMLOCK = @HAVE_RLIMIT_MEMLOCK@
+HAVE_RLIMIT_STACK = @HAVE_RLIMIT_STACK@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDADD_LIBNTP = @LDADD_LIBNTP@
+LDADD_NLIST = @LDADD_NLIST@
+LDADD_NTP = @LDADD_NTP@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_NTP = @LDFLAGS_NTP@
+LIBISC_PTHREADS_NOTHREADS = @LIBISC_PTHREADS_NOTHREADS@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBOPTS_CFLAGS = @LIBOPTS_CFLAGS@
+LIBOPTS_DIR = @LIBOPTS_DIR@
+LIBOPTS_LDADD = @LIBOPTS_LDADD@
+LIBPARSE = @LIBPARSE@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBTOOL_DEPS = @LIBTOOL_DEPS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LSCF = @LSCF@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_ADJTIMED = @MAKE_ADJTIMED@
+MAKE_CHECK_LAYOUT = @MAKE_CHECK_LAYOUT@
+MAKE_CHECK_Y2K = @MAKE_CHECK_Y2K@
+MAKE_LIBNTPSIM = @MAKE_LIBNTPSIM@
+MAKE_LIBPARSE = @MAKE_LIBPARSE@
+MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
+MAKE_NTPDSIM = @MAKE_NTPDSIM@
+MAKE_NTPSNMPD = @MAKE_NTPSNMPD@
+MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
+MAKE_TICKADJ = @MAKE_TICKADJ@
+MAKE_TIMETRIM = @MAKE_TIMETRIM@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MANTAGFMT = @MANTAGFMT@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTPDATE_DB = @NTPDATE_DB@
+NTPDATE_DL = @NTPDATE_DL@
+NTPDATE_DS = @NTPDATE_DS@
+NTPDATE_MS = @NTPDATE_MS@
+NTPDATE_NI = @NTPDATE_NI@
+NTPDC_DB = @NTPDC_DB@
+NTPDC_DL = @NTPDC_DL@
+NTPDC_DS = @NTPDC_DS@
+NTPDC_MS = @NTPDC_MS@
+NTPDC_NI = @NTPDC_NI@
+NTPDSIM_DB = @NTPDSIM_DB@
+NTPDSIM_DL = @NTPDSIM_DL@
+NTPDSIM_DS = @NTPDSIM_DS@
+NTPDSIM_MS = @NTPDSIM_MS@
+NTPDSIM_NI = @NTPDSIM_NI@
+NTPD_DB = @NTPD_DB@
+NTPD_DL = @NTPD_DL@
+NTPD_DS = @NTPD_DS@
+NTPD_MS = @NTPD_MS@
+NTPD_NI = @NTPD_NI@
+NTPQ_DB = @NTPQ_DB@
+NTPQ_DL = @NTPQ_DL@
+NTPQ_DS = @NTPQ_DS@
+NTPQ_MS = @NTPQ_MS@
+NTPQ_NI = @NTPQ_NI@
+NTPSNMPD_DB = @NTPSNMPD_DB@
+NTPSNMPD_DL = @NTPSNMPD_DL@
+NTPSNMPD_DS = @NTPSNMPD_DS@
+NTPSNMPD_MS = @NTPSNMPD_MS@
+NTPSNMPD_NI = @NTPSNMPD_NI@
+NTPSWEEP_DB = @NTPSWEEP_DB@
+NTPSWEEP_DL = @NTPSWEEP_DL@
+NTPSWEEP_DS = @NTPSWEEP_DS@
+NTPSWEEP_MS = @NTPSWEEP_MS@
+NTPSWEEP_NI = @NTPSWEEP_NI@
+NTPTIME_DB = @NTPTIME_DB@
+NTPTIME_DL = @NTPTIME_DL@
+NTPTIME_DS = @NTPTIME_DS@
+NTPTIME_MS = @NTPTIME_MS@
+NTPTIME_NI = @NTPTIME_NI@
+NTPTRACE_DB = @NTPTRACE_DB@
+NTPTRACE_DL = @NTPTRACE_DL@
+NTPTRACE_DS = @NTPTRACE_DS@
+NTPTRACE_MS = @NTPTRACE_MS@
+NTPTRACE_NI = @NTPTRACE_NI@
+NTP_KEYGEN_DB = @NTP_KEYGEN_DB@
+NTP_KEYGEN_DL = @NTP_KEYGEN_DL@
+NTP_KEYGEN_DS = @NTP_KEYGEN_DS@
+NTP_KEYGEN_MS = @NTP_KEYGEN_MS@
+NTP_KEYGEN_NI = @NTP_KEYGEN_NI@
+NTP_KEYSDIR = @NTP_KEYSDIR@
+NTP_WAIT_DB = @NTP_WAIT_DB@
+NTP_WAIT_DL = @NTP_WAIT_DL@
+NTP_WAIT_DS = @NTP_WAIT_DS@
+NTP_WAIT_MS = @NTP_WAIT_MS@
+NTP_WAIT_NI = @NTP_WAIT_NI@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_NET_SNMP_CONFIG = @PATH_NET_SNMP_CONFIG@
+PATH_PERL = @PATH_PERL@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PATH_TEST = @PATH_TEST@
+PERLLIBDIR = @PERLLIBDIR@
+PKG_CONFIG = @PKG_CONFIG@
+POSIX_SHELL = @POSIX_SHELL@
+PROPDELAY = @PROPDELAY@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMP_CFLAGS = @SNMP_CFLAGS@
+SNMP_CPPFLAGS = @SNMP_CPPFLAGS@
+SNMP_LIBS = @SNMP_LIBS@
+SNTP = @SNTP@
+SNTP_DB = @SNTP_DB@
+SNTP_DL = @SNTP_DL@
+SNTP_DS = @SNTP_DS@
+SNTP_MS = @SNTP_MS@
+SNTP_NI = @SNTP_NI@
+STDNORETURN_H = @STDNORETURN_H@
+STRIP = @STRIP@
+TESTDCF = @TESTDCF@
+TICKADJ_DB = @TICKADJ_DB@
+TICKADJ_DL = @TICKADJ_DL@
+TICKADJ_DS = @TICKADJ_DS@
+TICKADJ_MS = @TICKADJ_MS@
+TICKADJ_NI = @TICKADJ_NI@
+TIMETRIM_DB = @TIMETRIM_DB@
+TIMETRIM_DL = @TIMETRIM_DL@
+TIMETRIM_DS = @TIMETRIM_DS@
+TIMETRIM_MS = @TIMETRIM_MS@
+TIMETRIM_NI = @TIMETRIM_NI@
+VERSION = @VERSION@
+VER_SUFFIX = @VER_SUFFIX@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+NULL =
+BUILT_SOURCES = .deps-ver
+CLEANFILES = .deps-ver
+noinst_PROGRAMS = @TESTDCF@ @DCFD@
+AM_CFLAGS = $(CFLAGS_NTP)
+AM_CPPFLAGS = $(NTP_INCS) $(CPPFLAGS_NTP)
+LDADD = ../libntp/libntp.a $(LDADD_LIBNTP) $(LIBM)
+ETAGS_ARGS = Makefile.am
+DISTCLEANFILES = $(EXTRA_PROGRAMS)
+NTP_INCS = -I$(top_srcdir)/include -I$(top_srcdir)/lib/isc/include \
+ -I$(top_srcdir)/lib/isc/$(LIBISC_PTHREADS_NOTHREADS)/include \
+ -I$(top_srcdir)/lib/isc/unix/include
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/depsver.mf $(top_srcdir)/includes.mf $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign parseutil/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign parseutil/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+dcfd$(EXEEXT): $(dcfd_OBJECTS) $(dcfd_DEPENDENCIES)
+ @rm -f dcfd$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(dcfd_OBJECTS) $(dcfd_LDADD) $(LIBS)
+testdcf$(EXEEXT): $(testdcf_OBJECTS) $(testdcf_DEPENDENCIES)
+ @rm -f testdcf$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(testdcf_OBJECTS) $(testdcf_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dcfd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testdcf.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: all check check-am install install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am check-local clean \
+ clean-generic clean-libtool clean-noinstPROGRAMS ctags \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am
+
+
+check-local: @DCFD@
+ case "$(noinst_PROGRAMS)" in \
+ *dcfd*) ./dcfd -Y ;; \
+ esac
+$(DEPDIR)/deps-ver: $(top_srcdir)/deps-ver
+ @[ -f $@ ] || \
+ cp $(top_srcdir)/deps-ver $@
+ @[ -w $@ ] || \
+ chmod ug+w $@
+ @cmp $(top_srcdir)/deps-ver $@ > /dev/null || ( \
+ $(MAKE) $(AM_MAKEFLAGS) clean && \
+ echo -n "Prior $(subdir)/$(DEPDIR) version " && \
+ cat $@ && \
+ rm -rf $(DEPDIR) && \
+ mkdir $(DEPDIR) && \
+ case "$(top_builddir)" in \
+ .) \
+ ./config.status Makefile depfiles \
+ ;; \
+ *) \
+ cd "$(top_builddir)" && \
+ ./config.status $(subdir)/Makefile depfiles && \
+ cd $(subdir) \
+ ;; \
+ esac && \
+ echo -n "Cleaned $(subdir)/$(DEPDIR) version " && \
+ cat $(top_srcdir)/deps-ver \
+ )
+ cp $(top_srcdir)/deps-ver $@
+
+.deps-ver: $(top_srcdir)/deps-ver
+ @[ ! -d $(DEPDIR) ] || $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/deps-ver
+ @touch $@
+
+#
+# depsver.mf included in Makefile.am for directories with .deps
+#
+# When building in the same directory with sources that change over
+# time, such as when tracking using bk, the .deps files can become
+# stale with respect to moved, deleted, or superceded headers. Most
+# commonly, this would exhibit as make reporting a failure to make a
+# header file which is no longer in the location given. To address
+# this issue, we use a deps-ver file which is updated with each change
+# that breaks old .deps files. A copy of deps-ver is made into
+# $(DEPDIR) if not already present. If $(DEPDIR)/deps-ver is present
+# with different contents than deps-ver, we make clean to ensure all
+# .o files built before the incompatible change are rebuilt along with
+# their updated .deps files, then remove $(DEPDIR) and recreate it as
+# empty stubs.
+#
+# It is normal when configured with --disable-dependency-tracking for
+# the DEPDIR to not have been created. For this reason, we use the
+# intermediate target .deps-ver, which invokes make recursively if
+# DEPDIR exists.
+#
+# If you modify depsver.mf, please make the changes to the master
+# copy, the one in sntp is copied by the bootstrap script from it.
+#
+# This comment block follows rather than leads the related code so that
+# it stays with it in the generated Makefile.in and Makefile.
+#
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/parseutil/README b/parseutil/README
new file mode 100644
index 0000000..8bc5140
--- /dev/null
+++ b/parseutil/README
@@ -0,0 +1,16 @@
+This directory contains some DCF77 related programs.
+They have not yet fully been ported to architectures other than Sun with
+SunOS 4.x. So if you want to try them you are on your own - a little
+porting may be necessary.
+
+parsetest: simple parse streams module test
+ Works only under SunOS with parse Streams Module loaded
+ and Meinberg-Clocks
+
+testdcf: simple DCF77 raw impulse test program via 50Baud RS232
+
+dcfd: simple DCF77 raw impulse receiver with NTP loopfilter
+ mechanics for synchronisation (allows DCF77 synchronisation
+ without network code in a nutshell)
+
+Frank Kardel
diff --git a/parseutil/dcfd.c b/parseutil/dcfd.c
new file mode 100644
index 0000000..0db94c0
--- /dev/null
+++ b/parseutil/dcfd.c
@@ -0,0 +1,1872 @@
+/*
+ * /src/NTP/REPOSITORY/ntp4-dev/parseutil/dcfd.c,v 4.18 2005/10/07 22:08:18 kardel RELEASE_20051008_A
+ *
+ * dcfd.c,v 4.18 2005/10/07 22:08:18 kardel RELEASE_20051008_A
+ *
+ * DCF77 100/200ms pulse synchronisation daemon program (via 50Baud serial line)
+ *
+ * Features:
+ * DCF77 decoding
+ * simple NTP loopfilter logic for local clock
+ * interactive display for debugging
+ *
+ * Lacks:
+ * Leap second handling (at that level you should switch to NTP Version 4 - really!)
+ *
+ * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
+ * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <syslog.h>
+#include <time.h>
+
+/*
+ * NTP compilation environment
+ */
+#include "ntp_stdlib.h"
+#include "ntpd.h" /* indirectly include ntp.h to get YEAR_PIVOT Y2KFixes */
+
+/*
+ * select which terminal handling to use (currently only SysV variants)
+ */
+#if defined(HAVE_TERMIOS_H) || defined(STREAM)
+#include <termios.h>
+#define TTY_GETATTR(_FD_, _ARG_) tcgetattr((_FD_), (_ARG_))
+#define TTY_SETATTR(_FD_, _ARG_) tcsetattr((_FD_), TCSANOW, (_ARG_))
+#else /* not HAVE_TERMIOS_H || STREAM */
+# if defined(HAVE_TERMIO_H) || defined(HAVE_SYSV_TTYS)
+# include <termio.h>
+# define TTY_GETATTR(_FD_, _ARG_) ioctl((_FD_), TCGETA, (_ARG_))
+# define TTY_SETATTR(_FD_, _ARG_) ioctl((_FD_), TCSETAW, (_ARG_))
+# endif/* HAVE_TERMIO_H || HAVE_SYSV_TTYS */
+#endif /* not HAVE_TERMIOS_H || STREAM */
+
+
+#ifndef TTY_GETATTR
+#include "Bletch: MUST DEFINE ONE OF 'HAVE_TERMIOS_H' or 'HAVE_TERMIO_H'"
+#endif
+
+#ifndef days_per_year
+#define days_per_year(_x_) (((_x_) % 4) ? 365 : (((_x_) % 400) ? 365 : 366))
+#endif
+
+#define timernormalize(_a_) \
+ if ((_a_)->tv_usec >= 1000000) \
+ { \
+ (_a_)->tv_sec += (_a_)->tv_usec / 1000000; \
+ (_a_)->tv_usec = (_a_)->tv_usec % 1000000; \
+ } \
+ if ((_a_)->tv_usec < 0) \
+ { \
+ (_a_)->tv_sec -= 1 + (-(_a_)->tv_usec / 1000000); \
+ (_a_)->tv_usec = 999999 - (-(_a_)->tv_usec - 1); \
+ }
+
+#ifdef timeradd
+#undef timeradd
+#endif
+#define timeradd(_a_, _b_) \
+ (_a_)->tv_sec += (_b_)->tv_sec; \
+ (_a_)->tv_usec += (_b_)->tv_usec; \
+ timernormalize((_a_))
+
+#ifdef timersub
+#undef timersub
+#endif
+#define timersub(_a_, _b_) \
+ (_a_)->tv_sec -= (_b_)->tv_sec; \
+ (_a_)->tv_usec -= (_b_)->tv_usec; \
+ timernormalize((_a_))
+
+/*
+ * debug macros
+ */
+#define PRINTF if (interactive) printf
+#define LPRINTF if (interactive && loop_filter_debug) printf
+
+#ifdef DEBUG
+#define dprintf(_x_) LPRINTF _x_
+#else
+#define dprintf(_x_)
+#endif
+
+#ifdef DECL_ERRNO
+ extern int errno;
+#endif
+
+static char *revision = "4.18";
+
+/*
+ * display received data (avoids also detaching from tty)
+ */
+static int interactive = 0;
+
+/*
+ * display loopfilter (clock control) variables
+ */
+static int loop_filter_debug = 0;
+
+/*
+ * do not set/adjust system time
+ */
+static int no_set = 0;
+
+/*
+ * time that passes between start of DCF impulse and time stamping (fine
+ * adjustment) in microseconds (receiver/OS dependent)
+ */
+#define DEFAULT_DELAY 230000 /* rough estimate */
+
+/*
+ * The two states we can be in - eithe we receive nothing
+ * usable or we have the correct time
+ */
+#define NO_SYNC 0x01
+#define SYNC 0x02
+
+static int sync_state = NO_SYNC;
+static time_t last_sync;
+
+static unsigned long ticks = 0;
+
+static char pat[] = "-\\|/";
+
+#define LINES (24-2) /* error lines after which the two headlines are repeated */
+
+#define MAX_UNSYNC (10*60) /* allow synchronisation loss for 10 minutes */
+#define NOTICE_INTERVAL (20*60) /* mention missing synchronisation every 20 minutes */
+
+/*
+ * clock adjustment PLL - see NTP protocol spec (RFC1305) for details
+ */
+
+#define USECSCALE 10
+#define TIMECONSTANT 2
+#define ADJINTERVAL 0
+#define FREQ_WEIGHT 18
+#define PHASE_WEIGHT 7
+#define MAX_DRIFT 0x3FFFFFFF
+
+#define R_SHIFT(_X_, _Y_) (((_X_) < 0) ? -(-(_X_) >> (_Y_)) : ((_X_) >> (_Y_)))
+
+static long max_adj_offset_usec = 128000;
+
+static long clock_adjust = 0; /* current adjustment value (usec * 2^USECSCALE) */
+static long accum_drift = 0; /* accumulated drift value (usec / ADJINTERVAL) */
+static long adjustments = 0;
+static char skip_adjust = 1; /* discard first adjustment (bad samples) */
+
+/*
+ * DCF77 state flags
+ */
+#define DCFB_ANNOUNCE 0x0001 /* switch time zone warning (DST switch) */
+#define DCFB_DST 0x0002 /* DST in effect */
+#define DCFB_LEAP 0x0004 /* LEAP warning (1 hour prior to occurrence) */
+#define DCFB_ALTERNATE 0x0008 /* alternate antenna used */
+
+struct clocktime /* clock time broken up from time code */
+{
+ long wday; /* Day of week: 1: Monday - 7: Sunday */
+ long day;
+ long month;
+ long year;
+ long hour;
+ long minute;
+ long second;
+ long usecond;
+ long utcoffset; /* in minutes */
+ long flags; /* current clock status (DCF77 state flags) */
+};
+
+typedef struct clocktime clocktime_t;
+
+/*
+ * (usually) quick constant multiplications
+ */
+#define TIMES10(_X_) (((_X_) << 3) + ((_X_) << 1)) /* *8 + *2 */
+#define TIMES24(_X_) (((_X_) << 4) + ((_X_) << 3)) /* *16 + *8 */
+#define TIMES60(_X_) ((((_X_) << 4) - (_X_)) << 2) /* *(16 - 1) *4 */
+/*
+ * generic l_abs() function
+ */
+#define l_abs(_x_) (((_x_) < 0) ? -(_x_) : (_x_))
+
+/*
+ * conversion related return/error codes
+ */
+#define CVT_MASK 0x0000000F /* conversion exit code */
+#define CVT_NONE 0x00000001 /* format not applicable */
+#define CVT_FAIL 0x00000002 /* conversion failed - error code returned */
+#define CVT_OK 0x00000004 /* conversion succeeded */
+#define CVT_BADFMT 0x00000010 /* general format error - (unparsable) */
+#define CVT_BADDATE 0x00000020 /* invalid date */
+#define CVT_BADTIME 0x00000040 /* invalid time */
+
+/*
+ * DCF77 raw time code
+ *
+ * From "Zur Zeit", Physikalisch-Technische Bundesanstalt (PTB), Braunschweig
+ * und Berlin, Maerz 1989
+ *
+ * Timecode transmission:
+ * AM:
+ * time marks are send every second except for the second before the
+ * next minute mark
+ * time marks consist of a reduction of transmitter power to 25%
+ * of the nominal level
+ * the falling edge is the time indication (on time)
+ * time marks of a 100ms duration constitute a logical 0
+ * time marks of a 200ms duration constitute a logical 1
+ * FM:
+ * see the spec. (basically a (non-)inverted psuedo random phase shift)
+ *
+ * Encoding:
+ * Second Contents
+ * 0 - 10 AM: free, FM: 0
+ * 11 - 14 free
+ * 15 R - alternate antenna
+ * 16 A1 - expect zone change (1 hour before)
+ * 17 - 18 Z1,Z2 - time zone
+ * 0 0 illegal
+ * 0 1 MEZ (MET)
+ * 1 0 MESZ (MED, MET DST)
+ * 1 1 illegal
+ * 19 A2 - expect leap insertion/deletion (1 hour before)
+ * 20 S - start of time code (1)
+ * 21 - 24 M1 - BCD (lsb first) Minutes
+ * 25 - 27 M10 - BCD (lsb first) 10 Minutes
+ * 28 P1 - Minute Parity (even)
+ * 29 - 32 H1 - BCD (lsb first) Hours
+ * 33 - 34 H10 - BCD (lsb first) 10 Hours
+ * 35 P2 - Hour Parity (even)
+ * 36 - 39 D1 - BCD (lsb first) Days
+ * 40 - 41 D10 - BCD (lsb first) 10 Days
+ * 42 - 44 DW - BCD (lsb first) day of week (1: Monday -> 7: Sunday)
+ * 45 - 49 MO - BCD (lsb first) Month
+ * 50 MO0 - 10 Months
+ * 51 - 53 Y1 - BCD (lsb first) Years
+ * 54 - 57 Y10 - BCD (lsb first) 10 Years
+ * 58 P3 - Date Parity (even)
+ * 59 - usually missing (minute indication), except for leap insertion
+ */
+
+/*-----------------------------------------------------------------------
+ * conversion table to map DCF77 bit stream into data fields.
+ * Encoding:
+ * Each field of the DCF77 code is described with two adjacent entries in
+ * this table. The first entry specifies the offset into the DCF77 data stream
+ * while the length is given as the difference between the start index and
+ * the start index of the following field.
+ */
+static struct rawdcfcode
+{
+ char offset; /* start bit */
+} rawdcfcode[] =
+{
+ { 0 }, { 15 }, { 16 }, { 17 }, { 19 }, { 20 }, { 21 }, { 25 }, { 28 }, { 29 },
+ { 33 }, { 35 }, { 36 }, { 40 }, { 42 }, { 45 }, { 49 }, { 50 }, { 54 }, { 58 }, { 59 }
+};
+
+/*-----------------------------------------------------------------------
+ * symbolic names for the fields of DCF77 describes in "rawdcfcode".
+ * see comment above for the structure of the DCF77 data
+ */
+#define DCF_M 0
+#define DCF_R 1
+#define DCF_A1 2
+#define DCF_Z 3
+#define DCF_A2 4
+#define DCF_S 5
+#define DCF_M1 6
+#define DCF_M10 7
+#define DCF_P1 8
+#define DCF_H1 9
+#define DCF_H10 10
+#define DCF_P2 11
+#define DCF_D1 12
+#define DCF_D10 13
+#define DCF_DW 14
+#define DCF_MO 15
+#define DCF_MO0 16
+#define DCF_Y1 17
+#define DCF_Y10 18
+#define DCF_P3 19
+
+/*-----------------------------------------------------------------------
+ * parity field table (same encoding as rawdcfcode)
+ * This table describes the sections of the DCF77 code that are
+ * parity protected
+ */
+static struct partab
+{
+ char offset; /* start bit of parity field */
+} partab[] =
+{
+ { 21 }, { 29 }, { 36 }, { 59 }
+};
+
+/*-----------------------------------------------------------------------
+ * offsets for parity field descriptions
+ */
+#define DCF_P_P1 0
+#define DCF_P_P2 1
+#define DCF_P_P3 2
+
+/*-----------------------------------------------------------------------
+ * legal values for time zone information
+ */
+#define DCF_Z_MET 0x2
+#define DCF_Z_MED 0x1
+
+/*-----------------------------------------------------------------------
+ * symbolic representation if the DCF77 data stream
+ */
+static struct dcfparam
+{
+ unsigned char onebits[60];
+ unsigned char zerobits[60];
+} dcfparam =
+{
+ "###############RADMLS1248124P124812P1248121241248112481248P", /* 'ONE' representation */
+ "--------------------s-------p------p----------------------p" /* 'ZERO' representation */
+};
+
+/*-----------------------------------------------------------------------
+ * extract a bitfield from DCF77 datastream
+ * All numeric fields are LSB first.
+ * buf holds a pointer to a DCF77 data buffer in symbolic
+ * representation
+ * idx holds the index to the field description in rawdcfcode
+ */
+static unsigned long
+ext_bf(
+ register unsigned char *buf,
+ register int idx
+ )
+{
+ register unsigned long sum = 0;
+ register int i, first;
+
+ first = rawdcfcode[idx].offset;
+
+ for (i = rawdcfcode[idx+1].offset - 1; i >= first; i--)
+ {
+ sum <<= 1;
+ sum |= (buf[i] != dcfparam.zerobits[i]);
+ }
+ return sum;
+}
+
+/*-----------------------------------------------------------------------
+ * check even parity integrity for a bitfield
+ *
+ * buf holds a pointer to a DCF77 data buffer in symbolic
+ * representation
+ * idx holds the index to the field description in partab
+ */
+static unsigned
+pcheck(
+ register unsigned char *buf,
+ register int idx
+ )
+{
+ register int i,last;
+ register unsigned psum = 1;
+
+ last = partab[idx+1].offset;
+
+ for (i = partab[idx].offset; i < last; i++)
+ psum ^= (buf[i] != dcfparam.zerobits[i]);
+
+ return psum;
+}
+
+/*-----------------------------------------------------------------------
+ * convert a DCF77 data buffer into wall clock time + flags
+ *
+ * buffer holds a pointer to a DCF77 data buffer in symbolic
+ * representation
+ * size describes the length of DCF77 information in bits (represented
+ * as chars in symbolic notation
+ * clock points to a wall clock time description of the DCF77 data (result)
+ */
+static unsigned long
+convert_rawdcf(
+ unsigned char *buffer,
+ int size,
+ clocktime_t *clock_time
+ )
+{
+ if (size < 57)
+ {
+ PRINTF("%-30s", "*** INCOMPLETE");
+ return CVT_NONE;
+ }
+
+ /*
+ * check Start and Parity bits
+ */
+ if ((ext_bf(buffer, DCF_S) == 1) &&
+ pcheck(buffer, DCF_P_P1) &&
+ pcheck(buffer, DCF_P_P2) &&
+ pcheck(buffer, DCF_P_P3))
+ {
+ /*
+ * buffer OK - extract all fields and build wall clock time from them
+ */
+
+ clock_time->flags = 0;
+ clock_time->usecond= 0;
+ clock_time->second = 0;
+ clock_time->minute = ext_bf(buffer, DCF_M10);
+ clock_time->minute = TIMES10(clock_time->minute) + ext_bf(buffer, DCF_M1);
+ clock_time->hour = ext_bf(buffer, DCF_H10);
+ clock_time->hour = TIMES10(clock_time->hour) + ext_bf(buffer, DCF_H1);
+ clock_time->day = ext_bf(buffer, DCF_D10);
+ clock_time->day = TIMES10(clock_time->day) + ext_bf(buffer, DCF_D1);
+ clock_time->month = ext_bf(buffer, DCF_MO0);
+ clock_time->month = TIMES10(clock_time->month) + ext_bf(buffer, DCF_MO);
+ clock_time->year = ext_bf(buffer, DCF_Y10);
+ clock_time->year = TIMES10(clock_time->year) + ext_bf(buffer, DCF_Y1);
+ clock_time->wday = ext_bf(buffer, DCF_DW);
+
+ /*
+ * determine offset to UTC by examining the time zone
+ */
+ switch (ext_bf(buffer, DCF_Z))
+ {
+ case DCF_Z_MET:
+ clock_time->utcoffset = -60;
+ break;
+
+ case DCF_Z_MED:
+ clock_time->flags |= DCFB_DST;
+ clock_time->utcoffset = -120;
+ break;
+
+ default:
+ PRINTF("%-30s", "*** BAD TIME ZONE");
+ return CVT_FAIL|CVT_BADFMT;
+ }
+
+ /*
+ * extract various warnings from DCF77
+ */
+ if (ext_bf(buffer, DCF_A1))
+ clock_time->flags |= DCFB_ANNOUNCE;
+
+ if (ext_bf(buffer, DCF_A2))
+ clock_time->flags |= DCFB_LEAP;
+
+ if (ext_bf(buffer, DCF_R))
+ clock_time->flags |= DCFB_ALTERNATE;
+
+ return CVT_OK;
+ }
+ else
+ {
+ /*
+ * bad format - not for us
+ */
+ PRINTF("%-30s", "*** BAD FORMAT (invalid/parity)");
+ return CVT_FAIL|CVT_BADFMT;
+ }
+}
+
+/*-----------------------------------------------------------------------
+ * raw dcf input routine - fix up 50 baud
+ * characters for 1/0 decision
+ */
+static unsigned long
+cvt_rawdcf(
+ unsigned char *buffer,
+ int size,
+ clocktime_t *clock_time
+ )
+{
+ register unsigned char *s = buffer;
+ register unsigned char *e = buffer + size;
+ register unsigned char *b = dcfparam.onebits;
+ register unsigned char *c = dcfparam.zerobits;
+ register unsigned rtc = CVT_NONE;
+ register unsigned int i, lowmax, highmax, cutoff, span;
+#define BITS 9
+ unsigned char histbuf[BITS];
+ /*
+ * the input buffer contains characters with runs of consecutive
+ * bits set. These set bits are an indication of the DCF77 pulse
+ * length. We assume that we receive the pulse at 50 Baud. Thus
+ * a 100ms pulse would generate a 4 bit train (20ms per bit and
+ * start bit)
+ * a 200ms pulse would create all zeroes (and probably a frame error)
+ *
+ * The basic idea is that on corret reception we must have two
+ * maxima in the pulse length distribution histogram. (one for
+ * the zero representing pulses and one for the one representing
+ * pulses)
+ * There will always be ones in the datastream, thus we have to see
+ * two maxima.
+ * The best point to cut for a 1/0 decision is the minimum between those
+ * between the maxima. The following code tries to find this cutoff point.
+ */
+
+ /*
+ * clear histogram buffer
+ */
+ for (i = 0; i < BITS; i++)
+ {
+ histbuf[i] = 0;
+ }
+
+ cutoff = 0;
+ lowmax = 0;
+
+ /*
+ * convert sequences of set bits into bits counts updating
+ * the histogram alongway
+ */
+ while (s < e)
+ {
+ register unsigned int ch = *s ^ 0xFF;
+ /*
+ * check integrity and update histogramm
+ */
+ if (!((ch+1) & ch) || !*s)
+ {
+ /*
+ * character ok
+ */
+ for (i = 0; ch; i++)
+ {
+ ch >>= 1;
+ }
+
+ *s = i;
+ histbuf[i]++;
+ cutoff += i;
+ lowmax++;
+ }
+ else
+ {
+ /*
+ * invalid character (no consecutive bit sequence)
+ */
+ dprintf(("parse: cvt_rawdcf: character check for 0x%x@%ld FAILED\n",
+ (u_int)*s, (long)(s - buffer)));
+ *s = (unsigned char)~0;
+ rtc = CVT_FAIL|CVT_BADFMT;
+ }
+ s++;
+ }
+
+ /*
+ * first cutoff estimate (average bit count - must be between both
+ * maxima)
+ */
+ if (lowmax)
+ {
+ cutoff /= lowmax;
+ }
+ else
+ {
+ cutoff = 4; /* doesn't really matter - it'll fail anyway, but gives error output */
+ }
+
+ dprintf(("parse: cvt_rawdcf: average bit count: %d\n", cutoff));
+
+ lowmax = 0; /* weighted sum */
+ highmax = 0; /* bitcount */
+
+ /*
+ * collect weighted sum of lower bits (left of initial guess)
+ */
+ dprintf(("parse: cvt_rawdcf: histogram:"));
+ for (i = 0; i <= cutoff; i++)
+ {
+ lowmax += histbuf[i] * i;
+ highmax += histbuf[i];
+ dprintf((" %d", histbuf[i]));
+ }
+ dprintf((" <M>"));
+
+ /*
+ * round up
+ */
+ lowmax += highmax / 2;
+
+ /*
+ * calculate lower bit maximum (weighted sum / bit count)
+ *
+ * avoid divide by zero
+ */
+ if (highmax)
+ {
+ lowmax /= highmax;
+ }
+ else
+ {
+ lowmax = 0;
+ }
+
+ highmax = 0; /* weighted sum of upper bits counts */
+ cutoff = 0; /* bitcount */
+
+ /*
+ * collect weighted sum of lower bits (right of initial guess)
+ */
+ for (; i < BITS; i++)
+ {
+ highmax+=histbuf[i] * i;
+ cutoff +=histbuf[i];
+ dprintf((" %d", histbuf[i]));
+ }
+ dprintf(("\n"));
+
+ /*
+ * determine upper maximum (weighted sum / bit count)
+ */
+ if (cutoff)
+ {
+ highmax /= cutoff;
+ }
+ else
+ {
+ highmax = BITS-1;
+ }
+
+ /*
+ * following now holds:
+ * lowmax <= cutoff(initial guess) <= highmax
+ * best cutoff is the minimum nearest to higher bits
+ */
+
+ /*
+ * find the minimum between lowmax and highmax (detecting
+ * possibly a minimum span)
+ */
+ span = cutoff = lowmax;
+ for (i = lowmax; i <= highmax; i++)
+ {
+ if (histbuf[cutoff] > histbuf[i])
+ {
+ /*
+ * got a new minimum move beginning of minimum (cutoff) and
+ * end of minimum (span) there
+ */
+ cutoff = span = i;
+ }
+ else
+ if (histbuf[cutoff] == histbuf[i])
+ {
+ /*
+ * minimum not better yet - but it spans more than
+ * one bit value - follow it
+ */
+ span = i;
+ }
+ }
+
+ /*
+ * cutoff point for 1/0 decision is the middle of the minimum section
+ * in the histogram
+ */
+ cutoff = (cutoff + span) / 2;
+
+ dprintf(("parse: cvt_rawdcf: lower maximum %d, higher maximum %d, cutoff %d\n", lowmax, highmax, cutoff));
+
+ /*
+ * convert the bit counts to symbolic 1/0 information for data conversion
+ */
+ s = buffer;
+ while ((s < e) && *c && *b)
+ {
+ if (*s == (unsigned char)~0)
+ {
+ /*
+ * invalid character
+ */
+ *s = '?';
+ }
+ else
+ {
+ /*
+ * symbolic 1/0 representation
+ */
+ *s = (*s >= cutoff) ? *b : *c;
+ }
+ s++;
+ b++;
+ c++;
+ }
+
+ /*
+ * if everything went well so far return the result of the symbolic
+ * conversion routine else just the accumulated errors
+ */
+ if (rtc != CVT_NONE)
+ {
+ PRINTF("%-30s", "*** BAD DATA");
+ }
+
+ return (rtc == CVT_NONE) ? convert_rawdcf(buffer, size, clock_time) : rtc;
+}
+
+/*-----------------------------------------------------------------------
+ * convert a wall clock time description of DCF77 to a Unix time (seconds
+ * since 1.1. 1970 UTC)
+ */
+static time_t
+dcf_to_unixtime(
+ clocktime_t *clock_time,
+ unsigned *cvtrtc
+ )
+{
+#define SETRTC(_X_) { if (cvtrtc) *cvtrtc = (_X_); }
+ static int days_of_month[] =
+ {
+ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+ };
+ register int i;
+ time_t t;
+
+ /*
+ * map 2 digit years to 19xx (DCF77 is a 20th century item)
+ */
+ if ( clock_time->year < YEAR_PIVOT ) /* in case of Y2KFixes [ */
+ clock_time->year += 100; /* *year%100, make tm_year */
+ /* *(do we need this?) */
+ if ( clock_time->year < YEAR_BREAK ) /* (failsafe if) */
+ clock_time->year += 1900; /* Y2KFixes ] */
+
+ /*
+ * must have been a really bad year code - drop it
+ */
+ if (clock_time->year < (YEAR_PIVOT + 1900) ) /* Y2KFixes */
+ {
+ SETRTC(CVT_FAIL|CVT_BADDATE);
+ return -1;
+ }
+ /*
+ * sorry, slow section here - but it's not time critical anyway
+ */
+
+ /*
+ * calculate days since 1970 (watching leap years)
+ */
+ t = julian0( clock_time->year ) - julian0( 1970 );
+
+ /* month */
+ if (clock_time->month <= 0 || clock_time->month > 12)
+ {
+ SETRTC(CVT_FAIL|CVT_BADDATE);
+ return -1; /* bad month */
+ }
+ /* adjust current leap year */
+#if 0
+ if (clock_time->month < 3 && days_per_year(clock_time->year) == 366)
+ t--;
+#endif
+
+ /*
+ * collect days from months excluding the current one
+ */
+ for (i = 1; i < clock_time->month; i++)
+ {
+ t += days_of_month[i];
+ }
+ /* day */
+ if (clock_time->day < 1 || ((clock_time->month == 2 && days_per_year(clock_time->year) == 366) ?
+ clock_time->day > 29 : clock_time->day > days_of_month[clock_time->month]))
+ {
+ SETRTC(CVT_FAIL|CVT_BADDATE);
+ return -1; /* bad day */
+ }
+
+ /*
+ * collect days from date excluding the current one
+ */
+ t += clock_time->day - 1;
+
+ /* hour */
+ if (clock_time->hour < 0 || clock_time->hour >= 24)
+ {
+ SETRTC(CVT_FAIL|CVT_BADTIME);
+ return -1; /* bad hour */
+ }
+
+ /*
+ * calculate hours from 1. 1. 1970
+ */
+ t = TIMES24(t) + clock_time->hour;
+
+ /* min */
+ if (clock_time->minute < 0 || clock_time->minute > 59)
+ {
+ SETRTC(CVT_FAIL|CVT_BADTIME);
+ return -1; /* bad min */
+ }
+
+ /*
+ * calculate minutes from 1. 1. 1970
+ */
+ t = TIMES60(t) + clock_time->minute;
+ /* sec */
+
+ /*
+ * calculate UTC in minutes
+ */
+ t += clock_time->utcoffset;
+
+ if (clock_time->second < 0 || clock_time->second > 60) /* allow for LEAPs */
+ {
+ SETRTC(CVT_FAIL|CVT_BADTIME);
+ return -1; /* bad sec */
+ }
+
+ /*
+ * calculate UTC in seconds - phew !
+ */
+ t = TIMES60(t) + clock_time->second;
+ /* done */
+ return t;
+}
+
+/*-----------------------------------------------------------------------
+ * cheap half baked 1/0 decision - for interactive operation only
+ */
+static char
+type(
+ unsigned int c
+ )
+{
+ c ^= 0xFF;
+ return (c > 0xF);
+}
+
+/*-----------------------------------------------------------------------
+ * week day representation
+ */
+static const char *wday[8] =
+{
+ "??",
+ "Mo",
+ "Tu",
+ "We",
+ "Th",
+ "Fr",
+ "Sa",
+ "Su"
+};
+
+/*-----------------------------------------------------------------------
+ * generate a string representation for a timeval
+ */
+static char *
+pr_timeval(
+ struct timeval *val
+ )
+{
+ static char buf[20];
+
+ if (val->tv_sec == 0)
+ snprintf(buf, sizeof(buf), "%c0.%06ld",
+ (val->tv_usec < 0) ? '-' : '+',
+ (long int)l_abs(val->tv_usec));
+ else
+ snprintf(buf, sizeof(buf), "%ld.%06ld",
+ (long int)val->tv_sec,
+ (long int)l_abs(val->tv_usec));
+ return buf;
+}
+
+/*-----------------------------------------------------------------------
+ * correct the current time by an offset by setting the time rigorously
+ */
+static void
+set_time(
+ struct timeval *offset
+ )
+{
+ struct timeval the_time;
+
+ if (no_set)
+ return;
+
+ LPRINTF("set_time: %s ", pr_timeval(offset));
+ syslog(LOG_NOTICE, "setting time (offset %s)", pr_timeval(offset));
+
+ if (gettimeofday(&the_time, 0L) == -1)
+ {
+ perror("gettimeofday()");
+ }
+ else
+ {
+ timeradd(&the_time, offset);
+ if (settimeofday(&the_time, 0L) == -1)
+ {
+ perror("settimeofday()");
+ }
+ }
+}
+
+/*-----------------------------------------------------------------------
+ * slew the time by a given offset
+ */
+static void
+adj_time(
+ long offset
+ )
+{
+ struct timeval time_offset;
+
+ if (no_set)
+ return;
+
+ time_offset.tv_sec = offset / 1000000;
+ time_offset.tv_usec = offset % 1000000;
+
+ LPRINTF("adj_time: %ld us ", (long int)offset);
+ if (adjtime(&time_offset, 0L) == -1)
+ perror("adjtime()");
+}
+
+/*-----------------------------------------------------------------------
+ * read in a possibly previously written drift value
+ */
+static void
+read_drift(
+ const char *drift_file
+ )
+{
+ FILE *df;
+
+ df = fopen(drift_file, "r");
+ if (df != NULL)
+ {
+ int idrift = 0, fdrift = 0;
+
+ fscanf(df, "%4d.%03d", &idrift, &fdrift);
+ fclose(df);
+ LPRINTF("read_drift: %d.%03d ppm ", idrift, fdrift);
+
+ accum_drift = idrift << USECSCALE;
+ fdrift = (fdrift << USECSCALE) / 1000;
+ accum_drift += fdrift & (1<<USECSCALE);
+ LPRINTF("read_drift: drift_comp %ld ", (long int)accum_drift);
+ }
+}
+
+/*-----------------------------------------------------------------------
+ * write out the current drift value
+ */
+static void
+update_drift(
+ const char *drift_file,
+ long offset,
+ time_t reftime
+ )
+{
+ FILE *df;
+
+ df = fopen(drift_file, "w");
+ if (df != NULL)
+ {
+ int idrift = R_SHIFT(accum_drift, USECSCALE);
+ int fdrift = accum_drift & ((1<<USECSCALE)-1);
+
+ LPRINTF("update_drift: drift_comp %ld ", (long int)accum_drift);
+ fdrift = (fdrift * 1000) / (1<<USECSCALE);
+ fprintf(df, "%4d.%03d %c%ld.%06ld %.24s\n", idrift, fdrift,
+ (offset < 0) ? '-' : '+', (long int)(l_abs(offset) / 1000000),
+ (long int)(l_abs(offset) % 1000000), asctime(localtime(&reftime)));
+ fclose(df);
+ LPRINTF("update_drift: %d.%03d ppm ", idrift, fdrift);
+ }
+}
+
+/*-----------------------------------------------------------------------
+ * process adjustments derived from the DCF77 observation
+ * (controls clock PLL)
+ */
+static void
+adjust_clock(
+ struct timeval *offset,
+ const char *drift_file,
+ time_t reftime
+ )
+{
+ struct timeval toffset;
+ register long usecoffset;
+ int tmp;
+
+ if (no_set)
+ return;
+
+ if (skip_adjust)
+ {
+ skip_adjust = 0;
+ return;
+ }
+
+ toffset = *offset;
+ toffset.tv_sec = l_abs(toffset.tv_sec);
+ toffset.tv_usec = l_abs(toffset.tv_usec);
+ if (toffset.tv_sec ||
+ (!toffset.tv_sec && toffset.tv_usec > max_adj_offset_usec))
+ {
+ /*
+ * hopeless - set the clock - and clear the timing
+ */
+ set_time(offset);
+ clock_adjust = 0;
+ skip_adjust = 1;
+ return;
+ }
+
+ usecoffset = offset->tv_sec * 1000000 + offset->tv_usec;
+
+ clock_adjust = R_SHIFT(usecoffset, TIMECONSTANT); /* adjustment to make for next period */
+
+ tmp = 0;
+ while (adjustments > (1 << tmp))
+ tmp++;
+ adjustments = 0;
+ if (tmp > FREQ_WEIGHT)
+ tmp = FREQ_WEIGHT;
+
+ accum_drift += R_SHIFT(usecoffset << USECSCALE, TIMECONSTANT+TIMECONSTANT+FREQ_WEIGHT-tmp);
+
+ if (accum_drift > MAX_DRIFT) /* clamp into interval */
+ accum_drift = MAX_DRIFT;
+ else
+ if (accum_drift < -MAX_DRIFT)
+ accum_drift = -MAX_DRIFT;
+
+ update_drift(drift_file, usecoffset, reftime);
+ LPRINTF("clock_adjust: %s, clock_adjust %ld, drift_comp %ld(%ld) ",
+ pr_timeval(offset),(long int) R_SHIFT(clock_adjust, USECSCALE),
+ (long int)R_SHIFT(accum_drift, USECSCALE), (long int)accum_drift);
+}
+
+/*-----------------------------------------------------------------------
+ * adjust the clock by a small mount to simulate frequency correction
+ */
+static void
+periodic_adjust(
+ void
+ )
+{
+ register long adjustment;
+
+ adjustments++;
+
+ adjustment = R_SHIFT(clock_adjust, PHASE_WEIGHT);
+
+ clock_adjust -= adjustment;
+
+ adjustment += R_SHIFT(accum_drift, USECSCALE+ADJINTERVAL);
+
+ adj_time(adjustment);
+}
+
+/*-----------------------------------------------------------------------
+ * control synchronisation status (warnings) and do periodic adjusts
+ * (frequency control simulation)
+ */
+static void
+tick(
+ int signum
+ )
+{
+ static unsigned long last_notice = 0;
+
+#if !defined(HAVE_SIGACTION) && !defined(HAVE_SIGVEC)
+ (void)signal(SIGALRM, tick);
+#endif
+
+ periodic_adjust();
+
+ ticks += 1<<ADJINTERVAL;
+
+ if ((ticks - last_sync) > MAX_UNSYNC)
+ {
+ /*
+ * not getting time for a while
+ */
+ if (sync_state == SYNC)
+ {
+ /*
+ * completely lost information
+ */
+ sync_state = NO_SYNC;
+ syslog(LOG_INFO, "DCF77 reception lost (timeout)");
+ last_notice = ticks;
+ }
+ else
+ /*
+ * in NO_SYNC state - look whether its time to speak up again
+ */
+ if ((ticks - last_notice) > NOTICE_INTERVAL)
+ {
+ syslog(LOG_NOTICE, "still not synchronized to DCF77 - check receiver/signal");
+ last_notice = ticks;
+ }
+ }
+
+#ifndef ITIMER_REAL
+ (void) alarm(1<<ADJINTERVAL);
+#endif
+}
+
+/*-----------------------------------------------------------------------
+ * break association from terminal to avoid catching terminal
+ * or process group related signals (-> daemon operation)
+ */
+static void
+detach(
+ void
+ )
+{
+# ifdef HAVE_DAEMON
+ daemon(0, 0);
+# else /* not HAVE_DAEMON */
+ if (fork())
+ exit(0);
+
+ {
+ u_long s;
+ int max_fd;
+
+#if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
+ max_fd = sysconf(_SC_OPEN_MAX);
+#else /* HAVE_SYSCONF && _SC_OPEN_MAX */
+ max_fd = getdtablesize();
+#endif /* HAVE_SYSCONF && _SC_OPEN_MAX */
+ for (s = 0; s < max_fd; s++)
+ (void) close((int)s);
+ (void) open("/", 0);
+ (void) dup2(0, 1);
+ (void) dup2(0, 2);
+#ifdef SYS_DOMAINOS
+ {
+ uid_$t puid;
+ status_$t st;
+
+ proc2_$who_am_i(&puid);
+ proc2_$make_server(&puid, &st);
+ }
+#endif /* SYS_DOMAINOS */
+#if defined(HAVE_SETPGID) || defined(HAVE_SETSID)
+# ifdef HAVE_SETSID
+ if (setsid() == (pid_t)-1)
+ syslog(LOG_ERR, "dcfd: setsid(): %m");
+# else
+ if (setpgid(0, 0) == -1)
+ syslog(LOG_ERR, "dcfd: setpgid(): %m");
+# endif
+#else /* HAVE_SETPGID || HAVE_SETSID */
+ {
+ int fid;
+
+ fid = open("/dev/tty", 2);
+ if (fid >= 0)
+ {
+ (void) ioctl(fid, (u_long) TIOCNOTTY, (char *) 0);
+ (void) close(fid);
+ }
+# ifdef HAVE_SETPGRP_0
+ (void) setpgrp();
+# else /* HAVE_SETPGRP_0 */
+ (void) setpgrp(0, getpid());
+# endif /* HAVE_SETPGRP_0 */
+ }
+#endif /* HAVE_SETPGID || HAVE_SETSID */
+ }
+#endif /* not HAVE_DAEMON */
+}
+
+/*-----------------------------------------------------------------------
+ * list possible arguments and options
+ */
+static void
+usage(
+ char *program
+ )
+{
+ fprintf(stderr, "usage: %s [-n] [-f] [-l] [-t] [-i] [-o] [-d <drift_file>] [-D <input delay>] <device>\n", program);
+ fprintf(stderr, "\t-n do not change time\n");
+ fprintf(stderr, "\t-i interactive\n");
+ fprintf(stderr, "\t-t trace (print all datagrams)\n");
+ fprintf(stderr, "\t-f print all databits (includes PTB private data)\n");
+ fprintf(stderr, "\t-l print loop filter debug information\n");
+ fprintf(stderr, "\t-o print offet average for current minute\n");
+ fprintf(stderr, "\t-Y make internal Y2K checks then exit\n"); /* Y2KFixes */
+ fprintf(stderr, "\t-d <drift_file> specify alternate drift file\n");
+ fprintf(stderr, "\t-D <input delay>specify delay from input edge to processing in micro seconds\n");
+}
+
+/*-----------------------------------------------------------------------
+ * check_y2k() - internal check of Y2K logic
+ * (a lot of this logic lifted from ../ntpd/check_y2k.c)
+ */
+static int
+check_y2k( void )
+{
+ int year; /* current working year */
+ int year0 = 1900; /* sarting year for NTP time */
+ int yearend; /* ending year we test for NTP time.
+ * 32-bit systems: through 2036, the
+ **year in which NTP time overflows.
+ * 64-bit systems: a reasonable upper
+ **limit (well, maybe somewhat beyond
+ **reasonable, but well before the
+ **max time, by which time the earth
+ **will be dead.) */
+ time_t Time;
+ struct tm LocalTime;
+
+ int Fatals, Warnings;
+#define Error(year) if ( (year)>=2036 && LocalTime.tm_year < 110 ) \
+ Warnings++; else Fatals++
+
+ Fatals = Warnings = 0;
+
+ Time = time( (time_t *)NULL );
+ LocalTime = *localtime( &Time );
+
+ year = ( sizeof( u_long ) > 4 ) /* save max span using year as temp */
+ ? ( 400 * 3 ) /* three greater gregorian cycles */
+ : ((int)(0x7FFFFFFF / 365.242 / 24/60/60)* 2 ); /*32-bit limit*/
+ /* NOTE: will automacially expand test years on
+ * 64 bit machines.... this may cause some of the
+ * existing ntp logic to fail for years beyond
+ * 2036 (the current 32-bit limit). If all checks
+ * fail ONLY beyond year 2036 you may ignore such
+ * errors, at least for a decade or so. */
+ yearend = year0 + year;
+
+ year = 1900+YEAR_PIVOT;
+ printf( " starting year %04d\n", (int) year );
+ printf( " ending year %04d\n", (int) yearend );
+
+ for ( ; year < yearend; year++ )
+ {
+ clocktime_t ct;
+ time_t Observed;
+ time_t Expected;
+ unsigned Flag;
+ unsigned long t;
+
+ ct.day = 1;
+ ct.month = 1;
+ ct.year = year;
+ ct.hour = ct.minute = ct.second = ct.usecond = 0;
+ ct.utcoffset = 0;
+ ct.flags = 0;
+
+ Flag = 0;
+ Observed = dcf_to_unixtime( &ct, &Flag );
+ /* seems to be a clone of parse_to_unixtime() with
+ * *a minor difference to arg2 type */
+ if ( ct.year != year )
+ {
+ fprintf( stdout,
+ "%04d: dcf_to_unixtime(,%d) CORRUPTED ct.year: was %d\n",
+ (int)year, (int)Flag, (int)ct.year );
+ Error(year);
+ break;
+ }
+ t = julian0(year) - julian0(1970); /* Julian day from 1970 */
+ Expected = t * 24 * 60 * 60;
+ if ( Observed != Expected || Flag )
+ { /* time difference */
+ fprintf( stdout,
+ "%04d: dcf_to_unixtime(,%d) FAILURE: was=%lu s/b=%lu (%ld)\n",
+ year, (int)Flag,
+ (unsigned long)Observed, (unsigned long)Expected,
+ ((long)Observed - (long)Expected) );
+ Error(year);
+ break;
+ }
+
+ }
+
+ return ( Fatals );
+}
+
+/*--------------------------------------------------
+ * rawdcf_init - set up modem lines for RAWDCF receivers
+ */
+#if defined(TIOCMSET) && (defined(TIOCM_DTR) || defined(CIOCM_DTR))
+static void
+rawdcf_init(
+ int fd
+ )
+{
+ /*
+ * You can use the RS232 to supply the power for a DCF77 receiver.
+ * Here a voltage between the DTR and the RTS line is used. Unfortunately
+ * the name has changed from CIOCM_DTR to TIOCM_DTR recently.
+ */
+
+#ifdef TIOCM_DTR
+ int sl232 = TIOCM_DTR; /* turn on DTR for power supply */
+#else
+ int sl232 = CIOCM_DTR; /* turn on DTR for power supply */
+#endif
+
+ if (ioctl(fd, TIOCMSET, (caddr_t)&sl232) == -1)
+ {
+ syslog(LOG_NOTICE, "rawdcf_init: WARNING: ioctl(fd, TIOCMSET, [C|T]IOCM_DTR): %m");
+ }
+}
+#else
+static void
+rawdcf_init(
+ int fd
+ )
+{
+ syslog(LOG_NOTICE, "rawdcf_init: WARNING: OS interface incapable of setting DTR to power DCF modules");
+}
+#endif /* DTR initialisation type */
+
+/*-----------------------------------------------------------------------
+ * main loop - argument interpreter / setup / main loop
+ */
+int
+main(
+ int argc,
+ char **argv
+ )
+{
+ unsigned char c;
+ char **a = argv;
+ int ac = argc;
+ char *file = NULL;
+ const char *drift_file = "/etc/dcfd.drift";
+ int fd;
+ int offset = 15;
+ int offsets = 0;
+ int delay = DEFAULT_DELAY; /* average delay from input edge to time stamping */
+ int trace = 0;
+ int errs = 0;
+
+ /*
+ * process arguments
+ */
+ while (--ac)
+ {
+ char *arg = *++a;
+ if (*arg == '-')
+ while ((c = *++arg))
+ switch (c)
+ {
+ case 't':
+ trace = 1;
+ interactive = 1;
+ break;
+
+ case 'f':
+ offset = 0;
+ interactive = 1;
+ break;
+
+ case 'l':
+ loop_filter_debug = 1;
+ offsets = 1;
+ interactive = 1;
+ break;
+
+ case 'n':
+ no_set = 1;
+ break;
+
+ case 'o':
+ offsets = 1;
+ interactive = 1;
+ break;
+
+ case 'i':
+ interactive = 1;
+ break;
+
+ case 'D':
+ if (ac > 1)
+ {
+ delay = atoi(*++a);
+ ac--;
+ }
+ else
+ {
+ fprintf(stderr, "%s: -D requires integer argument\n", argv[0]);
+ errs=1;
+ }
+ break;
+
+ case 'd':
+ if (ac > 1)
+ {
+ drift_file = *++a;
+ ac--;
+ }
+ else
+ {
+ fprintf(stderr, "%s: -d requires file name argument\n", argv[0]);
+ errs=1;
+ }
+ break;
+
+ case 'Y':
+ errs=check_y2k();
+ exit( errs ? 1 : 0 );
+
+ default:
+ fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);
+ errs=1;
+ break;
+ }
+ else
+ if (file == NULL)
+ file = arg;
+ else
+ {
+ fprintf(stderr, "%s: device specified twice\n", argv[0]);
+ errs=1;
+ }
+ }
+
+ if (errs)
+ {
+ usage(argv[0]);
+ exit(1);
+ }
+ else
+ if (file == NULL)
+ {
+ fprintf(stderr, "%s: device not specified\n", argv[0]);
+ usage(argv[0]);
+ exit(1);
+ }
+
+ errs = LINES+1;
+
+ /*
+ * get access to DCF77 tty port
+ */
+ fd = open(file, O_RDONLY);
+ if (fd == -1)
+ {
+ perror(file);
+ exit(1);
+ }
+ else
+ {
+ int i, rrc;
+ struct timeval t, tt, tlast;
+ struct timeval timeout;
+ struct timeval phase;
+ struct timeval time_offset;
+ char pbuf[61]; /* printable version */
+ char buf[61]; /* raw data */
+ clocktime_t clock_time; /* wall clock time */
+ time_t utc_time = 0;
+ time_t last_utc_time = 0;
+ long usecerror = 0;
+ long lasterror = 0;
+#if defined(HAVE_TERMIOS_H) || defined(STREAM)
+ struct termios term;
+#else /* not HAVE_TERMIOS_H || STREAM */
+# if defined(HAVE_TERMIO_H) || defined(HAVE_SYSV_TTYS)
+ struct termio term;
+# endif/* HAVE_TERMIO_H || HAVE_SYSV_TTYS */
+#endif /* not HAVE_TERMIOS_H || STREAM */
+ unsigned int rtc = CVT_NONE;
+
+ rawdcf_init(fd);
+
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 500000;
+
+ phase.tv_sec = 0;
+ phase.tv_usec = delay;
+
+ /*
+ * setup TTY (50 Baud, Read, 8Bit, No Hangup, 1 character IO)
+ */
+ if (TTY_GETATTR(fd, &term) == -1)
+ {
+ perror("tcgetattr");
+ exit(1);
+ }
+
+ memset(term.c_cc, 0, sizeof(term.c_cc));
+ term.c_cc[VMIN] = 1;
+#ifdef NO_PARENB_IGNPAR
+ term.c_cflag = CS8|CREAD|CLOCAL;
+#else
+ term.c_cflag = CS8|CREAD|CLOCAL|PARENB;
+#endif
+ term.c_iflag = IGNPAR;
+ term.c_oflag = 0;
+ term.c_lflag = 0;
+
+ cfsetispeed(&term, B50);
+ cfsetospeed(&term, B50);
+
+ if (TTY_SETATTR(fd, &term) == -1)
+ {
+ perror("tcsetattr");
+ exit(1);
+ }
+
+ /*
+ * lose terminal if in daemon operation
+ */
+ if (!interactive)
+ detach();
+
+ /*
+ * get syslog() initialized
+ */
+#ifdef LOG_DAEMON
+ openlog("dcfd", LOG_PID, LOG_DAEMON);
+#else
+ openlog("dcfd", LOG_PID);
+#endif
+
+ /*
+ * setup periodic operations (state control / frequency control)
+ */
+#ifdef HAVE_SIGACTION
+ {
+ struct sigaction act;
+
+# ifdef HAVE_SA_SIGACTION_IN_STRUCT_SIGACTION
+ act.sa_sigaction = (void (*) (int, siginfo_t *, void *))0;
+# endif /* HAVE_SA_SIGACTION_IN_STRUCT_SIGACTION */
+ act.sa_handler = tick;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+
+ if (sigaction(SIGALRM, &act, (struct sigaction *)0) == -1)
+ {
+ syslog(LOG_ERR, "sigaction(SIGALRM): %m");
+ exit(1);
+ }
+ }
+#else
+#ifdef HAVE_SIGVEC
+ {
+ struct sigvec vec;
+
+ vec.sv_handler = tick;
+ vec.sv_mask = 0;
+ vec.sv_flags = 0;
+
+ if (sigvec(SIGALRM, &vec, (struct sigvec *)0) == -1)
+ {
+ syslog(LOG_ERR, "sigvec(SIGALRM): %m");
+ exit(1);
+ }
+ }
+#else
+ (void) signal(SIGALRM, tick);
+#endif
+#endif
+
+#ifdef ITIMER_REAL
+ {
+ struct itimerval it;
+
+ it.it_interval.tv_sec = 1<<ADJINTERVAL;
+ it.it_interval.tv_usec = 0;
+ it.it_value.tv_sec = 1<<ADJINTERVAL;
+ it.it_value.tv_usec = 0;
+
+ if (setitimer(ITIMER_REAL, &it, (struct itimerval *)0) == -1)
+ {
+ syslog(LOG_ERR, "setitimer: %m");
+ exit(1);
+ }
+ }
+#else
+ (void) alarm(1<<ADJINTERVAL);
+#endif
+
+ PRINTF(" DCF77 monitor %s - Copyright (C) 1993-2005 by Frank Kardel\n\n", revision);
+
+ pbuf[60] = '\0';
+ for ( i = 0; i < 60; i++)
+ pbuf[i] = '.';
+
+ read_drift(drift_file);
+
+ /*
+ * what time is it now (for interval measurement)
+ */
+ gettimeofday(&tlast, 0L);
+ i = 0;
+ /*
+ * loop until input trouble ...
+ */
+ do
+ {
+ /*
+ * get an impulse
+ */
+ while ((rrc = read(fd, &c, 1)) == 1)
+ {
+ gettimeofday(&t, 0L);
+ tt = t;
+ timersub(&t, &tlast);
+
+ if (errs > LINES)
+ {
+ PRINTF(" %s", &"PTB private....RADMLSMin....PHour..PMDay..DayMonthYear....P\n"[offset]);
+ PRINTF(" %s", &"---------------RADMLS1248124P124812P1248121241248112481248P\n"[offset]);
+ errs = 0;
+ }
+
+ /*
+ * timeout -> possible minute mark -> interpretation
+ */
+ if (timercmp(&t, &timeout, >))
+ {
+ PRINTF("%c %.*s ", pat[i % (sizeof(pat)-1)], 59 - offset, &pbuf[offset]);
+
+ if ((rtc = cvt_rawdcf((unsigned char *)buf, i, &clock_time)) != CVT_OK)
+ {
+ /*
+ * this data was bad - well - forget synchronisation for now
+ */
+ PRINTF("\n");
+ if (sync_state == SYNC)
+ {
+ sync_state = NO_SYNC;
+ syslog(LOG_INFO, "DCF77 reception lost (bad data)");
+ }
+ errs++;
+ }
+ else
+ if (trace)
+ {
+ PRINTF("\r %.*s ", 59 - offset, &buf[offset]);
+ }
+
+
+ buf[0] = c;
+
+ /*
+ * collect first character
+ */
+ if (((c^0xFF)+1) & (c^0xFF))
+ pbuf[0] = '?';
+ else
+ pbuf[0] = type(c) ? '#' : '-';
+
+ for ( i = 1; i < 60; i++)
+ pbuf[i] = '.';
+
+ i = 0;
+ }
+ else
+ {
+ /*
+ * collect character
+ */
+ buf[i] = c;
+
+ /*
+ * initial guess (usually correct)
+ */
+ if (((c^0xFF)+1) & (c^0xFF))
+ pbuf[i] = '?';
+ else
+ pbuf[i] = type(c) ? '#' : '-';
+
+ PRINTF("%c %.*s ", pat[i % (sizeof(pat)-1)], 59 - offset, &pbuf[offset]);
+ }
+
+ if (i == 0 && rtc == CVT_OK)
+ {
+ /*
+ * we got a good time code here - try to convert it to
+ * UTC
+ */
+ if ((utc_time = dcf_to_unixtime(&clock_time, &rtc)) == -1)
+ {
+ PRINTF("*** BAD CONVERSION\n");
+ }
+
+ if (utc_time != (last_utc_time + 60))
+ {
+ /*
+ * well, two successive sucessful telegrams are not 60 seconds
+ * apart
+ */
+ PRINTF("*** NO MINUTE INC\n");
+ if (sync_state == SYNC)
+ {
+ sync_state = NO_SYNC;
+ syslog(LOG_INFO, "DCF77 reception lost (data mismatch)");
+ }
+ errs++;
+ rtc = CVT_FAIL|CVT_BADTIME|CVT_BADDATE;
+ }
+ else
+ usecerror = 0;
+
+ last_utc_time = utc_time;
+ }
+
+ if (rtc == CVT_OK)
+ {
+ if (i == 0)
+ {
+ /*
+ * valid time code - determine offset and
+ * note regained reception
+ */
+ last_sync = ticks;
+ if (sync_state == NO_SYNC)
+ {
+ syslog(LOG_INFO, "receiving DCF77");
+ }
+ else
+ {
+ /*
+ * we had at least one minute SYNC - thus
+ * last error is valid
+ */
+ time_offset.tv_sec = lasterror / 1000000;
+ time_offset.tv_usec = lasterror % 1000000;
+ adjust_clock(&time_offset, drift_file, utc_time);
+ }
+ sync_state = SYNC;
+ }
+
+ time_offset.tv_sec = utc_time + i;
+ time_offset.tv_usec = 0;
+
+ timeradd(&time_offset, &phase);
+
+ usecerror += (time_offset.tv_sec - tt.tv_sec) * 1000000 + time_offset.tv_usec
+ -tt.tv_usec;
+
+ /*
+ * output interpreted DCF77 data
+ */
+ PRINTF(offsets ? "%s, %2ld:%02ld:%02d, %ld.%02ld.%02ld, <%s%s%s%s> (%c%ld.%06lds)" :
+ "%s, %2ld:%02ld:%02d, %ld.%02ld.%02ld, <%s%s%s%s>",
+ wday[clock_time.wday],
+ clock_time.hour, clock_time.minute, i, clock_time.day, clock_time.month,
+ clock_time.year,
+ (clock_time.flags & DCFB_ALTERNATE) ? "R" : "_",
+ (clock_time.flags & DCFB_ANNOUNCE) ? "A" : "_",
+ (clock_time.flags & DCFB_DST) ? "D" : "_",
+ (clock_time.flags & DCFB_LEAP) ? "L" : "_",
+ (lasterror < 0) ? '-' : '+', l_abs(lasterror) / 1000000, l_abs(lasterror) % 1000000
+ );
+
+ if (trace && (i == 0))
+ {
+ PRINTF("\n");
+ errs++;
+ }
+ lasterror = usecerror / (i+1);
+ }
+ else
+ {
+ lasterror = 0; /* we cannot calculate phase errors on bad reception */
+ }
+
+ PRINTF("\r");
+
+ if (i < 60)
+ {
+ i++;
+ }
+
+ tlast = tt;
+
+ if (interactive)
+ fflush(stdout);
+ }
+ } while ((rrc == -1) && (errno == EINTR));
+
+ /*
+ * lost IO - sorry guys
+ */
+ syslog(LOG_ERR, "TERMINATING - cannot read from device %s (%m)", file);
+
+ (void)close(fd);
+ }
+
+ closelog();
+
+ return 0;
+}
+
+/*
+ * History:
+ *
+ * dcfd.c,v
+ * Revision 4.18 2005/10/07 22:08:18 kardel
+ * make dcfd.c compile on NetBSD 3.99.9 again (configure/sigvec compatibility fix)
+ *
+ * Revision 4.17.2.1 2005/10/03 19:15:16 kardel
+ * work around configure not detecting a missing sigvec compatibility
+ * interface on NetBSD 3.99.9 and above
+ *
+ * Revision 4.17 2005/08/10 10:09:44 kardel
+ * output revision information
+ *
+ * Revision 4.16 2005/08/10 06:33:25 kardel
+ * cleanup warnings
+ *
+ * Revision 4.15 2005/08/10 06:28:45 kardel
+ * fix setting of baud rate
+ *
+ * Revision 4.14 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.13 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ */
diff --git a/parseutil/testdcf.c b/parseutil/testdcf.c
new file mode 100644
index 0000000..c78c242
--- /dev/null
+++ b/parseutil/testdcf.c
@@ -0,0 +1,541 @@
+/*
+ * /src/NTP/ntp4-dev/parseutil/testdcf.c,v 4.10 2005/08/06 14:18:43 kardel RELEASE_20050806_A
+ *
+ * testdcf.c,v 4.10 2005/08/06 14:18:43 kardel RELEASE_20050806_A
+ *
+ * simple DCF77 100/200ms pulse test program (via 50Baud serial line)
+ *
+ * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
+ * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <config.h>
+#include "ntp_stdlib.h"
+
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <termios.h>
+
+/*
+ * state flags
+ */
+#define DCFB_ANNOUNCE 0x0001 /* switch time zone warning (DST switch) */
+#define DCFB_DST 0x0002 /* DST in effect */
+#define DCFB_LEAP 0x0004 /* LEAP warning (1 hour prior to occurrence) */
+#define DCFB_ALTERNATE 0x0008 /* alternate antenna used */
+
+struct clocktime /* clock time broken up from time code */
+{
+ long wday;
+ long day;
+ long month;
+ long year;
+ long hour;
+ long minute;
+ long second;
+ long usecond;
+ long utcoffset; /* in minutes */
+ long flags; /* current clock status */
+};
+
+typedef struct clocktime clocktime_t;
+
+static char type(unsigned int);
+
+#define TIMES10(_X_) (((_X_) << 3) + ((_X_) << 1))
+
+/*
+ * parser related return/error codes
+ */
+#define CVT_MASK 0x0000000F /* conversion exit code */
+#define CVT_NONE 0x00000001 /* format not applicable */
+#define CVT_FAIL 0x00000002 /* conversion failed - error code returned */
+#define CVT_OK 0x00000004 /* conversion succeeded */
+#define CVT_BADFMT 0x00000010 /* general format error - (unparsable) */
+
+/*
+ * DCF77 raw time code
+ *
+ * From "Zur Zeit", Physikalisch-Technische Bundesanstalt (PTB), Braunschweig
+ * und Berlin, Maerz 1989
+ *
+ * Timecode transmission:
+ * AM:
+ * time marks are send every second except for the second before the
+ * next minute mark
+ * time marks consist of a reduction of transmitter power to 25%
+ * of the nominal level
+ * the falling edge is the time indication (on time)
+ * time marks of a 100ms duration constitute a logical 0
+ * time marks of a 200ms duration constitute a logical 1
+ * FM:
+ * see the spec. (basically a (non-)inverted psuedo random phase shift)
+ *
+ * Encoding:
+ * Second Contents
+ * 0 - 10 AM: free, FM: 0
+ * 11 - 14 free
+ * 15 R - alternate antenna
+ * 16 A1 - expect zone change (1 hour before)
+ * 17 - 18 Z1,Z2 - time zone
+ * 0 0 illegal
+ * 0 1 MEZ (MET)
+ * 1 0 MESZ (MED, MET DST)
+ * 1 1 illegal
+ * 19 A2 - expect leap insertion/deletion (1 hour before)
+ * 20 S - start of time code (1)
+ * 21 - 24 M1 - BCD (lsb first) Minutes
+ * 25 - 27 M10 - BCD (lsb first) 10 Minutes
+ * 28 P1 - Minute Parity (even)
+ * 29 - 32 H1 - BCD (lsb first) Hours
+ * 33 - 34 H10 - BCD (lsb first) 10 Hours
+ * 35 P2 - Hour Parity (even)
+ * 36 - 39 D1 - BCD (lsb first) Days
+ * 40 - 41 D10 - BCD (lsb first) 10 Days
+ * 42 - 44 DW - BCD (lsb first) day of week (1: Monday -> 7: Sunday)
+ * 45 - 49 MO - BCD (lsb first) Month
+ * 50 MO0 - 10 Months
+ * 51 - 53 Y1 - BCD (lsb first) Years
+ * 54 - 57 Y10 - BCD (lsb first) 10 Years
+ * 58 P3 - Date Parity (even)
+ * 59 - usually missing (minute indication), except for leap insertion
+ */
+
+static char revision[] = "4.10";
+
+static struct rawdcfcode
+{
+ char offset; /* start bit */
+} rawdcfcode[] =
+{
+ { 0 }, { 15 }, { 16 }, { 17 }, { 19 }, { 20 }, { 21 }, { 25 }, { 28 }, { 29 },
+ { 33 }, { 35 }, { 36 }, { 40 }, { 42 }, { 45 }, { 49 }, { 50 }, { 54 }, { 58 }, { 59 }
+};
+
+#define DCF_M 0
+#define DCF_R 1
+#define DCF_A1 2
+#define DCF_Z 3
+#define DCF_A2 4
+#define DCF_S 5
+#define DCF_M1 6
+#define DCF_M10 7
+#define DCF_P1 8
+#define DCF_H1 9
+#define DCF_H10 10
+#define DCF_P2 11
+#define DCF_D1 12
+#define DCF_D10 13
+#define DCF_DW 14
+#define DCF_MO 15
+#define DCF_MO0 16
+#define DCF_Y1 17
+#define DCF_Y10 18
+#define DCF_P3 19
+
+static struct partab
+{
+ char offset; /* start bit of parity field */
+} partab[] =
+{
+ { 21 }, { 29 }, { 36 }, { 59 }
+};
+
+#define DCF_P_P1 0
+#define DCF_P_P2 1
+#define DCF_P_P3 2
+
+#define DCF_Z_MET 0x2
+#define DCF_Z_MED 0x1
+
+static unsigned long
+ext_bf(
+ register unsigned char *buf,
+ register int idx
+ )
+{
+ register unsigned long sum = 0;
+ register int i, first;
+
+ first = rawdcfcode[idx].offset;
+
+ for (i = rawdcfcode[idx+1].offset - 1; i >= first; i--)
+ {
+ sum <<= 1;
+ sum |= (buf[i] != '-');
+ }
+ return sum;
+}
+
+static unsigned
+pcheck(
+ register unsigned char *buf,
+ register int idx
+ )
+{
+ register int i,last;
+ register unsigned psum = 1;
+
+ last = partab[idx+1].offset;
+
+ for (i = partab[idx].offset; i < last; i++)
+ psum ^= (buf[i] != '-');
+
+ return psum;
+}
+
+static unsigned long
+convert_rawdcf(
+ register unsigned char *buffer,
+ register int size,
+ register clocktime_t *clock_time
+ )
+{
+ if (size < 57)
+ {
+ printf("%-30s", "*** INCOMPLETE");
+ return CVT_NONE;
+ }
+
+ /*
+ * check Start and Parity bits
+ */
+ if ((ext_bf(buffer, DCF_S) == 1) &&
+ pcheck(buffer, DCF_P_P1) &&
+ pcheck(buffer, DCF_P_P2) &&
+ pcheck(buffer, DCF_P_P3))
+ {
+ /*
+ * buffer OK
+ */
+
+ clock_time->flags = 0;
+ clock_time->usecond= 0;
+ clock_time->second = 0;
+ clock_time->minute = ext_bf(buffer, DCF_M10);
+ clock_time->minute = TIMES10(clock_time->minute) + ext_bf(buffer, DCF_M1);
+ clock_time->hour = ext_bf(buffer, DCF_H10);
+ clock_time->hour = TIMES10(clock_time->hour) + ext_bf(buffer, DCF_H1);
+ clock_time->day = ext_bf(buffer, DCF_D10);
+ clock_time->day = TIMES10(clock_time->day) + ext_bf(buffer, DCF_D1);
+ clock_time->month = ext_bf(buffer, DCF_MO0);
+ clock_time->month = TIMES10(clock_time->month) + ext_bf(buffer, DCF_MO);
+ clock_time->year = ext_bf(buffer, DCF_Y10);
+ clock_time->year = TIMES10(clock_time->year) + ext_bf(buffer, DCF_Y1);
+ clock_time->wday = ext_bf(buffer, DCF_DW);
+
+ switch (ext_bf(buffer, DCF_Z))
+ {
+ case DCF_Z_MET:
+ clock_time->utcoffset = -60;
+ break;
+
+ case DCF_Z_MED:
+ clock_time->flags |= DCFB_DST;
+ clock_time->utcoffset = -120;
+ break;
+
+ default:
+ printf("%-30s", "*** BAD TIME ZONE");
+ return CVT_FAIL|CVT_BADFMT;
+ }
+
+ if (ext_bf(buffer, DCF_A1))
+ clock_time->flags |= DCFB_ANNOUNCE;
+
+ if (ext_bf(buffer, DCF_A2))
+ clock_time->flags |= DCFB_LEAP;
+
+ if (ext_bf(buffer, DCF_R))
+ clock_time->flags |= DCFB_ALTERNATE;
+
+ return CVT_OK;
+ }
+ else
+ {
+ /*
+ * bad format - not for us
+ */
+ printf("%-30s", "*** BAD FORMAT (invalid/parity)");
+ return CVT_FAIL|CVT_BADFMT;
+ }
+}
+
+static char
+type(
+ unsigned int c
+ )
+{
+ c ^= 0xFF;
+ return (c >= 0xF);
+}
+
+static const char *wday[8] =
+{
+ "??",
+ "Mo",
+ "Tu",
+ "We",
+ "Th",
+ "Fr",
+ "Sa",
+ "Su"
+};
+
+static char pat[] = "-\\|/";
+
+#define LINES (24-2) /* error lines after which the two headlines are repeated */
+
+int
+main(
+ int argc,
+ char *argv[]
+ )
+{
+ if ((argc != 2) && (argc != 3))
+ {
+ fprintf(stderr, "usage: %s [-f|-t|-ft|-tf] <device>\n", argv[0]);
+ exit(1);
+ }
+ else
+ {
+ unsigned char c;
+ char *file;
+ int fd;
+ int offset = 15;
+ int trace = 0;
+ int errs = LINES+1;
+
+ /*
+ * SIMPLE(!) argument "parser"
+ */
+ if (argc == 3)
+ {
+ if (strcmp(argv[1], "-f") == 0)
+ offset = 0;
+ if (strcmp(argv[1], "-t") == 0)
+ trace = 1;
+ if ((strcmp(argv[1], "-ft") == 0) ||
+ (strcmp(argv[1], "-tf") == 0))
+ {
+ offset = 0;
+ trace = 1;
+ }
+ file = argv[2];
+ }
+ else
+ {
+ file = argv[1];
+ }
+
+ fd = open(file, O_RDONLY);
+ if (fd == -1)
+ {
+ perror(file);
+ exit(1);
+ }
+ else
+ {
+ int i;
+#ifdef TIOCM_RTS
+ int on = TIOCM_RTS;
+#endif
+ struct timeval t, tt, tlast;
+ char buf[61];
+ clocktime_t clock_time;
+ struct termios term;
+ int rtc = CVT_NONE;
+
+ if (tcgetattr(fd, &term) == -1)
+ {
+ perror("tcgetattr");
+ exit(1);
+ }
+
+ memset(term.c_cc, 0, sizeof(term.c_cc));
+ term.c_cc[VMIN] = 1;
+#ifdef NO_PARENB_IGNPAR /* Was: defined(SYS_IRIX4) || defined (SYS_IRIX5) */
+ /* somehow doesn't grok PARENB & IGNPAR (mj) */
+ term.c_cflag = CS8|CREAD|CLOCAL;
+#else
+ term.c_cflag = CS8|CREAD|CLOCAL|PARENB;
+#endif
+ term.c_iflag = IGNPAR;
+ term.c_oflag = 0;
+ term.c_lflag = 0;
+
+ cfsetispeed(&term, B50);
+ cfsetospeed(&term, B50);
+
+ if (tcsetattr(fd, TCSANOW, &term) == -1)
+ {
+ perror("tcsetattr");
+ exit(1);
+ }
+
+#ifdef I_POP
+ while (ioctl(fd, I_POP, 0) == 0)
+ ;
+#endif
+#if defined(TIOCMBIC) && defined(TIOCM_RTS)
+ if (ioctl(fd, TIOCMBIC, (caddr_t)&on) == -1)
+ {
+ perror("TIOCM_RTS");
+ }
+#endif
+
+ printf(" DCF77 monitor %s - Copyright (C) 1993-2005, Frank Kardel\n\n", revision);
+
+ clock_time.hour = 0;
+ clock_time.minute = 0;
+ clock_time.day = 0;
+ clock_time.wday = 0;
+ clock_time.month = 0;
+ clock_time.year = 0;
+ clock_time.flags = 0;
+ buf[60] = '\0';
+ for ( i = 0; i < 60; i++)
+ buf[i] = '.';
+
+ gettimeofday(&tlast, 0L);
+ i = 0;
+ while (read(fd, &c, 1) == 1)
+ {
+ gettimeofday(&t, 0L);
+ tt = t;
+ t.tv_sec -= tlast.tv_sec;
+ t.tv_usec -= tlast.tv_usec;
+ if (t.tv_usec < 0)
+ {
+ t.tv_usec += 1000000;
+ t.tv_sec -= 1;
+ }
+
+ if (errs > LINES)
+ {
+ printf(" %s", &"PTB private....RADMLSMin....PHour..PMDay..DayMonthYear....P\n"[offset]);
+ printf(" %s", &"---------------RADMLS1248124P124812P1248121241248112481248P\n"[offset]);
+ errs = 0;
+ }
+
+ if (t.tv_sec > 1 ||
+ (t.tv_sec == 1 &&
+ t.tv_usec > 500000))
+ {
+ printf("%c %.*s ", pat[i % (sizeof(pat)-1)], 59 - offset, &buf[offset]);
+
+ if ((rtc = convert_rawdcf((unsigned char *)buf, i, &clock_time)) != CVT_OK)
+ {
+ printf("\n");
+ clock_time.hour = 0;
+ clock_time.minute = 0;
+ clock_time.day = 0;
+ clock_time.wday = 0;
+ clock_time.month = 0;
+ clock_time.year = 0;
+ clock_time.flags = 0;
+ errs++;
+ }
+
+ if (((c^0xFF)+1) & (c^0xFF))
+ buf[0] = '?';
+ else
+ buf[0] = type(c) ? '#' : '-';
+
+ for ( i = 1; i < 60; i++)
+ buf[i] = '.';
+
+ i = 0;
+ }
+ else
+ {
+ if (((c^0xFF)+1) & (c^0xFF))
+ buf[i] = '?';
+ else
+ buf[i] = type(c) ? '#' : '-';
+
+ printf("%c %.*s ", pat[i % (sizeof(pat)-1)], 59 - offset, &buf[offset]);
+ }
+
+ if (rtc == CVT_OK)
+ {
+ printf("%s, %2d:%02d:%02d, %d.%02d.%02d, <%s%s%s%s>",
+ wday[clock_time.wday],
+ (int)clock_time.hour, (int)clock_time.minute, (int)i, (int)clock_time.day, (int)clock_time.month,
+ (int)clock_time.year,
+ (clock_time.flags & DCFB_ALTERNATE) ? "R" : "_",
+ (clock_time.flags & DCFB_ANNOUNCE) ? "A" : "_",
+ (clock_time.flags & DCFB_DST) ? "D" : "_",
+ (clock_time.flags & DCFB_LEAP) ? "L" : "_"
+ );
+ if (trace && (i == 0))
+ {
+ printf("\n");
+ errs++;
+ }
+ }
+
+ printf("\r");
+
+ if (i < 60)
+ {
+ i++;
+ }
+
+ tlast = tt;
+
+ fflush(stdout);
+ }
+ close(fd);
+ }
+ }
+ return 0;
+}
+
+/*
+ * History:
+ *
+ * testdcf.c,v
+ * Revision 4.10 2005/08/06 14:18:43 kardel
+ * cleanup warnings
+ *
+ * Revision 4.9 2005/08/06 14:14:38 kardel
+ * document revision on startup
+ *
+ * Revision 4.8 2005/08/06 14:10:08 kardel
+ * fix setting of baud rate
+ *
+ * Revision 4.7 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.6 2004/11/14 15:29:42 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ */