a \d9@sdZddlmZmZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddlZ ddlZ dZdZdZdZdZd ZdZd Zd Zd Zd ZdadZdZdZeteeegZdZ dZ!dZ"da#e e!e"t#gZ$ee$fZ%ddZ&ddZ'dZ(dZ)dZ*ddZ+dd Z,d!d"Z-d#d$Z.d%d&Z/d'd(Z0d)d*Z1d+d,Z2d-d.Z3d/d0Z4d1d2Z5d3d4Z6d5d6Z7d7d8Z8d9d:Z9d;d<Z:d=d>Z;d?d@ZdEdFZ?dGdHZ@dIdJZAdudLdMZBdvdNdOZCdPdQZDdRdSZEdTdUZFGdVdWdWZGeGZHejIfdXdYZJeKdZd[d\gZLeMeNur.ddlOZOddlPZPddlQZQd]d^ZRGd_d`d`ZSdwdbdcZTGdddedeZUGdfdgdgZVGdhdidiZWGdjdkdkZXzddllmYZYWn$eZyGdmdndne[ZYYn0dxdodpZ\dydqdrZ]dsdtZ^dS)zzCommon utility functions)print_functiondivisionN@ nsuµsmssksZpptZppbZppmu‰cCsdtjjkrtdSdS)NzUTF-8TF)sysstdoutencodingdeunicode_unitsrr./usr/lib64/python3.9/site-packages/ntp/util.py check_unicode5s rcCs0d}d}|ttt<|ttt<|a|adS)zUnder certain conditions it is not possible to force unicode output, this overwrites units that contain unicode with safe versionsusZppkN) UNITS_SECindexUNIT_US UNITS_PPXUNIT_PPK)Znew_usZnew_ppkrrrr<s r)ZtaiZpoll) rootdelayrootdispZrootdistoffsetZ sys_jitterZ clk_jitterZleapsmearoffsetZ authdelayZkoffsetZkmaxerrZkesterrZkprecisZ kppsjitterZfuzzZclk_wander_thresholdZtickinoutZbiasdelayjitter dispersionZ fudgetime1Z fudgetime2)Z frequencyZ clk_wandercCsB|dur dSttd|d}||kr>|||dS)zQdebug is the current debug value threshold is the trigger for the current logN  )rfc3339timewriteflush)logfptextdebugZ thresholdrrrdologVs  r/cCsHz ||}Wn6tyBtj||tj|tdYn0|S)zAttempts to typecast an argument, prints and dies on failure. errtext must contain a %s for splicing in the argument, and be newline terminated.r ) ValueErrorrstderrr* SystemExit)argZcastfuncZerrtextusageZcastedrrr safeargcastas   r5cCsddS)z6Returns the NTPsec version string in a standard formatz ntpsec-%sz1.2.2arrrrr stdversionnsr6cCsVtdt|}t|}d|vrJ|ddd}t|dkrJ|d|7}|d7}|S)z|d 7}||dkrtnB||dkrT|n,||tjvrrrn|||d 7}qB|S)NFr?c spd}sNz t|}Wn2tyLz t|}WntyFYn0Yn0|f}|gdd<dS)Nr?)r@r=r0floatrI)tokenwrapper)currentinQuotetokensrr pushTokens       zparseConf..pushTokencs0r r,ddgdd<dSN)rIr)rXlinesr[rZrrpushLines zparseConf..pushLiner\r z'"n\z'\'#r'z'"T)rGrIeval SyntaxErrorstringZ whitespace)r-Z quoteStarterr^itlenr)rXrYr]r[rZr parseConfsT        rgcCs8|}g}|D]}t|d}||qd|}|S)z.Pretty print string of space separated numbersr&)r< fitinfieldrIr@)rLpartscookedpartfittedrenderedrrr stringfilts   rocCs|}i}d}|D]6}t|\}}t|}t||}||dd||<qd}d} |D]&} | |krjq\|| } | | kr\| }| } q\g} |D]"}t||}t|d} | | qd | dt |t t }|S)zECooks a filt* string of space separated numbers, expects millisecondsi`yrr rhr&) r< scalestring maxdownscalemaxgetkeys rescalestringrirIr@rrUNIT_MS)rLrjZoomcountZminscalerlrDZoomZdsZ mostcommonZ highestcountkeyrPrkrmrnrrrstringfiltcookers4      rxcCstD]}||vr|SqdS)z2Returns the unit group which contains a given unitN) unitgroups)unitgrouprrr getunitgroupsr|cCsNt|}|dur||dS||vrJ||}||}t||dSdS)z:Calculates how many orders of magnitude separate two unitsNr )r|rabs)abr{iaZibrrroomsbetweenunitss  rcCsL|ddkr|dd}d}nd}d|vr:|d\}}n|}d}|||fS) zEBreaks a number string into (aboveDecimal, belowDecimal, isNegative?)r-r NTFr7r?)r<)rDnegativeabovebelowrrrbreaknumberstring+s  rcCs4|dkr d}|r d||f}n|}|r0d|}|S)z'Glues together parts of a number stringr?0r7r)r@)rrZ isnegativenewvaluerrrgluenumberstring:srcCs,d|vr$t|dd}|d SdSdS)z?Maximum units a value can be scaled down without inventing datar7r r rN)rGr<)rDZ digitcountrrrrqGs rqc Cst|\}}}|dkr&t|||}|St|}t|}t|d}|dkr||krp||}d} d|||} q| } || d|} |d| } n0|dkr||krdS||d|} ||d} | d} t| | |} | S)z2Rescale a number string by a given number of unitsrr r?rN)rrrGr}lstrip) rDZ unitsscaledwholedecrhilenlolenZ digitsmovedpadcountnewwholenewdecZ choppointrrrrruRs.     rucCs t|}t||d}||fS)zDScale a zero value for the unit with the highest available precisionr)rqrur)rDZscalerrrr formatzerousrcCs t|rt|St|\}}}t|}|dks6t|rd}t|}||krb||dkrXqb|d7}qB|dd}|d}||kr|d}|d}|d|d} ||d} | } nD|d} |d} | dkr| d8} d} |d| } || d|} | } t| | |}|| fS)z4Scales a number string to fit in the range 1.0-999.9rrr r N) isstringzerorrrGrr)rDrrrrrerZlounitsZ movecharsrr unitsmovedZhiunitsZhidigitsrrrrrp|s:      rpc Cst|}|dur|}n||kr$|}n||krBd||}||}nd|vr||}t|dd}t||}||}ttt||}|d} t| d}|dkr| dd}q||kr||} |d| }n|}|S)zFAttempt to fit value into a field, preserving as much data as possibleNr&r7r rr)rGr<minr;roundrU) rDZ fieldsizeZvallenrZpaddiffZdeclenZcroplenZroundlenZsplittedrrrrris.     ricCshd|vr |S|dkr"|ddS|dd}t||}t||}||}|dkrd|d| }|S)z(Crops digits below the maximum precisionr7rr N)r<findrGr)rDoomsZdstartZdsize precisionZ cropcountrrr cropprecisions  rcCs|D]}|dvrdSqdS)z)Detects whether a string is equal to zero)rr7rFTr)rDrerrrrsrcCsjtD]`}||vr|dur$|dS||}||7}d|krNt|kr^nn ||SdSqdS)z7Returns a unit at a different scale from the input unitNr)ryrrG)rzmover{rrrrunitrelativetos   rFcCs>|tvrt}n |tvrt}n|tvr*t}n|St|||||S)z1Call unitify() with the correct units for varname)S_VARSUNIT_SMS_VARSrvPPM_VARSUNIT_PPMunitify)rDZvarnamebaseunitwidth unitSpacestartrrr unitifyvarsrc Cs|durt|d}t||}t|r4t|\}}nt||}t|\}}t||}|rbd} d} nd} d} |dur|durd} n|t|| } t|| | |}n || |}|dur| }|S)zEFormats a numberstring with relevant units. Attempts to fit in width.Nrr r&r?) r|rrrrrprrGristrip) rDZ startingunitrrrrrrZunitgetZspaceWidthAdjustmentZspacerZ realwidthrrrrs,      rcCst|trd|St|ttfs$dStt|dkrTry to get a monotonic clock value unaffected by NTP stepping.N)r) monotonicAttributeErrorrrrr monoclockWs  rc@s,eZdZdZd ddZddZd dd ZdS) CachezSimple time-based cache,cCs||_i|_dSr\)defaultTimeout_cache)selfrrrr__init__cszCache.__init__cCsB||jvr:|j|\}}}|t|kr,|S|j|=dSndSdSr\)rr)rrwrDZsettimettlrrrrsgs z Cache.getNcCs(|dur |n|j}|t|f|j|<dSr\)rrr)rrwrDZ customTTLrrrrsetrsz Cache.set)r)N)__name__ __module__ __qualname____doc__rrsrrrrrr`s  rcCst|}|dur|Std|}|s*tt|\}}zt|d|ddtj}Wntj yld|YS0|d\}}}} } z"t | tj } | d |} Wn(tj y| p|} | |} Yn0t || | S)z.Canonicalize a hostname or numeric IP address.Nz ([:.[\]]|\w)*rz DNSFAIL:%s)canonicalization_cachersrematch TypeErrorrTsocket getaddrinfoZ AI_CANONNAMEgaierrorZ getnameinfoZ NI_NAMEREQDrr)ZinhostZfamilyZresnamemrRrSaiZsocktypeprotoZ canonnamesockaddrnameresultZ canonicalizedrrrcanonicalize_dns{s,    rTermSizerZheightcCsd}tdr|ttur.td\}}||f}nNz:tdt dt j t ddddd\}}}}||f}Wnt yzYn0t|S)z!Return the current terminal size.)Pr ZHHHHr r)osisattyr;bytesshutilget_terminal_sizestructunpackfcntlZioctltermiosZ TIOCGWINSZpackIOErrorr)sizewhZhpZwprrrtermsizes       rc@s(eZdZdZejjfddZddZdS)PeerStatusWordz:A peer status word from readstats(), dissected for displaycCstj||_tj||_tj|}|tjj@rd|_nd|_n@|d@tkr\d|_n*|d@tkrrd|_n|d@tkrd|_tjj dtjj!dtjj"dtjj#dtjj$dtjj%dtjj&dtjj'dtjj(dtjj)dtjj*d i }|+tjj,|jBd|_-dS)!NZyesnoZnonerok ZbadZrejectZ falsetickZexcessZoutlier candidateZbackupzsys.peerzpps.peerrhr ZinsaneZhi_dispr?Zsel_candZ sync_candZsys_peerZmobilizeZ demobilizeZ unreachableZ reachableZrestartZno_replyZ rate_exceededZ access_deniedZ leap_armedZ clock_alarm).rAcontrolZCTL_PEER_EVENTZeventZCTL_PEER_NEVNTZ event_countCTL_PEER_STATVALZCTL_PST_CONFIGZconfZ CTL_PST_BCASTreachZ CTL_PST_REACHZCTL_PST_AUTHENABLEZauthZCTL_PST_AUTHENTICmagicNTP_OLDVERSIONZCTL_PST_SEL_REJECTZCTL_PST_SEL_SANEZCTL_PST_SEL_CORRECTZCTL_PST_SEL_SELCANDZCTL_PST_SEL_SYNCCANDZCTL_PST_SEL_EXCESSZCTL_PST_SEL_SYSPEERZCTL_PST_SEL_PPSZ conditionOLD_CTL_PST_SEL_REJECTOLD_CTL_PST_SANEOLD_CTL_PST_DISPOLD_CTL_PST_SEL_SELCANDOLD_CTL_PST_SEL_SYNCCANDOLD_CTL_PST_SEL_SYSPEERZ PEVNT_MOBILZ PEVNT_DEMOBILZ PEVNT_UNREACHZ PEVNT_REACHZ PEVNT_RESTARTZ PEVNT_REPLYZ PEVNT_RATEZ PEVNT_DENYZ PEVNT_ARMEDZ PEVNT_NEWPEERZ PEVNT_CLOCKrsZ PEER_EVENTZ last_event)rstatus pktversionZstatvalZseldictZ event_dictrrrrsh       zPeerStatusWord.__init__cCs d|jS)Nzjconf=%(conf)s, reach=%(reach)s, auth=%(auth)s, cond=%(condition)s, event=%(last_event)s ec=%(event_count)s)__dict__rrrr__str__szPeerStatusWord.__str__N) rrrrrArZ NTP_VERSIONrrrrrrrsDr, cCs|tjjd}d}d}tt|td}|D]4\}\}} ||vr`dt|d} | |} nd|} |dvr| tj |7} n|d vr| |7} nt|d kr| d |7} n\|d kr| d |7} nD||vr|r| t |7} n| d | 7} n|dkrf| d|7} |dkr"| d7} n6d} t | D](\} }d| >|@r.| | | d7} q.| dd} n|tvr|r| t| ttdd7} n | t|7} nr|tvr|r| t| ttdd7} n | t|7} n>|tvr|r| t| tdd7} n | t|7} n | t|7} | |7} d}|D]}|dkr0d}n|d7}q|t| |kr^|ddd}|| 7}q0|ddd}|S)zCooked-mode variable display.r r?) filtdelay filtoffsetfiltdispZ filterror)rw%zs =z%s=)reftimeZclockZorgrecxmt)srcadrpeeradrdstadrrefidleap)Z00Z01Z10Z11rz%03lo flashz%02x rr) Zpkt_dupZ pkt_bogusZ pkt_unsyncZ pkt_deniedZpkt_authZ pkt_stratumZ pkt_headerZ pkt_autokeyZ pkt_cryptoZ peer_stratumZ peer_distZ peer_loopZ peer_unreachr r&NrF)rr')rArBrrrGrritemsr;ntpcZ prettydaterxr@r< enumeraterrrvUNIT_NSreprrrrr) variables showunitsseprr-ZspecialsZlongestspecialrrDrawvalue formatteritemZ tstflagnamesrenZ lastcountcrrrcook sl             r!c@sheZdZdZdddejfddZeddZed d Z ed d Z d dZ ddZ ddZ ddZdS) PeerSummaryz-Reusable report generator for peer statisticsFNrc Csz||_||_||_||_||_||_||_||_t|p8ddd|_ d|j |_ d|_ d |j |_ d|_d|_g|_dS)Nrrz remote z(st t when poll reach delay offset ) displaymoder showhostnamesr wideremoter.r, termwidthrhorizontal_slack namewidth refidwidthljust_PeerSummary__remote_PeerSummary__common_PeerSummary__headerpolls) rr$rr%r&rr'r.r,rrrrgs zPeerSummary.__init__cCsrt|tr|dkrdS|dkr&t|S|dd}|dkrBd|S|dd}|dkr^d |S|d d }d |S) z(Print an interval in natural time units.rri<rz%dm`z%dh rz%dd)rr=r;)rrrrprettyintervals   zPeerSummary.prettyintervalcCs*t||kr|Sd|| ddSdS)z8Truncate on the left using leading _ to indicate 'more'.rr N)rG)rRmaxlenrrr high_truncates zPeerSummary.high_truncatecCsd|vod|ddvS)z;Does a set of variables look like it returned from a clock?srchost(rr)rrrris_clockszPeerSummary.is_clockcCs|jdkr*|jd|j|jd|_nZ|jdkrT|jd|j|jd|_n0|jdkrfd|_n|jd |j|jd|_|jS) zColumn headers for peer displayapeersz refid assid r$Zopeersz local z disprpeerszH st t when poll reach delay offset jitter refid T remotez refid )r$r,r+r*r-r.rrrrheaders4      zPeerSummary.headercCs d|jS)zWidth of displayO)r(rrrrrszPeerSummary.widthc3 Cs0d}d}d}d}d}d} d} d} d} d} d}d}d}d}d}d}d}d}d}d}d}d}d}d}d}d}d}d}d} d}!d}"d}#d}$d}%d }&t}'|D]}(d t|(ksd t|(d krq|(\})\}*}+|)d kr|jr|+n|*}t|+d kr|+ddkrd}q|)dkr"d|jvr|+}q|)dkr2|*}q|)dkrB|*} q|)dkrR|*} q|)dkrb|*} q|)dkrr|*}q|)dkr|*}q|)dkr|*}q|)dkr|*}|dkrtjj}q|)dkrd|jvr|jr|+n|*} d}q|)dkr|*}q|)dkr|*}q|)dkr|jr|+n|*} q|)dkr,|*}q|)dkrN|*}|dkrtjj}q|)d kr^|*}q|)d!krn|*}q|)d"krd"|jvr|+}q|)d#kr|*}t|'tj |}q|)d$kr|*}t|'tj |}q|)d%kr|*}q|)d&ks|)d'kr|jr|+n|*}q|)d(vr|*}q|)d)kr(|*} q|)d*ks<|)d+krB|*}!q|)d,krR|*}"q|)d-krb|*}#q|)d.krr|*}$q|)d/kr|*}%q|)d0kr|*}&qqq|tjj krd1}n|tjj kr| d2rd3}nd4}n|tjjkr2t|rd5}nB|d6krd7}n2| d2rd8}n |&d kr,t|&td9}nd:}n&|tjjkrFd;}n|tjjkrXd<}d},d t||>}-|j|-|jtjjkrd=tj|d>@}.nd?tj|d@@}.|dur^|dAkr^| dBs^|dCkr^|jd @rd)tvr| r| }n^|jd @rXz4|jr |j dDt!|}|jr<|j dEWnt"yTYdS0n|}n| }|dur||rx|}nd}|j#dFkr|j$rt||j%kr|,dG|.|f7},|,dH|j%d 7},n"|,dI|.|j%|j%|d|j%f7},|j#dJkrd>nd}/d|vrdK|vrd|d}|/r:t||j&|/kr:dL}0n|}0|j#dFkr|,|'|0|j&7},|j#dJkr|,dH|j&t|0|/d 7},|,dM|7},n|,dH|j&t|07},|dur|'}|r| n|}1|jrdNdO}2n|rdPdO}2ndQdO}2|,dR|"|t(|t(|-||2||2| |2|1f7},|,dS7},|,S)TzPeer status summary line.r?rr7gFN?rFr r r#iTrlocaldstportrrrrheadwayhmodehpollr$keyidrr pmodeppollrrrr r rrr%)r r r7srcportZpeerportstratummodeunreachr  ntscookiesrz224.MBlZPOOLpr~rurSz x.-+#*orhz .+*r z0.0.0.0z127.127z::zDNS lookup begins... zDNS lookup ends. r;z%c%s r&z %c%-*.*s r:rNz...z%-6dcSs t|tSr\)rrvxrrrz%PeerSummary.summary..cSst|Sr\)rrTrrrrVrWcSst|Sr\)rrTrrrrVrWz# %2ld %c %4.4s %4.4s %3lo %s %s %sr'))r)rrGrr.rArZ NTP_MINPOLLr=r lfptofloatZ MODE_BCLIENTXZMODE_BROADCASTx startswithZ MODE_CLIENTr"r9rJordZ MODE_ACTIVExZ MODE_PASSIVExrr/rIrrrrr%localsr.r,r*rrr$r&r)r*r6r4)3rZrstatusrZassocidZ clock_nameZ dstadr_refidrBZestdelayZestdispZ estjitterZ estoffsetrrrrZ have_jitterrCrDrErFZ last_syncrrGrHrZptyperr r rZsaw6r r7rIrJrKrLr rMnowrrrDrlineZpoll_secr Z assocwidthZvisibleZjdZfinirrrsummarys                                                        zPeerSummary.summarycCs|jdd}g|_|S)z3Return and flush the list of actual poll intervals.N)r/)rresrrr intervalsszPeerSummary.intervals)rrrrrr1r staticmethodr4r6r9r<rr^r`rrrrr"ds     r"c@s.eZdZdZddejfddZdZddZd S) MRUSummaryz0Reusable class for MRU entry summary generation.FrcCs"||_||_d|_||_||_dSr\)r.r,r\r%r&)rr%r&r.r,rrrrs zMRUSummary.__init__zE lstint avgint rstr r m v count score drop rport remote addressc Cstj|j}tj|j}t||}t|j}|jrt|j|d}d|}|dkr`d}n ||d}t|d} d|ksd|kr|d| 7}qd|kr|d|7}q|d |7}n(d } t t|d \} }d | | ||f}|j tj j @rd } n|j tj j @r d} nd} t|j\} }zh|jd@s4| }nt| }t|}|durd}zDt|d}|D].\}}}}}|rf|d| krfd}qqfWntjyYn0t|||sd| |f}|js|dd}|jr&t|j}|dkrd|}n|dkrd|}nd|}nd}|jdkrBd|j}nd}|d|j | tj |jtj |j|j|||dd|f 7}|WStyYdS0dS)Ng?z%7dr rg@z %6dg?z %6.2fz %6.3fiQz %5d %5d %6dKLr7FTz%s (%s)(rrrrrrz%4dz! %4hx %c %d %d %6d %8s %6s %5s %sr?)rArrXfirstlastrUr=Zctr\divmodZrsrZRES_KODZ RES_LIMITEDrTaddrr%rrrsrrrrr&ZscZdrZPKT_MODEmvZ PKT_VERSIONr0)rentryrgrhZactiverPZlstintZstatsZfavgintZavgintZMJD_1970ZdaysZrscodeZipportZdnsZ confirmedr_rZscoreZdroprrrr^s                     zMRUSummary.summaryN) rrrrrr1rr<r^rrrrrbs  rbc@s,eZdZdZdZdZeddZddZdS) ReslistSummaryz4Reusable class for reslist entry summary generation.z< hits addr/prefix or addr mask restrictions HcsJ|sd}d|vrd}dnd}dtfdd||D}dt|S) Nr?rNrr7 cs$g|]}|rtt|dqS)1)binr=rP).0rUbaserr -sz.ReslistSummary.__getPrefix../)sumr<r;)maskprefixrrrurZ __getPrefix#s zReslistSummary.__getPrefixcCs|dd}|dd}|dd}|dks4|dkr8dS|t|7}|dd}d|||f}|D]}|sd|dvrddSqd|S) Nhitsr>rjrzr?flagsz%10s %s %s z/.: )rsro_ReslistSummary__getPrefixisalnum)rrr|addressrzr}rr rrrr^1s    zReslistSummary.summaryN) rrrrr<rrar~r^rrrrros  roc@s4eZdZdZdZdZdddddddd Zd d Zd S) IfstatsSummaryz4Reusable class for ifstats entry summary generation.z interface name send # address/broadcast drop flag received sent failed peers uptime Jz%-24.24sz%4xz%6dz%5dr)rr}rxtxtxerrpcupc Csi}z|jD]4}||d}|dkr.|}n|j||}|||<q|ddrVdnd}|dd}|d} d||d ||d |d |d |d |d|d|f } | r| d| 7} WntyYdS0| D]} | s| dvrdSq| S)Nr>enFr7Drjbcastz#%3u %s %s %s %s %s %s %s %s %s rr}rrrrrz %s r?z /.:[] \% )fieldsrtrsrr) rrer formattedrrDrZenFlagrrrr rrrr^Ss@      zIfstatsSummary.summaryN)rrrrr<rrr^rrrrrCsr) OrderedDictc@sBeZdZdZdddZddZddZd d Zd d Zd dZ dS)rzBA stupid simple implementation in order to be back-portable to 2.6NcCs.t|g|_|r*|D]\}}|||<qdSr\)dictr_OrderedDict__keys)rrkvrrrrs   zOrderedDict.__init__cCst||||j|dSr\)r __setitem__rrI)rrwvalrrrrszOrderedDict.__setitem__cCst|||j|dSr\)r __delitem__rremoverrwrrrrs zOrderedDict.__delitem__cCs|jSr\rrrrrrtszOrderedDict.keyscstfddjDS)Ncsg|]}||fqSrr)rtrrrrrwrWz%OrderedDict.items..)tuplerrrrrrszOrderedDict.itemsccs|jD] }|VqdSr\rrrrr__iter__s zOrderedDict.__iter__)N) rrrrrrrrtrrrrrrr~s rcCszt|tsdS|dks$t|ttfs.|ddfS||krJ|t|||dfS|rf|t|||ddfS|t|||dfS)a Given a number of packets and a duration (s) return a tuple. return the packet quantity, and a two part rate in packets/seconds or seconds/packet. On error the latter fields should be blank, the first the number of packets if zero otherwise unhelpful text.)???r?r?rr?zp/sr z/pzs/p)rr=rUr periodize)Zpacketsperiod clipdigitsZ periodizedrrr packetizes  rcCst|ttfr|nd}t|ttfs(dSd}t||}|dkrFt|n|}|dkrb|d|d7}|d|dd|dd |d f7}||fS) z}Given a number of seconds, return number and pretty string. On error return None for the number and an unhelpful string.r)Nrr?r rcz%dD z%02d:%02d:%02dir1)rr=rUr)rrZcliprrnZnperiodrrrrs   rcCs t|dS)Nr )r)rQrrrrVrWrV)NrF)NrF)Fr)rF)r)_rZ __future__rr collectionsrrrrrdrr)Zntp.ntpcrAZ ntp.magicZ ntp.controlZOLD_CTL_PST_CONFIGZOLD_CTL_PST_AUTHENABLEZOLD_CTL_PST_AUTHENTICZOLD_CTL_PST_REACHrrrrrrrrrvrZUNIT_KSrZUNIT_PPTZUNIT_PPBrrrryrrrrrr/r5r6r(rErCrMrTrgrorxr|rrrrqrurrprirrrrrrrrrrZ AF_UNSPECr namedtuplerr;rrrrrrr!r"rbrorr ImportErrorrrrZuptimerrrrs     D"   #$ &!  M [^[(8