ansible-qubes/bin/qrun-bridge
Manuel Amador (Rudd-O) f2068b17dc initial commit
2015-06-15 12:08:51 -07:00

157 lines
3.3 KiB
Bash
Executable File

#!/bin/sh
echo "exec python -c '
import sys
import os
import socket
import subprocess
import threading
def start_process():
prefix = [\"su\", \"-\", \"root\"]
if socket.gethostname().startswith(\"dom0.\") or socket.gethostname() == \"dom0\":
prefix = [\"sudo\", \"-H\"]
if sys.argv[1:]:
cmd = prefix + [\"sh\", \"-c\", \" \".join(sys.argv[1:])]
else:
cmd = prefix + [\"sh\"]
p = subprocess.Popen(
cmd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
return p, p.stdin, p.stdout, p.stderr
def supervise_process(p):
ret = process.wait()
sys.stdout.write(\"P\" + str(ret) + \" \")
sys.stdout.flush()
def relay_stdin(i):
while True:
b = sys.stdin.read(1)
if b == \"i\":
data = sys.stdin.read(1)
i.write(data)
i.flush()
elif b == \"I\":
i.close()
break
elif not b:
i.close()
break
def relay_stdout(o):
while True:
b = o.read(1)
if not b:
sys.stdout.write(\"O\")
sys.stdout.flush()
break
sys.stdout.write(\"o\" + b)
sys.stdout.flush()
def relay_stderr(e):
while True:
b = e.read(1)
if not b:
sys.stdout.write(\"E\")
sys.stdout.flush()
break
sys.stdout.write(\"e\" + b)
sys.stdout.flush()
process, i, o, e = start_process()
relayer_stdin = threading.Thread(target=lambda: relay_stdin(i))
relayer_stdout = threading.Thread(target=lambda: relay_stdout(o))
relayer_stderr = threading.Thread(target=lambda: relay_stderr(e))
relayer_stdin.start()
relayer_stdout.start()
relayer_stderr.start()
process_supervisor = threading.Thread(target=lambda: supervise_process(process))
process_supervisor.start()
def close_stdout():
relayer_stdout.join()
relayer_stderr.join()
relayer_stdin.join()
process_supervisor.join()
sys.stdout.close()
stdout_closer = threading.Thread(target=close_stdout)
stdout_closer.start()
stdout_closer.join()
'" \"$@\" >&1
exec python -c '
import sys
import os
import threading
import select
import fcntl
saved_fd_0 = int(sys.argv[1])
local_stdin = os.fdopen(saved_fd_0, "r")
saved_fd_1 = int(sys.argv[2])
local_stdout = os.fdopen(saved_fd_1, "w")
saved_fd_2 = int(sys.argv[3])
local_stderr = os.fdopen(saved_fd_2, "w")
def relay_stdin():
while True:
b = local_stdin.read(1)
if not b:
sys.stdout.write("I")
sys.stdout.flush()
sys.stdout.close()
break
sys.stdout.write("i" + b)
sys.stdout.flush()
retval = 0
def display_stdouterr():
global retval
conditions = 3
while conditions:
b = sys.stdin.read(1)
if not b: break
elif b == "o":
b = sys.stdin.read(1)
local_stdout.write(b)
local_stdout.flush()
elif b == "e":
b = sys.stdin.read(1)
local_stderr.write(b)
local_stderr.flush()
elif b == "O":
conditions = conditions - 1
elif b == "E":
conditions = conditions - 1
elif b == "P":
chars = ""
while not chars.endswith(" "):
char = sys.stdin.read(1)
chars = chars + char
chars = chars.replace(" ", "")
retval = int(chars)
conditions = conditions - 1
stdin_relayer = threading.Thread(target=relay_stdin)
stdin_relayer.setDaemon(True)
stdin_relayer.start()
displayer = threading.Thread(target=display_stdouterr)
displayer.start()
displayer.join()
sys.exit(int(retval))
' $SAVED_FD_0 $SAVED_FD_1 $SAVED_FD_2