From 806aacf96ddbbb5de1c9ffdbe382e7de541b18dc Mon Sep 17 00:00:00 2001 From: steering7253 Date: Tue, 30 Jun 2026 19:53:21 -0600 Subject: v2 --- clickclack.py | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100755 clickclack.py 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() -- cgit v1.3.1-10-gc9f91