aboutsummaryrefslogtreecommitdiff
path: root/contrib/ntp/scripts
diff options
context:
space:
mode:
authorOllivier Robert <roberto@FreeBSD.org>2001-08-29 14:35:15 +0000
committerOllivier Robert <roberto@FreeBSD.org>2001-08-29 14:35:15 +0000
commit224ba2bd37e182b64f7d78defef8a6cacaad3415 (patch)
tree3cfb63f1a112ee17469b17fc1593a88d004ddda6 /contrib/ntp/scripts
parent1c80946020d06ca926154926c7c890d211708395 (diff)
downloadsrc-224ba2bd37e182b64f7d78defef8a6cacaad3415.tar.gz
src-224ba2bd37e182b64f7d78defef8a6cacaad3415.zip
Virgin import of ntpd 4.1.0
Notes
Notes: svn path=/vendor/ntp/dist/; revision=82498
Diffstat (limited to 'contrib/ntp/scripts')
-rw-r--r--contrib/ntp/scripts/Makefile.am5
-rw-r--r--contrib/ntp/scripts/Makefile.in201
-rw-r--r--contrib/ntp/scripts/README6
-rw-r--r--contrib/ntp/scripts/calc_tickadj.in38
-rw-r--r--contrib/ntp/scripts/checktime.in79
-rw-r--r--contrib/ntp/scripts/freq_adj.in97
-rw-r--r--contrib/ntp/scripts/mkver.in13
-rw-r--r--contrib/ntp/scripts/monitoring/README32
-rw-r--r--contrib/ntp/scripts/monitoring/lr.pl156
-rw-r--r--contrib/ntp/scripts/monitoring/ntp.pl9
-rw-r--r--contrib/ntp/scripts/monitoring/ntploopstat5
-rwxr-xr-xcontrib/ntp/scripts/ntp-close8
-rwxr-xr-xcontrib/ntp/scripts/ntp-restart7
-rw-r--r--contrib/ntp/scripts/ntp-wait.in42
-rw-r--r--contrib/ntp/scripts/ntpsweep.in301
-rw-r--r--contrib/ntp/scripts/plot_summary.in337
-rwxr-xr-xcontrib/ntp/scripts/stats/summary.sh2
-rw-r--r--contrib/ntp/scripts/summary.in373
18 files changed, 1547 insertions, 164 deletions
diff --git a/contrib/ntp/scripts/Makefile.am b/contrib/ntp/scripts/Makefile.am
index c3bb68415958..b970602547dd 100644
--- a/contrib/ntp/scripts/Makefile.am
+++ b/contrib/ntp/scripts/Makefile.am
@@ -1 +1,4 @@
-noinst_SCRIPTS = mkver ntpver
+bin_SCRIPTS = ntp-wait
+noinst_SCRIPTS = calc_tickadj checktime freq_adj mkver ntpsweep ntpver plot_summary summary
+EXTRA_DIST = fixautomakedepsmagic hpadjtime.sh monitoring ntp-close \
+ ntp-groper ntp-restart ntp-status rc1 rc2 stats support
diff --git a/contrib/ntp/scripts/Makefile.in b/contrib/ntp/scripts/Makefile.in
index bc662fbe053f..b85723431a01 100644
--- a/contrib/ntp/scripts/Makefile.in
+++ b/contrib/ntp/scripts/Makefile.in
@@ -1,6 +1,7 @@
-# Makefile.in generated automatically by automake 1.4a from Makefile.am
+# Makefile.in generated automatically by automake 1.4e from Makefile.am.
-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+# 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.
@@ -31,8 +32,6 @@ mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
-DESTDIR =
-
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
@@ -48,7 +47,7 @@ INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_FLAG =
+INSTALL_HEADER = $(INSTALL_DATA)
transform = @program_transform_name@
NORMAL_INSTALL = :
@@ -57,24 +56,30 @@ 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@
+
+@SET_MAKE@
AMDEP = @AMDEP@
AMTAR = @AMTAR@
+AUTOKEY = @AUTOKEY@
AWK = @AWK@
CC = @CC@
CFLAGS = @CFLAGS@
CHUTEST = @CHUTEST@
CLKTEST = @CLKTEST@
CPP = @CPP@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
DCFD = @DCFD@
DEPDIR = @DEPDIR@
+EF_LIBS = @EF_LIBS@
+EF_PROGS = @EF_PROGS@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTALL_STRIP_PROGRAM_ENV = @INSTALL_STRIP_PROGRAM_ENV@
LDFLAGS = @LDFLAGS@
LIBPARSE = @LIBPARSE@
LIBRSAREF = @LIBRSAREF@
@@ -86,88 +91,141 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@
MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@
MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
MAKE_TICKADJ = @MAKE_TICKADJ@
+MAKE_TIMETRIM = @MAKE_TIMETRIM@
+OPENSSL = @OPENSSL@
+OPENSSL_INC = @OPENSSL_INC@
+OPENSSL_LIB = @OPENSSL_LIB@
PACKAGE = @PACKAGE@
+PATH_PERL = @PATH_PERL@
PATH_SH = @PATH_SH@
PROPDELAY = @PROPDELAY@
RANLIB = @RANLIB@
+RSADIR = @RSADIR@
+RSAOBJS = @RSAOBJS@
RSAREF = @RSAREF@
+RSASRCS = @RSASRCS@
+STRIP = @STRIP@
TESTDCF = @TESTDCF@
U = @U@
VERSION = @VERSION@
+_am_include = @_am_include@
install_sh = @install_sh@
-noinst_SCRIPTS = mkver ntpver
+bin_SCRIPTS = ntp-wait
+noinst_SCRIPTS = calc_tickadj checktime freq_adj mkver ntpsweep ntpver plot_summary summary
+EXTRA_DIST = fixautomakedepsmagic hpadjtime.sh monitoring ntp-close \
+ ntp-groper ntp-restart ntp-status rc1 rc2 stats support
+
+EXEEXT =
+OBJEXT = o
subdir = scripts
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_HEADER = ../config.h
-CONFIG_CLEAN_FILES = mkver ntpver
-SCRIPTS = $(noinst_SCRIPTS)
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = calc_tickadj checktime freq_adj mkver ntp-wait \
+ntpsweep ntpver plot_summary summary
+SCRIPTS = $(bin_SCRIPTS) $(noinst_SCRIPTS)
-DIST_SOURCES =
-DIST_COMMON = README Makefile.am Makefile.in mkver.in ntpver.in
+DIST_SOURCES =
+DIST_COMMON = README Makefile.am Makefile.in calc_tickadj.in \
+checktime.in freq_adj.in mkver.in ntp-wait.in ntpsweep.in ntpver.in \
+plot_summary.in summary.in
+all: all-am
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-
-GZIP_ENV = --best
-all: all-redirect
.SUFFIXES:
-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
- cd $(top_srcdir) && $(AUTOMAKE) --gnu scripts/Makefile
-
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
- cd $(top_builddir) \
- && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu scripts/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && \
+ CONFIG_HEADERS= CONFIG_LINKS= \
+ CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status
+calc_tickadj: $(top_builddir)/config.status calc_tickadj.in
+ cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= CONFIG_LINKS= $(SHELL) ./config.status
+checktime: $(top_builddir)/config.status checktime.in
+ cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= CONFIG_LINKS= $(SHELL) ./config.status
+freq_adj: $(top_builddir)/config.status freq_adj.in
+ cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= CONFIG_LINKS= $(SHELL) ./config.status
mkver: $(top_builddir)/config.status mkver.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+ cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= CONFIG_LINKS= $(SHELL) ./config.status
+ntp-wait: $(top_builddir)/config.status ntp-wait.in
+ cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= CONFIG_LINKS= $(SHELL) ./config.status
+ntpsweep: $(top_builddir)/config.status ntpsweep.in
+ cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= CONFIG_LINKS= $(SHELL) ./config.status
ntpver: $(top_builddir)/config.status ntpver.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+ cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= CONFIG_LINKS= $(SHELL) ./config.status
+plot_summary: $(top_builddir)/config.status plot_summary.in
+ cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= CONFIG_LINKS= $(SHELL) ./config.status
+summary: $(top_builddir)/config.status summary.in
+ cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= CONFIG_LINKS= $(SHELL) ./config.status
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ f="`echo $$p|sed '$(transform)'`"; \
+ if test -f $$p; then \
+ echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/$$f"; \
+ $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/$$f; \
+ elif test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/$$f"; \
+ $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/$$f; \
+ else :; fi; \
+ done
+
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ f="`echo $$p|sed '$(transform)'`"; \
+ echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done
tags: TAGS
TAGS:
-distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
- cp -pR $$d/$$file $(distdir); \
+ cp -pR $$d/$$file $(distdir) \
+ || exit 1; \
else \
test -f $(distdir)/$$file \
- || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
- || cp -p $$d/$$file $(distdir)/$$file || :; \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
fi; \
done
-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-exec: install-exec-am
+all-am: Makefile $(SCRIPTS)
-install-data-am:
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+
+install: install-am
+install-exec: install-exec-am
install-data: install-data-am
+uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-install: install-am
-uninstall-am:
-uninstall: uninstall-am
-all-am: Makefile $(SCRIPTS)
-all-redirect: all-am
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_STRIP_FLAG=-s install
-installdirs:
+installcheck: installcheck-am
+
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ INSTALL_PROGRAM_ENV='$(INSTALL_STRIP_PROGRAM_ENV)' install
mostlyclean-generic:
@@ -178,31 +236,52 @@ distclean-generic:
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
-rm -f Makefile.in
-mostlyclean-am: mostlyclean-generic
+clean: clean-am
-mostlyclean: mostlyclean-am
+clean-am: clean-generic mostlyclean-am
-clean-am: clean-generic mostlyclean-am
+distclean: distclean-am
-clean: clean-am
+distclean-am: clean-am distclean-generic
-distclean-am: distclean-generic clean-am
+dvi:
-distclean: distclean-am
+dvi-am:
-maintainer-clean-am: 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."
+info:
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-binSCRIPTS
+
+install-info:
+
+install-man:
+
+installcheck-am:
maintainer-clean: maintainer-clean-am
-.PHONY: 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
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+uninstall-am: uninstall-binSCRIPTS
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+ distclean-generic distdir dvi dvi-am info info-am install \
+ install-am install-binSCRIPTS install-data install-data-am \
+ install-exec install-exec-am install-info install-man \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic uninstall uninstall-am uninstall-binSCRIPTS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/contrib/ntp/scripts/README b/contrib/ntp/scripts/README
index 9e2946748b45..673ddb4492e2 100644
--- a/contrib/ntp/scripts/README
+++ b/contrib/ntp/scripts/README
@@ -18,11 +18,17 @@ rc1 start/stop scripts for NTP
rc2 start/stop script for NTP
+ntp-close find public stratum 2 servers that don't respond
+
ntp-groper script useful for reaching out and rattling the cages of
NTP peers to see if animals are inside the bars
ntp-restart script useful for killing and restarting the NTP daemon
+ntp-wait Blocks until ntpd is in state 4 (synchronized).
+ Hopefully useful at boot time, to delay the boot sequence
+ until after "ntpd -g" has set the time.
+
ntpsweep prints per host given in <file> the NTP stratum level, the
clock offset in seconds, the daemon version, the operating
system and the processor.
diff --git a/contrib/ntp/scripts/calc_tickadj.in b/contrib/ntp/scripts/calc_tickadj.in
new file mode 100644
index 000000000000..32eae12964a2
--- /dev/null
+++ b/contrib/ntp/scripts/calc_tickadj.in
@@ -0,0 +1,38 @@
+#! @PATH_PERL@
+#
+# drift of 104.8576 -> +1 tick. Base of 10000 ticks.
+#
+# 970306 HMS Deal with nanoseconds. Fix sign of adjustments.
+
+$df="/etc/ntp.drift";
+# Assumes a 100Hz box with "tick" of 10000
+# Someday, we might call "tickadj" for better values...
+$base=10000; # tick: 1,000,000 / HZ
+$cvt=104.8576; # 2 ** 20 / $base
+$v1=0.;
+$v2="";
+
+if (open(DF, $df))
+ {
+ if ($_=<DF>)
+ {
+ ($v1, $v2) = split;
+ }
+
+ while ($v1 < 0)
+ {
+ $v1 += $cvt;
+ $base--;
+ }
+
+ while ($v1 > $cvt)
+ {
+ $v1 -= $cvt;
+ $base++;
+ }
+ }
+
+printf("%.3f (drift)\n", $v1);
+
+printf("%d usec; %d nsec\n", $base, ($base + ($v1/$cvt)) * 1000);
+
diff --git a/contrib/ntp/scripts/checktime.in b/contrib/ntp/scripts/checktime.in
new file mode 100644
index 000000000000..2fe8f711bc82
--- /dev/null
+++ b/contrib/ntp/scripts/checktime.in
@@ -0,0 +1,79 @@
+#! @PATH_PERL@
+#! @PATH_PERL@ -d
+#
+# This script compares the time of several machines with the
+# time on the local host.
+#
+# Use or modify it as you wish.
+#
+# As the original author is only expecting 14 minutes of fame,
+# leaving his name attached would be appreciated.
+#
+# R. Gary Cutbill <rgary@chrysalis.com>
+# 21 April 1999
+#
+$tol=2.0;
+$|=1;
+print "Time Check";
+
+open(HOSTS,"ypcat hosts.byaddr |"); # get a list of hosts from the yp server.
+
+while ($line=<HOSTS>) { # loop for each host getting the offset compared to localhost
+ ($addr,$host,$aliases)=split(/\s+/,$line,3);
+ $res=`/usr/local/bin/ntptrace -m 1 -r 1 -t 1 $host`;
+ print ".";
+ chop $res;
+ push (@results,$res);
+}
+print "\n";
+
+
+#
+# Sort the list of hosts, and print out there offsets
+# from the local host.
+#
+@list=sort appropriately @results;
+foreach $i ( @list ) {
+
+ @dargs=split(/\s+/,$i);
+ if ( $dargs[1] eq "\*Timeout\*" ) {
+ print "$i\n";
+ chop $dargs[0];
+ push(@down,$dargs[0]);
+ } else {
+ printf "%-25s %7s %3s %6s %10s %5s %8s %8s\n",@dargs;
+ if ( ( $dargs[4] > $tol ) || ( $dargs[4] < -$tol ) ) {
+ chop $dargs[0];
+ push(@toofarout,$dargs[0]); }
+ }
+}
+#
+# When the above list finishes, hosts that are different by +/- $tol (two seconds)
+# are in @toofarout. Hosts that are down are in @down. They are treated the same
+# way here, but you might want to do something different depending on your site.
+#
+# print a set of suggested rsh commands to run on the hosts that
+# don't have "good" time. "restartntp" is left as an excersize to the reader.
+# I usually use it to kill a running xntpd, ntpdate some server, and the start xntp
+# again.
+#
+print "\nConsider:\n";
+foreach $i ( (@down,@toofarout) ) {
+ print " rsh $i sudo restartntp\n";
+}
+
+
+#
+# sort the results from the list. First by stratum, then by time deviation
+# Put hosts that didn't respond (timed out) on the bottom.
+#
+sub appropriately {
+ @af=split(/\s+/,$a);
+ @bf=split(/\s+/,$b);
+ $aba= ($af[4]<0)?-$af[4]:$af[4];
+ $abb= ($bf[4]<0)?-$bf[4]:$bf[4];
+
+ ( $af[1] ne $bf[1] ) ? $bf[1] cmp $af[1] :
+ ( ( $af[2] != $bf[2] ) ? ( $bf[2] <=> $af[2] ) :
+ ( ( $aba != $abb ) ? ( $abb <=> $aba ) : ($af[0] cmp $bf[0] ) ) );
+}
diff --git a/contrib/ntp/scripts/freq_adj.in b/contrib/ntp/scripts/freq_adj.in
new file mode 100644
index 000000000000..88eb390e1db6
--- /dev/null
+++ b/contrib/ntp/scripts/freq_adj.in
@@ -0,0 +1,97 @@
+#! @PATH_PERL@ -w
+
+die "perl5 needed\n" unless ($] > 5);
+
+use Getopt::Std;
+use vars qw($opt_n);
+
+getopts('d:nt:');
+
+#chop($ncpu = `sysctl -n hw.ncpu`);
+#die "Found $ncpu CPUs; can only be run on systems with 1 CPU.\n" if ($ncpu > 1);
+
+$driftfile = "/etc/ntp.drift";
+$driftfile = $opt_d if defined($opt_d);
+
+chop($timer = `sysctl -n kern.timecounter.hardware 2> /dev/null`);
+
+$timer =~ tr/\U/\L/;
+
+if ($timer eq '') {
+ open(DM, "/var/run/dmesg.boot");
+ while(<DM>) {
+ # Timecounter "i8254" frequency 1193182 Hz
+ if (/^Timecounter "(\w+)"\s+/) {
+ $timer = $1;
+ last;
+ }
+ }
+ close(DM);
+}
+
+$opt_t = $timer if !defined($opt_t);
+
+if ($timer ne '') { # $timer found...
+ if ($opt_t ne '') { # - and $opt_t found
+ if ($timer ne $opt_t) { # - - and they differ
+ warn "You specified a $opt_t timer but I detected a $timer timer.\n";
+ usage();
+ exit 1;
+ } else { # - - and they are the same
+ ;
+ }
+ } else { # - but no $opt_t specified; this is OK
+ ;
+ }
+} else { # No $timer found...
+ if ($opt_t ne '') { # - but $opt_t was specified
+ $timer = $opt_t; # - - so use it.
+ } else { # - and neither was $opt_t
+ warn "I can't tell what timer you have. Please specify one.\n";
+ usage();
+ exit 1;
+ }
+}
+
+open(DF, $driftfile) || die "Can't open driftfile ($driftfile): $!\n";
+while(<DF>) {
+ chop;
+ if (/^(-?\d+\.\d+)(\s\d)?$/) {
+ $drift = $1;
+ } else {
+ die "Bogus value in driftfile $driftfile: <$_>\n";
+ }
+}
+close(DF);
+
+print "NTP drift is <$drift>\n";
+
+# Convert from NTP's idea of PPM to a decimal equivalent
+$freq_adj = int ( $drift * ( 10 ** 6 / 2 ** 20) );
+print "normalized freq_adj is <$freq_adj>\n";
+
+$freq_adj = int ( ( $freq_adj - 1 ) / 2 );
+print "Applying freq_adj of <".-$freq_adj.">\n";
+
+$sysctl = "machdep.".$timer."_freq";
+
+chop($mach_freq = `sysctl -n $sysctl`);
+
+print "$sysctl is <$mach_freq>\n";
+
+$n_mach_freq = $mach_freq - $freq_adj;
+
+if (defined($opt_n)) {
+ print "$sysctl $mach_freq -> $n_mach_freq\n";
+} else {
+ print "i8254: ".`sysctl -w $sysctl=$n_mach_freq`;
+}
+
+sub usage {
+ print STDERR <<EOUsage
+Usage: $0 [-d drift_file] [-n] [-t timer]
+where "drift_file" defaults to /etc/ntp.drift
+and "timer" is usually "tsc" or "i8254"
+and "-n" says "don't really change anything, just say what would happen".
+EOUsage
+}
diff --git a/contrib/ntp/scripts/mkver.in b/contrib/ntp/scripts/mkver.in
index 79d83f83993d..c6dc8da32758 100644
--- a/contrib/ntp/scripts/mkver.in
+++ b/contrib/ntp/scripts/mkver.in
@@ -3,12 +3,19 @@ PROG=${1-UNKNOWN}
ConfStr="$PROG"
+ConfStr="$ConfStr @VERSION@"
+
case "@LIBRSAREF@" in
- '') ;;
- *) ConfStr="$ConfStr RSAREF" ;;
+ '')
+ case "@AUTOKEY@" in
+ '') ;;
+ *) ConfStr="${ConfStr}-a" ;;
+ esac
+ ;;
+ *) ConfStr="${ConfStr}-r" ;;
esac
-ConfStr="$ConfStr @VERSION@ `date`"
+ConfStr="$ConfStr `LC_TIME=C date`"
if [ ! -f .version ]; then
echo 0 > .version
diff --git a/contrib/ntp/scripts/monitoring/README b/contrib/ntp/scripts/monitoring/README
index fa8ad8bb9585..f8eb0a9544f6 100644
--- a/contrib/ntp/scripts/monitoring/README
+++ b/contrib/ntp/scripts/monitoring/README
@@ -1,14 +1,14 @@
This directory contains support for monitoring the local clock of xntp daemons.
-WARNING: The scripts and routines contained in this directory are bete realease!
- Do not depend on their correct operation. They are, however, in regular
- use at University of Erlangen-Nuernberg. No severe problems are known
- for this code.
+WARNING: The scripts and routines contained in this directory are beta
+ release! Do not depend on their correct operation. They are,
+ however, in regular use at University of Erlangen-Nuernberg.
+ No severe problems are known for this code.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
PLEASE THINK TWICE BEFORE STARTING MONITORING REMOTE XNTP DEAMONS !!!!
MONITORING MAY INCREASE THE LOAD OF THE DEAMON MONITORED AND MAY
-INCREASE THE NETWORK LOAD SIGNIFICANTLY
+INCREASE THE NETWORK LOAD SIGNIFICANTLY
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -23,8 +23,8 @@ ntptrap:
It sends a set_trap request to each server given and dumps the
trap messages received. It handles refresh of set_trap.
Currently it handles only NTP V2, however the NTP V3 servers
- also accept v2 requests. It will not interpret v3 system and peer
- stati correctly.
+ also accept v2 requests. It will not interpret v3 system and
+ peer stati correctly.
usage:
ntptrap [-n] [-p <port>] [-l <debug-output>] servers...
@@ -72,7 +72,9 @@ ntploopstat:
if a timeout occurs the next sample is tried after delay/2 seconds
- The script will terminate after MAX_FAIL (currently 60) consecutive errors.
+ The script will terminate after MAX_FAIL (currently 60)
+ consecutive errors.
+
Errors are counted for:
- error on send call
- error on select call
@@ -114,10 +116,10 @@ ntploopwatch:
command line values would be replaced by settings from the config file.
printer: specify printer to print plot
- BSD print systems semantics apply; if printer is omitted
- the name "ps" is used; plots are prepared using
- PostScript, thus the printer should best accept
- postscript input
+ BSD print systems semantics apply; if printer
+ is omitted the name "ps" is used; plots are
+ prepared using PostScript, thus the printer
+ should best accept postscript input
For the following see also the comments in loopwatch.config.SAMPLE
@@ -139,8 +141,10 @@ lr.pl:
within display range
timelocal.pl:
- used during conversion of ISO_DATE_TIME values specified in loopwatch
- config files to unix epoch values (seconds since 1970-01-01_00:00_00 UTC)
+
+ used during conversion of ISO_DATE_TIME values specified in
+ loopwatch config files to unix epoch values (seconds since
+ 1970-01-01_00:00_00 UTC)
A version of this file is distributed with perl-4.x, however,
it has a bug related to dates crossing 1970, causing endless loops..
diff --git a/contrib/ntp/scripts/monitoring/lr.pl b/contrib/ntp/scripts/monitoring/lr.pl
index 02c7550ec3ad..7980d2258408 100644
--- a/contrib/ntp/scripts/monitoring/lr.pl
+++ b/contrib/ntp/scripts/monitoring/lr.pl
@@ -9,9 +9,14 @@
;# Frank Kardel, Rainer Pruy
;# Friedrich-Alexander Universitaet Erlangen-Nuernberg
;#
+;# Copyright (c) 1997 by
+;# Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de>
+;# (Converted to a PERL 5.004 package)
;#
;#############################################################
+package lr;
+
##
## y = A + Bx
##
@@ -23,123 +28,124 @@
##
## interface
##
-*lr_init = *lr'lr_init; #';# &lr_init(tag); initialize data set for tag
-*lr_sample = *lr'lr_sample; #';# &lr_sample(x,y,tag); enter sample
-*lr_Y = *lr'lr_Y; #';# &lr_Y(x,tag); compute y for given x
-*lr_X = *lr'lr_X; #';# &lr_X(y,tag); compute x for given y
-*lr_r = *lr'lr_r; #';# &lr_r(tag); regression coeffizient
-*lr_cov = *lr'lr_cov; #';# &lr_cov(tag); covariance
-*lr_A = *lr'lr_A; #';# &lr_A(tag);
-*lr_B = *lr'lr_B; #';# &lr_B(tag);
-*lr_sigma = *lr'lr_sigma; #';# &lr_sigma(tag); standard deviation
-*lr_mean = *lr'lr_mean; #';# &lr_mean(tag);
+;# init(tag); initialize data set for tag
+;# sample(x, y, tag); enter sample
+;# Y(x, tag); compute y for given x
+;# X(y, tag); compute x for given y
+;# r(tag); regression coefficient
+;# cov(tag); covariance
+;# A(tag);
+;# B(tag);
+;# sigma(tag); standard deviation
+;# mean(tag);
#########################
-package lr;
-
-sub tagify
+sub init
{
- local($tag) = @_;
- if (defined($tag))
- {
- *lr_n = eval "*${tag}_n";
- *lr_sx = eval "*${tag}_sx";
- *lr_sx2 = eval "*${tag}_sx2";
- *lr_sxy = eval "*${tag}_sxy";
- *lr_sy = eval "*${tag}_sy";
- *lr_sy2 = eval "*${tag}_sy2";
- }
+ my $self = shift;
+
+ $self->{n} = 0;
+ $self->{sx} = 0.0;
+ $self->{sx2} = 0.0;
+ $self->{sxy} = 0.0;
+ $self->{sy} = 0.0;
+ $self->{sy2} = 0.0;
}
-sub lr_init
+sub sample($$$)
{
- &tagify($_[$[]) if defined($_[$[]);
-
- $lr_n = 0;
- $lr_sx = 0.0;
- $lr_sx2 = 0.0;
- $lr_sxy = 0.0;
- $lr_sy = 0.0;
- $lr_sy2 = 0.0;
+ my $self = shift;
+ my($_x, $_y) = @_;
+
+ ++($self->{n});
+ $self->{sx} += $_x;
+ $self->{sy} += $_y;
+ $self->{sxy} += $_x * $_y;
+ $self->{sx2} += $_x**2;
+ $self->{sy2} += $_y**2;
}
-sub lr_sample
+sub B($)
{
- local($_x, $_y) = @_;
-
- &tagify($_[$[+2]) if defined($_[$[+2]);
+ my $self = shift;
- $lr_n++;
- $lr_sx += $_x;
- $lr_sy += $_y;
- $lr_sxy += $_x * $_y;
- $lr_sx2 += $_x**2;
- $lr_sy2 += $_y**2;
+ return 1 unless ($self->{n} * $self->{sx2} - $self->{sx}**2);
+ return ($self->{n} * $self->{sxy} - $self->{sx} * $self->{sy})
+ / ($self->{n} * $self->{sx2} - $self->{sx}**2);
}
-sub lr_B
+sub A($)
{
- &tagify($_[$[]) if defined($_[$[]);
+ my $self = shift;
- return 1 unless ($lr_n * $lr_sx2 - $lr_sx**2);
- return ($lr_n * $lr_sxy - $lr_sx * $lr_sy) / ($lr_n * $lr_sx2 - $lr_sx**2);
+ return ($self->{sy} - B($self) * $self->{sx}) / $self->{n};
}
-sub lr_A
+sub Y($$)
{
- &tagify($_[$[]) if defined($_[$[]);
+ my $self = shift;
- return ($lr_sy - &lr_B * $lr_sx) / $lr_n;
+ return A($self) + B($self) * $_[$[];
}
-sub lr_Y
+sub X($$)
{
- &tagify($_[$[]) if defined($_[$[]);
+ my $self = shift;
- return &lr_A + &lr_B * $_[$[];
+ return ($_[$[] - A($self)) / B($self);
}
-sub lr_X
+sub r($)
{
- &tagify($_[$[]) if defined($_[$[]);
+ my $self = shift;
- return ($_[$[] - &lr_A) / &lr_B;
-}
-
-sub lr_r
-{
- &tagify($_[$[]) if defined($_[$[]);
-
- local($s) = ($lr_n * $lr_sx2 - $lr_sx**2) * ($lr_n * $lr_sy2 - $lr_sy**2);
+ my $s = ($self->{n} * $self->{sx2} - $self->{sx}**2)
+ * ($self->{n} * $self->{sy2} - $self->{sy}**2);
return 1 unless $s;
- return ($lr_n * $lr_sxy - $lr_sx * $lr_sy) / sqrt($s);
+ return ($self->{n} * $self->{sxy} - $self->{sx} * $self->{sy}) / sqrt($s);
}
-sub lr_cov
+sub cov($)
{
- &tagify($_[$[]) if defined($_[$[]);
+ my $self = shift;
- return ($lr_sxy - $lr_sx * $lr_sy / $lr_n) / ($lr_n - 1);
+ return ($self->{sxy} - $self->{sx} * $self->{sy} / $self->{n})
+ / ($self->{n} - 1);
}
-sub lr_sigma
+sub sigma($)
{
- &tagify($_[$[]) if defined($_[$[]);
+ my $self = shift;
- return 0 if $lr_n <= 1;
- return sqrt(($lr_sy2 - ($lr_sy * $lr_sy) / $lr_n) / ($lr_n));
+ return 0 if $self->{n} <= 1;
+ return sqrt(($self->{sy2} - ($self->{sy} * $self->{sy}) / $self->{n})
+ / ($self->{n}));
}
-sub lr_mean
+sub mean($)
{
- &tagify($_[$[]) if defined($_[$[]);
+ my $self = shift;
- return 0 if $lr_n <= 0;
- return $lr_sy / $lr_n;
+ return 0 if $self->{n} <= 0;
+ return $self->{sy} / $self->{n};
}
-&lr_init();
+sub new
+{
+ my $class = shift;
+ my $self = {
+ (n => undef,
+ sx => undef,
+ sx2 => undef,
+ sxy => undef,
+ sy => undef,
+ sy2 => undef)
+ };
+ bless $self, $class;
+ init($self);
+ return $self;
+}
1;
diff --git a/contrib/ntp/scripts/monitoring/ntp.pl b/contrib/ntp/scripts/monitoring/ntp.pl
index ea9e69c2022a..b23f396ee024 100644
--- a/contrib/ntp/scripts/monitoring/ntp.pl
+++ b/contrib/ntp/scripts/monitoring/ntp.pl
@@ -1,4 +1,4 @@
-#!/local/bin/perl
+#!/usr/bin/perl -w
;#
;# ntp.pl,v 3.1 1993/07/06 01:09:09 jbj Exp
;#
@@ -43,7 +43,7 @@ $keyid=0;
;# N key
;# N2 checksum
-;# first bye of packet
+;# first byte of packet
sub pkt_LI { return ($_[$[] >> 6) & 0x3; }
sub pkt_VN { return ($_[$[] >> 3) & 0x7; }
sub pkt_MODE { return ($_[$[] ) & 0x7; }
@@ -223,6 +223,7 @@ sub PeerSelection
{
&getval(&psw_PSel($_[$[]),*PeerSelection);
}
+
sub PeerEvent
{
&getval(&psw_PCode($_[$[]),*PeerEvent);
@@ -394,14 +395,14 @@ sub handle_packet
$lastseen = 1 if !&pkt_M($r_e_m_op);
if (!defined(%FRAGS))
{
- # (&pkt_M($r_e_m_op) ? " more" : "")."\n";
+ print((&pkt_M($r_e_m_op) ? " more" : "")."\n");
$FRAGS{$offset} = $data;
;# save other info
@FRAGS = ($status,$associd,&pkt_OP($r_e_m_op),$seq,$auth_keyid,$r_e_m_op);
}
else
{
- # (&pkt_M($r_e_m_op) ? " more" : "")."\n";
+ print((&pkt_M($r_e_m_op) ? " more" : "")."\n");
;# add frag to previous - combine on the fly
if (defined($FRAGS{$offset}))
{
diff --git a/contrib/ntp/scripts/monitoring/ntploopstat b/contrib/ntp/scripts/monitoring/ntploopstat
index 75cdff227b27..7583c7cca018 100644
--- a/contrib/ntp/scripts/monitoring/ntploopstat
+++ b/contrib/ntp/scripts/monitoring/ntploopstat
@@ -1,4 +1,5 @@
-#!/local/bin/perl -w--*-perl-*-
+#!/usr/bin/perl -w
+# --*-perl-*-
;#
;# ntploopstat,v 3.1 1993/07/06 01:09:11 jbj Exp
;#
@@ -22,7 +23,7 @@
;# (Should have implemented &gettimeofday()..)
;#
-$0 =~ s!^.*/([^/]+)$!\1!; # beautify script name
+$0 =~ s!^.*/([^/]+)$!$1!; # beautify script name
$ntpserver = 'localhost'; # default host to poll
$delay = 60; # default sampling rate
diff --git a/contrib/ntp/scripts/ntp-close b/contrib/ntp/scripts/ntp-close
new file mode 100755
index 000000000000..b5077e67142c
--- /dev/null
+++ b/contrib/ntp/scripts/ntp-close
@@ -0,0 +1,8 @@
+#! /bin/sh
+
+lynx -source http://www.eecis.udel.edu/~mills/ntp/clock2.htm |
+ sed -n -e 's,).*,,' -e' /([0-9.]*$/s/.*(//p' |
+ xargs ntpdate -q |
+ sort -n +7 > /tmp/ntp-close
+
+# From: Neal McBurnett <neal@bcn.boulder.co.us>
diff --git a/contrib/ntp/scripts/ntp-restart b/contrib/ntp/scripts/ntp-restart
index d2023f0b67b2..0a1d58a5c56c 100755
--- a/contrib/ntp/scripts/ntp-restart
+++ b/contrib/ntp/scripts/ntp-restart
@@ -1,9 +1,10 @@
#!/bin/sh
#
# This script can be used to kill and restart the NTP daemon. Edit the
-# /usr/local/bin/xntpd line to fit.
+# /usr/local/bin/ntpd line to fit.
#
-kill -INT `ps -ax | egrep "xntpd" | egrep -v "egrep" | sed 's/^\([ 0-9]*\) .*/\1'/`
+kill -INT `ps -ax | egrep "ntpd" | egrep -v "egrep" | sed 's/^\([ 0-9]*\) .*/\1'/`
sleep 10
-/usr/local/bin/xntpd
+/usr/local/bin/ntpd -g
+/usr/local/bin/ntp-wait
exit 0
diff --git a/contrib/ntp/scripts/ntp-wait.in b/contrib/ntp/scripts/ntp-wait.in
new file mode 100644
index 000000000000..a26630bebf58
--- /dev/null
+++ b/contrib/ntp/scripts/ntp-wait.in
@@ -0,0 +1,42 @@
+#! @PATH_PERL@ -w
+
+die "perl5 needed\n" unless ($] > 5);
+
+use Getopt::Std;
+
+$opt_f = 0; # 'Hard' failure if 'state' is unknown
+$opt_n = 1000; # How many tries before we give up? (10 min+)
+$opt_s = 6; # Seconds to sleep between tries (6s = 10/min)
+$opt_v = 0; # Be verbose?
+
+getopts('fn:s:v');
+
+$cmd = 'ntpq -c "rv 0 state"';
+
+$| = 1; # Autoflush output.
+
+print "Waiting for ntpd to synchronize... " if ($opt_v);
+for ($i = 0; $i < $opt_n; ++$i) {
+ open(Q, $cmd." 2>&1 |") || die "Can't start ntpq: $!";
+ while(<Q>) {
+ if (/^state=4/) {
+ print "\bOK!\n" if ($opt_v);
+ exit 0;
+ }
+
+ if (/request variable was unknown/) {
+ print "\bCan't tell!\nPerhaps you are running an old version of ntpd.\n" if ($opt_v);
+ exit $opt_f;
+ }
+
+ if (/Connection refused/) {
+ print "\bntpd is not running!\n" if ($opt_v);
+ exit 1;
+ }
+ }
+ close(Q);
+ print "\b".substr("*+:.", $i % 4, 1) if ($opt_v);
+ sleep($opt_s);
+}
+print "\bNo!\nntpd did not synchronize.\n" if ($opt_v);
+exit 1;
diff --git a/contrib/ntp/scripts/ntpsweep.in b/contrib/ntp/scripts/ntpsweep.in
new file mode 100644
index 000000000000..eb41563ad1ca
--- /dev/null
+++ b/contrib/ntp/scripts/ntpsweep.in
@@ -0,0 +1,301 @@
+#! @PATH_PERL@ -w
+#
+# $Id: ntpsweep.in,v 1.1 2000/02/10 08:13:40 stenn Exp $
+#
+# DISCLAIMER
+#
+# Copyright (C) 1999,2000 Hans Lambermont and Origin B.V.
+#
+# Permission to use, copy, modify and distribute this software and its
+# documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appears in all copies and
+# that both the copyright notice and this permission notice appear in
+# supporting documentation. This software is supported as is and without
+# any express or implied warranties, including, without limitation, the
+# implied warranties of merchantability and fitness for a particular
+# purpose. The name Origin B.V. must not be used to endorse or promote
+# products derived from this software without prior written permission.
+#
+# Hans Lambermont <Hans.Lambermont@nl.origin-it.com>/<H.Lambermont@chello.nl>
+# 14 Jan 2000
+
+require 5.0; # But actually tested on 5.004 ;)
+use Getopt::Long; # GetOptions()
+use strict;
+
+my $version = 1.3;
+(my $program = $0) =~ s%.*/(.+?)(.pl)?$%$1%;
+
+# Hardcoded paths/program names
+my $ntpdate = "ntpdate";
+my $ntpq = "ntpq";
+
+# no STDOUT buffering
+$| = 1;
+
+my ($help, $single_host, $showpeers, $maxlevel, $strip, $askversion);
+my $res = GetOptions("help!" => \$help,
+ "host=s" => \$single_host,
+ "peers!" => \$showpeers,
+ "maxlevel=s" => \$maxlevel,
+ "strip=s" => \$strip,
+ "version!" => \$askversion);
+
+if ($askversion) {
+ print("$version\n");
+ exit 0;
+}
+
+if ($help || ((@ARGV != 1) && !$single_host)) {
+ warn <<EOF;
+This is $program, version $version
+Copyright (C) 1999,2000 Hans Lambermont and Origin B.V. Disclaimer inside.
+
+Usage:
+ $program [--help|--peers|--strip <string>|--maxlevel <level>|--version] \\
+ <file>|[--host <hostname>]
+
+Description:
+ $program prints per host given in <file> the NTP stratum level, the
+ clock offset in seconds, the daemon version, the operating system and
+ the processor. Optionally recursing through all peers.
+
+Options:
+--help
+ Print this short help text and exit.
+--version
+ Print version ($version) and exit.
+<file>
+ Specify hosts file. File format is one hostname or ip number per line.
+ Lines beginning with # are considered as comment.
+--host <hostname>
+ Speficy a single host, bypassing the need for a hosts file.
+--peers
+ Recursively list all peers a host synchronizes to.
+ An '= ' before a peer means a loop. Recursion stops here.
+--maxlevel <level>
+ Traverse peers up to this level (4 is a reasonable number).
+--strip <string>
+ Strip <string> from hostnames.
+
+Examples:
+ $program myhosts.txt --strip .foo.com
+ $program --host some.host --peers --maxlevel 4
+EOF
+ exit 1;
+}
+
+my $hostsfile = shift;
+my (@hosts, @known_hosts);
+my (%known_host_info, %known_host_peers);
+
+sub read_hosts()
+{
+ local *HOSTS;
+ open (HOSTS, $hostsfile) ||
+ die "$program: FATAL: unable to read $hostsfile: $!\n";
+ while (<HOSTS>) {
+ next if /^\s*(#|$)/; # comment/empty
+ chomp;
+ push(@hosts, $_);
+ }
+ close(HOSTS);
+}
+
+# translate IP to hostname if possible
+sub ip2name {
+ my($ip) = @_;
+ my($addr, $name, $aliases, $addrtype, $length, @addrs);
+ $addr = pack('C4', split(/\./, $ip));
+ ($name, $aliases, $addrtype, $length, @addrs) = gethostbyaddr($addr, 2);
+ if ($name) {
+ # return lower case name
+ return("\L$name");
+ } else {
+ return($ip);
+ }
+}
+
+# item_in_list($item, @list): returns 1 if $item is in @list, 0 if not
+sub item_in_list {
+ my($item, @list) = @_;
+ my($i);
+ foreach $i (@list) {
+ return 1 if ($item eq $i);
+ }
+ return 0;
+}
+
+sub scan_host($;$;$) {
+ my($host, $level, @trace) = @_;
+ my $stratum = 0;
+ my $offset = 0;
+ my $daemonversion = "";
+ my $system = "";
+ my $processor = "";
+ my @peers;
+ my $known_host = 0;
+
+ if (&item_in_list($host, @known_hosts)) {
+ $known_host = 1;
+ } else {
+ # ntpdate part
+ open(NTPDATE, "$ntpdate -bd $host 2>/dev/null |") ||
+ die "Cannot open ntpdate pipe: $!\n";
+ while (<NTPDATE>) {
+ /^stratum\s+(\d+).*$/ && do {
+ $stratum = $1;
+ };
+ /^offset\s+([0-9.-]+)$/ && do {
+ $offset = $1;
+ };
+ }
+ close(NTPDATE);
+
+ # got answers ? If so, go on.
+ if ($stratum) {
+ # ntpq part
+ my $ntpqparams = "-c 'rv 0 processor,system,daemon_version'";
+ open(NTPQ, "$ntpq $ntpqparams $host 2>/dev/null |") ||
+ die "Cannot open ntpq pipe: $!\n";
+ while (<NTPQ>) {
+ /daemon_version="(.*)"/ && do {
+ $daemonversion = $1;
+ };
+ /system="([^"]*)"/ && do {
+ $system = $1;
+ };
+ /processor="([^"]*)"/ && do {
+ $processor = $1;
+ };
+ }
+ close(NTPQ);
+
+ # Shorten daemon_version string.
+ $daemonversion =~ s/(;|Mon|Tue|Wed|Thu|Fri|Sat|Sun).*$//;
+ $daemonversion =~ s/version=//;
+ $daemonversion =~ s/(x|)ntpd //;
+ $daemonversion =~ s/(\(|\))//g;
+ $daemonversion =~ s/beta/b/;
+ $daemonversion =~ s/multicast/mc/;
+
+ # Shorten system string
+ $system =~ s/UNIX\///;
+ $system =~ s/RELEASE/r/;
+ $system =~ s/CURRENT/c/;
+
+ # Shorten processor string
+ $processor =~ s/unknown//;
+ }
+
+ # got answers ? If so, go on.
+ if ($daemonversion) {
+ # ntpq again, find out the peers this time
+ if ($showpeers) {
+ my $ntpqparams = "-pn";
+ open(NTPQ, "$ntpq $ntpqparams $host 2>/dev/null |") ||
+ die "Cannot open ntpq pipe: $!\n";
+ while (<NTPQ>) {
+ /^No association ID's returned$/ && do {
+ last;
+ };
+ /^ remote/ && do {
+ next;
+ };
+ /^==/ && do {
+ next;
+ };
+ /^( |x|\.|-|\+|#|\*|o)([^ ]+)/ && do {
+ push(@peers, ip2name($2));
+ next;
+ };
+ print "ERROR: $_";
+ }
+ close(NTPQ);
+ }
+ }
+
+ # Add scanned host to known_hosts array
+ push(@known_hosts, $host);
+ if ($stratum) {
+ $known_host_info{$host} = sprintf("%2d %9.3f %-11s %-12s %s",
+ $stratum, $offset, substr($daemonversion,0,11),
+ substr($system,0,12), substr($processor,0,9));
+ } else {
+ # Stratum level 0 is consider invalid
+ $known_host_info{$host} = sprintf(" ?");
+ }
+ $known_host_peers{$host} = [@peers];
+ }
+
+ if ($stratum || $known_host) { # Valid or known host
+ my $printhost = ' ' x $level . $host;
+ # Shorten host string
+ if ($strip) {
+ $printhost =~ s/$strip//;
+ }
+ # append number of peers in brackets if requested and valid
+ if ($showpeers && ($known_host_info{$host} ne " ?")) {
+ $printhost .= " (" . @{$known_host_peers{$host}} . ")";
+ }
+ # Finally print complete host line
+ printf("%-32s %s\n",
+ substr($printhost,0,32), $known_host_info{$host});
+ if ($showpeers && (eval($maxlevel ? $level < $maxlevel : 1))) {
+ my $peer;
+ push(@trace, $host);
+ # Loop through peers
+ foreach $peer (@{$known_host_peers{$host}}) {
+ if (&item_in_list($peer, @trace)) {
+ # we've detected a loop !
+ $printhost = ' ' x ($level + 1) . "= " . $peer;
+ # Shorten host string
+ if ($strip) {
+ $printhost =~ s/$strip//;
+ }
+ printf("%-32s %s\n",
+ substr($printhost,0,32));
+ } else {
+ if (substr($peer,0,3) ne "127") {
+ &scan_host($peer, $level + 1, @trace);
+ }
+ }
+ }
+ }
+ } else { # We did not get answers from this host
+ my $printhost = ' ' x $level . $host;
+ # Shorten host string
+ if ($strip) {
+ $printhost =~ s/$strip//;
+ }
+ printf("%-32s ?\n", substr($printhost,0,32));
+ }
+}
+
+sub scan_hosts()
+{
+ my $host;
+ for $host (@hosts) {
+ my @trace;
+ push(@trace, $host);
+ scan_host($host, 0, @trace);
+ }
+}
+
+# Main program
+
+if ($single_host) {
+ push(@hosts, $single_host);
+} else {
+ &read_hosts($hostsfile);
+}
+
+# Print header
+print <<EOF;
+Host st offset(s) version system processor
+--------------------------------+--+---------+-----------+------------+---------
+EOF
+
+&scan_hosts();
+
+exit 0;
diff --git a/contrib/ntp/scripts/plot_summary.in b/contrib/ntp/scripts/plot_summary.in
new file mode 100644
index 000000000000..03d8203eb027
--- /dev/null
+++ b/contrib/ntp/scripts/plot_summary.in
@@ -0,0 +1,337 @@
+#! @PATH_PERL@ -w
+# $Id: plot_summary.in,v 1.1 2000/02/10 08:13:40 stenn Exp $
+#
+# Use Gnuplot to display data in summary files produced by summary.pl.
+# This script requires GNUPLOT 3.7!
+#
+# Copyright (c) 1997, 1999 by Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+require 5.003; # "never tested with any other version of Perl"
+use strict;
+
+use Time::Local;
+use Getopt::Long;
+
+# parse command line
+my $summary_dir = "/tmp";
+my $identifier = "host " . `hostname`; # origin of these data
+chomp $identifier; # remove newline
+my $offset_limit = 0.128; # limit of absolute offset
+my $output_file = ""; # output file defaults to stdout
+my $output_file_number = 1; # numbering of output files
+my $gnuplot_terminal = $ENV{DISPLAY} ? "x11" : "dumb";
+my $wait_after_plot = 1;
+my @peer_list = ();
+
+my %options = ("directory|input-directory=s" => \$summary_dir,
+ "identifier=s" => \$identifier,
+ "offset-limit=f" => \$offset_limit,
+ "output-file=s" => \$output_file,
+ "peer=s@" => \@peer_list,
+ "plot-term|gnuplot-term=s" => \$gnuplot_terminal,
+ "wait-after-plot!" => \$wait_after_plot,
+ );
+
+if ( !GetOptions(%options) )
+{
+ print STDERR "valid options for $0 are:\n";
+ my $opt;
+ foreach $opt (sort(keys %options)) {
+ print STDERR "\t--$opt\t(default is ";
+ if ( ref($options{$opt}) eq "ARRAY" ) {
+ print STDERR join(", ", map { "'$_'" } @{$options{$opt}});
+ } else {
+ print STDERR "'${$options{$opt}}'";
+ }
+ print STDERR ")\n";
+ }
+ print STDERR "\n";
+ die;
+}
+
+chomp $identifier;
+die "illegal offset-limit: $offset_limit" unless $offset_limit > 0.0;
+$offset_limit *= 1e6; # scale to microseconds
+
+# return the smallest value in the given list
+sub min
+{
+ my ($result, @rest) = @_;
+ map { $result = $_ if ($_ < $result) } @rest;
+ return($result);
+}
+
+# return the largest value in the given list
+sub max
+{
+ my ($result, @rest) = @_;
+ map { $result = $_ if ($_ > $result) } @rest;
+ return($result);
+}
+
+# maybe open alternate output file
+sub open_output
+{
+ my $file;
+ if ($output_file) {
+ while ( -r ($file = "$output_file$output_file_number") ) {
+ ++$output_file_number;
+ }
+ open TOUCH, ">$file" and close TOUCH or die "$file: $!";
+ print "set output \"$file\"\n";
+ }
+}
+
+# make Gnuplot wait
+sub maybe_add_pause
+{
+ print "pause -1 \"Press key to continue...\"\n" if $wait_after_plot;
+}
+
+# plot data from loop summary
+sub do_loop
+{
+ my $fname = shift;
+ my $line;
+ my $out_file = "/tmp/tempdata$$";
+ my $cmd_file = "/tmp/tempcmd$$";
+ my ($first_day, $day_out) = ("", 0);
+ my ($lower_bound, $upper_bound, $rms);
+ my ($min_offs, $max_offs) = (1e9, -1e9);
+ my ($min_rms, $max_rms) = (1e9, -1e9);
+ open INPUT, "$fname" or die "$fname: $!";
+ open OUTPUT, ">$out_file" or die "$out_file: $!";
+ my @Fld;
+ while (<INPUT>) {
+ chop; # strip record separator
+ @Fld = split;
+ if ($#Fld == 0) {
+# loops.19960405
+ $_ = $Fld[0]; s/.*([12]\d{3}[01]\d[0-3]\d)$/$1/;
+ m/(\d{4})(\d{2})(\d{2})/;
+ $line = timegm(59, 59, 23, $3, $2 - 1, $1 - 1900, 0, 0, 0);
+ $line = int $line / 86400; # days relative to 1970
+ $first_day = "$1-$2-$3 ($line)" unless $day_out;
+ next;
+ }
+ if ($#Fld != 8) {
+ warn "Illegal number of fields in file $fname, line $.";
+ next;
+ }
+# loop 216, 856106+/-874041.5, rms 117239.8, freq 67.52+/-10.335, var 4.850
+ $_ = $Fld[1]; s/,/ /; $line .= " $_";
+ $_ = $Fld[2]; m:(.+?)\+/-(.+),:;
+ $lower_bound = $1 - $2;
+ $upper_bound = $1 + $2;
+ $line .= "$1 $lower_bound $upper_bound";
+ $min_offs = min($min_offs, $lower_bound);
+ $max_offs = max($max_offs, $upper_bound);
+ $_ = $Fld[4]; s/,/ /; $rms = $_;
+ $min_rms = min($min_rms, $rms);
+ $max_rms = max($max_rms, $rms);
+ $line .= " $rms";
+ $_ = $Fld[6]; m:(.+?)\+/-(.+),:;
+ $line .= " $1 " . ($1-$2) . " " . ($1+$2);
+ $line .= " $Fld[8]";
+ print OUTPUT "$line\n";
+ $day_out = 1;
+# 9621 216 856106 -17935.5 1730147.5 117239.8 67.52 57.185 77.855 4.850
+ }
+ close INPUT;
+ close OUTPUT or die "close failed on $out_file: $!";
+ my $ylimit = "[";
+ if ($min_offs < -$offset_limit) {
+ $ylimit .= "-$offset_limit";
+ }
+ $ylimit .= ":";
+ if ($max_offs > $offset_limit) {
+ $ylimit .= "$offset_limit";
+ }
+ if ( $ylimit eq "[:" ) {
+ $ylimit = "";
+ } else {
+ $ylimit = "[] $ylimit]";
+ }
+# build command file for GNUplot
+ open OUTPUT, "> $cmd_file" or die "$cmd_file: $!";
+ my $oldfh = select OUTPUT;
+ print "set term $gnuplot_terminal\n";
+ open_output;
+ print "set grid\n";
+ print "set title \"Loop Summary for $identifier: " .
+ "Daily mean values since $first_day\\n" .
+ "(Offset limit is $offset_limit microseconds)\"\n";
+ print "set ylabel \"[us]\"\n";
+ print "set data style yerrorbars\n";
+ print "set multiplot\n";
+ print "set size 1, 0.5\n";
+ print "set lmargin 8\n";
+ print "set origin 0, 0.5\n";
+ print "plot $ylimit \"$out_file\"" .
+ " using 1:3:4:5 title \"mean offset\", ";
+ print "\"$out_file\" using 1:(\$3-\$6/2) " .
+ "title \"(sigma low)\" with lines, ";
+ print "\"$out_file\" using 1:3 smooth bezier " .
+ "title \"(Bezier med)\" with lines, ";
+ print "\"$out_file\" using 1:(\$3+\$6/2) " .
+ "title \"(sigma high)\" with lines\n";
+ print "set ylabel \"[ppm]\"\n";
+ print "set origin 0, 0.0\n";
+ print "set title\n";
+ print "set xlabel \"Days relative to 1970\"\n";
+ print "plot \"$out_file\" using 1:7:8:9 title \"mean frequency\", ";
+ print "\"$out_file\" using 1:(\$7-\$10/2) " .
+ "title \"(sigma low)\" with lines, ";
+ print "\"$out_file\" using 1:7 smooth bezier " .
+ "title \"(Bezier med)\" with lines, ";
+ print "\"$out_file\" using 1:(\$7+\$10/2) " .
+ "title \"(sigma high)\" with lines\n";
+ print "set nomultiplot\n";
+ maybe_add_pause;
+
+ $ylimit = "[";
+ if ($min_rms < -$offset_limit) {
+ $ylimit .= "-$offset_limit";
+ }
+ $ylimit .= ":";
+ if ($max_rms > $offset_limit) {
+ $ylimit .= "$offset_limit";
+ }
+ if ( $ylimit eq "[:" ) {
+ $ylimit ="";
+ } else {
+ $ylimit = "[] $ylimit]";
+ }
+
+ open_output;
+ print "set title \"Loop Summary for $identifier: " .
+ "Standard deviation since $first_day\\n" .
+ "(Offset limit is $offset_limit microseconds)\"\n";
+ print "set xlabel\n";
+ print "set ylabel \"[us]\"\n";
+ print "set origin 0, 0.5\n";
+ print "set data style linespoints\n";
+ print "set multiplot\n";
+ print "plot $ylimit \"$out_file\" using 1:6 title \"Offset\", ";
+ print "\"$out_file\" using 1:6 smooth bezier " .
+ "title \"(Bezier)\" with lines\n";
+ print "set title\n";
+ print "set origin 0, 0.0\n";
+ print "set xlabel \"Days relative to 1970\"\n";
+ print "set ylabel \"[ppm]\"\n";
+ print "plot \"$out_file\" using 1:10 title \"Frequency\", ";
+ print "\"$out_file\" using 1:10 smooth bezier " .
+ "title \"(Bezier)\" with lines\n";
+ print "set nomultiplot\n";
+ maybe_add_pause;
+
+ close OUTPUT or die "close failed on $cmd_file: $!";
+ select $oldfh;
+ print `gnuplot $cmd_file`;
+ unlink $cmd_file;
+ unlink $out_file;
+}
+
+# plot data form peer summary
+sub do_peer
+{
+ my $fname = shift;
+ my $peer = shift;
+ my $out_file = "/tmp/tempdata$$";
+ my $cmd_file = "/tmp/tempcmd$$";
+ my $line;
+ my ($first_day, $day_out) = ("", 0);
+ open INPUT, "$fname" or die "$fname: $!";
+ open OUTPUT, ">$out_file" or die "$out_file: $!";
+ my @Fld;
+ while (<INPUT>) {
+ chop; # strip record separator
+ @Fld = split;
+ if ($#Fld == 0) {
+# peers.19960405
+ $_ = $Fld[0]; s/.*([12]\d{3}[01]\d[0-3]\d)$/$1/;
+ m/(\d{4})(\d{2})(\d{2})/ or next;
+ $line = timegm(59, 59, 23, $3, $2 - 1, $1 - 1900, 0, 0, 0);
+ $line = int $line / 86400; # days relative to 1970
+ $first_day = "$1-$2-$3 ($line)" unless $day_out;
+ next;
+ }
+ if ($#Fld != 7) {
+ warn "Illegal number of fields in file $fname, line $.";
+ next;
+ }
+ next if ($Fld[0] ne $peer);
+# ident cnt mean rms max delay dist disp
+# 127.127.8.1 38 30.972 189.867 1154.607 0.000 879.760 111.037
+ $Fld[0] = $line;
+ print OUTPUT join(' ', @Fld) . "\n";
+# 9969 38 30.972 189.867 1154.607 0.000 879.760 111.037
+ $day_out = 1;
+ }
+ close INPUT;
+ close OUTPUT or die "close failed on $out_file: $!";
+ die "no data found for peer $peer" if !$day_out;
+ open OUTPUT, "> $cmd_file" or die "$cmd_file: $!";
+ my $oldfh = select OUTPUT;
+ print "set term $gnuplot_terminal\n";
+ open_output;
+ print "set grid\n";
+ print "set multiplot\n";
+ print "set lmargin 8\n";
+ print "set size 1, 0.34\n";
+ print "set origin 0, 0.66\n";
+ print "set title " .
+ "\"Peer Summary for $peer on $identifier since $first_day\"\n";
+ print "set data style linespoints\n";
+ print "set ylabel \"[us]\"\n";
+ print "plot \"$out_file\" using 1:3 title \"mean offset\", ";
+ print "\"$out_file\" using 1:3 smooth bezier " .
+ "title \"(Bezier)\" with lines, ";
+ print "\"$out_file\" using 1:(\$3-\$7/2) " .
+ "title \"(sigma low)\" with lines, ";
+ print "\"$out_file\" using 1:(\$3+\$7/2) " .
+ "title \"(sigma high)\" with lines\n";
+ print "set title\n";
+ print "set origin 0, 0.34\n";
+ print "set size 1, 0.32\n";
+ print "set ylabel\n";
+ print "plot \"$out_file\" using 1:7 title \"dist\", ";
+ print "\"$out_file\" using 1:7 smooth bezier " .
+ "title \"(Bezier)\" with lines\n";
+ print "set origin 0, 0.00\n";
+ print "set size 1, 0.35\n";
+ print "set xlabel \"Days relative to 1970\"\n";
+ print "plot \"$out_file\" using 1:8 title \"disp\", ";
+ print "\"$out_file\" using 1:8 smooth bezier " .
+ "title \"(Bezier)\" with lines\n";
+ print "set nomultiplot\n";
+ maybe_add_pause;
+
+ select $oldfh;
+ close OUTPUT or die "close failed on $cmd_file: $!";
+ print `gnuplot $cmd_file`;
+ unlink $cmd_file;
+ unlink $out_file;
+}
+
+
+my $loop_summary ="$summary_dir/loop_summary";
+my $peer_summary ="$summary_dir/peer_summary";
+my $clock_summary="$summary_dir/clock_summary";
+
+do_loop $loop_summary;
+map { do_peer $peer_summary, $_ } @peer_list;
diff --git a/contrib/ntp/scripts/stats/summary.sh b/contrib/ntp/scripts/stats/summary.sh
index 655c4be9dcdd..dffdb0b1569f 100755
--- a/contrib/ntp/scripts/stats/summary.sh
+++ b/contrib/ntp/scripts/stats/summary.sh
@@ -6,7 +6,7 @@
# runs the file-specific summary script and appends the summary data to
# designated files.
#
-DATE=`date +19%y%m%d`
+DATE=`date +20%y%m%d`
S=/usr/local/bin/S
SIN=S.in
SOUT=S.out
diff --git a/contrib/ntp/scripts/summary.in b/contrib/ntp/scripts/summary.in
new file mode 100644
index 000000000000..ac259d4b19b7
--- /dev/null
+++ b/contrib/ntp/scripts/summary.in
@@ -0,0 +1,373 @@
+#! @PATH_PERL@ -w
+# $Id: summary.in,v 1.1 2000/02/10 08:13:40 stenn Exp $
+# Perl version of (summary.sh, loop.awk, peer.awk):
+# Create summaries from xntpd's loop and peer statistics.
+#
+# Copyright (c) 1997, 1999 by Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+require 5.003; # "never tested with any other version of Perl"
+use strict;
+
+use Getopt::Long;
+
+my $log_date_pattern = '[12]\d{3}[01]\d[0-3]\d';
+my $statsdir = "/var/log/ntp"; # directory with input files
+my $outputdir = "/tmp"; # directory for output files
+my $skip_time_steps = 3600.0; # ignore time offsets larger that this
+my $startdate = "19700101"; # first data file to use (YYYYMMDD)
+my $enddate=`date -u +%Y%m%d`; chomp $enddate; --$enddate;
+my $peer_dist_limit = 400.0;
+
+my %options = ("directory|input-directory=s" => \$statsdir,
+ "output-directory=s" => \$outputdir,
+ "skip-time-steps:f" => \$skip_time_steps,
+ "start-date=s" => \$startdate,
+ "end-date=s" => \$enddate,
+ "peer-dist-limit=f" => \$peer_dist_limit);
+
+if ( !GetOptions(%options) )
+{
+ print STDERR "valid options for $0 are:\n";
+ my $opt;
+ foreach $opt (sort(keys %options)) {
+ print STDERR "\t--$opt\t(default is ";
+ if ( ref($options{$opt}) eq "ARRAY" ) {
+ print STDERR join(", ", map { "'$_'" } @{$options{$opt}});
+ } else {
+ print STDERR "'${$options{$opt}}'";
+ }
+ print STDERR ")\n";
+ }
+ print STDERR "\n";
+ die;
+}
+
+# check possibly current values of options
+die "$statsdir: no such directory" unless (-d $statsdir);
+die "$outputdir: no such directory" unless (-d $outputdir);
+die "$skip_time_steps: skip-time-steps must be positive"
+ unless ($skip_time_steps >= 0.0);
+die "$startdate: invalid start date|$`|$&|$'"
+ unless ($startdate =~ m/.*$log_date_pattern$/);
+die "$enddate: invalid end date"
+ unless ($enddate =~ m/.*$log_date_pattern$/);
+
+$skip_time_steps = 0.128 if ($skip_time_steps == 0);
+
+sub min
+{
+ my ($result, @rest) = @_;
+ map { $result = $_ if ($_ < $result) } @rest;
+ return($result);
+}
+
+sub max
+{
+ my ($result, @rest) = @_;
+ map { $result = $_ if ($_ > $result) } @rest;
+ return($result);
+}
+
+# calculate mean, range, and standard deviation for offset and frequency
+sub do_loop
+{
+ my ($directory, $fname, $out_file) = @_;
+ print "$directory/$fname\n";
+ open INPUT, "$directory/$fname" or warn "can't open $directory/$fname: $!";
+ open OUTPUT, ">>$out_file" or die "can't open $out_file: $!";
+ print OUTPUT "$fname\n";
+ my ($loop_tmax, $loop_fmax) = (-1e9, -1e9);
+ my ($loop_tmin, $loop_fmin) = (1e9, 1e9);
+ my ($loop_time_rms, $loop_freq_rms) = (0, 0);
+ my $loop_count = 0;
+ my $loop_time = 0;
+ my $loop_freq = 0;
+ my ($freq, $offs);
+ my @Fld;
+ while (<INPUT>) {
+ chop; # strip record separator
+ @Fld = split;
+ next if ($#Fld < 4);
+#NTPv3: 50529 74356.259 -0.000112 16.1230 8
+#NTPv3: day, sec.msec, offset, drift_comp, sys_poll
+#NTPv4: 51333 54734.582 0.000001648 16.981964 0.000001094 0.020938 6
+#NTPv4: day, sec.msec, offset, drift_comp, sys_error, clock_stabil, sys_poll
+ if ($Fld[2] > $skip_time_steps || $Fld[2] < -$skip_time_steps) {
+ warn "ignoring loop offset $Fld[2] (file $fname, line $.)\n";
+ next
+ }
+ $loop_count++;
+ ($offs, $freq) = ($Fld[2], $Fld[3]);
+ $loop_tmax = max($loop_tmax, $offs);
+ $loop_tmin = min($loop_tmin, $offs);
+ $loop_fmax = max($loop_fmax, $freq);
+ $loop_fmin = min($loop_fmin, $freq);
+ $loop_time += $offs;
+ $loop_time_rms += $offs * $offs;
+ $loop_freq += $freq;
+ $loop_freq_rms += $freq * $freq;
+ }
+ close INPUT;
+ if ($loop_count > 1) {
+ $loop_time /= $loop_count;
+ $loop_time_rms = $loop_time_rms / $loop_count - $loop_time * $loop_time;
+ if ($loop_time_rms < 0) {
+ warn "loop_time_rms: $loop_time_rms < 0";
+ $loop_time_rms = 0;
+ }
+ $loop_time_rms = sqrt($loop_time_rms);
+ $loop_freq /= $loop_count;
+ $loop_freq_rms = $loop_freq_rms / $loop_count - $loop_freq * $loop_freq;
+ if ($loop_freq_rms < 0) {
+ warn "loop_freq_rms: $loop_freq_rms < 0";
+ $loop_freq_rms = 0;
+ }
+ $loop_freq_rms = sqrt($loop_freq_rms);
+ printf OUTPUT
+ ("loop %d, %.0f+/-%.1f, rms %.1f, freq %.2f+/-%0.3f, var %.3f\n",
+ $loop_count, ($loop_tmax + $loop_tmin) / 2 * 1e6,
+ ($loop_tmax - $loop_tmin) / 2 * 1e6, $loop_time_rms * 1e6,
+ ($loop_fmax + $loop_fmin) / 2, ($loop_fmax - $loop_fmin) / 2,
+ $loop_freq_rms);
+ }
+ else {
+ warn "no valid lines in $directory/$fname";
+ }
+ close OUTPUT
+}
+
+# calculate mean, standard deviation, maximum offset, mean dispersion,
+# and maximum distance for each peer
+sub do_peer
+{
+ my ($directory, $fname, $out_file) = @_;
+ print "$directory/$fname\n";
+ open INPUT, "$directory/$fname" or warn "can't open $directory/$fname: $!";
+ open OUTPUT, ">>$out_file" or die "can't open $out_file: $!";
+ print OUTPUT "$fname\n";
+# we toss out all distances greater than one second on the assumption the
+# peer is in initial acquisition
+ my ($n, $MAXDISTANCE) = (0, 1.0);
+ my %peer_time;
+ my %peer_time_rms;
+ my %peer_count;
+ my %peer_delay;
+ my %peer_disp;
+ my %peer_dist;
+ my %peer_ident;
+ my %peer_tmin;
+ my %peer_tmax;
+ my @Fld;
+ my ($i, $j);
+ my ($dist, $offs);
+ while (<INPUT>) {
+ chop; # strip record separator
+ @Fld = split;
+ next if ($#Fld < 6);
+#NTPv3: 50529 83316.249 127.127.8.1 9674 0.008628 0.00000 0.00700
+#NTPv3: day, sec.msec, addr, status, offset, delay, dispersion
+#NTPv4: 51333 56042.037 127.127.8.1 94f5 -0.000014657 0.000000000 0.000000000 0.000013214
+#NTPv4: day, sec.msec, addr, status, offset, delay, dispersion, skew
+
+ $dist = $Fld[6] + $Fld[5] / 2;
+ next if ($dist > $MAXDISTANCE);
+ $offs = $Fld[4];
+ if ($offs > $skip_time_steps || $offs < -$skip_time_steps) {
+ warn "ignoring peer offset $offs (file $fname, line $.)\n";
+ next
+ }
+ $i = $n;
+ for ($j = 0; $j < $n; $j++) {
+ if ($Fld[2] eq $peer_ident{$j}) {
+ $i = $j; # peer found
+ last;
+ }
+ }
+ if ($i == $n) { # add new peer
+ $peer_ident{$i} = $Fld[2];
+ $peer_tmax{$i} = $peer_dist{$i} = -1e9;
+ $peer_tmin{$i} = 1e9;
+ $peer_time{$i} = $peer_time_rms{$i} = 0;
+ $peer_delay{$i} = $peer_disp{$i} = 0;
+ $peer_count{$i} = 0;
+ $n++;
+ }
+ $peer_count{$i}++;
+ $peer_tmax{$i} = max($peer_tmax{$i}, $offs);
+ $peer_tmin{$i} = min($peer_tmin{$i}, $offs);
+ $peer_dist{$i} = max($peer_dist{$i}, $dist);
+ $peer_time{$i} += $offs;
+ $peer_time_rms{$i} += $offs * $offs;
+ $peer_delay{$i} += $Fld[5];
+ $peer_disp{$i} += $Fld[6];
+ }
+ close INPUT;
+ print OUTPUT
+" ident cnt mean rms max delay dist disp\n";
+ print OUTPUT
+"==========================================================================\n";
+ my @lines = ();
+ for ($i = 0; $i < $n; $i++) {
+ next if $peer_count{$i} < 2;
+ $peer_time{$i} /= $peer_count{$i};
+ eval { $peer_time_rms{$i} = sqrt($peer_time_rms{$i} / $peer_count{$i} -
+ $peer_time{$i} * $peer_time{$i}); };
+ $peer_time_rms{$i} = 0, warn $@ if $@;
+ $peer_delay{$i} /= $peer_count{$i};
+ $peer_disp{$i} /= $peer_count{$i};
+ $peer_tmax{$i} = $peer_tmax{$i} - $peer_time{$i};
+ $peer_tmin{$i} = $peer_time{$i} - $peer_tmin{$i};
+ if ($peer_tmin{$i} > $peer_tmax{$i}) { # can this happen at all?
+ $peer_tmax{$i} = $peer_tmin{$i};
+ }
+ push @lines, sprintf
+ "%-15s %4d %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f\n",
+ $peer_ident{$i}, $peer_count{$i}, $peer_time{$i} * 1e3,
+ $peer_time_rms{$i} * 1e3, $peer_tmax{$i} * 1e3,
+ $peer_delay{$i} * 1e3, $peer_dist{$i} * 1e3, $peer_disp{$i} * 1e3;
+ }
+ print OUTPUT sort @lines;
+ close OUTPUT;
+}
+
+sub do_clock
+{
+ my ($directory, $fname, $out_file) = @_;
+ print "$directory/$fname\n";
+ open INPUT, "$directory/$fname";
+ open OUTPUT, ">>$out_file" or die "can't open $out_file: $!";
+ print OUTPUT "$fname\n";
+ close INPUT;
+ close OUTPUT;
+}
+
+sub peer_summary
+{
+ my $in_file = shift;
+ my ($i, $j, $n);
+ my (%peer_ident, %peer_count, %peer_mean, %peer_var, %peer_max);
+ my (%peer_1, %peer_2, %peer_3, %peer_4);
+ my $dist;
+ my $max;
+ open INPUT, "<$in_file" or die "can't open $in_file: $!";
+ my @Fld;
+ $n = 0;
+ while (<INPUT>) {
+ chop; # strip record separator
+ @Fld = split;
+ next if ($#Fld < 7 || $Fld[0] eq 'ident');
+ $i = $n;
+ for ($j = 0; $j < $n; $j++) {
+ if ($Fld[0] eq $peer_ident{$j}) {
+ $i = $j;
+ last; # peer found
+ }
+ }
+ if ($i == $n) { # add new peer
+ $peer_count{$i} = $peer_mean{$i} = $peer_var{$i} = 0;
+ $peer_max{$i} = 0;
+ $peer_1{$i} = $peer_2{$i} = $peer_3{$i} = $peer_4{$i} = 0;
+ $peer_ident{$i} = $Fld[0];
+ ++$n;
+ }
+ $dist = $Fld[6] - $Fld[5] / 2;
+ if ($dist < $peer_dist_limit) {
+ $peer_count{$i}++;
+ $peer_mean{$i} += $Fld[2];
+ $peer_var{$i} += $Fld[3] * $Fld[3];
+ $max = $Fld[4];
+ $peer_max{$i} = max($peer_max{$i}, $max);
+ if ($max > 1) {
+ $peer_1{$i}++;
+ if ($max > 5) {
+ $peer_2{$i}++;
+ if ($max > 10) {
+ $peer_3{$i}++;
+ if ($max > 50) {
+ $peer_4{$i}++;
+ }
+ }
+ }
+ }
+ }
+ else {
+ warn "dist exceeds limit: $dist (file $in_file, line $.)\n";
+ }
+ }
+ close INPUT;
+ my @lines = ();
+ print
+ " host days mean rms max >1 >5 >10 >50\n";
+ print
+ "==================================================================\n";
+ for ($i = 0; $i < $n; $i++) {
+ next if ($peer_count{$i} < 2);
+ $peer_mean{$i} /= $peer_count{$i};
+ eval { $peer_var{$i} = sqrt($peer_var{$i} / $peer_count{$i} -
+ $peer_mean{$i} * $peer_mean{$i}); };
+ $peer_var{$i} = 0, warn $@ if $@;
+ push @lines, sprintf
+ "%-15s %3d %9.3f% 9.3f %9.3f %3d %3d %3d %3d\n",
+ $peer_ident{$i}, $peer_count{$i}, $peer_mean{$i}, $peer_var{$i},
+ $peer_max{$i}, $peer_1{$i}, $peer_2{$i}, $peer_3{$i}, $peer_4{$i};
+ }
+ print sort @lines;
+}
+
+my $loop_summary="$outputdir/loop_summary";
+my $peer_summary="$outputdir/peer_summary";
+my $clock_summary="$outputdir/clock_summary";
+my (@loopfiles, @peerfiles, @clockfiles);
+
+print STDERR "Creating summaries from $statsdir ($startdate to $enddate)\n";
+
+opendir SDIR, $statsdir or die "directory ${statsdir}: $!";
+rewinddir SDIR;
+@loopfiles=sort grep /loop.*$log_date_pattern/, readdir SDIR;
+rewinddir SDIR;
+@peerfiles=sort grep /peer.*$log_date_pattern/, readdir SDIR;
+rewinddir SDIR;
+@clockfiles=sort grep /clock.*$log_date_pattern/, readdir SDIR;
+closedir SDIR;
+
+# remove old summary files
+map { unlink $_ if -f $_ } ($loop_summary, $peer_summary, $clock_summary);
+
+my $date;
+map {
+ $date = $_; $date =~ s/.*($log_date_pattern)$/$1/;
+ if ($date ge $startdate && $date le $enddate) {
+ do_loop $statsdir, $_, $loop_summary;
+ }
+} @loopfiles;
+
+map {
+ $date = $_; $date =~ s/.*($log_date_pattern)$/$1/;
+ if ($date ge $startdate && $date le $enddate) {
+ do_peer $statsdir, $_, $peer_summary;
+ }
+} @peerfiles;
+
+map {
+ $date = $_; $date =~ s/.*($log_date_pattern)$/$1/;
+ if ($date ge $startdate && $date le $enddate) {
+ do_clock $statsdir, $_, $clock_summary;
+ }
+} @clockfiles;
+
+print STDERR "Creating peer summary with limit $peer_dist_limit\n";
+peer_summary $peer_summary if (-f $peer_summary);