So for some reason, I decided to make python call up a bash shell while outputting everything from the terminal to a web page. I don’t think this is supposed to even work but with FF4 it seems to. Basically the python script starts by setting stdin to raw (canon) i/o mode. Then it forks a child process (bash) in which it can write to it’s stdin and read from it’s stdout/stderror. It then fires up a simple TCP socket HTTP server which sends any viewers the output of the shell’s stdout. It uses basic alarm interrupts to prevent blocking calls and basically acts as a service-in-the-middle. In English, this thing lets web viewers monitor your command line input/output. I don’t know why you would even want or need this but I guess it’s a cool hack/proof of concept.
#!/usr/bin/python
import os
import re
import signal
import socket
import sys
import time
import tty
import termios
def cleanstr(inptstri):
backspce = (chr(8) + chr(27) + "[K")
outpstri = inptstri
outpstri = outpstri.replace(backspce, "^H")
outpstri = outpstri.replace("&", "&")
outpstri = outpstri.replace("<", "<")
outpstri = outpstri.replace(">", ">")
outpstri = outpstri.replace(" ", " ")
outpstri = outpstri.replace("\t", " ")
outpstri = outpstri.replace("\r", "")
outpstri = outpstri.replace("\n", "<br /> \n")
fnalstri = ""
for c in outpstri:
d = ord(c)
if ((d != 10) and (d < 32)):
fnalstri += ("[%d]" % (d))
else:
fnalstri += c
return fnalstri
# define a dummy alarm handler
def alarmhan(signanum, framenum):
pass
signal.signal(signal.SIGALRM, alarmhan)
# spawn a new child shell
(shelcpid, shelcdes) = os.forkpty()
if (shelcpid == 0):
os.execve("/bin/bash", [], os.environ)
sys.exit(0)
# init some socket variables for our server
hostname = ""
portnumb = 8080
sockobjc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sockobjc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sockobjc.bind((hostname, portnumb))
sockobjc.listen(5)
sockobjc.setblocking(0)
# set stdin i/o to raw (canon) mode
stdidesc = sys.stdin.fileno()
stdiolds = termios.tcgetattr(stdidesc)
tty.setraw(stdidesc)
# become a man-in-the-middle : user <-> us <-> shell -> us -> viewer
timeouta = 0.05
socklist = []
while (1):
signal.setitimer(signal.ITIMER_REAL, timeouta)
try:
c = sys.stdin.read(1)
if (ord(c) == 4):
break
if (ord(c) == 13):
c = chr(10)
os.write(shelcdes, c)
except:
pass
signal.alarm(0)
try:
(clieconn, clieaddr) = sockobjc.accept()
clieconn.send("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n")
clieconn.send("<script>function stob() { window.scrollTo(0, document.body.scrollHeight); } setInterval('stob();', 250);</script> \n")
for x in range(0, 64):
clieconn.send(" <br /> \n ")
socklist.append(clieconn)
except:
pass
signal.setitimer(signal.ITIMER_REAL, timeouta)
try:
r = os.read(shelcdes, 1024)
sys.stdout.write(r)
sys.stdout.flush()
l = []
s = cleanstr(r)
for sockitem in socklist:
try:
sockitem.send(s)
except:
l.append(sockitem)
for i in l:
socklist.remove(i)
except:
pass
signal.alarm(0)
termios.tcsetattr(stdidesc, termios.TCSADRAIN, stdiolds)
print("")