[Git][NTPsec/ntpsec][master] 3 commits: Typo

Eric S. Raymond gitlab at mg.gitlab.com
Sun Aug 14 10:59:02 UTC 2016


Eric S. Raymond pushed to branch master at NTPsec / ntpsec


Commits:
acef301d by Matt Selsky at 2016-08-13T16:58:29-04:00
Typo

- - - - -
37f9790f by Matt Selsky at 2016-08-13T16:58:29-04:00
Port ntptrace to python

- - - - -
5f537432 by Matt Selsky at 2016-08-13T16:58:29-04:00
Python scripts are also not installed

- - - - -


5 changed files:

- INSTALL
- docs/includes/ntptrace-body.txt
- ntpstats/ntpviz
- − ntptrace/ntptrace
- + ntptrace/ntptrace.py


Changes:

=====================================
INSTALL
=====================================
--- a/INSTALL
+++ b/INSTALL
@@ -183,7 +183,7 @@ Other behaviors may be added in future releases.
 == Uninstalled binaries and scripts ==
 
 Due to variations in Perl library paths, our stock source distribution
-makes no attempt to install certain Perl scripts: notably
+makes no attempt to install certain Perl/Python/shell scripts: notably
 ntpleapfetch, ntpwait, and ntptrace.  If you installed this software
 from a binary package prepared by your OS distributor, the OS
 distributor may install them, arranging a rendezvous with the


=====================================
docs/includes/ntptrace-body.txt
=====================================
--- a/docs/includes/ntptrace-body.txt
+++ b/docs/includes/ntptrace-body.txt
@@ -12,7 +12,7 @@
 
 == DESCRIPTION ==
 
-+ntptrace+ is a perl script that uses the {ntpq} utility program to follow
++ntptrace+ is a python script that uses the {ntpq} utility program to follow
 the chain of NTP servers from a given host back to the primary time
 source. For ntptrace to work properly, each of these servers must
 implement the NTP Control and Monitoring Protocol specified in RFC 1305


=====================================
ntpstats/ntpviz
=====================================
--- a/ntpstats/ntpviz
+++ b/ntpstats/ntpviz
@@ -22,7 +22,7 @@ from ntpstats import *
 # Investigate.
 
 class NTPViz(NTPStats):
