Aurora
Adminer
Auto Root
WP Admin
cPanel Reset
Anti Backdoor
Root
usr
lib64
python3.9
site-packages
ntp
Upload
New Folder
New File
Name
Size
Permissions
Actions
..
-
-
-
Upload File
Select File
New Folder
Folder Name
New File
File Name
Add WordPress Admin
Database Host
Database Name
Database User
Database Password
Admin Username
Admin Password
cPanel Password Reset
Email Address
Edit: statfiles.py
# -*- coding: utf-8 -*- """ statfiles.py - class for digesting and plotting NTP logfiles Requires gnuplot and liberation fonts installed. """ # SPDX-License-Identifier: BSD-2-Clause from __future__ import print_function, division import calendar import glob import gzip import os import socket import sys import time class NTPStats: "Gather statistics for a specified NTP site" SecondsInDay = 24*60*60 DefaultPeriod = 7*24*60*60 # default 7 days, 604800 secs peermap = {} # cached result of peersplit() period = None starttime = None endtime = None sitename = '' @staticmethod def unixize(lines, starttime, endtime): """Extract first two fields, MJD and seconds past midnight. convert timestamp (MJD & seconds past midnight) to Unix time Replace MJD+second with Unix time.""" # HOT LOOP! Do not change w/o profiling before and after lines1 = [] for line in lines: try: split = line.split() mjd = int(split[0]) second = float(split[1]) except ValueError: # unparseable, skip this line continue # warning: 32 bit overflows time = NTPStats.SecondsInDay * mjd + second - 3506716800 if starttime <= time <= endtime: # time as integer number milli seconds split[0] = int(time * 1000) # time as string split[1] = str(time) lines1.append(split) return lines1 @staticmethod def timestamp(line): "get Unix time from converted line." return float(line.split()[0]) @staticmethod def percentiles(percents, values): """Return given percentiles of a given row in a given set of entries. assuming values are already split and sorted""" ret = {} length = len(values) if 1 >= length: # uh, oh... if 1 == length: # just one data value, set all to that one value value = values[0] else: # no data, set all to zero value = 0 for perc in percents: ret["p" + str(perc)] = value else: for perc in percents: if perc == 100: ret["p100"] = values[length - 1] else: ret["p" + str(perc)] = values[int(length * (perc/100))] return ret @staticmethod def ip_label(key): "Produce appropriate label for an IP address." # If it's a new-style NTPsep clock label, pass it through, # Otherwise we expect it to be an IP address and the next guard fires if key[0].isdigit(): # TO BE REMOVED SOMEDAY # Clock address - only possible if we're looking at a logfile made # by NTP Classic or an NTPsec version configured with # --enable-classic-mode. Nasty that we have to emit a numeric # driver type here. if key.startswith("127.127."): (_, _, clock_type, unit) = key.split(".") return "REFCLOCK(type=%s,unit=%s)" % (clock_type, unit) # Ordinary IP address - replace with primary hostname. # Punt if the lookup fails. try: (hostname, _, _) = socket.gethostbyaddr(key) return hostname except socket.herror: pass return key # Someday, be smarter than this. def __init__(self, statsdir, sitename=None, period=None, starttime=None, endtime=None): "Grab content of logfiles, sorted by timestamp." if period is None: period = NTPStats.DefaultPeriod self.period = period # Default to one week before the latest date if endtime is None and starttime is None: endtime = int(time.time()) starttime = endtime - period elif starttime is None and endtime is not None: starttime = endtime - period elif starttime is not None and endtime is None: endtime = starttime + period self.starttime = starttime self.endtime = endtime self.sitename = sitename or os.path.basename(statsdir) if 'ntpstats' == self.sitename: # boring, use hostname self.sitename = socket.getfqdn() if not os.path.isdir(statsdir): # pragma: no cover sys.stderr.write("ntpviz: ERROR: %s is not a directory\n" % statsdir) raise SystemExit(1) self.clockstats = [] self.peerstats = [] self.loopstats = [] self.rawstats = [] self.temps = [] self.gpsd = [] for stem in ("clockstats", "peerstats", "loopstats", "rawstats", "temps", "gpsd"): lines = self.__load_stem(statsdir, stem) processed = self.__process_stem(stem, lines) setattr(self, stem, processed) def __load_stem(self, statsdir, stem): lines = [] try: pattern = os.path.join(statsdir, stem) if stem != "temps" and stem != "gpsd": pattern += "." for logpart in glob.glob(pattern + "*"): # skip files older than starttime if self.starttime > os.path.getmtime(logpart): continue if logpart.endswith("gz"): lines += gzip.open(logpart, 'rt').readlines() else: lines += open(logpart, 'r').readlines() except IOError: # pragma: no cover sys.stderr.write("ntpviz: WARNING: could not read %s\n" % logpart) return lines def __process_stem(self, stem, lines): lines1 = [] if stem == "temps" or stem == "gpsd": # temps and gpsd are already in UNIX time for line in lines: split = line.split() if 3 > len(split): # skip short lines continue try: time_float = float(split[0]) except ValueError: # ignore comment lines, lines with no time continue if self.starttime <= time_float <= self.endtime: # prefix with int milli sec. split.insert(0, int(time_float * 1000)) lines1.append(split) else: # Morph first fields into Unix time with fractional seconds # ut into nice dictionary of dictionary rows lines1 = NTPStats.unixize(lines, self.starttime, self.endtime) # Sort by datestamp # by default, a tuple sort()s on the 1st item, which is a nice # integer of milli seconds. This is faster than using # cmp= or key= lines1.sort() return lines1 def peersplit(self): """Return a dictionary mapping peerstats IPs to entry subsets. This is very expensive, so cache the result""" if self.peermap: return self.peermap for row in self.peerstats: try: ip_address = row[2] # peerstats field 2, refclock id if ip_address not in self.peermap: self.peermap[ip_address] = [] self.peermap[ip_address].append(row) except IndexError: # pragma: no cover # ignore corrupted rows pass return self.peermap def gpssplit(self): "Return a dictionary mapping gps sources to entry subsets." gpsmap = {} for row in self.gpsd: try: source = row[2] if source not in gpsmap: gpsmap[source] = [] gpsmap[source].append(row) except IndexError: # pragma: no cover # ignore corrupted rows pass return gpsmap def tempssplit(self): "Return a dictionary mapping temperature sources to entry subsets." tempsmap = {} for row in self.temps: try: source = row[2] if source not in tempsmap: tempsmap[source] = [] tempsmap[source].append(row) except IndexError: # pragma: no cover # ignore corrupted rows pass return tempsmap def iso_to_posix(time_string): "Accept timestamps in ISO 8661 format or numeric POSIX time. UTC only." if str(time_string).isdigit(): return int(time_string) time_struct = time.strptime(time_string, "%Y-%m-%dT%H:%M:%S") # don't use time.mktime() as that is local tz return calendar.timegm(time_struct) def posix_to_iso(unix_time): "ISO 8601 string in UTC from Unix time." return time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime(unix_time)) # end