[Git][NTPsec/ntpsec][master] 3 commits: Implement C ntpq's odd hostname-truncation rules in pyntpq.
Eric S. Raymond
gitlab at mg.gitlab.com
Wed Oct 26 05:04:12 UTC 2016
Eric S. Raymond pushed to branch master at NTPsec / ntpsec
Commits:
44aae17d by Eric S. Raymond at 2016-10-26T01:01:23-04:00
Implement C ntpq's odd hostname-truncation rules in pyntpq.
- - - - -
ee50d579 by Eric S. Raymond at 2016-10-26T01:01:23-04:00
Method for shipping configuration in Python - untested.
- - - - -
7ec55328 by Eric S. Raymond at 2016-10-26T01:02:46-04:00
Incomplete implementation of cooked output.
- - - - -
2 changed files:
- ntpq/pyntpq
- pylib/packet.py
Changes:
=====================================
ntpq/pyntpq
=====================================
--- a/ntpq/pyntpq
+++ b/ntpq/pyntpq
@@ -128,58 +128,6 @@ NTP_LFP = 0x7 # NTP timestamp
NTP_MODE = 0x8 # peer mode
NTP_2BIT = 0x9 # leap bits
-# Format values
-PADDING = 0
-HA = 1 # host address
-NA = 2 # network address
-LP = 3 # leap (print in binary)
-RF = 4 # refid (sometimes string, sometimes not)
-AR = 5 # array of times
-FX = 6 # test flags
-TS = 7 # l_fp timestamp in hex
-OC = 8 # integer, print in octal
-EOV = 255 # end of table
-
-# For the most part ntpq simply displays what ntpd provides in the
-# mostly plain-text mode 6 responses. A few variable names are by
-# default "cooked" to provide more human-friendly output. This is
-# a dictionary of cooked variables.
-cookedvars = {
- "leap": LP,
- "reach": OC,
- "refid": RF,
- "reftime": TS,
- "clock": TS,
- "org": TS,
- "rec": TS,
- "xmt": TS,
- "flash": FX,
- "srcadr": HA,
- "peeradr": HA, # compat with others
- "dstadr": NA,
- "filtdelay": AR,
- "filtoffset": AR,
- "filtdisp": AR,
- "filterror": AR, # compat with others
-}
-
-# flasher bits
-tstflagnames = (
- "pkt_dup", # BOGON1
- "pkt_bogus", # BOGON2
- "pkt_unsync", # BOGON3
- "pkt_denied", # BOGON4
- "pkt_auth", # BOGON5
- "pkt_stratum", # BOGON6
- "pkt_header", # BOGON7
- "pkt_autokey", # BOGON8
- "pkt_crypto", # BOGON9
- "peer_stratum", # BOGON10
- "peer_dist", # BOGON11
- "peer_loop", # BOGON12
- "peer_unreach" # BOGON13
-)
-
class Ntpq(cmd.Cmd):
"ntpq command interpreter"
@@ -226,6 +174,15 @@ usage: help [ command ]
__peerheader = " remote refid " + __common + "jitter\n"
__apeerheader = " remote refid assid " + __common + "jitter\n"
+ @staticmethod
+ def high_truncate(hostname, maxlen):
+ "Truncate on the left using leading _ to indicate 'more'."
+ # Used for local IPv6 addresses, best distinguashed by low bits
+ if len(hostname) <= maxlen:
+ return hostname
+ else:
+ return '-' + hostname[-maxlen+1:]
+
def __dogetassoc(self):
try:
self.peers = self.session.readstat()
@@ -436,7 +393,7 @@ usage: help [ command ]
c = " .+*"[CTL_PEER_STATVAL(self.session.rstatus) & 0x3]
if len(self.chosts) > 1:
maxhostlen = max([len(host) for (host, _af) in self.chosts])
- self.say("%-*s " % (maxhostlen, self.session.hostname))
+ self.say(Ntpq.high_truncate(self.session.hostname, maxhostlen)+ " ")
def is_ipv6(addr): return ":" in addr and "." not in addr
if socket.AF_UNSPEC == af or af == (socket.AF_INET6 if is_ipv6(srcaddr) else socket.AF_INET):
# Source host or clockname
@@ -507,7 +464,7 @@ usage: help [ command ]
if len(self.chosts) > 1:
maxhostlen = max([len(host) for (host, _af) in self.chosts])
self.say("%-*.*s " % \
- (maxhostlen, maxhostlen, "server"))
+ (maxhostlen, maxhostlen+1, "server"))
self.say(header)
self.say(("=" * (maxhostlen + 78)) + "\n")
for peer in self.peers:
@@ -562,7 +519,7 @@ usage: help [ command ]
return ()
return (lo, hi)
- def __printvars(self, variables, type, quiet):
+ def __printvars(self, variables, dtype, quiet):
if self.rawmode:
if not quiet:
self.say("status=0x%04x,\n" % self.session.rstatus)
@@ -570,10 +527,67 @@ usage: help [ command ]
# high-half characters. We won't do that unless somebody
# files a bug, Mode 6 never seems to generate those in
# variable fetches.
- raw = session.response.replace(",\r\n",",\n")
- self.say(raw)
+ text = session.response.replace(",\r\n",",\n")
else:
- pass
+ if not quiet:
+ self.say("status=%04x %s,\n" % \
+ (self.session.rstatus,
+ statustoa(dtype, self.session.rstatus)))
+
+ out_chars = 0
+ text = ""
+ print(variables)
+ for (name, value) in variables.items():
+ item = "%s=" % name
+ if name in ("reftime", "clock", "org", "rec", "xmt"):
+ item += prettydate(value)
+ elif name in ("srcadr", "peeradr", "dstadr", "refid"):
+ # C ntpq cooked these in obscure ways. Since they
+ # came up from the daemon as human-readable
+ # strings this was probably a bad idea, but we'll
+ # leave this case separated in case somebody thinks
+ # re-cooking them is a good idea.
+ item += value
+ elif name == "leap":
+ item += ("00", "01", "10", "11")[value]
+ elif name == "reach":
+ item += "%03lo" % value
+ elif name in("filtdelay", "filtoffset", "filtdisp", "filterror"):
+ item += "\t".join(value.split())
+ elif name == "flash":
+ item += "%02x" % value
+ if value == 0:
+ item += " ok"
+ else:
+ # flasher bits
+ tstflagnames = (
+ "pkt_dup", # BOGON1
+ "pkt_bogus", # BOGON2
+ "pkt_unsync", # BOGON3
+ "pkt_denied", # BOGON4
+ "pkt_auth", # BOGON5
+ "pkt_stratum", # BOGON6
+ "pkt_header", # BOGON7
+ "pkt_autokey", # BOGON8
+ "pkt_crypto", # BOGON9
+ "peer_stratum", # BOGON10
+ "peer_dist", # BOGON11
+ "peer_loop", # BOGON12
+ "peer_unreach" # BOGON13
+ )
+ for (i, n) in enumerate(tstflagnames):
+ if (1 << i) & value:
+ item += tstflagnames + " "
+ item = item[:-1]
+ else:
+ item += repr(value)
+ item += ","
+ if len(text + item) > 78:
+ text += "\n"
+ else:
+ text += " "
+ text = text[:-2] + "\n"
+ self.say(text)
def __dolist(self, varlist, associd, op, type):
"List variables associated with a specified peer."
@@ -583,7 +597,6 @@ usage: help [ command ]
quiet = False;
else:
quiet = not (not varlist) # nonempty?
-
try:
variables = self.session.readvar(associd, varlist, op)
except Mode6Exception as e:
@@ -653,7 +666,7 @@ usage: timeout [ msec ]
elif fmt == NTP_LFP:
self.say("%s %s\n" % (legend, prettydate(value)))
elif fmt in (NTP_2BIT, NTP_MODE):
- self.say("%s %s\n" % (legend, bin(value)[2:]))
+ self.say("%s %s\n" % (legend, ("00", "01", "10", "11")[value]))
else:
self.warn("unexpected vc type %s for %s, value %s\n" % (fmt, name, value))
=====================================
pylib/packet.py
=====================================
--- a/pylib/packet.py
+++ b/pylib/packet.py
@@ -636,4 +636,10 @@ class Mode6Session:
# string-valued variables.
items.append((pair, ""))
return collections.OrderedDict(items)
+
+ def config(self, configtext):
+ "Send configuration text to the daemon."
+ self.doquery(opcode=CTL_OP_CONFIGURE, qdata=configtext, auth=True)
+ return self.response
+
# end
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/6d22f121a9bb635e209e27c13de1eca094b8549f...7ec553280d604ed4fa7564cdf10894239e549af9
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ntpsec.org/pipermail/vc/attachments/20161026/8e62c07a/attachment.html>
More information about the vc
mailing list