#!/usr/bin/env python3 import sys oldexcepthook = sys.excepthook def newexcepthook(type,value,traceback): oldexcepthook(type,value,traceback) #input("Press ENTER to quit.") sys.excepthook = newexcepthook import os p = os.path.join pUp = os.path.dirname s = False if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'): s = os.path.realpath(sys.executable) else: s = os.path.realpath(__file__) sp = pUp(s) # script start import subprocess import socket import threading import queue def eprint(*args, **kwargs): print(*args, file=sys.stderr, **kwargs) bufferSize = 10000 # buffer size in bytes queueLengthWait = 10 # How many buffers can be in the queue before waiting for it to empty? 0 for infinite, maxAccumulatedData comes into play. Raise for smoother playback, lower for less delay. maxAccumulatedData = 50*1000*1000 # If queueLengthWait is 0, how much data can be in an outbound thread's queue at maximum before the connection is closed? timeout = 15 # timeout in seconds connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM) class stdoutThread(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.queue = queue.Queue() def run(self): while True: data = self.queue.get(timeout=timeout) sys.stdout.buffer.write(data) class stdinThread(threading.Thread): def __init__(self,connection): threading.Thread.__init__(self) self.queue = queue.Queue(queueLengthWait) self.connection = connection def run(self): try: while True: accumulatedData = self.queue.qsize() * bufferSize if queueLengthWait < 1: eprint("Accumulated MB: " +str(accumulatedData/1000000)) if accumulatedData > maxAccumulatedData: eprint("Accumulated data limit reached. Closing.") self.connection.close() self.queue = False return data = self.queue.get() self.connection.sendall(data) except: self.connection.close() self.queue = False raise def listToCommand(lst): cmd = "" for arg in lst: arg = arg.replace("\\","\\\\") arg = arg.replace(",","\\,") #arg = arg.replace('"','\\"') #if " " in arg: arg = '"' +arg+ '"' cmd += arg + "," return cmd[:-1] def makePayload(lst): cmdText = listToCommand(lst) cmdBytes = cmdText.encode("utf-8") while len(cmdBytes) < 1000: cmdBytes += b" " return cmdBytes def main(): global serverAddr serverAddr = sys.argv[1].rsplit(":",1) serverAddr[1] = int(serverAddr[1]) serverAddr = tuple(serverAddr) eprint("Connecting to server...") connection.settimeout(timeout) connection.connect(serverAddr) eprint("Sending payload...") connection.sendall(makePayload(sys.argv[2:])) if sys.argv[2] == "watch": try: eprint("Receiving data...") stdoutThr = stdoutThread() stdoutThr.start() while True: data = connection.recv(bufferSize) if data == b"": return stdoutThr.queue.put(data) except: connection.close() raise if sys.argv[2] == "broadcast": try: eprint("Sending data...") stdinThr = stdinThread(connection) stdinThr.start() while True: data = sys.stdin.buffer.read(bufferSize) stdinThr.queue.put(data) except: connection.close() raise if __name__ == '__main__': main()