From bdab5265fcbf3f472545073a23f8999749a9f2b9 Mon Sep 17 00:00:00 2001 From: Lorry Tar Creator Date: Tue, 2 Dec 2014 09:01:21 +0000 Subject: Imported from /home/lorry/working-area/delta_ntp/ntp-dev-4.2.7p482.tar.gz. --- parseutil/Makefile.am | 24 + parseutil/Makefile.in | 752 ++++++++++++++++++++ parseutil/README | 16 + parseutil/dcfd.c | 1872 +++++++++++++++++++++++++++++++++++++++++++++++++ parseutil/testdcf.c | 541 ++++++++++++++ 5 files changed, 3205 insertions(+) create mode 100644 parseutil/Makefile.am create mode 100644 parseutil/Makefile.in create mode 100644 parseutil/README create mode 100644 parseutil/dcfd.c create mode 100644 parseutil/testdcf.c (limited to 'parseutil') 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 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 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * 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 +#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 +# 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((" ")); + + /* + * 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< 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< 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< 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 ] [-D ] \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 specify alternate drift file\n"); + fprintf(stderr, "\t-D 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< 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 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 +#include "ntp_stdlib.h" + +#include +#include +#include +#include +#include + +/* + * 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] \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 + * + */ -- cgit v1.2.1