summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar steering72532026-06-30 19:53:21 -0600
committerGravatar steering72532026-06-30 19:53:21 -0600
commit806aacf96ddbbb5de1c9ffdbe382e7de541b18dc (patch)
treeb99a38c761a36c371ad00a51e841242c6965c597
-rwxr-xr-xclickclack.py91
1 files changed, 91 insertions, 0 deletions
diff --git a/clickclack.py b/clickclack.py
new file mode 100755
index 0000000..7ba5c97
--- /dev/null
+++ b/clickclack.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python
+# ~/clickclack.py -s -r <(echo 'CAPAB START 1206\r\nSERVER test.1459.io dummy 1S2 :moo.\r\nBURST %s\r\nENDBURST\r\n' socat stdio openssl:127.0.0.1:6005,cert=1S1.cert,key=1S1.key,snihost=chaos.1459.io,commonname=chaos.1459.io
+
+CLIENT_MODE = True
+DEBUG = False
+CONN_SEND = b''
+import select, subprocess, sys, os, tty, termios, time
+
+
+def parse_irc_line(line):
+ source = b''
+ cmd = b''
+ _trailing = None
+ args = []
+ if line[0:1] == b':':
+ source_pieces = line.split(None, 1)
+ source = source_pieces[0][1:]
+ line = source_pieces[1]
+ if b' :' in line:
+ trailing_pieces = line.split(b' :', 1)
+ _trailing = trailing_pieces[1]
+ line = trailing_pieces[0]
+ cmd, *args = line.split()
+ if _trailing is not None:
+ args.append(_trailing)
+ return (source, cmd, args)
+
+def format_irc_args(args):
+ if b' ' in args[-1]:
+ args[-1] = b':' + args[-1]
+ return b' '.join(args)
+
+if __name__ == '__main__':
+ argv = sys.argv[1:]
+ while len(argv) and len(argv[0]) and argv[0][0] == '-':
+ opt = argv[0][1:]
+ del argv[0]
+ if opt == 's':
+ CLIENT_MODE = False
+ elif opt == 'r':
+ CONN_SEND = argv[0]
+ del argv[0]
+ elif opt == '-':
+ break
+ else: #h
+ print(f'Usage: {sys.argv[0]} [-h|-s|-r "send on connect file"|--] [socat command...]', file=sys.stderr)
+ sys.exit()
+
+ proc = subprocess.Popen(argv, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ conn_send_cmds = open(CONN_SEND, 'rb').read()
+ conn_send_cmds = conn_send_cmds.replace(b'%s', bytes(str(time.time()).encode('ascii')))
+ proc.stdin.write(conn_send_cmds)
+ proc.stdin.flush()
+
+ os.set_blocking(proc.stdout.fileno(), False)
+ os.set_blocking(proc.stderr.fileno(), False)
+ child_buffer = bytearray()
+ while True:
+ if DEBUG: print('selecting')
+ rd = select.select([proc.stdout, proc.stderr, sys.stdin.buffer], [], [])[0]
+ for f in rd:
+ if DEBUG: print(f'reading {f!r}')
+ if f is proc.stdout:
+ if DEBUG: print(f'writing to stdout')
+ child_buffer += f.read()
+ child_buffer.replace(b'\r',b'')
+ if b'\n' in child_buffer:
+ lines = child_buffer.split(b'\n')
+ for line in lines[:-1]:
+ if line == b'': continue
+ source, cmd, args = parse_irc_line(line)
+ sys.stdout.buffer.write(line+b'\r\n')
+ sys.stdout.buffer.flush()
+ if cmd == b'PING':
+ if CLIENT_MODE:
+ pong = b'PONG %s\r\n' % (format_irc_args(args))
+ else:
+ pong = b'PONG %s\r\n' % (source)
+ sys.stdout.buffer.write(pong)
+ sys.stdout.buffer.flush()
+ proc.stdin.write(pong)
+ proc.stdin.flush()
+ child_buffer = lines[-1]
+ if f is proc.stderr:
+ if DEBUG: print(f'writing to stderr')
+ sys.stderr.buffer.write(f.read())
+ sys.stderr.buffer.flush()
+ if f is sys.stdin.buffer:
+ if DEBUG: print(f'writing to child')
+ proc.stdin.write(f.readline())
+ proc.stdin.flush()