aboutsummaryrefslogtreecommitdiff
path: root/contrib/ntp/util
diff options
context:
space:
mode:
authorOllivier Robert <roberto@FreeBSD.org>1999-12-09 13:01:21 +0000
committerOllivier Robert <roberto@FreeBSD.org>1999-12-09 13:01:21 +0000
commitc0b746e5e8d9479f05b3749cbf1f73b8928719bd (patch)
treefc0cfa1aab0ff6b228f511b410733ef4f35d1ead /contrib/ntp/util
downloadsrc-c0b746e5e8d9479f05b3749cbf1f73b8928719bd.tar.gz
src-c0b746e5e8d9479f05b3749cbf1f73b8928719bd.zip
Virgin import of ntpd 4.0.98fvendor/ntp/4.0.98f
Notes
Notes: svn path=/vendor/ntp/dist/; revision=54359 svn path=/vendor/ntp/4.0.98f/; revision=54361; tag=vendor/ntp/4.0.98f
Diffstat (limited to 'contrib/ntp/util')
-rw-r--r--contrib/ntp/util/Makefile.am18
-rw-r--r--contrib/ntp/util/Makefile.in492
-rw-r--r--contrib/ntp/util/README37
-rw-r--r--contrib/ntp/util/ansi2knr.136
-rw-r--r--contrib/ntp/util/ansi2knr.c720
-rw-r--r--contrib/ntp/util/byteorder.c56
-rw-r--r--contrib/ntp/util/hist.c107
-rw-r--r--contrib/ntp/util/jitter.c70
-rw-r--r--contrib/ntp/util/kern.c224
-rw-r--r--contrib/ntp/util/longsize.c11
-rw-r--r--contrib/ntp/util/ntptime.c399
-rw-r--r--contrib/ntp/util/precision.c172
-rw-r--r--contrib/ntp/util/sht.c185
-rw-r--r--contrib/ntp/util/testrs6000.c55
-rw-r--r--contrib/ntp/util/tickadj.c904
-rw-r--r--contrib/ntp/util/timetrim.c95
16 files changed, 3581 insertions, 0 deletions
diff --git a/contrib/ntp/util/Makefile.am b/contrib/ntp/util/Makefile.am
new file mode 100644
index 000000000000..4d703182773f
--- /dev/null
+++ b/contrib/ntp/util/Makefile.am
@@ -0,0 +1,18 @@
+#AUTOMAKE_OPTIONS = ../ansi2knr no-dependencies
+AUTOMAKE_OPTIONS = ansi2knr
+bin_PROGRAMS = @MAKE_TICKADJ@ @MAKE_NTPTIME@
+EXTRA_PROGRAMS = byteorder hist jitter kern longsize ntptime \
+precision tickadj testrs6000 timetrim sht
+
+INCLUDES = -I$(top_srcdir)/include
+# LDADD might need RESLIB and ADJLIB
+LDADD = ../libntp/libntp.a
+#EXTRA_DIST = README TAGS
+EXTRA_DIST =
+ETAGS_ARGS = Makefile.am
+
+../libntp/libntp.a:
+ cd ../libntp && $(MAKE)
+
+kern.o: kern.c
+ $(COMPILE) -DHAVE_TIMEX_H -c kern.c
diff --git a/contrib/ntp/util/Makefile.in b/contrib/ntp/util/Makefile.in
new file mode 100644
index 000000000000..6de4f225863a
--- /dev/null
+++ b/contrib/ntp/util/Makefile.in
@@ -0,0 +1,492 @@
+# Makefile.in generated automatically by automake 1.4a from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 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.
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_FLAG =
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AMTAR = @AMTAR@
+AMTARFLAGS = @AMTARFLAGS@
+AWK = @AWK@
+CC = @CC@
+CFLAGS = @CFLAGS@
+CHUTEST = @CHUTEST@
+CLKTEST = @CLKTEST@
+CPP = @CPP@
+DCFD = @DCFD@
+LDFLAGS = @LDFLAGS@
+LIBPARSE = @LIBPARSE@
+LIBRSAREF = @LIBRSAREF@
+LN_S = @LN_S@
+MAKEINFO = @MAKEINFO@
+MAKE_ADJTIMED = @MAKE_ADJTIMED@
+MAKE_CHECK_Y2K = @MAKE_CHECK_Y2K@
+MAKE_LIBPARSE = @MAKE_LIBPARSE@
+MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
+MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
+MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
+MAKE_TICKADJ = @MAKE_TICKADJ@
+PACKAGE = @PACKAGE@
+PATH_SH = @PATH_SH@
+PROPDELAY = @PROPDELAY@
+RANLIB = @RANLIB@
+RSAREF = @RSAREF@
+TESTDCF = @TESTDCF@
+U = @U@
+VERSION = @VERSION@
+
+#AUTOMAKE_OPTIONS = ../ansi2knr no-dependencies
+
+
+AUTOMAKE_OPTIONS = ansi2knr
+bin_PROGRAMS = @MAKE_TICKADJ@ @MAKE_NTPTIME@
+EXTRA_PROGRAMS = byteorder hist jitter kern longsize ntptime \
+precision tickadj testrs6000 timetrim sht
+
+
+INCLUDES = -I$(top_srcdir)/include
+# LDADD might need RESLIB and ADJLIB
+LDADD = ../libntp/libntp.a
+#EXTRA_DIST = README TAGS
+EXTRA_DIST =
+ETAGS_ARGS = Makefile.am
+subdir = util
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+PROGRAMS = $(bin_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+CPPFLAGS = @CPPFLAGS@
+LIBS = @LIBS@
+ANSI2KNR = @ANSI2KNR@
+byteorder_SOURCES = byteorder.c
+byteorder_OBJECTS = byteorder$U.o
+byteorder_LDADD = $(LDADD)
+byteorder_DEPENDENCIES = ../libntp/libntp.a
+byteorder_LDFLAGS =
+hist_SOURCES = hist.c
+hist_OBJECTS = hist$U.o
+hist_LDADD = $(LDADD)
+hist_DEPENDENCIES = ../libntp/libntp.a
+hist_LDFLAGS =
+jitter_SOURCES = jitter.c
+jitter_OBJECTS = jitter$U.o
+jitter_LDADD = $(LDADD)
+jitter_DEPENDENCIES = ../libntp/libntp.a
+jitter_LDFLAGS =
+kern_SOURCES = kern.c
+kern_OBJECTS = kern$U.o
+kern_LDADD = $(LDADD)
+kern_DEPENDENCIES = ../libntp/libntp.a
+kern_LDFLAGS =
+longsize_SOURCES = longsize.c
+longsize_OBJECTS = longsize$U.o
+longsize_LDADD = $(LDADD)
+longsize_DEPENDENCIES = ../libntp/libntp.a
+longsize_LDFLAGS =
+ntptime_SOURCES = ntptime.c
+ntptime_OBJECTS = ntptime$U.o
+ntptime_LDADD = $(LDADD)
+ntptime_DEPENDENCIES = ../libntp/libntp.a
+ntptime_LDFLAGS =
+precision_SOURCES = precision.c
+precision_OBJECTS = precision$U.o
+precision_LDADD = $(LDADD)
+precision_DEPENDENCIES = ../libntp/libntp.a
+precision_LDFLAGS =
+sht_SOURCES = sht.c
+sht_OBJECTS = sht$U.o
+sht_LDADD = $(LDADD)
+sht_DEPENDENCIES = ../libntp/libntp.a
+sht_LDFLAGS =
+testrs6000_SOURCES = testrs6000.c
+testrs6000_OBJECTS = testrs6000$U.o
+testrs6000_LDADD = $(LDADD)
+testrs6000_DEPENDENCIES = ../libntp/libntp.a
+testrs6000_LDFLAGS =
+tickadj_SOURCES = tickadj.c
+tickadj_OBJECTS = tickadj$U.o
+tickadj_LDADD = $(LDADD)
+tickadj_DEPENDENCIES = ../libntp/libntp.a
+tickadj_LDFLAGS =
+timetrim_SOURCES = timetrim.c
+timetrim_OBJECTS = timetrim$U.o
+timetrim_LDADD = $(LDADD)
+timetrim_DEPENDENCIES = ../libntp/libntp.a
+timetrim_LDFLAGS =
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = byteorder.c hist.c jitter.c kern.c longsize.c ntptime.c \
+precision.c sht.c testrs6000.c tickadj.c timetrim.c
+DIST_COMMON = README Makefile.am Makefile.in ansi2knr.1 ansi2knr.c
+
+
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+GZIP_ENV = --best
+SOURCES = byteorder.c hist.c jitter.c kern.c longsize.c ntptime.c precision.c sht.c testrs6000.c tickadj.c timetrim.c
+OBJECTS = byteorder$U.o hist$U.o jitter$U.o kern$U.o longsize$U.o ntptime$U.o precision$U.o sht$U.o testrs6000$U.o tickadj$U.o timetrim$U.o
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .c .o
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps util/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ f="`echo $$p|sed -e 's/$(EXEEXT)$$//' -e '$(transform)' -e 's/$$/$(EXEEXT)/'`"; \
+ echo " $(INSTALL_PROGRAM) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(bindir)/$$f"; \
+ $(INSTALL_PROGRAM) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(bindir)/$$f; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f="`echo $$p|sed -e 's/$(EXEEXT)$$//' -e '$(transform)' -e 's/$$/$(EXEEXT)/'`"; \
+ echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+mostlyclean-krextra:
+
+clean-krextra:
+ -rm -f ansi2knr
+
+distclean-krextra:
+
+maintainer-clean-krextra:
+ansi2knr: ansi2knr.o
+ $(LINK) ansi2knr.o $(LIBS)
+ansi2knr.o: $(CONFIG_HEADER)
+
+
+mostlyclean-kr:
+ -rm -f *_.c
+
+clean-kr:
+
+distclean-kr:
+
+maintainer-clean-kr:
+byteorder$U.o:
+
+byteorder: $(byteorder_OBJECTS) $(byteorder_DEPENDENCIES)
+ @rm -f byteorder
+ $(LINK) $(byteorder_LDFLAGS) $(byteorder_OBJECTS) $(byteorder_LDADD) $(LIBS)
+hist$U.o:
+
+hist: $(hist_OBJECTS) $(hist_DEPENDENCIES)
+ @rm -f hist
+ $(LINK) $(hist_LDFLAGS) $(hist_OBJECTS) $(hist_LDADD) $(LIBS)
+jitter$U.o:
+
+jitter: $(jitter_OBJECTS) $(jitter_DEPENDENCIES)
+ @rm -f jitter
+ $(LINK) $(jitter_LDFLAGS) $(jitter_OBJECTS) $(jitter_LDADD) $(LIBS)
+kern$U.o:
+
+kern: $(kern_OBJECTS) $(kern_DEPENDENCIES)
+ @rm -f kern
+ $(LINK) $(kern_LDFLAGS) $(kern_OBJECTS) $(kern_LDADD) $(LIBS)
+longsize$U.o:
+
+longsize: $(longsize_OBJECTS) $(longsize_DEPENDENCIES)
+ @rm -f longsize
+ $(LINK) $(longsize_LDFLAGS) $(longsize_OBJECTS) $(longsize_LDADD) $(LIBS)
+ntptime$U.o:
+
+ntptime: $(ntptime_OBJECTS) $(ntptime_DEPENDENCIES)
+ @rm -f ntptime
+ $(LINK) $(ntptime_LDFLAGS) $(ntptime_OBJECTS) $(ntptime_LDADD) $(LIBS)
+precision$U.o:
+
+precision: $(precision_OBJECTS) $(precision_DEPENDENCIES)
+ @rm -f precision
+ $(LINK) $(precision_LDFLAGS) $(precision_OBJECTS) $(precision_LDADD) $(LIBS)
+sht$U.o:
+
+sht: $(sht_OBJECTS) $(sht_DEPENDENCIES)
+ @rm -f sht
+ $(LINK) $(sht_LDFLAGS) $(sht_OBJECTS) $(sht_LDADD) $(LIBS)
+testrs6000$U.o:
+
+testrs6000: $(testrs6000_OBJECTS) $(testrs6000_DEPENDENCIES)
+ @rm -f testrs6000
+ $(LINK) $(testrs6000_LDFLAGS) $(testrs6000_OBJECTS) $(testrs6000_LDADD) $(LIBS)
+tickadj$U.o:
+
+tickadj: $(tickadj_OBJECTS) $(tickadj_DEPENDENCIES)
+ @rm -f tickadj
+ $(LINK) $(tickadj_LDFLAGS) $(tickadj_OBJECTS) $(tickadj_LDADD) $(LIBS)
+timetrim$U.o:
+
+timetrim: $(timetrim_OBJECTS) $(timetrim_DEPENDENCIES)
+ @rm -f timetrim
+ $(LINK) $(timetrim_LDFLAGS) $(timetrim_OBJECTS) $(timetrim_LDADD) $(LIBS)
+byteorder_.c: byteorder.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/byteorder.c; then echo $(srcdir)/byteorder.c; else echo byteorder.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > byteorder_.c
+hist_.c: hist.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/hist.c; then echo $(srcdir)/hist.c; else echo hist.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > hist_.c
+jitter_.c: jitter.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/jitter.c; then echo $(srcdir)/jitter.c; else echo jitter.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > jitter_.c
+kern_.c: kern.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/kern.c; then echo $(srcdir)/kern.c; else echo kern.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > kern_.c
+longsize_.c: longsize.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/longsize.c; then echo $(srcdir)/longsize.c; else echo longsize.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > longsize_.c
+ntptime_.c: ntptime.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntptime.c; then echo $(srcdir)/ntptime.c; else echo ntptime.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntptime_.c
+precision_.c: precision.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/precision.c; then echo $(srcdir)/precision.c; else echo precision.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > precision_.c
+sht_.c: sht.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/sht.c; then echo $(srcdir)/sht.c; else echo sht.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > sht_.c
+testrs6000_.c: testrs6000.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/testrs6000.c; then echo $(srcdir)/testrs6000.c; else echo testrs6000.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > testrs6000_.c
+tickadj_.c: tickadj.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tickadj.c; then echo $(srcdir)/tickadj.c; else echo tickadj.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tickadj_.c
+timetrim_.c: timetrim.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/timetrim.c; then echo $(srcdir)/timetrim.c; else echo timetrim.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > timetrim_.c
+byteorder_.o hist_.o jitter_.o kern_.o longsize_.o ntptime_.o \
+precision_.o sht_.o testrs6000_.o tickadj_.o timetrim_.o : $(ANSI2KNR)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ ${AWK:-awk} ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ ${AWK:-awk} ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+byteorder.o byteorder.lo: byteorder.c
+hist.o hist.lo: hist.c ../config.h ../include/ntp_types.h \
+ ../include/ntp_machine.h ../include/ntp_proto.h
+jitter.o jitter.lo: jitter.c
+kern.o kern.lo: kern.c ../config.h
+longsize.o longsize.lo: longsize.c
+ntptime.o: ntptime.c ../config.h ../include/ntp_fp.h \
+ ../include/ntp_types.h ../include/ntp_machine.h \
+ ../include/ntp_proto.h ../include/ntp_unixtime.h \
+ ../include/ntp_syscall.h ../include/ntp_stdlib.h \
+ ../include/ntp_string.h ../include/l_stdlib.h
+precision.o precision.lo: precision.c ../include/ntp_unixtime.h \
+ ../include/ntp_types.h ../include/ntp_machine.h ../config.h \
+ ../include/ntp_proto.h
+sht.o sht.lo: sht.c
+testrs6000.o testrs6000.lo: testrs6000.c
+tickadj.o: tickadj.c ../config.h ../include/ntp_types.h \
+ ../include/ntp_machine.h ../include/ntp_proto.h \
+ ../include/l_stdlib.h ../include/ntp_io.h \
+ ../include/ntp_stdlib.h ../include/ntp_string.h
+timetrim.o timetrim.lo: timetrim.c
+
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-binPROGRAMS
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-binPROGRAMS
+uninstall: uninstall-am
+all-am: Makefile $(ANSI2KNR) $(PROGRAMS)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_STRIP_FLAG=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \
+ mostlyclean-krextra mostlyclean-kr mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-binPROGRAMS clean-compile clean-krextra clean-kr \
+ clean-tags clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-binPROGRAMS distclean-compile distclean-krextra \
+ distclean-kr distclean-tags distclean-generic clean-am
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-binPROGRAMS \
+ maintainer-clean-compile maintainer-clean-krextra \
+ maintainer-clean-kr maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-krextra distclean-krextra \
+clean-krextra maintainer-clean-krextra mostlyclean-kr distclean-kr \
+clean-kr maintainer-clean-kr tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
+check-am installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all install-strip installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+../libntp/libntp.a:
+ cd ../libntp && $(MAKE)
+
+kern.o: kern.c
+ $(COMPILE) -DHAVE_TIMEX_H -c kern.c
+
+# 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/contrib/ntp/util/README b/contrib/ntp/util/README
new file mode 100644
index 000000000000..b9ed50e19c1e
--- /dev/null
+++ b/contrib/ntp/util/README
@@ -0,0 +1,37 @@
+README file for directory ./util of the NTP Version 4 distribution
+
+This directory contains the sources for the various utility programs.
+See the README and RELNOTES files in the parent directory for directions
+on how to make and install these programs.
+
+The ntptime.c program checks the kernel configuration for the NTP user
+interface syscalls ntp_gettime() and ntp_adjtime(). If present, the
+current timekeeping data are displayed. If not, a dissapointment is
+displayed. See the kernel page file in the HTML documentation in
+distribution for further details. ntptime will be built be if configure
+believes your system can use it.
+
+The jitter.c program can be used to determine the timing jitter due to
+the operating system in a gettimeofday() call. For most systems the
+dominant contribution to the jitter budget is the period of the hardware
+interrupt, usually in the range 10 us-1 ms. For those systems with
+microsecond counters, such as recent Sun and certain HP and DEC systems,
+the jitter is dominated only by the operating system.
+
+The timetrim.c program can be used with SGI machines to implement a
+scheme to discipline the hardware clock frequency. See the source code
+for further information.
+
+The byteorder.c and longsize.c programs are used during the configuration
+process to determine the byte order (little or big endian) and longword
+size (32 or 64 bits). See the configure scripts for further details.
+
+The testrs6000.c program is used for testing purposes with the IBM
+RS/6000 AIX machines. Bill Jones <jones@chpc.utexas.edu> reports:
+"I could not get a tickadj of less then 40 us to work on a RS6000.
+If you set it less then 40 us do so at your own risk!"
+
+The tickadj.c program can be used to read and set various kernel
+parameters affecting NTP operations. See the tickadj page in the HTML
+documentation for further details. tickadj will be built if configure
+believes your system can use it.
diff --git a/contrib/ntp/util/ansi2knr.1 b/contrib/ntp/util/ansi2knr.1
new file mode 100644
index 000000000000..f9ee5a631c2e
--- /dev/null
+++ b/contrib/ntp/util/ansi2knr.1
@@ -0,0 +1,36 @@
+.TH ANSI2KNR 1 "19 Jan 1996"
+.SH NAME
+ansi2knr \- convert ANSI C to Kernighan & Ritchie C
+.SH SYNOPSIS
+.I ansi2knr
+[--varargs] input_file [output_file]
+.SH DESCRIPTION
+If no output_file is supplied, output goes to stdout.
+.br
+There are no error messages.
+.sp
+.I ansi2knr
+recognizes function definitions by seeing a non-keyword identifier at the left
+margin, followed by a left parenthesis, with a right parenthesis as the last
+character on the line, and with a left brace as the first token on the
+following line (ignoring possible intervening comments). It will recognize a
+multi-line header provided that no intervening line ends with a left or right
+brace or a semicolon. These algorithms ignore whitespace and comments, except
+that the function name must be the first thing on the line.
+.sp
+The following constructs will confuse it:
+.br
+ - Any other construct that starts at the left margin and follows the
+above syntax (such as a macro or function call).
+.br
+ - Some macros that tinker with the syntax of the function header.
+.sp
+The --varargs switch is obsolete, and is recognized only for
+backwards compatibility. The present version of
+.I ansi2knr
+will always attempt to convert a ... argument to va_alist and va_dcl.
+.SH AUTHOR
+L. Peter Deutsch <ghost@aladdin.com> wrote the original ansi2knr and
+continues to maintain the current version; most of the code in the current
+version is his work. ansi2knr also includes contributions by Francois
+Pinard <pinard@iro.umontreal.ca> and Jim Avera <jima@netcom.com>.
diff --git a/contrib/ntp/util/ansi2knr.c b/contrib/ntp/util/ansi2knr.c
new file mode 100644
index 000000000000..bc36ce4b51fc
--- /dev/null
+++ b/contrib/ntp/util/ansi2knr.c
@@ -0,0 +1,720 @@
+/* Copyright (C) 1989, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved. */
+
+/*$Id: ansi2knr.c,v 1.2 1999/08/18 23:33:56 stenn Exp $*/
+/* Convert ANSI C function definitions to K&R ("traditional C") syntax */
+
+/*
+ansi2knr is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY. No author or distributor accepts responsibility to anyone for the
+consequences of using it or for whether it serves any particular purpose or
+works at all, unless he says so in writing. Refer to the GNU General Public
+License (the "GPL") for full details.
+
+Everyone is granted permission to copy, modify and redistribute ansi2knr,
+but only under the conditions described in the GPL. A copy of this license
+is supposed to have been given to you along with ansi2knr so you can know
+your rights and responsibilities. It should be in a file named COPYLEFT,
+or, if there is no file named COPYLEFT, a file named COPYING. Among other
+things, the copyright notice and this notice must be preserved on all
+copies.
+
+We explicitly state here what we believe is already implied by the GPL: if
+the ansi2knr program is distributed as a separate set of sources and a
+separate executable file which are aggregated on a storage medium together
+with another program, this in itself does not bring the other program under
+the GPL, nor does the mere fact that such a program or the procedures for
+constructing it invoke the ansi2knr executable bring any other part of the
+program under the GPL.
+*/
+
+/*
+ * Usage:
+ ansi2knr [--filename FILENAME] [INPUT_FILE [OUTPUT_FILE]]
+ * --filename provides the file name for the #line directive in the output,
+ * overriding input_file (if present).
+ * If no input_file is supplied, input is read from stdin.
+ * If no output_file is supplied, output goes to stdout.
+ * There are no error messages.
+ *
+ * ansi2knr recognizes function definitions by seeing a non-keyword
+ * identifier at the left margin, followed by a left parenthesis, with a
+ * right parenthesis as the last character on the line, and with a left
+ * brace as the first token on the following line (ignoring possible
+ * intervening comments and/or preprocessor directives), except that a line
+ * consisting of only
+ * identifier1(identifier2)
+ * will not be considered a function definition unless identifier2 is
+ * the word "void", and a line consisting of
+ * identifier1(identifier2, <<arbitrary>>)
+ * will not be considered a function definition.
+ * ansi2knr will recognize a multi-line header provided that no intervening
+ * line ends with a left or right brace or a semicolon. These algorithms
+ * ignore whitespace, comments, and preprocessor directives, except that
+ * the function name must be the first thing on the line. The following
+ * constructs will confuse it:
+ * - Any other construct that starts at the left margin and
+ * follows the above syntax (such as a macro or function call).
+ * - Some macros that tinker with the syntax of function headers.
+ */
+
+/*
+ * The original and principal author of ansi2knr is L. Peter Deutsch
+ * <ghost@aladdin.com>. Other authors are noted in the change history
+ * that follows (in reverse chronological order):
+ lpd 1999-08-17 added code to allow preprocessor directives
+ wherever comments are allowed
+ lpd 1999-04-12 added minor fixes from Pavel Roskin
+ <pavel_roskin@geocities.com> for clean compilation with
+ gcc -W -Wall
+ lpd 1999-03-22 added hack to recognize lines consisting of
+ identifier1(identifier2, xxx) as *not* being procedures
+ lpd 1999-02-03 made indentation of preprocessor commands consistent
+ lpd 1999-01-28 fixed two bugs: a '/' in an argument list caused an
+ endless loop; quoted strings within an argument list
+ confused the parser
+ lpd 1999-01-24 added a check for write errors on the output,
+ suggested by Jim Meyering <meyering@ascend.com>
+ lpd 1998-11-09 added further hack to recognize identifier(void)
+ as being a procedure
+ lpd 1998-10-23 added hack to recognize lines consisting of
+ identifier1(identifier2) as *not* being procedures
+ lpd 1997-12-08 made input_file optional; only closes input and/or
+ output file if not stdin or stdout respectively; prints
+ usage message on stderr rather than stdout; adds
+ --filename switch (changes suggested by
+ <ceder@lysator.liu.se>)
+ lpd 1996-01-21 added code to cope with not HAVE_CONFIG_H and with
+ compilers that don't understand void, as suggested by
+ Tom Lane
+ lpd 1996-01-15 changed to require that the first non-comment token
+ on the line following a function header be a left brace,
+ to reduce sensitivity to macros, as suggested by Tom Lane
+ <tgl@sss.pgh.pa.us>
+ lpd 1995-06-22 removed #ifndefs whose sole purpose was to define
+ undefined preprocessor symbols as 0; changed all #ifdefs
+ for configuration symbols to #ifs
+ lpd 1995-04-05 changed copyright notice to make it clear that
+ including ansi2knr in a program does not bring the entire
+ program under the GPL
+ lpd 1994-12-18 added conditionals for systems where ctype macros
+ don't handle 8-bit characters properly, suggested by
+ Francois Pinard <pinard@iro.umontreal.ca>;
+ removed --varargs switch (this is now the default)
+ lpd 1994-10-10 removed CONFIG_BROKETS conditional
+ lpd 1994-07-16 added some conditionals to help GNU `configure',
+ suggested by Francois Pinard <pinard@iro.umontreal.ca>;
+ properly erase prototype args in function parameters,
+ contributed by Jim Avera <jima@netcom.com>;
+ correct error in writeblanks (it shouldn't erase EOLs)
+ lpd 1989-xx-xx original version
+ */
+
+/* Most of the conditionals here are to make ansi2knr work with */
+/* or without the GNU configure machinery. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+
+#if HAVE_CONFIG_H
+
+/*
+ For properly autoconfiguring ansi2knr, use AC_CONFIG_HEADER(config.h).
+ This will define HAVE_CONFIG_H and so, activate the following lines.
+ */
+
+# if STDC_HEADERS || HAVE_STRING_H
+# include <string.h>
+# else
+# include <strings.h>
+# endif
+
+#else /* not HAVE_CONFIG_H */
+
+/* Otherwise do it the hard way */
+
+# ifdef BSD
+# include <strings.h>
+# else
+# ifdef VMS
+ extern int strlen(), strncmp();
+# else
+# include <string.h>
+# endif
+# endif
+
+#endif /* not HAVE_CONFIG_H */
+
+#if STDC_HEADERS
+# include <stdlib.h>
+#else
+/*
+ malloc and free should be declared in stdlib.h,
+ but if you've got a K&R compiler, they probably aren't.
+ */
+# ifdef MSDOS
+# include <malloc.h>
+# else
+# ifdef VMS
+ extern char *malloc();
+ extern void free();
+# else
+ extern char *malloc();
+ extern int free();
+# endif
+# endif
+
+#endif
+
+/* Define NULL (for *very* old compilers). */
+#ifndef NULL
+# define NULL (0)
+#endif
+
+/*
+ * The ctype macros don't always handle 8-bit characters correctly.
+ * Compensate for this here.
+ */
+#ifdef isascii
+# undef HAVE_ISASCII /* just in case */
+# define HAVE_ISASCII 1
+#else
+#endif
+#if STDC_HEADERS || !HAVE_ISASCII
+# define is_ascii(c) 1
+#else
+# define is_ascii(c) isascii(c)
+#endif
+
+#define is_space(c) (is_ascii(c) && isspace(c))
+#define is_alpha(c) (is_ascii(c) && isalpha(c))
+#define is_alnum(c) (is_ascii(c) && isalnum(c))
+
+/* Scanning macros */
+#define isidchar(ch) (is_alnum(ch) || (ch) == '_')
+#define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_')
+
+/* Forward references */
+char *ppdirforward();
+char *ppdirbackward();
+char *skipspace();
+char *scanstring();
+int writeblanks();
+int test1();
+int convert1();
+
+/* The main program */
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{ FILE *in = stdin;
+ FILE *out = stdout;
+ char *filename = 0;
+ char *program_name = argv[0];
+ char *output_name = 0;
+#define bufsize 5000 /* arbitrary size */
+ char *buf;
+ char *line;
+ char *more;
+ char *usage =
+ "Usage: ansi2knr [--filename FILENAME] [INPUT_FILE [OUTPUT_FILE]]\n";
+ /*
+ * In previous versions, ansi2knr recognized a --varargs switch.
+ * If this switch was supplied, ansi2knr would attempt to convert
+ * a ... argument to va_alist and va_dcl; if this switch was not
+ * supplied, ansi2knr would simply drop any such arguments.
+ * Now, ansi2knr always does this conversion, and we only
+ * check for this switch for backward compatibility.
+ */
+ int convert_varargs = 1;
+ int output_error;
+
+ while ( argc > 1 && argv[1][0] == '-' ) {
+ if ( !strcmp(argv[1], "--varargs") ) {
+ convert_varargs = 1;
+ argc--;
+ argv++;
+ continue;
+ }
+ if ( !strcmp(argv[1], "--filename") && argc > 2 ) {
+ filename = argv[2];
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+ fprintf(stderr, "%s: Unrecognized switch: %s\n", program_name,
+ argv[1]);
+ fprintf(stderr, usage);
+ exit(1);
+ }
+ switch ( argc )
+ {
+ default:
+ fprintf(stderr, usage);
+ exit(0);
+ case 3:
+ output_name = argv[2];
+ out = fopen(output_name, "w");
+ if ( out == NULL ) {
+ fprintf(stderr, "%s: Cannot open output file %s\n",
+ program_name, output_name);
+ exit(1);
+ }
+ /* falls through */
+ case 2:
+ in = fopen(argv[1], "r");
+ if ( in == NULL ) {
+ fprintf(stderr, "%s: Cannot open input file %s\n",
+ program_name, argv[1]);
+ exit(1);
+ }
+ if ( filename == 0 )
+ filename = argv[1];
+ /* falls through */
+ case 1:
+ break;
+ }
+ if ( filename )
+ fprintf(out, "#line 1 \"%s\"\n", filename);
+ buf = malloc(bufsize);
+ if ( buf == NULL )
+ {
+ fprintf(stderr, "Unable to allocate read buffer!\n");
+ exit(1);
+ }
+ line = buf;
+ while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
+ {
+test: line += strlen(line);
+ switch ( test1(buf) )
+ {
+ case 2: /* a function header */
+ convert1(buf, out, 1, convert_varargs);
+ break;
+ case 1: /* a function */
+ /* Check for a { at the start of the next line. */
+ more = ++line;
+f: if ( line >= buf + (bufsize - 1) ) /* overflow check */
+ goto wl;
+ if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL )
+ goto wl;
+ switch ( *skipspace(ppdirforward(more), 1) )
+ {
+ case '{':
+ /* Definitely a function header. */
+ convert1(buf, out, 0, convert_varargs);
+ fputs(more, out);
+ break;
+ case 0:
+ /* The next line was blank or a comment: */
+ /* keep scanning for a non-comment. */
+ line += strlen(line);
+ goto f;
+ default:
+ /* buf isn't a function header, but */
+ /* more might be. */
+ fputs(buf, out);
+ strcpy(buf, more);
+ line = buf;
+ goto test;
+ }
+ break;
+ case -1: /* maybe the start of a function */
+ if ( line != buf + (bufsize - 1) ) /* overflow check */
+ continue;
+ /* falls through */
+ default: /* not a function */
+wl: fputs(buf, out);
+ break;
+ }
+ line = buf;
+ }
+ if ( line != buf )
+ fputs(buf, out);
+ free(buf);
+ if ( output_name ) {
+ output_error = ferror(out);
+ output_error |= fclose(out);
+ } else { /* out == stdout */
+ fflush(out);
+ output_error = ferror(out);
+ }
+ if ( output_error ) {
+ fprintf(stderr, "%s: error writing to %s\n", program_name,
+ (output_name ? output_name : "stdout"));
+ exit(1);
+ }
+ if ( in != stdin )
+ fclose(in);
+ return 0;
+}
+
+/*
+ * Skip forward or backward over one or more preprocessor directives.
+ */
+char *
+ppdirforward(p)
+ char *p;
+{
+ for (; *p == '#'; ++p) {
+ for (; *p != '\r' && *p != '\n'; ++p)
+ if (*p == 0)
+ return p;
+ if (*p == '\r' && p[1] == '\n')
+ ++p;
+ }
+ return p;
+}
+char *
+ppdirbackward(p, limit)
+ char *p;
+ char *limit;
+{
+ char *np = p;
+
+ for (;; p = --np) {
+ if (*np == '\n' && np[-1] == '\r')
+ --np;
+ for (; np > limit && np[-1] != '\r' && np[-1] != '\n'; --np)
+ if (np[-1] == 0)
+ return np;
+ if (*np != '#')
+ return p;
+ }
+}
+
+/*
+ * Skip over whitespace, comments, and preprocessor directives,
+ * in either direction.
+ */
+char *
+skipspace(p, dir)
+ char *p;
+ int dir; /* 1 for forward, -1 for backward */
+{
+ for ( ; ; ) {
+ while ( is_space(*p) )
+ p += dir;
+ if ( !(*p == '/' && p[dir] == '*') )
+ break;
+ p += dir; p += dir;
+ while ( !(*p == '*' && p[dir] == '/') ) {
+ if ( *p == 0 )
+ return p; /* multi-line comment?? */
+ p += dir;
+ }
+ p += dir; p += dir;
+ }
+ return p;
+}
+
+/* Scan over a quoted string, in either direction. */
+char *
+scanstring(p, dir)
+ char *p;
+ int dir;
+{
+ for (p += dir; ; p += dir)
+ if (*p == '"' && p[-dir] != '\\')
+ return p + dir;
+}
+
+/*
+ * Write blanks over part of a string.
+ * Don't overwrite end-of-line characters.
+ */
+int
+writeblanks(start, end)
+ char *start;
+ char *end;
+{ char *p;
+ for ( p = start; p < end; p++ )
+ if ( *p != '\r' && *p != '\n' )
+ *p = ' ';
+ return 0;
+}
+
+/*
+ * Test whether the string in buf is a function definition.
+ * The string may contain and/or end with a newline.
+ * Return as follows:
+ * 0 - definitely not a function definition;
+ * 1 - definitely a function definition;
+ * 2 - definitely a function prototype (NOT USED);
+ * -1 - may be the beginning of a function definition,
+ * append another line and look again.
+ * The reason we don't attempt to convert function prototypes is that
+ * Ghostscript's declaration-generating macros look too much like
+ * prototypes, and confuse the algorithms.
+ */
+int
+test1(buf)
+ char *buf;
+{ char *p = buf;
+ char *bend;
+ char *endfn;
+ int contin;
+
+ if ( !isidfirstchar(*p) )
+ return 0; /* no name at left margin */
+ bend = skipspace(ppdirbackward(buf + strlen(buf) - 1, buf), -1);
+ switch ( *bend )
+ {
+ case ';': contin = 0 /*2*/; break;
+ case ')': contin = 1; break;
+ case '{': return 0; /* not a function */
+ case '}': return 0; /* not a function */
+ default: contin = -1;
+ }
+ while ( isidchar(*p) )
+ p++;
+ endfn = p;
+ p = skipspace(p, 1);
+ if ( *p++ != '(' )
+ return 0; /* not a function */
+ p = skipspace(p, 1);
+ if ( *p == ')' )
+ return 0; /* no parameters */
+ /* Check that the apparent function name isn't a keyword. */
+ /* We only need to check for keywords that could be followed */
+ /* by a left parenthesis (which, unfortunately, is most of them). */
+ { static char *words[] =
+ { "asm", "auto", "case", "char", "const", "double",
+ "extern", "float", "for", "if", "int", "long",
+ "register", "return", "short", "signed", "sizeof",
+ "static", "switch", "typedef", "unsigned",
+ "void", "volatile", "while", 0
+ };
+ char **key = words;
+ char *kp;
+ unsigned len = endfn - buf;
+
+ while ( (kp = *key) != 0 )
+ { if ( strlen(kp) == len && !strncmp(kp, buf, len) )
+ return 0; /* name is a keyword */
+ key++;
+ }
+ }
+ {
+ char *id = p;
+ int len;
+ /*
+ * Check for identifier1(identifier2) and not
+ * identifier1(void), or identifier1(identifier2, xxxx).
+ */
+
+ while ( isidchar(*p) )
+ p++;
+ len = p - id;
+ p = skipspace(p, 1);
+ if (*p == ',' ||
+ (*p == ')' && (len != 4 || strncmp(id, "void", 4)))
+ )
+ return 0; /* not a function */
+ }
+ /*
+ * If the last significant character was a ), we need to count
+ * parentheses, because it might be part of a formal parameter
+ * that is a procedure.
+ */
+ if (contin > 0) {
+ int level = 0;
+
+ for (p = skipspace(buf, 1); *p; p = skipspace(p + 1, 1))
+ level += (*p == '(' ? 1 : *p == ')' ? -1 : 0);
+ if (level > 0)
+ contin = -1;
+ }
+ return contin;
+}
+
+/* Convert a recognized function definition or header to K&R syntax. */
+int
+convert1(buf, out, header, convert_varargs)
+ char *buf;
+ FILE *out;
+ int header; /* Boolean */
+ int convert_varargs; /* Boolean */
+{ char *endfn;
+ char *p;
+ /*
+ * The breaks table contains pointers to the beginning and end
+ * of each argument.
+ */
+ char **breaks;
+ unsigned num_breaks = 2; /* for testing */
+ char **btop;
+ char **bp;
+ char **ap;
+ char *vararg = 0;
+
+ /* Pre-ANSI implementations don't agree on whether strchr */
+ /* is called strchr or index, so we open-code it here. */
+ for ( endfn = buf; *(endfn++) != '('; )
+ ;
+top: p = endfn;
+ breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
+ if ( breaks == NULL )
+ { /* Couldn't allocate break table, give up */
+ fprintf(stderr, "Unable to allocate break table!\n");
+ fputs(buf, out);
+ return -1;
+ }
+ btop = breaks + num_breaks * 2 - 2;
+ bp = breaks;
+ /* Parse the argument list */
+ do
+ { int level = 0;
+ char *lp = NULL;
+ char *rp = NULL;
+ char *end = NULL;
+
+ if ( bp >= btop )
+ { /* Filled up break table. */
+ /* Allocate a bigger one and start over. */
+ free((char *)breaks);
+ num_breaks <<= 1;
+ goto top;
+ }
+ *bp++ = p;
+ /* Find the end of the argument */
+ for ( ; end == NULL; p++ )
+ { switch(*p)
+ {
+ case ',':
+ if ( !level ) end = p;
+ break;
+ case '(':
+ if ( !level ) lp = p;
+ level++;
+ break;
+ case ')':
+ if ( --level < 0 ) end = p;
+ else rp = p;
+ break;
+ case '/':
+ if (p[1] == '*')
+ p = skipspace(p, 1) - 1;
+ break;
+ case '"':
+ p = scanstring(p, 1) - 1;
+ break;
+ default:
+ ;
+ }
+ }
+ /* Erase any embedded prototype parameters. */
+ if ( lp && rp )
+ writeblanks(lp + 1, rp);
+ p--; /* back up over terminator */
+ /* Find the name being declared. */
+ /* This is complicated because of procedure and */
+ /* array modifiers. */
+ for ( ; ; )
+ { p = skipspace(p - 1, -1);
+ switch ( *p )
+ {
+ case ']': /* skip array dimension(s) */
+ case ')': /* skip procedure args OR name */
+ { int level = 1;
+ while ( level )
+ switch ( *--p )
+ {
+ case ']': case ')':
+ level++;
+ break;
+ case '[': case '(':
+ level--;
+ break;
+ case '/':
+ if (p > buf && p[-1] == '*')
+ p = skipspace(p, -1) + 1;
+ break;
+ case '"':
+ p = scanstring(p, -1) + 1;
+ break;
+ default: ;
+ }
+ }
+ if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
+ { /* We found the name being declared */
+ while ( !isidfirstchar(*p) )
+ p = skipspace(p, 1) + 1;
+ goto found;
+ }
+ break;
+ default:
+ goto found;
+ }
+ }
+found: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
+ { if ( convert_varargs )
+ { *bp++ = "va_alist";
+ vararg = p-2;
+ }
+ else
+ { p++;
+ if ( bp == breaks + 1 ) /* sole argument */
+ writeblanks(breaks[0], p);
+ else
+ writeblanks(bp[-1] - 1, p);
+ bp--;
+ }
+ }
+ else
+ { while ( isidchar(*p) ) p--;
+ *bp++ = p+1;
+ }
+ p = end;
+ }
+ while ( *p++ == ',' );
+ *bp = p;
+ /* Make a special check for 'void' arglist */
+ if ( bp == breaks+2 )
+ { p = skipspace(breaks[0], 1);
+ if ( !strncmp(p, "void", 4) )
+ { p = skipspace(p+4, 1);
+ if ( p == breaks[2] - 1 )
+ { bp = breaks; /* yup, pretend arglist is empty */
+ writeblanks(breaks[0], p + 1);
+ }
+ }
+ }
+ /* Put out the function name and left parenthesis. */
+ p = buf;
+ while ( p != endfn ) putc(*p, out), p++;
+ /* Put out the declaration. */
+ if ( header )
+ { fputs(");", out);
+ for ( p = breaks[0]; *p; p++ )
+ if ( *p == '\r' || *p == '\n' )
+ putc(*p, out);
+ }
+ else
+ { for ( ap = breaks+1; ap < bp; ap += 2 )
+ { p = *ap;
+ while ( isidchar(*p) )
+ putc(*p, out), p++;
+ if ( ap < bp - 1 )
+ fputs(", ", out);
+ }
+ fputs(") ", out);
+ /* Put out the argument declarations */
+ for ( ap = breaks+2; ap <= bp; ap += 2 )
+ (*ap)[-1] = ';';
+ if ( vararg != 0 )
+ { *vararg = 0;
+ fputs(breaks[0], out); /* any prior args */
+ fputs("va_dcl", out); /* the final arg */
+ fputs(bp[0], out);
+ }
+ else
+ fputs(breaks[0], out);
+ }
+ free((char *)breaks);
+ return 0;
+}
diff --git a/contrib/ntp/util/byteorder.c b/contrib/ntp/util/byteorder.c
new file mode 100644
index 000000000000..188536fa89ab
--- /dev/null
+++ b/contrib/ntp/util/byteorder.c
@@ -0,0 +1,56 @@
+/*
+ * This works on:
+ * Crays
+ * Conven
+ * sparc's
+ * Dec mip machines
+ * Dec alpha machines
+ * RS6000
+ * SGI's
+ */
+
+#include <stdio.h>
+
+int
+main(
+ int argc,
+ char *argv[]
+ )
+{
+ int i;
+ int big;
+ union {
+ unsigned long l;
+ char c[sizeof(long)];
+ } u;
+
+#if defined(LONG8)
+ u.l = (((long)0x08070605) << 32) | (long)0x04030201;
+#else
+ u.l = 0x04030201;
+#endif
+ if (sizeof(long) > 4) {
+ if (u.c[0] == 0x08) big = 1;
+ else big = 0;
+ } else {
+ if (u.c[0] == 0x04) big = 1;
+ else big = 0;
+ }
+ for (i=0; i< sizeof(long); i++) {
+ if (big == 1 && (u.c[i] == (sizeof(long) - i))) {
+ continue;
+ } else if (big == 0 && (u.c[i] == (i+1))) {
+ continue;
+ } else {
+ big = -1;
+ break;
+ }
+ }
+
+ if (big == 1) {
+ printf("XNTP_BIG_ENDIAN\n");
+ } else if (big == 0) {
+ printf("XNTP_LITTLE_ENDIAN\n");
+ }
+ exit(0);
+}
diff --git a/contrib/ntp/util/hist.c b/contrib/ntp/util/hist.c
new file mode 100644
index 000000000000..ee4e93ad6a27
--- /dev/null
+++ b/contrib/ntp/util/hist.c
@@ -0,0 +1,107 @@
+/*
+ * This program can be used to calibrate the clock reading jitter of a
+ * particular CPU and operating system. It first tickles every element
+ * of an array, in order to force pages into memory, then repeatedly calls
+ * gettimeofday() and, finally, writes out the time values for later
+ * analysis. From this you can determine the jitter and if the clock ever
+ * runs backwards.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "ntp_types.h"
+
+#define NBUF 100001 /* size of basic histogram */
+#define NSRT 20000 /* size of overflow histogram */
+#define NCNT (600 * 1000000) /* sample interval (us) */
+
+int col P((long *, long *));
+
+int
+main(
+ int argc,
+ char *argv[]
+ )
+{
+ struct timeval ts, tr, tp;
+ struct timezone tzp;
+ int i, j, n;
+ long t, u, v, w, gtod[NBUF], ovfl[NSRT];
+
+ /*
+ * Force pages into memory
+ */
+ for (i = 0; i < NBUF; i++)
+ gtod[i] = 0;
+ for (i = 0; i < NSRT; i++)
+ ovfl[i] = 0;
+
+ /*
+ * Construct histogram
+ */
+ n = 0;
+ gettimeofday(&ts, &tzp);
+ t = ts.tv_sec * 1000000 + ts.tv_usec;
+ v = t;
+ while (1) {
+ gettimeofday(&tr, &tzp);
+ u = tr.tv_sec * 1000000 + tr.tv_usec;
+ if (u - v > NCNT)
+ break;
+ w = u - t;
+ if (w <= 0) {
+/*
+ printf("error <= 0 %ld %d %d, %d %d\n", w, ts.tv_sec,
+ ts.tv_usec, tr.tv_sec, tr.tv_usec);
+*/
+ } else if (w > NBUF - 1) {
+ ovfl[n] = w;
+ if (n < NSRT - 1)
+ n++;
+ } else {
+ gtod[w]++;
+ }
+ ts = tr;
+ t = u;
+ }
+
+ /*
+ * Write out histogram
+ */
+ for (i = 0; i < NBUF - 1; i++) {
+ if (gtod[i] > 0)
+ printf("%ld %ld\n", i, gtod[i]);
+ }
+ if (n == 0)
+ return;
+ qsort((char *)ovfl, (int)n, sizeof(long), col);
+ w = 0;
+ j = 0;
+ for (i = 0; i < n; i++) {
+ if (ovfl[i] != w) {
+ if (j > 0)
+ printf("%ld %ld\n", w, j);
+ w = ovfl[i];
+ j = 1;
+ } else
+ j++;
+ }
+ if (j > 0)
+ printf("%ld %ld\n", w, j);
+
+ exit(0);
+}
+
+int
+col(
+ long *x,
+ long *y
+ )
+{
+ return (*x - *y);
+}
diff --git a/contrib/ntp/util/jitter.c b/contrib/ntp/util/jitter.c
new file mode 100644
index 000000000000..79f47573f584
--- /dev/null
+++ b/contrib/ntp/util/jitter.c
@@ -0,0 +1,70 @@
+/*
+ * This program can be used to calibrate the clock reading jitter of a
+ * particular CPU and operating system. It first tickles every element
+ * of an array, in order to force pages into memory, then repeatedly calls
+ * gettimeofday() and, finally, writes out the time values for later
+ * analysis. From this you can determine the jitter and if the clock ever
+ * runs backwards.
+ */
+#include <sys/time.h>
+#include <stdio.h>
+
+#define NBUF 20002
+
+int
+main(
+ int argc,
+ char *argv[]
+ )
+{
+ struct timeval ts, tr;
+ struct timezone tzp;
+ long temp, j, i, gtod[NBUF];
+
+ gettimeofday(&ts, &tzp);
+
+ /*
+ * Force pages into memory
+ */
+ for (i = 0; i < NBUF; i ++)
+ gtod[i] = 0;
+
+ /*
+ * Construct gtod array
+ */
+ for (i = 0; i < NBUF; i ++) {
+ gettimeofday(&tr, &tzp);
+ gtod[i] = (tr.tv_sec - ts.tv_sec) * 1000000 + tr.tv_usec;
+ }
+
+ /*
+ * Write out gtod array for later processing with S
+ */
+ for (i = 0; i < NBUF - 2; i++) {
+ /*
+ printf("%lu\n", gtod[i]);
+ */
+ gtod[i] = gtod[i + 1] - gtod[i];
+ printf("%lu\n", gtod[i]);
+ }
+
+ /*
+ * Sort the gtod array and display deciles
+ */
+ for (i = 0; i < NBUF - 2; i++) {
+ for (j = 0; j <= i; j++) {
+ if (gtod[j] > gtod[i]) {
+ temp = gtod[j];
+ gtod[j] = gtod[i];
+ gtod[i] = temp;
+ }
+ }
+ }
+ fprintf(stderr, "First rank\n");
+ for (i = 0; i < 10; i++)
+ fprintf(stderr, "%10ld%10ld\n", i, gtod[i]);
+ fprintf(stderr, "Last rank\n");
+ for (i = NBUF - 12; i < NBUF - 2; i++)
+ fprintf(stderr, "%10ld%10ld\n", i, gtod[i]);
+ exit(0);
+}
diff --git a/contrib/ntp/util/kern.c b/contrib/ntp/util/kern.c
new file mode 100644
index 000000000000..37d925723761
--- /dev/null
+++ b/contrib/ntp/util/kern.c
@@ -0,0 +1,224 @@
+/*
+ * This program simulates a first-order, type-II phase-lock loop using
+ * actual code segments from modified kernel distributions for SunOS,
+ * Ultrix and OSF/1 kernels. These segments do not use any licensed code.
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+#include <sys/time.h>
+
+#ifdef HAVE_TIMEX_H
+# include "timex.h"
+#endif
+
+/*
+ * Phase-lock loop definitions
+ */
+#define HZ 100 /* timer interrupt frequency (Hz) */
+#define MAXPHASE 512000 /* max phase error (us) */
+#define MAXFREQ 200 /* max frequency error (ppm) */
+#define TAU 2 /* time constant (shift 0 - 6) */
+#define POLL 16 /* interval between updates (s) */
+#define MAXSEC 1200 /* max interval between updates (s) */
+
+/*
+ * Function declarations
+ */
+void hardupdate();
+void hardclock();
+void second_overflow();
+
+/*
+ * Kernel variables
+ */
+int tick; /* timer interrupt period (us) */
+int fixtick; /* amortization constant (ppm) */
+struct timeval timex; /* ripoff of kernel time variable */
+
+/*
+ * Phase-lock loop variables
+ */
+int time_status = TIME_BAD; /* clock synchronization status */
+long time_offset = 0; /* time adjustment (us) */
+long time_constant = 0; /* pll time constant */
+long time_tolerance = MAXFREQ; /* frequency tolerance (ppm) */
+long time_precision = 1000000 / HZ; /* clock precision (us) */
+long time_maxerror = MAXPHASE; /* maximum error (us) */
+long time_esterror = MAXPHASE; /* estimated error (us) */
+long time_phase = 0; /* phase offset (scaled us) */
+long time_freq = 0; /* frequency offset (scaled ppm) */
+long time_adj = 0; /* tick adjust (scaled 1 / HZ) */
+long time_reftime = 0; /* time at last adjustment (s) */
+
+/*
+ * Simulation variables
+ */
+double timey = 0; /* simulation time (us) */
+long timez = 0; /* current error (us) */
+long poll_interval = 0; /* poll counter */
+
+/*
+ * Simulation test program
+ */
+int
+main(
+ int argc,
+ char *argv[]
+ )
+{
+ tick = 1000000 / HZ;
+ fixtick = 1000000 % HZ;
+ timex.tv_sec = 0;
+ timex.tv_usec = MAXPHASE;
+ time_freq = 0;
+ time_constant = TAU;
+ printf("tick %d us, fixtick %d us\n", tick, fixtick);
+ printf(" time offset freq _offset _freq _adj\n");
+
+ /*
+ * Grind the loop until ^C
+ */
+ while (1) {
+ timey += (double)(1000000) / HZ;
+ if (timey >= 1000000)
+ timey -= 1000000;
+ hardclock();
+ if (timex.tv_usec >= 1000000) {
+ timex.tv_usec -= 1000000;
+ timex.tv_sec++;
+ second_overflow();
+ poll_interval++;
+ if (!(poll_interval % POLL)) {
+ timez = (long)timey - timex.tv_usec;
+ if (timez > 500000)
+ timez -= 1000000;
+ if (timez < -500000)
+ timez += 1000000;
+ hardupdate(timez);
+ printf("%10li%10li%10.2f %08lx %08lx %08lx\n",
+ timex.tv_sec, timez,
+ (double)time_freq / (1 << SHIFT_KF),
+ time_offset, time_freq, time_adj);
+ }
+ }
+ }
+}
+
+/*
+ * This routine simulates the ntp_adjtime() call
+ *
+ * For default SHIFT_UPDATE = 12, offset is limited to +-512 ms, the
+ * maximum interval between updates is 4096 s and the maximum frequency
+ * offset is +-31.25 ms/s.
+ */
+void
+hardupdate(
+ long offset
+ )
+{
+ long ltemp, mtemp;
+
+ time_offset = offset << SHIFT_UPDATE;
+ mtemp = timex.tv_sec - time_reftime;
+ time_reftime = timex.tv_sec;
+ if (mtemp > MAXSEC)
+ mtemp = 0;
+
+ /* ugly multiply should be replaced */
+ if (offset < 0)
+ time_freq -= (-offset * mtemp) >>
+ (time_constant + time_constant);
+ else
+ time_freq += (offset * mtemp) >>
+ (time_constant + time_constant);
+ ltemp = time_tolerance << SHIFT_KF;
+ if (time_freq > ltemp)
+ time_freq = ltemp;
+ else if (time_freq < -ltemp)
+ time_freq = -ltemp;
+ if (time_status == TIME_BAD)
+ time_status = TIME_OK;
+}
+
+/*
+ * This routine simulates the timer interrupt
+ */
+void
+hardclock(void)
+{
+ int ltemp, time_update;
+
+ time_update = tick; /* computed by adjtime() */
+ time_phase += time_adj;
+ if (time_phase < -FINEUSEC) {
+ ltemp = -time_phase >> SHIFT_SCALE;
+ time_phase += ltemp << SHIFT_SCALE;
+ time_update -= ltemp;
+ }
+ else if (time_phase > FINEUSEC) {
+ ltemp = time_phase >> SHIFT_SCALE;
+ time_phase -= ltemp << SHIFT_SCALE;
+ time_update += ltemp;
+ }
+ timex.tv_usec += time_update;
+}
+
+/*
+ * This routine simulates the overflow of the microsecond field
+ *
+ * With SHIFT_SCALE = 23, the maximum frequency adjustment is +-256 us
+ * per tick, or 25.6 ms/s at a clock frequency of 100 Hz. The time
+ * contribution is shifted right a minimum of two bits, while the frequency
+ * contribution is a right shift. Thus, overflow is prevented if the
+ * frequency contribution is limited to half the maximum or 15.625 ms/s.
+ */
+void
+second_overflow(void)
+{
+ int ltemp;
+
+ time_maxerror += time_tolerance;
+ if (time_offset < 0) {
+ ltemp = -time_offset >>
+ (SHIFT_KG + time_constant);
+ time_offset += ltemp;
+ time_adj = -(ltemp <<
+ (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE));
+ } else {
+ ltemp = time_offset >>
+ (SHIFT_KG + time_constant);
+ time_offset -= ltemp;
+ time_adj = ltemp <<
+ (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
+ }
+ if (time_freq < 0)
+ time_adj -= -time_freq >> (SHIFT_KF + SHIFT_HZ - SHIFT_SCALE);
+ else
+ time_adj += time_freq >> (SHIFT_KF + SHIFT_HZ - SHIFT_SCALE);
+ time_adj += fixtick << (SHIFT_SCALE - SHIFT_HZ);
+
+ /* ugly divide should be replaced */
+ if (timex.tv_sec % 86400 == 0) {
+ switch (time_status) {
+
+ case TIME_INS:
+ timex.tv_sec--; /* !! */
+ time_status = TIME_OOP;
+ break;
+
+ case TIME_DEL:
+ timex.tv_sec++;
+ time_status = TIME_OK;
+ break;
+
+ case TIME_OOP:
+ time_status = TIME_OK;
+ break;
+ }
+ }
+}
diff --git a/contrib/ntp/util/longsize.c b/contrib/ntp/util/longsize.c
new file mode 100644
index 000000000000..bba19557ad74
--- /dev/null
+++ b/contrib/ntp/util/longsize.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+main()
+{
+ if (sizeof(long) == 8) {
+ printf("-DLONG8\n");
+ } else if (sizeof(long) == 4) {
+ printf("-DLONG4\n");
+ }
+ exit(0);
+}
diff --git a/contrib/ntp/util/ntptime.c b/contrib/ntp/util/ntptime.c
new file mode 100644
index 000000000000..1a6f2f363723
--- /dev/null
+++ b/contrib/ntp/util/ntptime.c
@@ -0,0 +1,399 @@
+/*
+ * NTP test program
+ *
+ * This program tests to see if the NTP user interface routines
+ * ntp_gettime() and ntp_adjtime() have been implemented in the kernel.
+ * If so, each of these routines is called to display current timekeeping
+ * data.
+ *
+ * For more information, see the README.kern file in the doc directory
+ * of the xntp3 distribution.
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <setjmp.h>
+
+#include "ntp_fp.h"
+#include "ntp_unixtime.h"
+#include "ntp_syscall.h"
+#include "ntp_stdlib.h"
+
+#ifdef NTP_SYSCALLS_STD
+# ifndef SYS_DECOSF1
+# define BADCALL -1 /* this is supposed to be a bad syscall */
+# endif /* SYS_DECOSF1 */
+#endif
+
+#ifdef HAVE_TV_NSEC_IN_NTPTIMEVAL
+#define tv_frac_sec tv_nsec
+#else
+#define tv_frac_sec tv_usec
+#endif
+
+
+#define TIMEX_MOD_BITS \
+"\20\1OFFSET\2FREQUENCY\3MAXERROR\4ESTERROR\5STATUS\6TIMECONST\
+\13PLL\14FLL\15MICRO\16NANO\17CLKB\20CLKA"
+
+#define TIMEX_STA_BITS \
+"\20\1PLL\2PPSFREQ\3PPSTIME\4FLL\5INS\6DEL\7UNSYNC\10FREQHOLD\
+\11PPSSIGNAL\12PPSJITTER\13PPSWANDER\14PPSERROR\15CLOCKERR\
+\16NANO\17MODE\20CLK"
+
+#define SCALE_FREQ 65536 /* frequency scale */
+
+
+/*
+ * Function prototypes
+ */
+char *sprintb P((u_int, const char *));
+const char *timex_state P((int));
+volatile int debug = 0;
+
+#ifdef SIGSYS
+void pll_trap P((int));
+
+static struct sigaction newsigsys; /* new sigaction status */
+static struct sigaction sigsys; /* current sigaction status */
+static sigjmp_buf env; /* environment var. for pll_trap() */
+#endif
+
+static volatile int pll_control; /* (0) daemon, (1) kernel loop */
+static volatile int status; /* most recent status bits */
+static volatile int flash; /* most recent ntp_adjtime() bits */
+char* progname;
+static char optargs[] = "cde:f:hm:o:rs:t:";
+
+int
+main(
+ int argc,
+ char *argv[]
+ )
+{
+ extern int ntp_optind;
+ extern char *ntp_optarg;
+#ifdef SUBST_ADJTIMEX
+ struct timex ntv;
+#else
+ struct ntptimeval ntv;
+#endif
+ struct timeval tv;
+ struct timex ntx, _ntx;
+ int times[20];
+ double ftemp, gtemp, htemp;
+ long time_frac; /* ntv.time.tv_frac_sec (us/ns) */
+ l_fp ts;
+ unsigned ts_mask = TS_MASK; /* defaults to 20 bits (us) */
+ unsigned ts_roundbit = TS_ROUNDBIT; /* defaults to 20 bits (us) */
+ int fdigits = 6; /* fractional digits for us */
+ int c;
+ int errflg = 0;
+ int cost = 0;
+ int rawtime = 0;
+
+ memset((char *)&ntx, 0, sizeof(ntx));
+ progname = argv[0];
+ while ((c = ntp_getopt(argc, argv, optargs)) != EOF) switch (c) {
+ case 'c':
+ cost++;
+ break;
+ case 'd':
+ debug++;
+ break;
+ case 'e':
+ ntx.modes |= MOD_ESTERROR;
+ ntx.esterror = atoi(ntp_optarg);
+ break;
+ case 'f':
+ ntx.modes |= MOD_FREQUENCY;
+ ntx.freq = (long)(atof(ntp_optarg) * SCALE_FREQ);
+ break;
+ case 'm':
+ ntx.modes |= MOD_MAXERROR;
+ ntx.maxerror = atoi(ntp_optarg);
+ break;
+ case 'o':
+ ntx.modes |= MOD_OFFSET;
+ ntx.offset = atoi(ntp_optarg);
+ break;
+ case 'r':
+ rawtime++;
+ break;
+ case 's':
+ ntx.modes |= MOD_STATUS;
+ ntx.status = atoi(ntp_optarg);
+ if (ntx.status < 0 || ntx.status > 4) errflg++;
+ break;
+ case 't':
+ ntx.modes |= MOD_TIMECONST;
+ ntx.constant = atoi(ntp_optarg);
+ break;
+ default:
+ errflg++;
+ }
+ if (errflg || (ntp_optind != argc)) {
+ (void) fprintf(stderr,
+ "usage: %s [-%s]\n\n\
+-c display the time taken to call ntp_gettime (us)\n\
+-e esterror estimate of the error (us)\n\
+-f frequency Frequency error (-500 .. 500) (ppm)\n\
+-h display this help info\n\
+-m maxerror max possible error (us)\n\
+-o offset current offset (ms)\n\
+-r print the unix and NTP time raw\n\
+-l leap Set the leap bits\n\
+-t timeconstant log2 of PLL time constant (0 .. %d)\n",
+ progname, optargs, MAXTC);
+ exit(2);
+ }
+
+#ifdef SIGSYS
+ /*
+ * Test to make sure the sigaction() works in case of invalid
+ * syscall codes.
+ */
+ newsigsys.sa_handler = pll_trap;
+ newsigsys.sa_flags = 0;
+ if (sigaction(SIGSYS, &newsigsys, &sigsys)) {
+ perror("sigaction() fails to save SIGSYS trap");
+ exit(1);
+ }
+#endif /* SIGSYS */
+
+#ifdef BADCALL
+ /*
+ * Make sure the trapcatcher works.
+ */
+ pll_control = 1;
+#ifdef SIGSYS
+ if (sigsetjmp(env, 1) == 0)
+ {
+#endif
+ status = syscall(BADCALL, &ntv); /* dummy parameter */
+ if ((status < 0) && (errno == ENOSYS))
+ --pll_control;
+#ifdef SIGSYS
+ }
+#endif
+ if (pll_control)
+ printf("sigaction() failed to catch an invalid syscall\n");
+#endif /* BADCALL */
+
+ if (cost) {
+#ifdef SIGSYS
+ if (sigsetjmp(env, 1) == 0) {
+#endif
+ for (c = 0; c < sizeof times / sizeof times[0]; c++) {
+ status = ntp_gettime(&ntv);
+ if ((status < 0) && (errno == ENOSYS))
+ --pll_control;
+ if (pll_control < 0)
+ break;
+ times[c] = ntv.time.tv_frac_sec;
+ }
+#ifdef SIGSYS
+ }
+#endif
+ if (pll_control >= 0) {
+ printf("[ us %06d:", times[0]);
+ for (c = 1; c < sizeof times / sizeof times[0]; c++)
+ printf(" %d", times[c] - times[c - 1]);
+ printf(" ]\n");
+ }
+ }
+#ifdef SIGSYS
+ if (sigsetjmp(env, 1) == 0) {
+#endif
+ status = ntp_gettime(&ntv);
+ if ((status < 0) && (errno == ENOSYS))
+ --pll_control;
+#ifdef SIGSYS
+ }
+#endif
+ _ntx.modes = 0; /* Ensure nothing is set */
+#ifdef SIGSYS
+ if (sigsetjmp(env, 1) == 0) {
+#endif
+ status = ntp_adjtime(&_ntx);
+ if ((status < 0) && (errno == ENOSYS))
+ --pll_control;
+ flash = _ntx.status;
+#ifdef SIGSYS
+ }
+#endif
+ if (pll_control < 0) {
+ printf("NTP user interface routines are not configured in this kernel.\n");
+ goto lexit;
+ }
+
+ /*
+ * Fetch timekeeping data and display.
+ */
+ status = ntp_gettime(&ntv);
+ if (status < 0)
+ perror("ntp_gettime() call fails");
+ else {
+ printf("ntp_gettime() returns code %d (%s)\n",
+ status, timex_state(status));
+ time_frac = ntv.time.tv_frac_sec;
+#ifdef STA_NANO
+ if (flash & STA_NANO) {
+ ntv.time.tv_frac_sec /= 1000;
+ ts_mask = 0xfffffffc; /* 1/2^30 */
+ ts_roundbit = 0x00000002;
+ fdigits = 9;
+ }
+#endif
+ tv.tv_sec = ntv.time.tv_sec;
+ tv.tv_usec = ntv.time.tv_frac_sec;
+ TVTOTS(&tv, &ts);
+ ts.l_ui += JAN_1970;
+ ts.l_uf += ts_roundbit;
+ ts.l_uf &= ts_mask;
+ printf(" time %s, (.%0*d),\n",
+ prettydate(&ts), fdigits, (int) time_frac);
+ printf(" maximum error %lu us, estimated error %lu us.\n",
+ (u_long)ntv.maxerror, (u_long)ntv.esterror);
+ if (rawtime) printf(" ntptime=%x.%x unixtime=%x.%0*d %s",
+ (unsigned int) ts.l_ui, (unsigned int) ts.l_uf,
+ (int) ntv.time.tv_sec, fdigits, (int) time_frac,
+ ctime((const time_t *) &ntv.time.tv_sec));
+ }
+ status = ntp_adjtime(&ntx);
+ if (status < 0)
+ perror((errno == EPERM) ?
+ "Must be root to set kernel values\nntp_adjtime() call fails" :
+ "ntp_adjtime() call fails");
+ else {
+ flash = ntx.status;
+ printf("ntp_adjtime() returns code %d (%s)\n",
+ status, timex_state(status));
+ printf(" modes %s,\n", sprintb(ntx.modes, TIMEX_MOD_BITS));
+ ftemp = (double)ntx.offset;
+#ifdef STA_NANO
+ if (flash & STA_NANO)
+ ftemp /= 1000.0;
+#endif
+ printf(" offset %.3f", ftemp);
+ ftemp = (double)ntx.freq / SCALE_FREQ;
+ printf(" us, frequency %.3f ppm, interval %d s,\n",
+ ftemp, 1 << ntx.shift);
+ printf(" maximum error %lu us, estimated error %lu us,\n",
+ (u_long)ntx.maxerror, (u_long)ntx.esterror);
+ printf(" status %s,\n", sprintb((u_int)ntx.status, TIMEX_STA_BITS));
+ ftemp = (double)ntx.tolerance / SCALE_FREQ;
+ gtemp = (double)ntx.precision;
+#ifdef STA_NANO
+ if (flash & STA_NANO)
+ gtemp /= 1000.0;
+#endif
+ printf(
+ " time constant %lu, precision %.3f us, tolerance %.0f ppm,\n",
+ (u_long)ntx.constant, gtemp, ftemp);
+ if (ntx.shift == 0)
+ exit (0);
+ ftemp = (double)ntx.ppsfreq / SCALE_FREQ;
+ gtemp = (double)ntx.stabil / SCALE_FREQ;
+ htemp = (double)ntx.jitter;
+#ifdef STA_NANO
+ if (flash & STA_NANO)
+ htemp /= 1000.0;
+#endif
+ printf(
+ " pps frequency %.3f ppm, stability %.3f ppm, jitter %.3f us,\n",
+ ftemp, gtemp, htemp);
+ printf(" intervals %lu, jitter exceeded %lu, stability exceeded %lu, errors %lu.\n",
+ (u_long)ntx.calcnt, (u_long)ntx.jitcnt,
+ (u_long)ntx.stbcnt, (u_long)ntx.errcnt);
+ return (0);
+ }
+
+ /*
+ * Put things back together the way we found them.
+ */
+ lexit:
+#ifdef SIGSYS
+ if (sigaction(SIGSYS, &sigsys, (struct sigaction *)NULL)) {
+ perror("sigaction() fails to restore SIGSYS trap");
+ exit(1);
+ }
+#endif
+ exit(0);
+}
+
+#ifdef SIGSYS
+/*
+ * pll_trap - trap processor for undefined syscalls
+ */
+void
+pll_trap(
+ int arg
+ )
+{
+ pll_control--;
+ siglongjmp(env, 1);
+}
+#endif
+
+/*
+ * Print a value a la the %b format of the kernel's printf
+ */
+char *
+sprintb(
+ register u_int v,
+ register const char *bits
+ )
+{
+ register char *cp;
+ register int i, any = 0;
+ register char c;
+ static char buf[132];
+
+ if (bits && *bits == 8)
+ (void)sprintf(buf, "0%o", v);
+ else
+ (void)sprintf(buf, "0x%x", v);
+ cp = buf + strlen(buf);
+ bits++;
+ if (bits) {
+ *cp++ = ' ';
+ *cp++ = '(';
+ while ((i = *bits++) != 0) {
+ if (v & (1 << (i-1))) {
+ if (any)
+ *cp++ = ',';
+ any = 1;
+ for (; (c = *bits) > 32; bits++)
+ *cp++ = c;
+ } else
+ for (; *bits > 32; bits++)
+ continue;
+ }
+ *cp++ = ')';
+ }
+ *cp = '\0';
+ return (buf);
+}
+
+const char *timex_states[] = {
+ "OK", "INS", "DEL", "OOP", "WAIT", "ERROR"
+};
+
+const char *
+timex_state(
+ register int s
+ )
+{
+ static char buf[32];
+
+ if (s >= 0 && s <= sizeof(timex_states) / sizeof(timex_states[0]))
+ return (timex_states[s]);
+ sprintf(buf, "TIME-#%d", s);
+ return (buf);
+}
diff --git a/contrib/ntp/util/precision.c b/contrib/ntp/util/precision.c
new file mode 100644
index 000000000000..0fd3c3a3a726
--- /dev/null
+++ b/contrib/ntp/util/precision.c
@@ -0,0 +1,172 @@
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include "ntp_unixtime.h"
+
+#define DEFAULT_SYS_PRECISION -99
+
+int default_get_resolution();
+int default_get_precision();
+
+int
+main(
+ int argc,
+ char *argv[]
+ )
+{
+ printf("log2(resolution) = %d, log2(precision) = %d\n",
+ default_get_resolution(),
+ default_get_precision());
+ return 0;
+}
+
+/* Find the resolution of the system clock by watching how the current time
+ * changes as we read it repeatedly.
+ *
+ * struct timeval is only good to 1us, which may cause problems as machines
+ * get faster, but until then the logic goes:
+ *
+ * If a machine has resolution (i.e. accurate timing info) > 1us, then it will
+ * probably use the "unused" low order bits as a counter (to force time to be
+ * a strictly increaing variable), incrementing it each time any process
+ * requests the time [[ or maybe time will stand still ? ]].
+ *
+ * SO: the logic goes:
+ *
+ * IF the difference from the last time is "small" (< MINSTEP)
+ * THEN this machine is "counting" with the low order bits
+ * ELIF this is not the first time round the loop
+ * THEN this machine *WAS* counting, and has now stepped
+ * ELSE this machine has resolution < time to read clock
+ *
+ * SO: if it exits on the first loop, assume "full accuracy" (1us)
+ * otherwise, take the log2(observered difference, rounded UP)
+ *
+ * MINLOOPS > 1 ensures that even if there is a STEP between the initial call
+ * and the first loop, it doesn't stop too early.
+ * Making it even greater allows MINSTEP to be reduced, assuming that the
+ * chance of MINSTEP-1 other processes getting in and calling gettimeofday
+ * between this processes's calls.
+ * Reducing MINSTEP may be necessary as this sets an upper bound for the time
+ * to actually call gettimeofday.
+ */
+
+#define DUSECS 1000000
+#define HUSECS (1024 * 1024)
+#define MINSTEP 5 /* some systems increment uS on each call */
+/* Don't use "1" as some *other* process may read too*/
+/*We assume no system actually *ANSWERS* in this time*/
+#define MAXSTEP 20000 /* maximum clock increment (us) */
+#define MINLOOPS 5 /* minimum number of step samples */
+#define MAXLOOPS HUSECS /* Assume precision < .1s ! */
+
+int
+default_get_resolution(void)
+{
+ struct timeval tp;
+ struct timezone tzp;
+ long last;
+ int i;
+ long diff;
+ long val;
+ int minsteps = MINLOOPS; /* need at least this many steps */
+
+ gettimeofday(&tp, &tzp);
+ last = tp.tv_usec;
+ for (i = - --minsteps; i< MAXLOOPS; i++) {
+ gettimeofday(&tp, &tzp);
+ diff = tp.tv_usec - last;
+ if (diff < 0) diff += DUSECS;
+ if (diff > MINSTEP) if (minsteps-- <= 0) break;
+ last = tp.tv_usec;
+ }
+
+ printf("resolution = %ld usec after %d loop%s\n",
+ diff, i, (i==1) ? "" : "s");
+
+ diff = (diff *3)/2;
+ if (i >= MAXLOOPS) {
+ printf(
+ " (Boy this machine is fast ! %d loops without a step)\n",
+ MAXLOOPS);
+ diff = 1; /* No STEP, so FAST machine */
+ }
+ if (i == 0) {
+ printf(
+ " (The resolution is less than the time to read the clock -- Assume 1us)\n");
+ diff = 1; /* time to read clock >= resolution */
+ }
+ for (i=0, val=HUSECS; val>0; i--, val >>= 1) if (diff >= val) return i;
+ printf(" (Oh dear -- that wasn't expected ! I'll guess !)\n");
+ return DEFAULT_SYS_PRECISION /* Something's BUST, so lie ! */;
+}
+
+/* ===== Rest of this code lifted straight from xntpd/ntp_proto.c ! ===== */
+
+/*
+ * This routine calculates the differences between successive calls to
+ * gettimeofday(). If a difference is less than zero, the us field
+ * has rolled over to the next second, so we add a second in us. If
+ * the difference is greater than zero and less than MINSTEP, the
+ * clock has been advanced by a small amount to avoid standing still.
+ * If the clock has advanced by a greater amount, then a timer interrupt
+ * has occurred and this amount represents the precision of the clock.
+ * In order to guard against spurious values, which could occur if we
+ * happen to hit a fat interrupt, we do this for MINLOOPS times and
+ * keep the minimum value obtained.
+ */
+int
+default_get_precision(void)
+{
+ struct timeval tp;
+ struct timezone tzp;
+#ifdef HAVE_GETCLOCK
+ struct timespec ts;
+#endif
+ long last;
+ int i;
+ long diff;
+ long val;
+ long usec;
+
+ usec = 0;
+ val = MAXSTEP;
+#ifdef HAVE_GETCLOCK
+ (void) getclock(TIMEOFDAY, &ts);
+ tp.tv_sec = ts.tv_sec;
+ tp.tv_usec = ts.tv_nsec / 1000;
+#else /* not HAVE_GETCLOCK */
+ GETTIMEOFDAY(&tp, &tzp);
+#endif /* not HAVE_GETCLOCK */
+ last = tp.tv_usec;
+ for (i = 0; i < MINLOOPS && usec < HUSECS;) {
+#ifdef HAVE_GETCLOCK
+ (void) getclock(TIMEOFDAY, &ts);
+ tp.tv_sec = ts.tv_sec;
+ tp.tv_usec = ts.tv_nsec / 1000;
+#else /* not HAVE_GETCLOCK */
+ GETTIMEOFDAY(&tp, &tzp);
+#endif /* not HAVE_GETCLOCK */
+ diff = tp.tv_usec - last;
+ last = tp.tv_usec;
+ if (diff < 0)
+ diff += DUSECS;
+ usec += diff;
+ if (diff > MINSTEP) {
+ i++;
+ if (diff < val)
+ val = diff;
+ }
+ }
+ printf("precision = %ld usec after %d loop%s\n",
+ val, i, (i == 1) ? "" : "s");
+ if (usec >= HUSECS) {
+ printf(" (Boy this machine is fast ! usec was %ld)\n",
+ usec);
+ val = MINSTEP; /* val <= MINSTEP; fast machine */
+ }
+ diff = HUSECS;
+ for (i = 0; diff > val; i--)
+ diff >>= 1;
+ return (i);
+}
diff --git a/contrib/ntp/util/sht.c b/contrib/ntp/util/sht.c
new file mode 100644
index 000000000000..4abd350505e1
--- /dev/null
+++ b/contrib/ntp/util/sht.c
@@ -0,0 +1,185 @@
+/*
+ * sht.c - Testprogram for shared memory refclock
+ * read/write shared memory segment; see usage
+ */
+#ifndef SYS_WINNT
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdlib.h>
+#else
+#include <windows.h>
+#include <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream.h>
+#define sleep(x) Sleep(x*1000)
+#endif
+#include <assert.h>
+struct shmTime {
+ int mode; /* 0 - if valid set
+ * use values,
+ * clear valid
+ * 1 - if valid set
+ * if count before and after read of values is equal,
+ * use values
+ * clear valid
+ */
+ int count;
+ time_t clockTimeStampSec;
+ int clockTimeStampUSec;
+ time_t receiveTimeStampSec;
+ int receiveTimeStampUSec;
+ int leap;
+ int precision;
+ int nsamples;
+ int valid;
+};
+
+struct shmTime *
+getShmTime (
+ int unit
+ )
+{
+#ifndef SYS_WINNT
+ int shmid=shmget (0x4e545030+unit, sizeof (struct shmTime), IPC_CREAT|0777);
+ if (shmid==-1) {
+ perror ("shmget");
+ exit (1);
+ }
+ else {
+ struct shmTime *p=(struct shmTime *)shmat (shmid, 0, 0);
+ if ((int)(long)p==-1) {
+ perror ("shmat");
+ p=0;
+ }
+ assert (p!=0);
+ return p;
+ }
+#else
+ char buf[10];
+ LPSECURITY_ATTRIBUTES psec=0;
+ sprintf (buf,"NTP%d",unit);
+ SECURITY_DESCRIPTOR sd;
+ SECURITY_ATTRIBUTES sa;
+ HANDLE shmid;
+
+ assert (InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION));
+ assert (SetSecurityDescriptorDacl(&sd,1,0,0));
+ sa.nLength=sizeof (SECURITY_ATTRIBUTES);
+ sa.lpSecurityDescriptor=&sd;
+ sa.bInheritHandle=0;
+ shmid=CreateFileMapping ((HANDLE)0xffffffff, 0, PAGE_READWRITE,
+ psec, sizeof (struct shmTime),buf);
+ if (!shmid) {
+ shmid=CreateFileMapping ((HANDLE)0xffffffff, 0, PAGE_READWRITE,
+ 0, sizeof (struct shmTime),buf);
+ cout <<"CreateFileMapping with psec!=0 failed"<<endl;
+ }
+
+ if (!shmid) {
+ char mbuf[1000];
+ FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM,
+ 0, GetLastError (), 0, mbuf, sizeof (mbuf), 0);
+ int x=GetLastError ();
+ cout <<"CreateFileMapping "<<buf<<":"<<mbuf<<endl;
+ exit (1);
+ }
+ else {
+ struct shmTime *p=(struct shmTime *) MapViewOfFile (shmid,
+ FILE_MAP_WRITE, 0, 0, sizeof (struct shmTime));
+ if (p==0) {
+ char mbuf[1000];
+ FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM,
+ 0, GetLastError (), 0, mbuf, sizeof (mbuf), 0);
+ cout <<"MapViewOfFile "<<buf<<":"<<mbuf<<endl;
+ exit (1);
+ }
+ return p;
+ }
+ return 0;
+#endif
+}
+
+
+int
+main (
+ int argc,
+ char *argv[]
+ )
+{
+ volatile struct shmTime *p=getShmTime(2);
+ if (argc<=1) {
+ printf ("usage: %s r[c][l]|w|snnn\n",argv[0]);
+ printf (" r read shared memory\n");
+ printf (" c clear valid-flag\n");
+ printf (" l loop (so, rcl will read and clear in a loop\n");
+ printf (" w write shared memory with current time\n");
+ printf (" snnnn set nsamples to nnn\n");
+ printf (" lnnnn set leap to nnn\n");
+ printf (" pnnnn set precision to -nnn\n");
+ exit (0);
+ }
+ switch (argv[1][0]) {
+ case 's': {
+ p->nsamples=atoi(&argv[1][1]);
+ }
+ break;
+ case 'l': {
+ p->leap=atoi(&argv[1][1]);
+ }
+ break;
+ case 'p': {
+ p->precision=-atoi(&argv[1][1]);
+ }
+ break;
+ case 'r': {
+ char *ap=&argv[1][1];
+ int clear=0;
+ int loop=0;
+ printf ("reader\n");
+ while (*ap) {
+ switch (*ap) {
+ case 'l' : loop=1; break;
+ case 'c' : clear=1; break;
+ }
+ ap++;
+ }
+ do {
+ printf ("mode=%d, count=%d, clock=%d.%d, rec=%d.%d,\n",
+ p->mode,p->count,p->clockTimeStampSec,p->clockTimeStampUSec,
+ p->receiveTimeStampSec,p->receiveTimeStampUSec);
+ printf (" leap=%d, precision=%d, nsamples=%d, valid=%d\n",
+ p->leap, p->precision, p->nsamples, p->valid);
+ if (!p->valid)
+ printf ("***\n");
+ if (clear) {
+ p->valid=0;
+ printf ("cleared\n");
+ }
+ if (loop)
+ sleep (1);
+ } while (loop);
+ }
+ break;
+ case 'w': {
+ printf ("writer\n");
+ p->mode=0;
+ if (!p->valid) {
+ p->clockTimeStampSec=time(0)-20;
+ p->clockTimeStampUSec=0;
+ p->receiveTimeStampSec=time(0)-1;
+ p->receiveTimeStampUSec=0;
+ printf ("%d %d\n",p->clockTimeStampSec, p->receiveTimeStampSec);
+ p->valid=1;
+ }
+ else {
+ printf ("p->valid still set\n"); // not an error!
+ }
+ }
+ break;
+ }
+}
diff --git a/contrib/ntp/util/testrs6000.c b/contrib/ntp/util/testrs6000.c
new file mode 100644
index 000000000000..e4d939ae4f0a
--- /dev/null
+++ b/contrib/ntp/util/testrs6000.c
@@ -0,0 +1,55 @@
+/* Checks for the RS/6000 AIX adjtime() bug, in which if a negative
+ * offset is given, the system gets messed up and never completes the
+ * adjustment. If the problem is fixed, this program will print the
+ * time, sit there for 10 seconds, and exit. If the problem isn't fixed,
+ * the program will print an occasional "result=nnnnnn" (the residual
+ * slew from adjtime()).
+ *
+ * Compile this with bsdcc and run it as root!
+ */
+#include <signal.h>
+#include <sys/time.h>
+#include <time.h>
+#include <stdio.h>
+
+int timeout();
+struct timeval adjustment, result;
+
+int
+main (
+ int argc,
+ char *argv[]
+ )
+{
+ struct itimerval value, oldvalue;
+ int i;
+ time_t curtime;
+
+ curtime = time(0);
+ printf("Starting: %s", ctime(&curtime));
+ value.it_interval.tv_sec = value.it_value.tv_sec = 1;
+ value.it_interval.tv_usec = value.it_value.tv_usec = 0;
+ adjustment.tv_sec = 0;
+ adjustment.tv_usec = -2000;
+ signal(SIGALRM, timeout);
+ setitimer(ITIMER_REAL, &value, &oldvalue);
+ for (i=0; i<10; i++) {
+ pause();
+ }
+}
+
+int
+timeout(
+ int sig,
+ int code,
+ struct sigcontext *scp
+ )
+{
+ signal (SIGALRM, timeout);
+ if (adjtime(&adjustment, &result))
+ printf("adjtime call failed\n");
+ if (result.tv_sec != 0 || result.tv_usec != 0) {
+ printf("result.u = %d.%06.6d ", (int) result.tv_sec,
+ (int) result.tv_usec);
+ }
+}
diff --git a/contrib/ntp/util/tickadj.c b/contrib/ntp/util/tickadj.c
new file mode 100644
index 000000000000..5ac812142dbc
--- /dev/null
+++ b/contrib/ntp/util/tickadj.c
@@ -0,0 +1,904 @@
+/*
+ * tickadj - read, and possibly modify, the kernel `tick' and
+ * `tickadj' variables, as well as `dosynctodr'. Note that
+ * this operates on the running kernel only. I'd like to be
+ * able to read and write the binary as well, but haven't
+ * mastered this yet.
+ *
+ * HMS: The #includes here are different from those in xntpd/ntp_unixclock.c
+ * These seem "worse".
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include "ntp_types.h"
+#include "l_stdlib.h"
+
+#ifdef HAVE___ADJTIMEX /* Linux */
+
+#include <sys/timex.h>
+struct timex txc;
+
+#if 0
+int
+main(
+ int argc,
+ char *argv[]
+ )
+{
+ int c, i;
+ int quiet = 0;
+ int errflg = 0;
+ char *progname;
+ extern int ntp_optind;
+ extern char *ntp_optarg;
+
+ progname = argv[0];
+ if (argc==2 && argv[1][0] != '-') { /* old Linux format, for compatability */
+ if ((i = atoi(argv[1])) > 0) {
+ txc.time_tick = i;
+ txc.modes = ADJ_TIMETICK;
+ } else {
+ fprintf(stderr, "Silly value for tick: %s\n", argv[1]);
+ errflg++;
+ }
+ } else {
+ while ((c = ntp_getopt(argc, argv, "a:qt:")) != EOF) {
+ switch (c) {
+ case 'a':
+ if ((i=atoi(ntp_optarg)) > 0) {
+ txc.tickadj = i;
+ txc.modes |= ADJ_TICKADJ;
+ } else {
+ (void) fprintf(stderr,
+ "%s: unlikely value for tickadj: %s\n",
+ progname, ntp_optarg);
+ errflg++;
+ }
+ break;
+
+ case 'q':
+ quiet = 1;
+ break;
+
+ case 't':
+ if ((i=atoi(ntp_optarg)) > 0) {
+ txc.time_tick = i;
+ txc.modes |= ADJ_TIMETICK;
+ } else {
+ (void) fprintf(stderr,
+ "%s: unlikely value for tick: %s\n",
+ progname, ntp_optarg);
+ errflg++;
+ }
+ break;
+
+ default:
+ fprintf(stderr,
+ "Usage: %s [tick_value]\n-or- %s [ -q ] [ -t tick ] [ -a tickadj ]\n",
+ progname, progname);
+ errflg++;
+ break;
+ }
+ }
+ }
+
+ if (!errflg) {
+ if (__adjtimex(&txc) < 0)
+ perror("adjtimex");
+ else if (!quiet)
+ printf("tick = %ld\ntick_adj = %d\n",
+ txc.time_tick, txc.tickadj);
+ }
+
+ exit(errflg ? 1 : 0);
+}
+#else
+int
+main(
+ int argc,
+ char *argv[]
+ )
+{
+ if (argc > 2)
+ {
+ fprintf(stderr, "Usage: %s [tick_value]\n", argv[0]);
+ exit(-1);
+ }
+ else if (argc == 2)
+ {
+#ifdef ADJ_TIMETICK
+ if ( (txc.time_tick = atoi(argv[1])) < 1 )
+#else
+ if ( (txc.tick = atoi(argv[1])) < 1 )
+#endif
+ {
+ fprintf(stderr, "Silly value for tick: %s\n", argv[1]);
+ exit(-1);
+ }
+#ifdef ADJ_TIMETICK
+ txc.modes = ADJ_TIMETICK;
+#else
+#ifdef MOD_OFFSET
+ txc.modes = ADJ_TICK;
+#else
+ txc.mode = ADJ_TICK;
+#endif
+#endif
+ }
+ else
+ {
+#ifdef ADJ_TIMETICK
+ txc.modes = 0;
+#else
+#ifdef MOD_OFFSET
+ txc.modes = 0;
+#else
+ txc.mode = 0;
+#endif
+#endif
+ }
+
+ if (__adjtimex(&txc) < 0)
+ {
+ perror("adjtimex");
+ }
+ else
+ {
+#ifdef ADJ_TIMETICK
+ printf("tick = %ld\ntick_adj = %ld\n", txc.time_tick, txc.tickadj);
+#else
+ printf("tick = %ld\n", txc.tick);
+#endif
+ }
+
+ exit(0);
+}
+#endif
+
+#else /* not Linux... kmem tweaking: */
+
+#ifdef HAVE_SYS_FILE_H
+# include <sys/file.h>
+#endif
+#include <sys/stat.h>
+
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+
+#ifdef NLIST_STRUCT
+# include <nlist.h>
+#else /* not NLIST_STRUCT */ /* was defined(SYS_AUX3) || defined(SYS_AUX2) */
+# include <sys/time.h>
+# include <sys/resource.h>
+# include <sys/file.h>
+# include <a.out.h>
+# include <sys/var.h>
+#endif
+
+#include "ntp_io.h"
+#include "ntp_stdlib.h"
+
+#ifdef hz /* Was: RS6000 */
+# undef hz
+#endif /* hz */
+
+#ifdef HAVE_KVM_OPEN
+# include <kvm.h>
+#endif
+
+#ifdef SYS_VXWORKS
+/* vxWorks needs mode flag -casey*/
+#define open(name, flags) open(name, flags, 0777)
+#endif
+
+#ifndef L_SET /* Was: defined(SYS_PTX) || defined(SYS_IX86OSF1) */
+# define L_SET SEEK_SET
+#endif
+
+#ifndef HZ
+# define HZ DEFAULT_HZ
+#endif
+
+#define KMEM "/dev/kmem"
+#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
+
+char *progname;
+volatile int debug;
+
+int dokmem = 1;
+int writetickadj = 0;
+int writeopttickadj = 0;
+int unsetdosync = 0;
+int writetick = 0;
+int quiet = 0;
+int setnoprintf = 0;
+
+const char *kmem = KMEM;
+const char *file = NULL;
+int fd = -1;
+
+static void getoffsets P((off_t *, off_t *, off_t *, off_t *));
+static int openfile P((const char *, int));
+static void writevar P((int, off_t, int));
+static void readvar P((int, off_t, int *));
+
+/*
+ * main - parse arguments and handle options
+ */
+int
+main(
+ int argc,
+ char *argv[]
+ )
+{
+ int c;
+ int errflg = 0;
+ off_t tickadj_offset;
+ off_t tick_offset;
+ off_t dosync_offset;
+ off_t noprintf_offset;
+ int tickadj, ktickadj; /* HMS: Why isn't this u_long? */
+ int tick, ktick; /* HMS: Why isn't this u_long? */
+ int dosynctodr;
+ int noprintf;
+ int hz;
+ int hz_int, hz_hundredths;
+ int recommend_tickadj;
+ long tmp;
+
+ progname = argv[0];
+ while ((c = ntp_getopt(argc, argv, "a:Adkpqst:")) != EOF)
+ {
+ switch (c)
+ {
+ case 'a':
+ writetickadj = atoi(ntp_optarg);
+ if (writetickadj <= 0)
+ {
+ (void) fprintf(stderr,
+ "%s: unlikely value for tickadj: %s\n",
+ progname, ntp_optarg);
+ errflg++;
+ }
+
+#if defined SCO5_CLOCK
+ if (writetickadj % HZ)
+ {
+ writetickadj = (writetickadj / HZ) * HZ;
+ (void) fprintf(stderr,
+ "tickadj truncated to: %d\n", writetickadj);
+ }
+#endif /* SCO5_CLOCK */
+
+ break;
+ case 'A':
+ writeopttickadj = 1;
+ break;
+ case 'd':
+ ++debug;
+ break;
+ case 'k':
+ dokmem = 1;
+ break;
+ case 'p':
+ setnoprintf = 1;
+ break;
+ case 'q':
+ quiet = 1;
+ break;
+ case 's':
+ unsetdosync = 1;
+ break;
+ case 't':
+ writetick = atoi(ntp_optarg);
+ if (writetick <= 0)
+ {
+ (void) fprintf(stderr,
+ "%s: unlikely value for tick: %s\n",
+ progname, ntp_optarg);
+ errflg++;
+ }
+ break;
+ default:
+ errflg++;
+ break;
+ }
+ }
+ if (errflg || ntp_optind != argc)
+ {
+ (void) fprintf(stderr,
+ "usage: %s [-Adkpqs] [-a newadj] [-t newtick]\n", progname);
+ exit(2);
+ }
+
+ getoffsets(&tick_offset, &tickadj_offset, &dosync_offset, &noprintf_offset);
+
+ if (debug)
+ {
+ (void) printf("tick offset = %lu\n", (unsigned long)tick_offset);
+ (void) printf("tickadj offset = %lu\n", (unsigned long)tickadj_offset);
+ (void) printf("dosynctodr offset = %lu\n", (unsigned long)dosync_offset);
+ (void) printf("noprintf offset = %lu\n", (unsigned long)noprintf_offset);
+ }
+
+ if (writetick && (tick_offset == 0))
+ {
+ (void) fprintf(stderr,
+ "No tick kernel variable\n");
+ errflg++;
+ }
+
+ if (writeopttickadj && (tickadj_offset == 0))
+ {
+ (void) fprintf(stderr,
+ "No tickadj kernel variable\n");
+ errflg++;
+ }
+
+ if (unsetdosync && (dosync_offset == 0))
+ {
+ (void) fprintf(stderr,
+ "No dosynctodr kernel variable\n");
+ errflg++;
+ }
+
+ if (setnoprintf && (noprintf_offset == 0))
+ {
+ (void) fprintf(stderr,
+ "No noprintf kernel variable\n");
+ errflg++;
+ }
+
+ if (tick_offset != 0)
+ {
+ readvar(fd, tick_offset, &tick);
+#if defined(TICK_NANO) && defined(K_TICK_NAME)
+ if (!quiet)
+ (void) printf("KERNEL %s = %d nsec\n", K_TICK_NAME, tick);
+#endif /* TICK_NANO && K_TICK_NAME */
+
+#ifdef TICK_NANO
+ tick /= 1000;
+#endif
+ }
+ else
+ {
+ tick = 0;
+ }
+
+ if (tickadj_offset != 0)
+ {
+ readvar(fd, tickadj_offset, &tickadj);
+
+#ifdef SCO5_CLOCK
+ /* scale from nsec/sec to usec/tick */
+ tickadj /= (1000L * HZ);
+#endif /*SCO5_CLOCK */
+
+#if defined(TICKADJ_NANO) && defined(K_TICKADJ_NAME)
+ if (!quiet)
+ (void) printf("KERNEL %s = %d nsec\n", K_TICKADJ_NAME, tickadj);
+#endif /* TICKADJ_NANO && K_TICKADJ_NAME */
+
+#ifdef TICKADJ_NANO
+ tickadj += 999;
+ tickadj /= 1000;
+#endif
+ }
+ else
+ {
+ tickadj = 0;
+ }
+
+ if (dosync_offset != 0)
+ {
+ readvar(fd, dosync_offset, &dosynctodr);
+ }
+
+ if (noprintf_offset != 0)
+ {
+ readvar(fd, noprintf_offset, &noprintf);
+ }
+
+ (void) close(fd);
+
+ if (unsetdosync && dosync_offset == 0)
+ {
+ (void) fprintf(stderr,
+ "%s: can't find %s in namelist\n",
+ progname,
+#ifdef K_DOSYNCTODR_NAME
+ K_DOSYNCTODR_NAME
+#else /* not K_DOSYNCTODR_NAME */
+ "dosynctodr"
+#endif /* not K_DOSYNCTODR_NAME */
+ );
+ exit(1);
+ }
+
+ hz = HZ;
+#if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
+ hz = (int) sysconf (_SC_CLK_TCK);
+#endif /* not HAVE_SYSCONF && _SC_CLK_TCK */
+#ifdef OVERRIDE_HZ
+ hz = DEFAULT_HZ;
+#endif
+ ktick = tick;
+#ifdef PRESET_TICK
+ tick = PRESET_TICK;
+#endif /* PRESET_TICK */
+#ifdef TICKADJ_NANO
+ tickadj /= 1000;
+ if (tickadj == 0)
+ tickadj = 1;
+#endif
+ ktickadj = tickadj;
+#ifdef PRESET_TICKADJ
+ tickadj = (PRESET_TICKADJ) ? PRESET_TICKADJ : 1;
+#endif /* PRESET_TICKADJ */
+
+ if (!quiet)
+ {
+ if (tick_offset != 0)
+ {
+ (void) printf("KERNEL tick = %d usec (from %s kernel variable)\n",
+ ktick,
+#ifdef K_TICK_NAME
+ K_TICK_NAME
+#else
+ "<this can't happen>"
+#endif
+ );
+ }
+#ifdef PRESET_TICK
+ (void) printf("PRESET tick = %d usec\n", tick);
+#endif /* PRESET_TICK */
+ if (tickadj_offset != 0)
+ {
+ (void) printf("KERNEL tickadj = %d usec (from %s kernel variable)\n",
+ ktickadj,
+#ifdef K_TICKADJ_NAME
+ K_TICKADJ_NAME
+#else
+ "<this can't happen>"
+#endif
+ );
+ }
+#ifdef PRESET_TICKADJ
+ (void) printf("PRESET tickadj = %d usec\n", tickadj);
+#endif /* PRESET_TICKADJ */
+ if (dosync_offset != 0)
+ {
+ (void) printf("dosynctodr is %s\n", dosynctodr ? "on" : "off");
+ }
+ if (noprintf_offset != 0)
+ {
+ (void) printf("kernel level printf's: %s\n",
+ noprintf ? "off" : "on");
+ }
+ }
+
+ if (tick <= 0)
+ {
+ (void) fprintf(stderr, "%s: the value of tick is silly!\n",
+ progname);
+ exit(1);
+ }
+
+ hz_int = (int)(1000000L / (long)tick);
+ hz_hundredths = (int)((100000000L / (long)tick) - ((long)hz_int * 100L));
+ if (!quiet)
+ {
+ (void) printf("KERNEL hz = %d\n", hz);
+ (void) printf("calculated hz = %d.%02d Hz\n", hz_int,
+ hz_hundredths);
+ }
+
+#if defined SCO5_CLOCK
+ recommend_tickadj = 100;
+#else /* SCO5_CLOCK */
+ tmp = (long) tick * 500L;
+ recommend_tickadj = (int)(tmp / 1000000L);
+ if (tmp % 1000000L > 0)
+ {
+ recommend_tickadj++;
+ }
+
+#ifdef MIN_REC_TICKADJ
+ if (recommend_tickadj < MIN_REC_TICKADJ)
+ {
+ recommend_tickadj = MIN_REC_TICKADJ;
+ }
+#endif /* MIN_REC_TICKADJ */
+#endif /* SCO5_CLOCK */
+
+
+ if ((!quiet) && (tickadj_offset != 0))
+ {
+ (void) printf("recommended value of tickadj = %d us\n",
+ recommend_tickadj);
+ }
+
+ if ( writetickadj == 0
+ && !writeopttickadj
+ && !unsetdosync
+ && writetick == 0
+ && !setnoprintf)
+ {
+ exit(errflg ? 1 : 0);
+ }
+
+ if (writetickadj == 0 && writeopttickadj)
+ {
+ writetickadj = recommend_tickadj;
+ }
+
+ fd = openfile(file, O_WRONLY);
+
+ if (setnoprintf && (noprintf_offset != 0))
+ {
+ if (!quiet)
+ {
+ (void) fprintf(stderr, "setting noprintf: ");
+ (void) fflush(stderr);
+ }
+ writevar(fd, noprintf_offset, 1);
+ if (!quiet)
+ {
+ (void) fprintf(stderr, "done!\n");
+ }
+ }
+
+ if ((writetick > 0) && (tick_offset != 0))
+ {
+ if (!quiet)
+ {
+ (void) fprintf(stderr, "writing tick, value %d: ",
+ writetick);
+ (void) fflush(stderr);
+ }
+ writevar(fd, tick_offset, writetick);
+ if (!quiet)
+ {
+ (void) fprintf(stderr, "done!\n");
+ }
+ }
+
+ if ((writetickadj > 0) && (tickadj_offset != 0))
+ {
+ if (!quiet)
+ {
+ (void) fprintf(stderr, "writing tickadj, value %d: ",
+ writetickadj);
+ (void) fflush(stderr);
+ }
+
+#ifdef SCO5_CLOCK
+ /* scale from usec/tick to nsec/sec */
+ writetickadj *= (1000L * HZ);
+#endif /* SCO5_CLOCK */
+
+ writevar(fd, tickadj_offset, writetickadj);
+ if (!quiet)
+ {
+ (void) fprintf(stderr, "done!\n");
+ }
+ }
+
+ if (unsetdosync && (dosync_offset != 0))
+ {
+ if (!quiet)
+ {
+ (void) fprintf(stderr, "zeroing dosynctodr: ");
+ (void) fflush(stderr);
+ }
+ writevar(fd, dosync_offset, 0);
+ if (!quiet)
+ {
+ (void) fprintf(stderr, "done!\n");
+ }
+ }
+ (void) close(fd);
+ return(errflg ? 1 : 0);
+}
+
+/*
+ * getoffsets - read the magic offsets from the specified file
+ */
+static void
+getoffsets(
+ off_t *tick_off,
+ off_t *tickadj_off,
+ off_t *dosync_off,
+ off_t *noprintf_off
+ )
+{
+
+#ifndef NOKMEM
+# ifndef HAVE_KVM_OPEN
+ const char **kname;
+# endif
+#endif
+
+#ifndef NOKMEM
+# ifdef NLIST_NAME_UNION
+# define NL_B {{
+# define NL_E }}
+# else
+# define NL_B {
+# define NL_E }
+# endif
+#endif
+
+#define K_FILLER_NAME "DavidLetterman"
+
+#ifdef NLIST_EXTRA_INDIRECTION
+ int i;
+#endif
+
+#ifndef NOKMEM
+ static struct nlist nl[] =
+ {
+ NL_B
+#ifdef K_TICKADJ_NAME
+#define N_TICKADJ 0
+ K_TICKADJ_NAME
+#else
+ K_FILLER_NAME
+#endif
+ NL_E,
+ NL_B
+#ifdef K_TICK_NAME
+#define N_TICK 1
+ K_TICK_NAME
+#else
+ K_FILLER_NAME
+#endif
+ NL_E,
+ NL_B
+#ifdef K_DOSYNCTODR_NAME
+#define N_DOSYNC 2
+ K_DOSYNCTODR_NAME
+#else
+ K_FILLER_NAME
+#endif
+ NL_E,
+ NL_B
+#ifdef K_NOPRINTF_NAME
+#define N_NOPRINTF 3
+ K_NOPRINTF_NAME
+#else
+ K_FILLER_NAME
+#endif
+ NL_E,
+ NL_B "" NL_E,
+ };
+
+#ifndef HAVE_KVM_OPEN
+ static const char *kernels[] =
+ {
+#ifdef HAVE_GETBOOTFILE
+ NULL, /* *** SEE BELOW! *** */
+#endif
+ "/kernel/unix",
+ "/kernel",
+ "/vmunix",
+ "/unix",
+ "/mach",
+ "/hp-ux",
+ "/386bsd",
+ "/netbsd",
+ "/stand/vmunix",
+ "/bsd",
+ NULL
+ };
+#endif /* not HAVE_KVM_OPEN */
+
+#ifdef HAVE_KVM_OPEN
+ /*
+ * Solaris > 2.5 doesn't have a kernel file. Use the kvm_* interface
+ * to read the kernel name list. -- stolcke 3/4/96
+ */
+ kvm_t *kvm_handle = kvm_open(NULL, NULL, NULL, O_RDONLY, progname);
+
+ if (kvm_handle == NULL)
+ {
+ (void) fprintf(stderr,
+ "%s: kvm_open failed\n",
+ progname);
+ exit(1);
+ }
+ if (kvm_nlist(kvm_handle, nl) == -1)
+ {
+ (void) fprintf(stderr,
+ "%s: kvm_nlist failed\n",
+ progname);
+ exit(1);
+ }
+ kvm_close(kvm_handle);
+#else /* not HAVE_KVM_OPEN */
+#ifdef HAVE_GETBOOTFILE /* *** SEE HERE! *** */
+ if (kernels[0] == NULL)
+ {
+ char * cp = (char *)getbootfile();
+
+ if (cp)
+ {
+ kernels[0] = cp;
+ }
+ else
+ {
+ kernels[0] = "/Placeholder";
+ }
+ }
+#endif /* HAVE_GETBOOTFILE */
+ for (kname = kernels; *kname != NULL; kname++)
+ {
+ struct stat stbuf;
+
+ if (stat(*kname, &stbuf) == -1)
+ {
+ continue;
+ }
+ if (nlist(*kname, nl) >= 0)
+ {
+ break;
+ }
+ else
+ {
+ (void) fprintf(stderr,
+ "%s: nlist didn't find needed symbols from <%s>: %m\n",
+ progname, *kname);
+ }
+ }
+ if (*kname == NULL)
+ {
+ (void) fprintf(stderr,
+ "%s: Couldn't find the kernel\n",
+ progname);
+ exit(1);
+ }
+#endif /* HAVE_KVM_OPEN */
+
+ if (dokmem)
+ {
+ file = kmem;
+
+ fd = openfile(file, O_RDONLY);
+#ifdef NLIST_EXTRA_INDIRECTION
+ /*
+ * Go one more round of indirection.
+ */
+ for (i = 0; i < (sizeof(nl) / sizeof(struct nlist)); i++)
+ {
+ if ((nl[i].n_value) && (nl[i].n_sclass == 0x6b))
+ {
+ readvar(fd, nl[i].n_value, &nl[i].n_value);
+ }
+ }
+#endif /* NLIST_EXTRA_INDIRECTION */
+ }
+#endif /* not NOKMEM */
+
+ *tickadj_off = 0;
+ *tick_off = 0;
+ *dosync_off = 0;
+ *noprintf_off = 0;
+
+#if defined(N_TICKADJ)
+ *tickadj_off = nl[N_TICKADJ].n_value;
+#endif
+
+#if defined(N_TICK)
+ *tick_off = nl[N_TICK].n_value;
+#endif
+
+#if defined(N_DOSYNC)
+ *dosync_off = nl[N_DOSYNC].n_value;
+#endif
+
+#if defined(N_NOPRINTF)
+ *noprintf_off = nl[N_NOPRINTF].n_value;
+#endif
+ return;
+}
+
+#undef N_TICKADJ
+#undef N_TICK
+#undef N_DOSYNC
+#undef N_NOPRINTF
+
+
+/*
+ * openfile - open the file, check for errors
+ */
+static int
+openfile(
+ const char *name,
+ int mode
+ )
+{
+ int ifd;
+
+ ifd = open(name, mode);
+ if (ifd < 0)
+ {
+ (void) fprintf(stderr, "%s: open %s: ", progname, name);
+ perror("");
+ exit(1);
+ }
+ return ifd;
+}
+
+
+/*
+ * writevar - write a variable into the file
+ */
+static void
+writevar(
+ int ofd,
+ off_t off,
+ int var
+ )
+{
+
+ if (lseek(ofd, off, L_SET) == -1)
+ {
+ (void) fprintf(stderr, "%s: lseek fails: ", progname);
+ perror("");
+ exit(1);
+ }
+ if (write(ofd, (char *)&var, sizeof(int)) != sizeof(int))
+ {
+ (void) fprintf(stderr, "%s: write fails: ", progname);
+ perror("");
+ exit(1);
+ }
+ return;
+}
+
+
+/*
+ * readvar - read a variable from the file
+ */
+static void
+readvar(
+ int ifd,
+ off_t off,
+ int *var
+ )
+{
+ int i;
+
+ if (lseek(ifd, off, L_SET) == -1)
+ {
+ (void) fprintf(stderr, "%s: lseek fails: ", progname);
+ perror("");
+ exit(1);
+ }
+ i = read(ifd, (char *)var, sizeof(int));
+ if (i < 0)
+ {
+ (void) fprintf(stderr, "%s: read fails: ", progname);
+ perror("");
+ exit(1);
+ }
+ if (i != sizeof(int))
+ {
+ (void) fprintf(stderr, "%s: read expected %d, got %d\n",
+ progname, (int)sizeof(int), i);
+ exit(1);
+ }
+ return;
+}
+#endif /* not Linux */
diff --git a/contrib/ntp/util/timetrim.c b/contrib/ntp/util/timetrim.c
new file mode 100644
index 000000000000..4397b569aff6
--- /dev/null
+++ b/contrib/ntp/util/timetrim.c
@@ -0,0 +1,95 @@
+#ifdef sgi
+/*
+ * timetrim.c
+ *
+ * "timetrim" allows setting and adjustment of the system clock frequency
+ * trim parameter on Silicon Graphics machines. The trim value native
+ * units are nanoseconds per second (10**-9), so a trim value of 1 makes
+ * the system clock step ahead 1 nanosecond more per second than a value
+ * of zero. Xntpd currently uses units of 2**-20 secs for its frequency
+ * offset (drift) values; to convert to a timetrim value, multiply by
+ * 1E9 / 2**20 (about 954).
+ *
+ * "timetrim" with no arguments just prints out the current kernel value.
+ * With a numeric argument, the kernel value is set to the supplied value.
+ * The "-i" flag causes the supplied value to be added to the kernel value.
+ * The "-n" option causes all input and output to be in xntpd units rather
+ * than timetrim native units.
+ *
+ * Note that there is a limit of +-3000000 (0.3%) on the timetrim value
+ * which is (silently?) enforced by the kernel.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#ifdef HAVE_SYS_SYSSGI_H
+# include <sys/syssgi.h>
+#endif
+
+#define abs(X) (((X) < 0) ? -(X) : (X))
+#define USAGE "usage: timetrim [-n] [[-i] value]\n"
+#define SGITONTP(X) ((double)(X) * 1048576.0/1.0e9)
+#define NTPTOSGI(X) ((long)((X) * 1.0e9/1048576.0))
+
+int
+main(
+ int argc,
+ char *argv[]
+ )
+{
+ char *rem;
+ int c, incremental = 0, ntpunits = 0;
+ long timetrim;
+ double value, strtod();
+
+ while (--argc && **++argv == '-' && isalpha(argv[0][1])) {
+ switch (argv[0][1]) {
+ case 'i':
+ incremental++;
+ break;
+ case 'n':
+ ntpunits++;
+ break;
+ default:
+ fprintf(stderr, USAGE);
+ exit(1);
+ }
+ }
+
+ if (syssgi(SGI_GETTIMETRIM, &timetrim) < 0) {
+ perror("syssgi");
+ exit(2);
+ }
+
+ if (argc == 0) {
+ if (ntpunits)
+ fprintf(stdout, "%0.5lf\n", SGITONTP(timetrim));
+ else
+ fprintf(stdout, "%ld\n", timetrim);
+ } else if (argc != 1) {
+ fprintf(stderr, USAGE);
+ exit(1);
+ } else {
+ value = strtod(argv[0], &rem);
+ if (*rem != '\0') {
+ fprintf(stderr, USAGE);
+ exit(1);
+ }
+ if (ntpunits)
+ value = NTPTOSGI(value);
+ if (incremental)
+ timetrim += value;
+ else
+ timetrim = value;
+ if (syssgi(SGI_SETTIMETRIM, timetrim) < 0) {
+ perror("syssgi");
+ exit(2);
+ }
+ }
+}
+#endif