+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TODO b/TODO
index 2484600..6078222 100644
--- a/TODO
+++ b/TODO
@@ -26,4 +26,9 @@ probably need to package https://packages.debian.org/source/stretch/freebsd-buil
-port in sslchk
--script that uses uconv(?) and pymysql to export database to .ods
\ No newline at end of file
+-script that uses uconv(?) and pymysql to export database to .ods
+
+-IRC
+-- i should use the python IRC module on pypi to join an irc network (freenode, probably, for my personal interests) and
+ run an iteration over all nicks in a channel with /ctcp version. handy when i'm trying to find someone running
+ a certain platform/client i have some questions about.
diff --git a/aif/scripts/post/sshsecure.py b/aif/scripts/post/sshsecure.py
index c6c307d..9dac237 100644
--- a/aif/scripts/post/sshsecure.py
+++ b/aif/scripts/post/sshsecure.py
@@ -1,6 +1,8 @@
#!/usr/bin/env python3
# Pythonized automated way of running https://sysadministrivia.com/news/hardening-ssh-security
+# TODO: check for cryptography module. if it exists, we can do this entirely pythonically
+# without ever needing to use subprocess/ssh-keygen, i think!
import datetime
import glob
diff --git a/centos/isomirror_sort.py b/centos/isomirror_sort.py
index d787fd7..842b6c0 100755
--- a/centos/isomirror_sort.py
+++ b/centos/isomirror_sort.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3.6
+#!/usr/bin/env python3
# requires python lxml module as well
import os
diff --git a/centos/repoclone/centos.dflts.ini b/centos/repoclone/centos.dflts.ini
index 096571f..be66fc0 100644
--- a/centos/repoclone/centos.dflts.ini
+++ b/centos/repoclone/centos.dflts.ini
@@ -99,8 +99,10 @@ bwlimit = 0
# will be created if necessary (assuming we have proper permissions).
lockfile = /var/run/repo-sync_{name}.lck
-# The logfile for this repository. The parent directories will be created if
-# necessary (assuming we have proper permissions).
+# The logfile. This setting is actually for all repositories; changing it below
+# will have no effect as all entries use the same log file. The parent
+# directories will be created if necessary (assuming we have proper
+# permissions).
logfile = /var/log/repo/centos.log
# The releases to clone for. Note that we follow symlinks, so you should *NOT*
diff --git a/centos/repoclone/repoclone.py b/centos/repoclone/repoclone.py
index e149176..24f3ed4 100755
--- a/centos/repoclone/repoclone.py
+++ b/centos/repoclone/repoclone.py
@@ -3,6 +3,7 @@
import configparser
import copy
import datetime
+import importlib
import os
import platform
import re
@@ -16,6 +17,20 @@ cfgfile = os.path.join(os.environ['HOME'],
'repoclone',
'centos.ini')
+# Set up the logger.
+_selfpath = os.path.abspath(os.path.expanduser(__file__))
+_logmodpath = os.path.join(_selfpath,
+ '..', '..', '..',
+ 'lib',
+ 'python',
+ 'logger.py')
+logger = importlib.util.module_from_spec(
+ importlib.util.spec_from_file_location(
+ 'logger',
+ _logmodpath))
+_loglevel = 'warning'
+#_loglevel = 'debug'
+
class cur_ver(object):
def __init__(self):
_distname = platform.linux_distribution()[0]
@@ -90,6 +105,10 @@ class MirrorMgr(object):
self.get_cfg()
self.chk_cur_ver()
self.parse_cfg()
+ self.log = logger.log(os.path.abspath(os.path.expanduser(
+ logfile = self.cfg['DEFAULT'])),
+ logname = 'optools.repoclone.centos',
+ loglvl = _loglevel)
def get_cfg(self):
with open(cfgfile, 'r') as f:
diff --git a/centos/repoclone/test.py b/centos/repoclone/test.py
new file mode 100755
index 0000000..c5e9c1b
--- /dev/null
+++ b/centos/repoclone/test.py
@@ -0,0 +1,9 @@
+#!/usr/bin/env python3
+
+import os
+
+selfpath = os.path.abspath(os.path.expanduser(__file__))
+print(selfpath)
+
+logmodpath = os.path.abspath(os.path.join(selfpath, '..', '..', '..', 'lib', 'python'))
+print(logmodpath)
diff --git a/net/bofh_gen.py b/net/bofh_gen.py
new file mode 100755
index 0000000..845711e
--- /dev/null
+++ b/net/bofh_gen.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+
+import telnetlib
+import time
+
+counter = 8
+
+def get_excuse():
+ # http://www.blinkenlights.nl/services.html
+ # port 23 (default) is Star Wars.
+ # port 666 is BOfH excuses
+ with telnetlib.Telnet('towel.blinkenlights.nl', port = 666) as t:
+ excuse = [x.decode('utf-8').strip() \
+ for x in t.read_all().split(b'===\r\n')]
+ return(excuse[2])
+
+def main():
+ for i in range(counter):
+ e = get_excuse()
+ print(e)
+ time.sleep(1)
+
+if __name__ == '__main__':
+ main()
diff --git a/net/devices/actiontec/ActionTec/Cmd.py b/net/devices/actiontec/ActionTec/Cmd.py
new file mode 100755
index 0000000..66c3d36
--- /dev/null
+++ b/net/devices/actiontec/ActionTec/Cmd.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3.6
\ No newline at end of file
diff --git a/net/devices/actiontec/ActionTec/Connector.py b/net/devices/actiontec/ActionTec/Connector.py
new file mode 100755
index 0000000..f90a243
--- /dev/null
+++ b/net/devices/actiontec/ActionTec/Connector.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3.6
+
+# stdlib
+import re
+import socket
+
+def CheckConnection(host, port):
+ # We favor socket over telnetlib's check because it has a little better
+ # handling of exceptions.
+ try:
+ port = int(port) # just in case we were passed a str()
+ except ValueError:
+ raise ValueError('"{0}" is not a port number'.format(port))
+ # In case they're catching the exception...
+ return(False)
+ s = socket.socket()
+ try:
+ s.connect((host, port))
+ except Exception as e:
+ raise RuntimeError(('We were unable to successfully connect to ' +
+ '"{0}:{1}": {2}').format(host, port, e))
+ return(False)
+ finally:
+ s.close()
+ return(True)
+
+def Login(host, port, ssl, user, password):
+ user_prompt = [re.compile('^\s*user(name)?\s*:?\s*'.encode('utf-8'),
+ re.IGNORECASE)]
+ passwd_prompt = [re.compile('^\s*passw(or)d?\s*:?\s*'.encode('utf-8'),
+ re.IGNORECASE)]
+ # Are there any other valid chars? Will need to experiment.
+ # How is this even set? The default is "Wireless Broadband Router".
+ # I think it can't be changed, at least via the Web GUI.
+ cmd_prompt = [re.compile('[-_a-z0-9\s]*>'.encode('utf-8'),
+ re.IGNORECASE)]
+ ctx = None
+ ctxargs = {'host': host, 'port': port}
+ try:
+ if ssl:
+ try:
+ from ssltelnet import SslTelnet as telnet
+ ctxargs['force_ssl'] = True
+ except ImportError:
+ raise ImportError(('You have enabled SSL but do not have ' +
+ 'the ssltelnet module installed. See ' +
+ 'the README file, footnote [1].'))
+ else:
+ from telnetlib import Telnet as telnet
+ ctx = telnet(**ctxargs)
+ ctx.expect(user_prompt, timeout = 8)
+ ctx.write((user + '\n').encode('utf-8'))
+ ctx.expect(passwd_prompt, timeout = 8)
+ ctx.write((password + '\n').encode('utf-8'))
+ ctx.expect(cmd_prompt, timeout = 15)
+ except EOFError:
+ if ctx:
+ ctx.close()
+ ctx = None
+ except Exception as e:
+ raise RuntimeError(('We encountered an error when trying to connect:' +
+ ' {0}').format(e))
+ if ctx:
+ ctx.close()
+ ctx = None
+ return(ctx)
\ No newline at end of file
diff --git a/net/devices/actiontec/ActionTec/__init__.py b/net/devices/actiontec/ActionTec/__init__.py
new file mode 100755
index 0000000..6d09dbb
--- /dev/null
+++ b/net/devices/actiontec/ActionTec/__init__.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python3.6
+
+import .Cmd as Cmd
+import .Connector as Connector
+
+class Router(object):
+ def __init__(self, host, port, user, password, ssl = False):
+ self.host = host
+ self.port = port
+ self.user = user
+ self.password = password
+ self.ssl = ssl
+ self.ctx = None
+ # Convenient shorthand. See "help.all.txt".
+ self.cmds = {'reboot': 'system reboot',
+ 'wipe': 'conf factory restore',
+ # this will... require an interactive session
+ 'shell': 'system shell'}
+
+ def connect(self):
+ # We don't need to define an except, really.
+ # The function handles that for us.
+ Connector.CheckConnection(self.host, self.port)
+ self.ctx = Connector.Login(self.host, self.port, self.ssl, self.user,
+ self.password)
+ return()
+
+ def execute(self):
+ pass
+
+ def close(self):
+ if self.ctx:
+ self.ctx.close()
\ No newline at end of file
diff --git a/net/devices/actiontec/ActionTec/help.all.txt b/net/devices/actiontec/ActionTec/help.all.txt
new file mode 100644
index 0000000..375258b
--- /dev/null
+++ b/net/devices/actiontec/ActionTec/help.all.txt
@@ -0,0 +1,177 @@
+Command Category wanmonitor - wanmonitor commands for rtd, do not use it directly
+get notify wanmonitor to send wan type to rtd
+exit Exit sub menu
+help Show help for commands within this menu
+
+Command Category conf - Read and write Wireless Broadband Router configuration data
+factory Factory related commands
+print Print Wireless Broadband Router configuration
+set Set Wireless Broadband Router configuration path to value
+set_obscure Set Wireless Broadband Router configuration path to an
+ obscured value
+del Delete subtree from Wireless Broadband Router configuration
+ram_set Set Wireless Broadband Router dynamic configuration
+ram_print Print Wireless Broadband Router dynamic configuration
+reconf Reconfigure the system according to the current Wireless
+ Broadband Router configuration
+firmware_restore Restore to saved firmware and reboot.
+exit Exit sub menu
+help Show help for commands within this menu
+
+Command Category upnp - UPnP commands
+igd IGD commands
+status Display UPnP status
+exit Exit sub menu
+help Show help for commands within this menu
+
+Command Category qos - Control and display QoS data
+utilization Connection utilization information
+exit Exit sub menu
+help Show help for commands within this menu
+
+Command Category wmm - wmm configuration and control
+get get the specified entry
+set set the specified entry
+del del the specified entry
+get_dev get the entries of the specified device
+exit Exit sub menu
+help Show help for commands within this menu
+
+Command Category cwmp - CWMP related commands
+status Print CWMP status
+session_start Start CWMP session to ACS
+session_stop Stop CWMP session
+indexes Print CWMP devices indexes
+exit Exit sub menu
+help Show help for commands within this menu
+
+Command Category bridge - API for managing ethernet bridge
+connection connect separate network interfaces to form one seamless LAN
+config Configure bridge
+info Print bridge information
+exit Exit sub menu
+help Show help for commands within this menu
+
+Command Category firewall - Control and display Firewall and NAT data
+restart Stop and start Firewall & NAT
+start Start Firewall & NAT
+stop Stop Firewall & NAT
+filter Turn Firewall packet inspection on/off
+mac_cache_dump Dump MAC cache data
+dump Display Firewall data
+variable Display variables of the firewall rules
+trace Trace packet traversal via the Firewall ruleset
+fastpath Turns firewall fastpath feature on/off (default is on)
+exit Exit sub menu
+help Show help for commands within this menu
+
+Command Category connection - API for managing connections
+pppoe Configure pppoe interface
+vlan Configure vlan interface
+exit Exit sub menu
+help Show help for commands within this menu
+
+Command Category inet_connection - API for managing internet connections
+pppoe Configure pppoe internet connection
+ether Configure ethernet internet connection
+exit Exit sub menu
+help Show help for commands within this menu
+
+Command Category misc - API for Wireless Broadband Router miscellaneous tasks
+print_ram print ram consumption for each process
+vlan_add Add VLAN interface
+top Profiling over event loop and estream
+wbm_debug_set Stop and start WBM debug mode
+wbm_border_set Stop and start WBM border mode
+knet_hooks_dump Dump to console which knet_hooks run on each device
+malloc_info Print memory information of malloc module
+malloc_trim Free unused allocated memory in malloc module
+exit Exit sub menu
+help Show help for commands within this menu
+
+Command Category firmware_update - Firmware update commands
+start Remotely upgrade Wireless Broadband Router
+cancel Kill running remote upgrade
+exit Exit sub menu
+help Show help for commands within this menu
+
+Command Category log - Controls Wireless Broadband Router logging behavior
+filter Controls the CLI session logging behavior
+print Print the contents of a given syslog buffer to the console
+clear Clear the contents of a given syslog buffer
+exit Exit sub menu
+help Show help for commands within this menu
+
+Command Category dev - Device related commands
+mv88e60xx Marvell MV88e60xx Ethernet Switch commands
+moca MOCA commands
+mii_reg_get Get Ethernet MII register value
+mii_reg_set Set Ethernet MII register value
+mii_phy_reg_get Get Ethernet MII register value
+mii_phy_reg_set Set Ethernet MII register value
+exit Exit sub menu
+help Show help for commands within this menu
+
+Command Category kernel - Kernel related commands
+sys_ioctl issue openrg ioctl
+meminfo Print memory information
+top Print Wireless Broadband Router's processes memory usage
+cpu_load_on Periodically shows cpu usage.
+cpu_load_off Stop showing cpu usage (triggered by cpu_load_on).
+cpu_load_avg Shows average cpu usage of last 1, 5 and 15 minutes.
+exit Exit sub menu
+help Show help for commands within this menu
+
+Command Category system - Commands to control Wireless Broadband Router execution
+http_intercept_status Display HTTP intercept status
+diag_test run diagtest 0=all or select 1-9 for TBHR
+ ..TLANIPSTB
+diag_correction run corrections -- may reboot or reset BHR
+die Exit from Wireless Broadband Router and return ret
+ps Print Wireless Broadband Router's tasks
+entity_close Close an entity
+etask_list_dump Dump back trace of all etasks
+restore_factory_settings Restore factory configuration
+reboot Reboot the system
+ver Display version information
+print_config Print compilation configuration. Search for option
+ if specified
+exec Execute program
+cat Print file contents to console
+shell Spawn busybox shell in foreground
+date Print the current UTC and local time
+print_page Print page id and name
+exit Exit sub menu
+help Show help for commands within this menu
+
+Command Category flash - Flash and loader related commands
+commit Save Wireless Broadband Router configuration to flash
+erase Erase a given section in the flash
+load Load and burn image
+boot Boot the system
+bset Configure bootloader
+layout Print the flash layout and content
+dump Dump the flash content
+lock Lock mtd region
+unlock Unlock mtd region
+exit Exit sub menu
+help Show help for commands within this menu
+
+Command Category net - Network related commands
+dns_route Dyncamic Routing according to DNS replies
+igmp IGMP Proxy related commands
+host Resolve host by name
+protected_setup Network related commands
+wsc wps related commands
+ifconfig Configure network interface
+ping Test network connectivity
+rg_ifconfig List Wireless Broadband Router Network Devices
+route Print route table
+main_wan Print the name of the current main wan device
+intercept_state Print interception state
+exit Exit sub menu
+help Show help for commands within this menu
+
+Command Category cmd - Commands related to the Command module
+exit Exit from the current CLI session
+help Show help for commands within this menu
\ No newline at end of file
diff --git a/net/devices/actiontec/README b/net/devices/actiontec/README
new file mode 100644
index 0000000..abeb4e5
--- /dev/null
+++ b/net/devices/actiontec/README
@@ -0,0 +1,122 @@
+This has been confirmed to work for, at the very least, my own Verizon Fi-OS
+Actiontec MI424WR-GEN3I on firmware 40.21.24. It might work on other models as
+well, but this hasn't been tested.
+
+No non-stdlib modules are required.
+
+Place your routers credentials in ~/.config/optools/actiontec_mgmt.json
+in the following format:
+(pay close attention to the quoting)
+(minified json is OK/whitespace-insensitive):
+_______________________________________________________________________________
+ {
+ "ip_addr": "192.168.1.1",
+ "user": "admin",
+ "password": "admin",
+ "ssl": false,
+ "port": 23
+ }
+_______________________________________________________________________________
+
+IF:
+
+- That file isn't found:
+-- A default (blank) one will be created (with secure permissions). All values
+ will be null (see below).
+
+- "ip_addr" is null:
+-- You will be prompted for the IP address interactively. (If you don't know
+ the IP address of it, it's probably the default -- "192.168.1.1".)
+
+- "user" is null:
+-- You will be prompted for the username to log in interactively. (If you don't
+ know the username, it's probably the default -- "admin".)
+
+- "password" is null:
+-- You will be prompted for the password. When being prompted, it will NOT echo
+ back (like a sudo prompt).
+
+- "ssl" is null:
+-- The default (false) will be used.
+
+- "port" is null:
+-- The default port (23) will be used.
+
+
+
+TIPS:
+
+- You need to ensure that you have the management interface enabled. Log into
+ your Actiontec's web interface, and:
+ 1.) "Advanced" button (at the top)
+ 2.) "Yes" button
+ 3.) a.) Choose "Local administration" if you'll be managing the device within
+ the network it provides.[0]
+ b.) Choose "Remote administration" if you'll be managing the device
+ outside the network it provides (i.e. over the Internet).[0]
+ 3.5) The "Telnet" options are what you want, ignore the "Web" settings.
+ 4.) Select the protocols/ports you'll be using. SEE FOOTNOTE 0 ([0])!
+ 5.) Click the "Apply" button.
+
+- "ip_addr" can also be a host/DNS name -- just make sure it resolves on your
+ local machine to your Actiontec IP address! The default, at least on mine,
+ was "wireless_broadband_router" (can be changed via Advanced > Yes > System
+ Settings > Wireless Broadband Router's Hostname):
+
+ [bts@cylon ~]$ nslookup wireless_broadband_router 192.168.1.1
+ Server: 192.168.1.1
+ Address: 192.168.1.1#53
+
+ Name: wireless_broadband_router
+ Address: 192.168.1.1
+ Name: wireless_broadband_router
+ Address:
+
+
+- Unfortunately it's a necessity to store the password in plaintext currently.
+ Future versions may give the option of encrypting it via GPG and using an
+ existing GPG agent session to unlock (if there's demand for such a feature).
+ Make sure your machine's files are safe (I recommend full-disk encryption).
+
+
+[0] NOTE: ENABLING MANAGEMENT CAN BE HIGHLY INSECURE, *ESPECIALLY* IF ENABLING
+ "REMOTE ADMINISTRATION"! *ONLY* DO THIS IF YOU UNDERSTAND THE RISKS
+ AND HAVE ACCOUNTED FOR THEM. TELNET PASSES CREDENTIALS IN PLAINTEXT
+ BY DEFAULT, AND IF SOMEONE NASTY GETS THEIR HANDS ON YOUR DEVICE'S
+ CREDENTIALS THEY CAN DO *VERY* NASTY THINGS. I REFUSE ANY AND ALL
+ LIABILITY YOU OPEN YOURSELF UP TO BY ENABLING THIS. AT *LEAST* USE
+ THE "USING SECURE TELNET OVER SSL PORT"[1] OPTION.
+ YOU HAVE BEEN WARNED.
+
+[1] NOTE: Even if using SSL, it's HIGHLY insecure and not to be trusted. The
+ key has been leaked (as of 2018-04-12):
+ https://code.google.com/archive/p/littleblackbox/
+ and it uses VERY weak ciphers, at that:
+ _____________________________________________________________________
+ | ssl-cert: Subject: commonName=ORname_Jungo: OpenRG Products Group/|
+ | countryName=US |
+ | Not valid before: 2004-06-03T11:11:43 |
+ |_Not valid after: 2024-05-29T11:11:43 |
+ |_ssl-date: 2018-04-12T09:42:22+00:00; -1s from scanner time. |
+ |_ssl-known-key: Found in Little Black Box 0.1 - |
+ | http://code.google.com/p/littleblackbox/ |
+ | (SHA-1: 4388 33c0 94f6 afc8 64c6 0e4a 6f57 e9f4 d128 1411)|
+ | sslv2: |
+ | SSLv2 supported |
+ | ciphers: |
+ | SSL2_RC4_128_WITH_MD5 |
+ | SSL2_RC4_64_WITH_MD5 |
+ | SSL2_RC2_128_CBC_EXPORT40_WITH_MD5 |
+ | SSL2_RC4_128_EXPORT40_WITH_MD5 |
+ | SSL2_DES_192_EDE3_CBC_WITH_MD5 |
+ | SSL2_RC2_128_CBC_WITH_MD5 |
+ |_ SSL2_DES_64_CBC_WITH_MD5 |
+ |___________________________________________________________________|
+
+ It's generally probably not even worth it, to be honest. You'll get
+ more security mileage out of firewalling off to select hosts/nets.
+ But, if you insist on having it and using it, you will ALSO need to
+ install the following module:
+
+ ssltelnet
+ https://pypi.python.org/pypi/ssltelnet
\ No newline at end of file
diff --git a/net/devices/actiontec/actiontec_mgmt.py b/net/devices/actiontec/actiontec_mgmt.py
new file mode 100755
index 0000000..66c3d36
--- /dev/null
+++ b/net/devices/actiontec/actiontec_mgmt.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3.6
\ No newline at end of file
diff --git a/net/dns/rfc4183.py b/net/dns/rfc4183.py
new file mode 100755
index 0000000..18b8fbe
--- /dev/null
+++ b/net/dns/rfc4183.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python3
+
+# https://tools.ietf.org/html/rfc2317
+# https://tools.ietf.org/html/rfc4183
+desc = 'Gets the RFC 2317/4183 PTR of given IP addresses or A/AAAA records.'
+
+# stdlib
+import argparse
+import copy
+import ipaddress
+import os
+# pypi/pip
+#try:
+# import ipwhois
+#except ImportError:
+# exit('You need to install the ipwhois module.')
+try:
+ import dns.resolver
+ import dns.reversename
+except ImportError:
+ exit('You need to install the dnspython module.')
+try:
+ import fqdn
+except ImportError:
+ exit('You need to install the fqdn module.')
+
+def resolveRecord(addr):
+ r = dns.resolver.Resolver()
+ ipaddrs = {'A': [],
+ 'AAAA': []}
+ for rtype in ipaddrs.keys():
+ for record in r.query(addr, 'A'):
+ ipaddrs[rtype].append(record)
+ ipaddrs['ipv4'] = sorted(list(set(copy.deepcopy(ipaddrs['A']))))
+ ipaddrs['ipv6'] = sorted(list(set(copy.deepcopy(ipaddrs['AAAA']))))
+ del(ipaddrs['A'], ipaddrs['AAAA'])
+ if ipaddrs['ipv4'] == ipaddrs['ipv6']:
+ del(ipaddrs['ipv6'])
+ return(ipaddrs)
+
+def genPTR(ipaddr, iptype):
+ _suffix = ''
+ # TODO: get the current PTR.
+ # TODO: do this more manually. We should use ipaddress and ipwhois to get
+ # the proper return for e.g. network gateways.
+ return(dns.reversename.from_address(ipaddr))
+
+def chkInput(src):
+ # Determine the input, if we can.
+ src_out = (None, None)
+ try:
+ ipaddress.IPv4Address(src)
+ return(('ipv4', src))
+ except ipaddress.AddressValueError:
+ pass
+ try:
+ ipaddress.IPv6Address(src)
+ return(('ipv6', src))
+ except ipaddress.AddressValueError:
+ pass
+ _p = os.path.abspath(os.path.expanduser(src))
+ if os.path.isfile(_p):
+ return(('file', _p))
+ # Last shot - is it a DNS record?
+ # Not quite perfect, as it's strictly RFC and there are plenty of
+ # subdomains out there that break RFC.
+ f = fqdn.FQDN(src)
+ if f.is_valid:
+ return(('dns', src))
+ return(src_out)
+
+def parseArgs():
+ def chkArg(src):
+ src_out = chkInput(src)
+ if src_out == (None, None):
+ raise argparse.ArgumentTypeError(('"{0}" does not seem to be a ' +
+ 'path to a file, an A/AAAA ' +
+ 'record, or IPv4/IPv6 ' +
+ 'address.').format(src))
+ return(src_out)
+ args = argparse.ArgumentParser(description = desc)
+ args.add_argument('data_in',
+ type = chkArg,
+ metavar = 'ADDRESS_OR_FILE',
+ help = ('The path to a file containing domains and IP ' +
+ 'addresses OR a single IPv4/IPv6 address or ' +
+ 'A/AAAA record. If an A/AAAA record, your ' +
+ 'machine must be able to resolve it (and it ' +
+ 'must exist)'))
+ return(args)
+
+def main():
+ # TODO: clean this up, migrate the duplicated code into a func
+ args = vars(parseArgs().parse_args())['data_in']
+ if args[0] == 'dns':
+ r = resolveRecord(args[1])
+ for k in r.keys():
+ for ip in r[k]:
+ print('IP: {0}'.format(ip))
+ print('PTR: {0}'.format(genPTR(str(ip), k)))
+ elif args[0] in ('ipv4', 'ipv6'):
+ print('PTR: {0}'.format(genPTR(args[1], args[0])))
+ elif args[0] == 'file':
+ with open(args[1], 'r') as f:
+ recordlst = [i.strip() for i in f.readlines()]
+ for i in recordlst:
+ ltype, data = chkInput(i)
+ print('== {0} =='.format(i))
+ if ltype == 'dns':
+ r = resolveRecord(data)
+ for k in r.keys():
+ for ip in r[k]:
+ print('IP: {0}'.format(ip))
+ print('PTR: {0}'.format(genPTR(str(ip), k)))
+ elif ltype in ('ipv4', 'ipv6'):
+ print('PTR: {0}'.format(genPTR(data, ltype)))
+ print()
+
+if __name__ == '__main__':
+ main()
diff --git a/net/irc/irssilogparse.py b/net/irc/irssilogparse.py
index 553b124..be72513 100755
--- a/net/irc/irssilogparse.py
+++ b/net/irc/irssilogparse.py
@@ -7,6 +7,30 @@
# http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
# https://github.com/shabble/irssi-docs/wiki/Formats#Colourising-Text-in-IRC-Messages
# https://askubuntu.com/a/528938
+# /themes/default.theme and ..docs/formats.txt holds SOME clues to
+# these.
+# e.g.
+# # text to insert at the beginning of each non-message line
+# line_start = "%B-%n!%B-%n ";
+#
+# # timestamp styling, nothing by default
+# timestamp = "$*";
+#
+# # any kind of text that needs hilighting, default is to bold
+# hilight = "%_$*%_";
+#####################
+# ^D = \x04
+# ^D8/ = bold dark grey (14)
+# ^D9/ = cyan (10)
+# ^Dg = color/fmting? reset
+# ^D;/ = bold light cyan(11)
+# ^Dc = bold
+# ^D>/ = (incl. bell for ">"?)
+## The key seems to be /opt/dev/optools/net/irc/irssilogparse.py (& assoc. .c file)
+## see also /src/core/log.c/h
+## !!! HUGE THANKS to Nei@Freenode#irssi! He pointed me to http://anti.teamidiot.de/static/nei/*/Code/Irssi/control2format.pl
+# which nicely maps those internal command/control chars to the irssi
+# templated stuff in their official docs (e.g. %b).
# Sorry for the copious comments, but the majority of the Irssi log stuff isn't
# really documented... anywhere. Just the color codes and \x03.
@@ -70,8 +94,8 @@ colormap = {8: {'0': ('97', '107'),
'13': ('95', '105'),
'14': ('90', '100'),
'15': ('37', '47'),
- 'ansi_wrap': {'fg': '\x1b[{0}',
- 'bg': ';{0}m'}},
+ 'ansi_wrap': {'fg': '\x1b[{0[0]}',
+ 'bg': ';{0[1]}m'}},
## https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit
256: {'0': '15',
'1': '0',
@@ -148,7 +172,8 @@ def get_palette():
# TODO: 24-bit support (16777216 colors) instead of 8-bit.
# See note above.
#return('truecolor')
- return(256)
+ #return(256)
+ return(8)
else:
curses.initscr()
curses.start_color()
@@ -189,7 +214,8 @@ def color_converter(data_in, palette_map):
'\g<1>',
i.strip()) for i in _ch['stripped'].split(',', 1)]
# Color-handling
- if _ch['ctrl'].startswith('\x03'):
+ #if _ch['ctrl'].startswith('\x03'):
+ if re.search('[\x00-\x03]', _ch['ctrl']):
if len(_ch['c']) == 1:
fg_only = True
elif len(_ch['c']) == 2:
@@ -202,6 +228,9 @@ def color_converter(data_in, palette_map):
if not fg_only:
bg = _colors['ansi_wrap']['bg'].format(_colors[_ch['c'][1]])
ch_out += bg
+ else:
+ if palette_map == 8:
+ ch_out += 'm'
# Control-character handling
else:
if _ch['ctrl'] in irssi_ctrl:
@@ -210,11 +239,14 @@ def color_converter(data_in, palette_map):
if _ch['ctrl'] == 'g':
color_inverter()
elif re.search('^[0-9]', _ch['ctrl']):
- # pass
ch_out = _colors['ansi_wrap']['fg'].format(
_colors[_ch['c'][0]])
+ if palette_map == 8:
+ ch_out += 'm'
else:
- print(_ch['ctrl'])
+ # _ch['ctrl'] is not found and we don't have a color number
+ # to look up, so leave ch_out as ''
+ pass
return(ch_out)
#color_ptrn = re.compile('\x03[0-9]{1,2}(,[0-9]{1,2})?')
catch = re.compile('(\x03[0-9]{2}(,[0-9]{1, 2})?|'
@@ -384,12 +416,17 @@ if __name__ == '__main__':
l = irssiLogParser(args)
import shutil
cols = shutil.get_terminal_size().columns
+ #print('ARGS:')
#pprint.pprint(l.args, width = cols)
- pprint.pprint(l.raw, width = cols)
- with open('/tmp/freenode.formatted', 'r') as f:
- print(f.read())
+ # print('RAW')
+ # pprint.pprint(l.raw, width = cols)
+ # with open('/tmp/freenode.formatted', 'r') as f:
+ # print(f.read())
+ #print('DATA')
#pprint.pprint(l.data, width = cols)
+ #print('DATA (REPR)')
#pprint.pprint(repr(l.data).split('\\n'))
+ print('DATA')
print(l.data)
with open('/tmp/log.raw', 'w') as f:
for line in repr(l.data).split('\\n'):
diff --git a/ref/progress.py b/ref/progress.py
new file mode 100755
index 0000000..9e97616
--- /dev/null
+++ b/ref/progress.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+import datetime
+import subprocess
+import time
+
+def waiter(seconds = 1):
+ prefix = ''
+ idx = 0
+ anims = ('|', '/', '-', '\\', 'O', '*', '\'', '^', '-', 'v', '_', '-')
+ max = len(anims) - 1
+ global is_done
+ print('Beginning dhparam gen...')
+ # This is just an example commant that takes a looong time.
+ c = subprocess.Popen(['openssl', 'dhparam', '-out', '/tmp/dhpem', '4096'],
+ #c = subprocess.Popen(['openssl', 'genrsa', '-out', '/tmp/dhpem', '4096'],
+ stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE)
+ print('dhparam gen started.')
+ while c.poll() is None:
+ #print('.', end = '', flush = True)
+ try:
+ char = anims[idx]
+ except IndexError:
+ exit()
+ print('{0} => {1}'.format(prefix, char), end = '', flush = True)
+ idx = (idx + 1 if idx < max else 0)
+ prefix += '.'
+ if seconds:
+ time.sleep(seconds)
+ #print('\b', end = '')
+ print('\033[F')
+ with open('/tmp/dhpem.out', 'w') as f:
+ f.write(c.stdout.read().decode('utf-8'))
+ f.write(c.stderr.read().decode('utf-8'))
+ print('\nDone.')
+ is_done = True
+
+if __name__ == '__main__':
+ waiter(1)
diff --git a/text/conf_minify.py b/text/conf_minify.py
index 607f54e..4c68736 100755
--- a/text/conf_minify.py
+++ b/text/conf_minify.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3.6
+#!/usr/bin/env python3
import argparse
import os