-    "Class for visualizing statistics from a sincle server."
+    "Class for visualizing statistics from a single server."
     Common = """\
 set terminal png size 900,600
 set xdata time


=====================================
ntptrace/ntptrace deleted
=====================================
--- a/ntptrace/ntptrace
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/usr/bin/env perl
-# John Hay -- John.Hay at icomtek.csir.co.za / jhay at FreeBSD.org
-
-package ntptrace;
-use 5.006_000;
-use strict;
-use NTP::Util qw(ntp_read_vars do_dns);
-use Getopt::Long qw(GetOptionsFromArray);
-Getopt::Long::Configure(qw(no_auto_abbrev no_ignore_case_always));
-
-my $usage;
-
-sub usage {
-    my ($ret) = @_;
-    print STDERR $usage;
-    exit $ret;
-}
-
-sub paged_usage {
-    my ($ret) = @_;
-    my $pager = $ENV{PAGER} || '(less || more)';
-
-    open STDOUT, "| $pager" or die "Can't fork a pager: $!";
-    print $usage;
-
-    exit $ret;
-}
-
-sub processOptions {
-    my $args = shift;
-
-    my $opts = {
-        'numeric' => '',
-        'max-hosts' => '99',
-        'host' => '127.0.0.1',
-        'help' => '', 'more-help' => ''
-    };
-    my $argument = '[host]';
-    my $ret = GetOptionsFromArray($args, $opts, (
-        'numeric|n', 'max-hosts|m=i', 'host|r=s',
-        'help|?', 'more-help'));
-
-    $usage = <<'USAGE';
-ntptrace - Trace peers of an NTP server.
-USAGE: ntptrace [ -<flag> [<val>] | --<name>[{=| }<val>] ]... [host]
-
-    -n, --numeric                Print IP addresses instead of hostnames
-    -m, --max-hosts=num          Maximum number of peers to trace
-    -r, --host=str               Single remote host
-    -?, --help                   Display usage information and exit
-        --more-help              Pass the extended usage text through a pager
-
-Options are specified by doubled hyphens and their name or by a single
-hyphen and the flag character.
-USAGE
-
-    usage(0)       if $opts->{'help'};
-    paged_usage(0) if $opts->{'more-help'};
-    $_[0] = $opts;
-    return $ret;
-}
-
-exit run(@ARGV) unless caller;
-
-sub run {
-    my $opts;
-    if (!processOptions(\@_, $opts)) {
-        usage(1);
-    };
-
-    my $dodns     = $opts->{numeric} ? 0 : 1;
-    my $max_hosts = $opts->{'max-hosts'};
-    my $host      = shift || $opts->{host};
-    my $nb_host   = 0;
-
-    for (;;) {
-        $nb_host++;
-
-        my %info = get_info($host);
-        last if not %info;
-
-        my $dhost = $host;
-        if ($dodns) {
-            my $name = do_dns($host);
-            $dhost = $name if defined $name;
-        }
-
-        printf "%s: stratum %d, offset %f, synch distance %f",
-            $dhost, $info{stratum}, $info{offset}, $info{syncdistance};
-        printf ", refid '%s'", $info{refid} if $info{stratum} == 1;
-        print "\n";
-
-        last if $info{stratum} == 0 || $info{stratum} == 1 || 
-                $info{stratum} == 16;
-        last if $info{refid} =~ /^127\.127\.\d{1,3}\.\d{1,3}$/;
-        last if $nb_host == $max_hosts;
-
-        my $next_host = get_next_host($info{peer}, $host);
-        last if $next_host eq '';
-        last if $next_host  =~ /^127\.127\.\d{1,3}\.\d{1,3}$/;
-
-        $host = $next_host;
-    }
-    return 0;
-}
-
-sub get_info {
-    my ($host) = @_;
-    my ($rootdelay, $rootdisp, $info) = (0, 0);
-
-    $info = ntp_read_vars(0, [], $host);
-    return if not defined $info;
-    return if not exists $info->{stratum};
-
-    $info->{offset} /= 1000;
-    $info->{syncdistance} = ($info->{rootdisp} + ($info->{rootdelay} / 2)) / 1000;
-
-    return %$info;
-}
-
-
-sub get_next_host {
-    my ($peer, $host) = @_;
-
-    my $info = ntp_read_vars($peer, [qw(srcadr)], $host);
-    return if not defined $info;
-    return $info->{srcadr};
-}
-
-END { close STDOUT };
-
-
-1;
-__END__


=====================================
ntptrace/ntptrace.py
=====================================
--- /dev/null
+++ b/ntptrace/ntptrace.py
@@ -0,0 +1,175 @@
+#!/usr/bin/env python
+"""
+ntptrace - trace peers of an NTP server
+
+Usage: ntptrace [-n | --numeric] [-m number | --max-hosts=number]
+                [-r hostname | --host=hostname] [--help | --more-help]
+                hostname
+
+See the manual page for details.
+"""
+#SPDX-License-Identifier: BSD-2-Clause
+
+from __future__ import print_function
+
+import getopt
+import re
+import socket
+import subprocess
+import sys
+
+
+def get_info(host):
+    info = ntp_read_vars(0, [], host)
+    if info is None or not 'stratum' in info:
+        return
+
+    info['offset'] = round(float(info['offset']) / 1000, 6)
+    info['syncdistance'] = \
+        (float(info['rootdisp']) + (float(info['rootdelay']) / 2)) / 1000
+
+    return info
+
+
+def get_next_host(peer, host):
+    info = ntp_read_vars(peer, ["srcadr"], host)
+    if info is None:
+        return
+    return info['srcadr']
+
+
+def ntp_read_vars(peer, vars, host):
+    obsolete = {'phase': 'offset',
+                'rootdispersion': 'rootdisp'}
+
+    if not len(vars):
+        do_all = True
+    else:
+        do_all = False
+    outvars = {}.fromkeys(vars)
+
+    if do_all:
+        outvars['status_line'] = {}
+
+    cmd = ["ntpq", "-n", "-c", "rv %s %s" % (peer, ",".join(vars))]
+    if not host is None:
+        cmd.append(host)
+
+    try:
+        output = subprocess.check_output(cmd).decode('utf-8').splitlines()
+    except CalledProcessError:
+        print("Could not start ntpq: %s" % CalledProcessError.output, file=sys.stderr)
+        raise SystemExit(1)
+
+    for line in output:
+        if re.search(r'Connection refused', line):
+            return
+
+        match = re.search(r'^asso?c?id=0 status=(\S{4}) (\S+), (\S+),', line, flags=re.IGNORECASE)
+        if match:
+            outvars['status_line']['status'] = match.group(1)
+            outvars['status_line']['leap'] = match.group(2)
+            outvars['status_line']['sync'] = match.group(3)
+
+        iterator = re.finditer(r'(\w+)=([^,]+),?\s?', line)
+        for match in iterator:
+            key = match.group(1)
+            val = match.group(2)
+            val = re.sub(r'^"([^"]+)"$', r'\1', val)
+            if key in obsolete:
+                key = obsolete[key]
+            if do_all or key in outvars:
+                outvars[key] = val
+
+    return outvars
+
+
+def do_dns(hostname):
+    try:
+        ai = socket.getaddrinfo(hostname, None, 0, 0, 0,
+                                socket.AI_CANONNAME)
+    except socket.gaierror as e:
+        print('getaddrinfo failed: %s' % e.strerr, file=sys.stderr)
+        raise SystemExit(1)
+    (family, socktype, proto, canonname, sockaddr) = ai[0]
+    try:
+        name = socket.getnameinfo(sockaddr, socket.NI_NAMEREQD)
+    except socket.gaierror:
+        return canonname.lower()
+    return name[0].lower()
+
+
+usage = r"""ntptrace - Trace peers of an NTP server.
+USAGE: ntptrace [ -<flag> [<val>] | --<name>[{=| }<val>] ]... [host]
+
+    -n, --numeric                Print IP addresses instead of hostnames
+    -m, --max-hosts=num          Maximum number of peers to trace
+    -r, --host=str               Single remote host
+    -?, --help                   Display usage information and exit
+        --more-help              Pass the extended usage text through a pager
+
+Options are specified by doubled hyphens and their name or by a single
+hyphen and the flag character."""
+
+try:
+    (options, arguments) = getopt.getopt(
+        sys.argv[1:], "m:nr:?",
+        ["help", "host=", "max-hosts=", "more-help", "numeric"])
+except getopt.GetoptError as err:
+    sys.stderr.write(str(err) + "\n")
+    raise SystemExit(1)
+
+numeric = False
+maxhosts = 99
+host = '127.0.0.1'
+
+for (switch, val) in options:
+    if switch == "-m" or switch == "--max-hosts":
+        maxhosts = int(val)
+    elif switch == "-n" or switch == "--numeric":
+        numeric = True
+    elif switch == "-r" or switch == "--host":
+        host = val
+    elif switch == "-?" or switch == "--help" or switch == "--more-help":
+        print(usage, file=sys.stderr)
+        raise SystemExit(0)
+
+if len(arguments):
+    host = arguments[0]
+
+hostcount = 0
+
+while True:
+    hostcount += 1
+
+    info = get_info(host)
+
+    if info is None:
+        break
+
+    if not numeric:
+        host = do_dns(host)
+
+    print("%s: stratum %d, offset %f, synch distance %f" %
+          (host, int(info['stratum']), info['offset'], info['syncdistance']), end='')
+    if int(info['stratum']) == 1:
+        print(", refid '%s'" % info['refid'], end='')
+    print()
+
+    if int(info['stratum']) == 0 or int(info['stratum']) == 1 or int(info['stratum']) == 16:
+        break
+
+    if re.search(r'^127\.127\.\d{1,3}\.\d{1,3}$', info['refid']):
+        break
+
+    if hostcount == maxhosts:
+        break
+
+    next_host = get_next_host(info['peer'], host)
+
+    if next_host is None:
+        break
+    if re.search(r'^127\.127\.\d{1,3}\.\d{1,3}$', next_host):
+        break
+
+    host = next_host



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/a0e4ca0ca54f595f188a91074459db1ca0e3baf4...5f53743271c59be876242d7a4e7061ef3fa2ea0f
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ntpsec.org/pipermail/vc/attachments/20160814/25cea472/attachment.html>


More information about the vc mailing list