Created
August 2, 2024 20:43
-
-
Save ftoledo/aa62ef4965c11023feb9cddcc2907cbf to your computer and use it in GitHub Desktop.
binkit.js outbound statics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2 | |
import glob | |
import os.path | |
import stat | |
import sys | |
from datetime import datetime | |
#-------------------------------------------------------------------------- | |
def IsoTime(t): | |
return datetime.fromtimestamp(int(t)).strftime('%Y-%m-%d %H:%M:%S') | |
#-------------------------------------------------------------------------- | |
class OBFile: | |
flavours = { 'f':"Normal", 'i':"Immediate", 'c':"Continuous", 'd':"Direct", 'h':"Hold", 'o':"Normal" } | |
def __init__(self, path, zone, net=-1, node=-1): | |
self.fullpath = os.path.abspath(path) | |
self.zone = zone | |
self.net = net | |
self.node = node | |
self.point = 0 | |
self.txt = "" | |
self.type = "unk" | |
self.refs = [] | |
try: | |
st = os.stat(path) | |
self.mtime = st.st_mtime | |
self.size = st.st_size | |
self.isDir = stat.S_ISDIR(st.st_mode) | |
self.fname = os.path.basename(path) | |
self.root, self.ext = os.path.splitext(self.fname) | |
self.ext = self.ext[1:].lower() | |
if len(self.root) == 8: | |
if self.net < 0: | |
self.net = int(self.root[:4], 16) | |
if self.node < 0: | |
self.node = int(self.root[4:], 16) | |
else: | |
self.point = int(self.root[4:], 16) | |
self.nn = str(self.zone) + ':' + str(self.net) + '/' + str(self.node) | |
if self.point > 0: | |
self.nn += '.' + str(self.point) | |
if self.ext == "try": | |
tfile = open(path) | |
tfile.seek(5) | |
self.txt = "Try result: " + tfile.readline().strip() | |
tfile.close() | |
self.type = "try" | |
elif self.ext == "bsy" or self.ext == "csy": | |
self.txt = "" | |
self.type = "bsy" | |
elif self.ext == "hld": | |
self.txt = "Holding until: " + IsoTime(open(path).readline()) | |
self.type = "hld" | |
elif self.ext == "req": | |
self.txt = "" | |
self.type = "req" | |
elif self.ext[1:] == "ut" and self.ext[0] in "oicdh": | |
self.txt = "Flavour: " + self.flavours[self.ext[0]] | |
self.type = "out" | |
elif self.ext[1:] == "lo" and self.ext[0] in "ficdh": | |
self.txt = "Flavour: " + self.flavours[self.ext[0]] | |
self.type = "flo" | |
elif self.ext == "pnt" and self.isDir: | |
self.txt = "Point directory" | |
self.type = "pnt" | |
self.obdir = OutBoundDir(path, 5, self.zone, self.net, self.node) | |
except ValueError: | |
self.txt = "" | |
self.type = "err" | |
# The following directives are documented as a standard: | |
# | |
# "#" - Indicates that the files should be truncated to zero- | |
# length after successfully sending the file to the remote | |
# system. This is normally only employed when sending compressed | |
# mail (archived mail) to the remote. | |
# | |
# "^" - delete the file after successfully sending the file to | |
# the remote system. | |
# | |
# "~" - skip the line from treatment. It may be useful to mark | |
# an already processed line. | |
# | |
# <none> - indicates that the file should be sent and neither be | |
# truncated nor deleted after sending. Listing the file with the | |
# full path circumvents problems with files that have a name | |
# starting with a character that is a known directive. | |
# | |
# | |
# Software may optionally recognise the following directives: | |
# | |
# "-" As an alternate for "^" | |
# | |
# "!" As an alternate for "~" | |
# | |
# "@" Send file, do not truncate or delete. | |
def OrphansToRefs(self, orphans, fname, flochar): | |
for i, obfile in reversed(list(enumerate(orphans))): | |
if obfile.FileName() == fname: | |
obfile.flochar = flochar | |
self.refs.append(obfile) | |
del orphans[i] | |
break | |
def HandleLine(self, line, orphans): | |
if line[0] in "#^~-!@": | |
flochar = line[0] | |
fpath = line[1:].strip() | |
else: | |
flochar = ' ' | |
fpath = line.strip() | |
fname = os.path.basename(fpath) | |
self.OrphansToRefs(orphans, fname, flochar) | |
def GetRefFiles(self, orphans): | |
if self.type == "flo": | |
tfile = open(self.fullpath) | |
for line in tfile: | |
self.HandleLine(line, orphans) | |
tfile.close() | |
def NodeNumber(self): | |
return self.nn if hasattr(self, 'nn') else '' | |
def FileName(self): | |
return self.fname if hasattr(self, 'fname') else '' | |
def KnownType(self): | |
return hasattr(self, 'type') and self.type != "unk" and self.type != "err" | |
def Size(self): | |
return " <dir>" if self.isDir else "%7d" % (self.size, ) | |
def FileInfoStr(self): | |
return "%-12s - %s - %s" % (self.fname, IsoTime(self.mtime), self.Size()) | |
def Print(self, indent): | |
print (' ' * indent), '+', self.FileInfoStr(), '-', self.txt | |
for obfile in self.refs: | |
obfile.PrintRef(indent) | |
if hasattr(self, 'obdir'): | |
self.obdir.PrintFiles() | |
def FloActionTxt(self): | |
if self.flochar == '#': | |
return "Truncate after send" | |
elif self.flochar == '^' or self.flochar == '-': | |
return "Delete after send" | |
elif self.flochar == '!' or self.flochar == '~': | |
return "Skip" | |
else: | |
return "Keep after send" | |
def PrintRef(self, indent): | |
print (' ' * indent), self.flochar, self.FileInfoStr(), "- Action:", self.FloActionTxt() | |
def PrintOrphan(self, indent): | |
print (' ' * (indent + 2)), self.FileInfoStr() | |
#-------------------------------------------------------------------------- | |
class OutBoundDir: | |
def __init__(self, oDir, indent, zone, net=-1, node=-1): | |
self.oDir = oDir | |
self.zone = zone | |
self.net = net | |
self.node = node | |
self.indent = indent | |
self.nfiles = {} | |
self.orphans = [] | |
self.AddFiles(glob.glob(os.path.join(oDir, "*"))) | |
def AddFiles(self, files): | |
if files: | |
self.FilesToLists(files) | |
self.orphans.sort(key=OBFile.FileName) | |
self.AddOrphansToFloFiles() | |
def FilesToLists(self, files): | |
for oFile in files: | |
obf = OBFile(oFile, self.zone, self.net, self.node) | |
if obf.KnownType(): | |
self.AddFile(obf) | |
else: | |
self.orphans += obf, | |
def AddFile(self, obfile): | |
if obfile.nn not in self.nfiles: | |
self.nfiles[obfile.nn] = [] | |
self.nfiles[obfile.nn] += obfile, | |
def AddOrphansToFloFiles(self): | |
for key, obfiles in self.nfiles.iteritems(): | |
for obfile in obfiles: | |
obfile.GetRefFiles(self.orphans) | |
def PrintNodes(self): | |
for key in sorted(self.nfiles): | |
print (' ' * self.indent) + key | |
for obfile in self.nfiles[key]: | |
obfile.Print(self.indent) | |
def PrintOrphans(self): | |
if self.orphans: | |
print (' ' * self.indent) + "Orphaned files:" | |
for orphan in self.orphans: | |
orphan.PrintOrphan(self.indent) | |
def PrintFiles(self): | |
self.PrintNodes() | |
self.PrintOrphans() | |
def NodeStrs(self): | |
if self.net >= 0: | |
return "Node", str(self.zone) + ':' + str(self.net) + '/' + str(self.node if self.node >= 0 else 0) | |
else: | |
return "Zone", str(self.zone) | |
def PrintHeader(self): | |
print self.oDir, "- %s %s" % self.NodeStrs() | |
def Print(self): | |
self.PrintHeader() | |
self.PrintFiles() | |
""" | |
Netmail: .?ut | |
Referemce: .?lo | |
"#" - truncate | |
"^" "-" - delete | |
"~" "!" - skip the line from treatment. It may be useful to mark an already processed line. | |
<none> "@" Send file, do not truncate or delete | |
file request: .req | |
flavours: | |
i - Immediate | |
c - Continuous | |
d - Direct | |
h - Hold | |
o/f - Normal (Netmail/Reference) | |
Immediate ("iut" or "ilo") | |
Continuous ("cut" or "clo") | |
Direct ("dut" or "dlo") | |
Normal ("out" or "flo") | |
Hold ("hut" or "hlo") | |
bsy (busy) control file | |
csy (call) control file | |
For information purposes a [bc]sy file may contain one line of | |
PID information (less than 70 characters). | |
hld (hold) control file | |
A hld file must contain a one line string with the expiration | |
of the hold period expressed in UNIX-time. | |
try control file | |
A try file must contain one line string with a diagnostic | |
message. It is for information purposes only. | |
For information purposes the second line of a try file may | |
contain one line of PID information. ( < 70 characters) | |
""" | |
#-------------------------------------------------------------------------- | |
class OutBoundDirs: | |
def __init__(self, outbound, defzone): | |
self.outbound = outbound | |
self.defzone = defzone | |
def Handle(self): | |
if not os.path.isdir(self.outbound): | |
print "Error:", self.outbound, "is not a dir." | |
return 1 | |
self.outboundDirs = [ (self.outbound, self.defzone), ] | |
self.GetOutboundDirs() | |
self.ProcessOutboundDirs() | |
return 0 | |
def GetOutboundDirs(self): | |
dirs = glob.glob(self.outbound + ".*") | |
dirs.sort() | |
self.outboundStrLen = len(self.outbound) + 1 | |
for dir in dirs: | |
self.GetOutboundDir(dir) | |
def GetOutboundDir(self, dir): | |
ext = dir[self.outboundStrLen:] | |
try: | |
zone = int(ext, 16) | |
self.outboundDirs += ((dir, zone),) | |
except ValueError: | |
pass | |
def ProcessOutboundDirs(self): | |
for od in self.outboundDirs: | |
obd = OutBoundDir(od[0], 2, od[1]) | |
obd.Print() | |
#-------------------------------------------------------------------------- | |
if __name__ == "__main__": | |
rv = 0 | |
print "bsostatus 1.1.0 Copyright (C) 2022-01-17 by Wilfred van Velzen" | |
if len(sys.argv) < 3: | |
print "usage:", sys.argv[0], "<default outbound dir> <default zone>" | |
rv = 1 | |
else: | |
rv = OutBoundDirs(sys.argv[1], int(sys.argv[2])).Handle() | |
sys.exit(rv) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment