Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Switch to GitLab Next
Sign in / Register
Toggle navigation
Menu
Open sidebar
NTPsec
ntpsec
Commits
663353b3
Commit
663353b3
authored
Sep 11, 2020
by
James Browning
Browse files
Codacy: Add unclean fixes.
parent
96178b76
Pipeline
#189556141
failed with stages
in 6 minutes and 3 seconds
Changes
13
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
ntpclients/ntploggps.py
View file @
663353b3
...
...
@@ -46,9 +46,11 @@ except ImportError as e:
class
logfile_header_class
(
logging
.
handlers
.
TimedRotatingFileHandler
):
'A class to modify the file logging handler.'
"""A class to modify the file logging handler."""
def
doRollover
(
self
):
'function to a
dd header to new file on rotation.
'
"""A
dd header to new file on rotation.
"""
if
str
is
bytes
:
super
(
logfile_header_class
,
self
).
doRollover
()
else
:
...
...
@@ -57,7 +59,7 @@ class logfile_header_class(logging.handlers.TimedRotatingFileHandler):
def
logging_setup
():
"Create logging object"
""
"Create logging object
.""
"
logFormat
=
logging
.
Formatter
(
'%(message)s'
)
# Create logger for gpsd
Logger
=
logging
.
getLogger
()
...
...
@@ -170,7 +172,7 @@ class GpsPoller(threading.Thread):
@
property
def
time
(
self
):
"Return the gpsd time fix"
""
"Return the gpsd time fix
.""
"
t
=
self
.
gpsd
.
fix
.
time
if
isinstance
(
t
,
int
):
return
t
...
...
ntpclients/ntplogtemp.py
View file @
663353b3
...
...
@@ -33,9 +33,10 @@ import time
class
logfile_header_class
(
logging
.
handlers
.
TimedRotatingFileHandler
):
'A class to modify the file logging handler.'
"""A class to modify the file logging handler."""
def
doRollover
(
self
):
'function to a
dd header to new file on rotation.
'
"""A
dd header to new file on rotation.
"""
if
str
is
bytes
:
super
(
logfile_header_class
,
self
).
doRollover
()
else
:
...
...
@@ -44,11 +45,7 @@ class logfile_header_class(logging.handlers.TimedRotatingFileHandler):
def
run_binary
(
cmd
):
"""
\
Run a binary
Return output if good, None if bad
"""
"""Run a binary Return output if good, None if bad."""
try
:
# sadly subprocess.check_output() is not in Python 2.6
# so use Popen()
...
...
@@ -72,7 +69,8 @@ Return output if good, None if bad
class
CpuTemp
:
"Sensors on the CPU Core"
"""Sensors on the CPU Core."""
has_sensors
=
False
def
__init__
(
self
):
...
...
@@ -85,7 +83,7 @@ class CpuTemp:
self
.
_pattern
=
re
.
compile
(
'^\s+temp\d+_input:\s+([\d\.]+).*$'
)
def
get_data
(
self
):
"Collects the data and return the output as an array"
""
"Collects the data and return the output as an array
.""
"
if
not
self
.
has_sensors
:
return
None
...
...
@@ -113,7 +111,8 @@ class CpuTemp:
class
SmartCtl
:
"Sensor on the Hard Drive"
"""Sensor on the Hard Drive."""
_drives
=
[]
has_smartctl
=
False
...
...
@@ -129,7 +128,7 @@ class SmartCtl:
self
.
_drives
=
sorted
(
self
.
_drives
)
def
get_data
(
self
):
"Collects the data and return the output as an array"
""
"Collects the data and return the output as an array
.""
"
if
not
self
.
has_smartctl
:
return
None
...
...
@@ -150,13 +149,13 @@ class SmartCtl:
class
Temper
:
"""
\
Reads 'temper-poll -c' for room temperature data.
"""
Reads 'temper-poll -c' for room temperature data.
Before you can use this class you must have a TEMPer USB thermometer
plugged in, and the temper-python package must be installed and
configured.
See their documentation for that procedure.
"""
plugged in, and the temper-python package must be installed and
configured.
See their documentation for that procedure.
"""
has_temper
=
False
def
__init__
(
self
):
...
...
@@ -166,7 +165,7 @@ class Temper:
self
.
has_temper
=
True
def
get_data
(
self
):
"Collects the data and return the output as an array"
""
"Collects the data and return the output as an array
.""
"
if
not
self
.
has_temper
:
return
None
...
...
@@ -194,8 +193,8 @@ class Temper:
class
ZoneTemp
:
"Zone sensors"
"""Zone sensors."""
def
__init__
(
self
):
base_dir
=
'/sys/class/thermal/thermal_zone?/'
self
.
zones
=
[]
...
...
@@ -203,7 +202,7 @@ class ZoneTemp:
self
.
zones
.
append
(
child
)
def
get_data
(
self
):
"Collects the data and return the output as an array"
""
"Collects the data and return the output as an array
.""
"
_zone
=
0
_data
=
[]
for
zone
in
self
.
zones
:
...
...
@@ -249,7 +248,7 @@ args = parser.parse_args()
def
logging_setup
():
"Create logging object"
""
"Create logging object
.""
"
logFormat
=
logging
.
Formatter
(
'%(message)s'
)
# Create logger for cpuTemp
tempLogger
=
logging
.
getLogger
()
...
...
@@ -275,14 +274,14 @@ def logging_setup():
def
logData
(
log
,
data
):
"
l
og the data"
"
""L
og the data
.""
"
if
data
is
not
None
:
for
_item
in
data
:
log
.
info
(
_item
)
def
log_data
():
"Write all temperature readings to one file"
""
"Write all temperature readings to one file
.""
"
# Create objects
cpu
=
CpuTemp
()
zone
=
ZoneTemp
()
...
...
ntpclients/ntpq.py
View file @
663353b3
This diff is collapsed.
Click to expand it.
ntpclients/ntpviz.py
View file @
663353b3
...
...
@@ -69,7 +69,7 @@ if sys.version_info[0] == 2:
sys
.
setdefaultencoding
(
'utf8'
)
def
open
(
file
,
mode
=
'r'
,
buffering
=-
1
,
encoding
=
None
,
errors
=
None
):
"Redefine open()"
""
"Redefine open()"
""
return
(
codecs
.
open
(
filename
=
file
,
mode
=
mode
,
encoding
=
encoding
,
errors
=
errors
,
buffering
=
buffering
))
...
...
@@ -103,8 +103,8 @@ refclock_name = {'127.127.20.0': 'NMEA(0)',
# Gack, python before 3.2 has no defined tzinfo for utc...
# define our own
class
UTC
(
datetime
.
tzinfo
):
"""UTC"""
"""UTC."""
def
utcoffset
(
self
,
dt
):
return
datetime
.
timedelta
(
0
)
...
...
@@ -132,10 +132,10 @@ if (3 > sys.version_info[0]) and (7 > sys.version_info[1]):
# overload ArgumentParser
class
MyArgumentParser
(
argparse
.
ArgumentParser
):
"class to parse arguments"
"""class to parse arguments."""
def
convert_arg_line_to_args
(
self
,
arg_line
):
'''
Make options file more tolerant
'''
"""
Make options file more tolerant
."""
# strip out trailing comments
arg_line
=
re
.
sub
(
'\s+#.*$'
,
''
,
arg_line
)
...
...
@@ -150,7 +150,7 @@ class MyArgumentParser(argparse.ArgumentParser):
def
print_profile
():
"""called by atexit() on normal exit to print profile data"""
"""called by atexit() on normal exit to print profile data
.
"""
pr
.
disable
()
pr
.
print_stats
(
'tottime'
)
pr
.
print_stats
(
'cumtime'
)
...
...
@@ -164,8 +164,8 @@ def print_profile():
# Mean, Variance, Standard Deviation, Skewness and Kurtosis
class
RunningStats
(
object
):
"Calculate mean, variance, sigma, skewness and kurtosis"
"""Calculate mean, variance, sigma, skewness and kurtosis."""
def
__init__
(
self
,
values
):
self
.
num
=
len
(
values
)
# number of samples
self
.
mu
=
0.0
# simple arithmetic mean
...
...
@@ -202,8 +202,8 @@ class RunningStats(object):
# class for calced values
class
VizStats
(
ntp
.
statfiles
.
NTPStats
):
"Class for calculated values"
"""Class for calculated values."""
percs
=
{}
# dictionary of percentages
title
=
''
# title
unit
=
's'
# display units: s, ppm, etc.
...
...
@@ -373,7 +373,7 @@ class VizStats(ntp.statfiles.NTPStats):
def
gnuplot_fmt
(
min_val
,
max_val
):
"return optimal gnuplot format"
""
"return optimal gnuplot format
.""
"
span
=
max_val
-
min_val
if
6
<=
span
:
fmt
=
'%.0f'
...
...
@@ -392,7 +392,7 @@ def gnuplot_fmt(min_val, max_val):
# Investigate.
def
gnuplot
(
template
,
outfile
=
None
):
"Run a specified gnuplot program."
""
"Run a specified gnuplot program."
""
if
not
template
:
# silently ignore empty plots
...
...
@@ -444,8 +444,8 @@ def gnuplot(template, outfile=None):
class
NTPViz
(
ntp
.
statfiles
.
NTPStats
):
"Class for visualizing statistics from a single server."
"""Class for visualizing statistics from a single server."""
# Python takes single quotes here. Since no % substitution
Common
=
"""
\
set grid
...
...
@@ -468,7 +468,7 @@ set rmargin 10
endtime
=
endtime
)
def
plot_slice
(
self
,
rows
,
item1
,
item2
=
None
):
"slice 0,item1, maybe item2, from rows, ready for gnuplot"
""
"slice 0,item1, maybe item2, from rows, ready for gnuplot
.""
"
# speed up by only sending gnuplot the data it will actually use
# WARNING: this is hot code, only modify if you profile
# since we are looping the data, get the values too
...
...
@@ -515,7 +515,7 @@ set rmargin 10
return
(
plot_data
,
values1
)
def
local_offset_gnuplot
(
self
):
"Generate gnuplot code graphing local clock loop statistics"
""
"Generate gnuplot code graphing local clock loop statistics
.""
"
if
not
self
.
loopstats
:
sys
.
stderr
.
write
(
"ntpviz: WARNING: no loopstats to graph
\n
"
)
return
''
...
...
@@ -578,7 +578,7 @@ file.</p>
return
ret
def
local_freq_temps_plot
(
self
):
"Generate gnuplot code graphing local frequency and temps"
""
"Generate gnuplot code graphing local frequency and temps
.""
"
if
not
self
.
loopstats
:
sys
.
stderr
.
write
(
"ntpviz: WARNING: no loopstats to graph
\n
"
)
return
''
...
...
@@ -671,7 +671,7 @@ file, and field 3 from the tempstats log file.</p>
return
ret
def
local_temps_gnuplot
(
self
):
"Generate gnuplot code graphing local temperature statistics"
""
"Generate gnuplot code graphing local temperature statistics
.""
"
sitename
=
self
.
sitename
tempsmap
=
self
.
tempssplit
()
tempslist
=
list
(
tempsmap
.
keys
())
...
...
@@ -733,7 +733,7 @@ component of frequency drift.</p>
return
ret
def
local_gps_gnuplot
(
self
):
"Generate gnuplot code graphing local GPS statistics"
""
"Generate gnuplot code graphing local GPS statistics
.""
"
sitename
=
self
.
sitename
gpsmap
=
self
.
gpssplit
()
gpslist
=
list
(
gpsmap
.
keys
())
...
...
@@ -816,7 +816,7 @@ impossible.</p>
return
ret
def
local_error_gnuplot
(
self
):
"Plot the local clock frequency error."
""
"Plot the local clock frequency error."
""
if
not
self
.
loopstats
:
sys
.
stderr
.
write
(
"ntpviz: WARNING: no loopstats to graph
\n
"
)
return
''
...
...
@@ -875,7 +875,7 @@ line at 0ppm. Expected values of 99%-1% percentiles: 0.4ppm</p>
return
ret
def
loopstats_gnuplot
(
self
,
fld
,
title
,
legend
,
freq
):
"Generate gnuplot code of a given loopstats field"
""
"Generate gnuplot code of a given loopstats field
.""
"
if
not
self
.
loopstats
:
sys
.
stderr
.
write
(
"ntpviz: WARNING: no loopstats to graph
\n
"
)
return
''
...
...
@@ -943,16 +943,16 @@ plot \
return
ret
def
local_offset_jitter_gnuplot
(
self
):
"Generate gnuplot code of local clock loop standard deviation"
""
"Generate gnuplot code of local clock loop standard deviation
.""
"
return
self
.
loopstats_gnuplot
(
4
,
"Local RMS Time Jitter"
,
"Jitter"
,
0
)
def
local_offset_stability_gnuplot
(
self
):
"Generate gnuplot code graphing local clock stability"
""
"Generate gnuplot code graphing local clock stability
.""
"
return
self
.
loopstats_gnuplot
(
5
,
"Local RMS Frequency Jitter"
,
"Stability"
,
1
)
def
peerstats_gnuplot
(
self
,
peerlist
,
fld
,
title
,
ptype
):
"Plot a specified field from peerstats."
""
"Plot a specified field from peerstats."
""
peerdict
=
self
.
peersplit
()
if
not
peerlist
:
...
...
@@ -1167,17 +1167,17 @@ plot \
return
ret
def
peer_offsets_gnuplot
(
self
,
peerlist
=
None
):
"gnuplot Peer Offsets"
""
"gnuplot Peer Offsets
.""
"
return
self
.
peerstats_gnuplot
(
peerlist
,
4
,
"Server Offset"
,
"offset"
)
def
peer_jitters_gnuplot
(
self
,
peerlist
=
None
):
"gnuplot Peer Jitters"
""
"gnuplot Peer Jitters
.""
"
return
self
.
peerstats_gnuplot
(
peerlist
,
7
,
"Server Jitter"
,
"jitter"
)
def
local_offset_histogram_gnuplot
(
self
):
"Plot a histogram of clock offset values from loopstats."
""
"Plot a histogram of clock offset values from loopstats."
""
if
not
self
.
loopstats
:
sys
.
stderr
.
write
(
"ntpviz: WARNING: no loopstats to graph
\n
"
)
return
''
...
...
@@ -1286,7 +1286,7 @@ plot \
def
local_offset_multiplot
(
statlist
):
"Plot comparative local offsets for a list of NTPViz objects."
""
"Plot comparative local offsets for a list of NTPViz objects."
""
out
=
{}
out
[
'size'
]
=
args
.
img_size
...
...
pylib/agentx.py
View file @
663353b3
...
...
@@ -106,15 +106,15 @@ class MIBControl:
# These exist instead of just using getOID_core so semantics are clearer
def
getOID
(
self
,
searchoid
,
returnGenerator
=
False
):
"Get the requested OID"
""
"Get the requested OID
.""
"
return
self
.
getOID_core
(
False
,
searchoid
,
returnGenerator
)
def
getNextOID
(
self
,
searchoid
,
returnGenerator
=
False
):
"Get the next lexicographical OID"
""
"Get the next lexicographical OID
.""
"
return
self
.
getOID_core
(
True
,
searchoid
,
returnGenerator
)
def
getOIDsInRange
(
self
,
oidrange
,
firstOnly
=
False
):
"Get a list of every (optionally the first) OID in a range"
""
"Get a list of every (optionally the first) OID in a range
.""
"
oids
=
[]
gen
=
walkMIBTree
(
self
.
oidTree
,
self
.
mibRoot
)
# Find the first OID
...
...
@@ -246,7 +246,8 @@ class PacketControl:
self
.
stillConnected
=
True
def
waitForResponse
(
self
,
opkt
,
ignoreSID
=
False
):
"Wait for a response to a specific packet, dropping everything else"
"""Wait for a response to a specific packet, dropping everything
else."""
while
True
:
self
.
packetEater
()
while
self
.
receivedPackets
:
...
...
@@ -263,7 +264,7 @@ class PacketControl:
time
.
sleep
(
self
.
spinGap
)
def
checkResponses
(
self
):
"Check for expected responses that have timed out"
""
"Check for expected responses that have timed out
.""
"
currentTime
=
time
.
time
()
for
key
in
list
(
self
.
packetLog
.
keys
()):
expiration
,
originalPkt
,
callback
=
self
.
packetLog
[
key
]
...
...
@@ -273,7 +274,8 @@ class PacketControl:
del
self
.
packetLog
[
key
]
def
packetEater
(
self
):
"Slurps data from the input buffer and tries to parse packets from it"
"""Slurps data from the input buffer and tries to parse packets from
it."""
self
.
pollSocket
()
while
True
:
datalen
=
len
(
self
.
receivedData
)
...
...
@@ -345,7 +347,7 @@ class PacketControl:
self
.
sendPacket
(
err
,
False
)
def
pollSocket
(
self
):
"Reads all currently available data from the socket, non-blocking"
""
"Reads all currently available data from the socket, non-blocking
.""
"
data
=
b
""
while
True
:
tmp
=
select
.
select
([
self
.
socket
],
[],
[],
0
)[
0
]
...
...
pylib/agentx_packet.py
View file @
663353b3
...
...
@@ -86,7 +86,8 @@ class AgentXPDU:
self
.
_hascontext
=
hascontext
def
packetVars
(
self
):
"Assembles a list of class variables that it is desirable to print"
"""Assembles a list of class variables that it is desirable to
print."""
pktvars
=
{}
names
=
dir
(
self
)
names
.
remove
(
"context"
)
...
...
@@ -730,7 +731,8 @@ class ResponsePDU(AgentXPDU):
def
classifyOID
(
oid
):
"Utility function to allow the user to send a bare tuple for some cases"
"""Utility function to allow the user to send a bare tuple for some
cases."""
if
isinstance
(
oid
,
OID
):
return
oid
return
OID
(
oid
,
False
)
...
...
pylib/packet.py
View file @
663353b3
...
...
@@ -262,7 +262,8 @@ MAX_BARE_MAC_LENGTH = 20
class
Packet
:
"Encapsulate an NTP fragment"
"""Encapsulate an NTP fragment."""
# The following two methods are copied from macros in includes/control.h
@
staticmethod
def
VN_MODE
(
v
,
m
):
...
...
@@ -311,7 +312,8 @@ class SyncException(BaseException): # pragma: no cover
class
SyncPacket
(
Packet
):
"Mode 1-5 time-synchronization packet, including SNTP."
"""Mode 1-5 time-synchronization packet, including SNTP."""
format
=
"!BBBbIIIQQQQ"
HEADER_LEN
=
48
UNIX_EPOCH
=
2208988800
# Midnight 1 Jan 1970 in secs since NTP epoch
...
...
@@ -384,19 +386,19 @@ class SyncPacket(Packet):
@
staticmethod
def
ntp_to_posix
(
t
):
"Scale from NTP time to POSIX time"
""
"Scale from NTP time to POSIX time
.""
"
# Note: assumes we're in the same NTP era as the transmitter...
return
(
t
/
(
2
**
32
))
-
SyncPacket
.
UNIX_EPOCH
@
staticmethod
def
posix_to_ntp
(
t
):
"Scale from POSIX time to NTP time"
""
"Scale from POSIX time to NTP time
.""
"
# Note: assumes we're in the same NTP era as the transmitter...
# This receives floats, can't use shifts
return
int
((
t
+
SyncPacket
.
UNIX_EPOCH
)
*
2
**
32
)
def
posixize
(
self
):
"Rescale all timestamps to POSIX time."
""
"Rescale all timestamps to POSIX time."
""
if
not
self
.
rescaled
:
self
.
rescaled
=
True
self
.
root_delay
>>=
16
...
...
@@ -424,16 +426,16 @@ class SyncPacket(Packet):
return
self
.
received
def
delta
(
self
):
"Packet flight time"
""
"Packet flight time
.""
"
return
(
self
.
t4
()
-
self
.
t1
())
-
(
self
.
t3
()
-
self
.
t2
())
def
epsilon
(
self
):
"Residual error due to clock imprecision."
""
"Residual error due to clock imprecision."
""
# FIXME: Include client imprecision.
return
SyncPacket
.
PHI
*
(
self
.
t4
()
-
self
.
t1
())
+
2
**
self
.
precision
def
synchd
(
self
):
"Synchronization distance, estimates worst-case error in seconds"
""
"Synchronization distance, estimates worst-case error in seconds
.""
"
# This is "lambda" in NTP-speak, but that's a Python keyword
return
abs
(
self
.
delta
()
/
2
+
self
.
epsilon
())
...
...
@@ -442,7 +444,7 @@ class SyncPacket(Packet):
return
((
self
.
t2
()
-
self
.
t1
())
+
(
self
.
t3
()
-
self
.
t4
()))
/
2
def
flatten
(
self
):
"Flatten the packet into an octet sequence."
""
"Flatten the packet into an octet sequence."
""
body
=
struct
.
pack
(
SyncPacket
.
format
,
self
.
li_vn_mode
,
self
.
stratum
,
...
...
@@ -458,18 +460,18 @@ class SyncPacket(Packet):
return
body
+
self
.
extension
def
refid_octets
(
self
):
"Analyze refid into octets."
""
"Analyze refid into octets."
""
return
((
self
.
refid
>>
24
)
&
0xff
,
(
self
.
refid
>>
16
)
&
0xff
,
(
self
.
refid
>>
8
)
&
0xff
,
self
.
refid
&
0xff
)
def
refid_as_string
(
self
):
"Sometimes it's a clock name or KOD type"
""
"Sometimes it's a clock name or KOD type
.""
"
return
ntp
.
poly
.
polystr
(
struct
.
pack
(
*
((
"BBBB"
,)
+
self
.
refid_octets
())))
def
refid_as_address
(
self
):
"Sometimes it's an IPV4 address."
""
"Sometimes it's an IPV4 address."
""
return
ntp
.
poly
.
polystr
(
"%d.%d.%d.%d"
%
self
.
refid_octets
())
def
is_crypto_nak
(
self
):
...
...
@@ -482,7 +484,7 @@ class SyncPacket(Packet):
return
len
(
self
.
mac
)
==
24
def
__repr__
(
self
):
"Represent a posixized sync packet in an eyeball-friendly format."
""
"Represent a posixized sync packet in an eyeball-friendly format."
""
r
=
"<NTP:%s:%d:%d:"
%
(
self
.
leap
(),
self
.
version
(),
self
.
mode
())
r
+=
"%f:%f"
%
(
self
.
root_delay
,
self
.
root_dispersion
)
rs
=
self
.
refid_as_string
()
...
...
@@ -506,7 +508,8 @@ class SyncPacket(Packet):
class
ControlPacket
(
Packet
):
"Mode 6 request/response."
"""Mode 6 request/response."""
def
__init__
(
self
,
session
,
opcode
=
0
,
associd
=
0
,
qdata
=
''
):
Packet
.
__init__
(
self
,
mode
=
ntp
.
magic
.
MODE_CONTROL
,
...
...
@@ -541,7 +544,7 @@ class ControlPacket(Packet):
return
self
.
count
+
self
.
offset
def
stats
(
self
):
"Return statistics on a fragment."
""
"Return statistics on a fragment."
""
return
"%5d %5d
\t
%3d octets
\n
"
%
(
self
.
offset
,
self
.
end
(),
self
.
count
)
def
analyze
(
self
,
rawdata
):
...
...
@@ -558,7 +561,7 @@ class ControlPacket(Packet):
return
(
self
.
sequence
,
self
.
status
,
self
.
associd
,
self
.
offset
)
def
flatten
(
self
):
"Flatten the packet into an octet sequence."
""
"Flatten the packet into an octet sequence."
""
body
=
struct
.
pack
(
ControlPacket
.
format
,
self
.
li_vn_mode
,
self
.
r_e_m_op
,
...
...
@@ -574,7 +577,8 @@ class ControlPacket(Packet):
class
Peer
:
"The information we have about an NTP peer."
"""The information we have about an NTP peer."""
def
__init__
(
self
,
session
,
associd
,
status
):
self
.
session
=
session
...
...
@@ -618,7 +622,7 @@ SERR_NOTRUST = "***No trusted keys have been declared"
def
dump_hex_printable
(
xdata
,
outfp
=
sys
.
stdout
):
"Dump a packet in hex, in a familiar hex format"
""
"Dump a packet in hex, in a familiar hex format
.""
"
rowsize
=
16
while
xdata
:
# Slice one row off of our data
...
...
@@ -638,7 +642,8 @@ def dump_hex_printable(xdata, outfp=sys.stdout):
class
MRUEntry
:
"A traffic entry for an MRU list."
"""A traffic entry for an MRU list."""
def
__init__
(
self
):
self
.
addr
=
None
# text of IPv4 or IPv6 address and port
...
...
@@ -678,14 +683,16 @@ class MRUEntry:
class
MRUList
:
"A sequence of address-timespan pairs returned by ntpd in one response."
"""A sequence of address-timespan pairs returned by ntpd in one
response."""
def
__init__
(
self
):
self
.
entries
=
[]
# A list of MRUEntry objects
self
.
now
=
None
# server timestamp marking end of operation
def
is_complete
(
self
):
"Is the server done shipping entries for this span?"
""
"Is the server done shipping entries for this span?"
""
return
self
.
now
is
not
None
def
__repr__
(
self
):
...
...
@@ -703,7 +710,8 @@ class ControlException(BaseException):
class
ControlSession
:
"A session to a host"
"""A session to a host."""
MRU_ROW_LIMIT
=
256
_authpass
=
True
server_errors
=
{
...
...
@@ -750,11 +758,11 @@ class ControlSession:
self
.
sock
=
None
def
havehost
(
self
):
"Is the session connected to a host?"
""
"Is the session connected to a host?"
""
return
self
.
sock
is
not
None
def
__lookuphost
(
self
,
hname
,
fam
):
"Try different ways to interpret an address and family"
""
"Try different ways to interpret an address and family
.""
"
if
hname
.
startswith
(
"["
):
hname
=
hname
[
1
:
-
1
]
# First try to resolve it as an ip address and if that fails,
...
...
@@ -838,7 +846,7 @@ class ControlSession:
return
True
def
password
(
self
):
"Get a keyid and the password if we don't have one."
""
"Get a keyid and the password if we don't have one."
""
if
self
.
keyid
is
None
:
if
self
.
auth
is
None
:
try
:
...
...
@@ -879,7 +887,7 @@ class ControlSession: