import sys
from code import InteractiveConsole
from eventlet import greenlib

try:
    sys.ps1
except AttributeError:
    sys.ps1 = '>>> '
try:
    sys.ps2
except AttributeError:
    sys.ps2 = '... '

class SocketConsole(greenlib.GreenletContext):
    def __init__(self, desc):
        # mangle the socket
        self.desc = desc
        readline = desc.readline
        self.old = {}
        self.fixups = {
            'softspace': 0,
            'isatty': lambda: True,
            'flush': lambda: None,
            'readline': lambda *a: readline(*a).replace('\r\n', '\n'),
        }
        for key, value in self.fixups.iteritems():
            if hasattr(desc, key):
                self.old[key] = getattr(desc, key)
            setattr(desc, key, value)

    def finalize(self):
        # restore the state of the socket
        for key in self.fixups:
            try:
                value = self.old[key]
            except KeyError:
                delattr(self.desc, key)
            else:
                setattr(self.desc, key, value)
        self.fixups.clear()
        self.old.clear()
        self.desc = None

    def swap_in(self):
        self.saved = sys.stdin, sys.stderr, sys.stdout
        sys.stdin = sys.stdout = sys.stderr = self.desc

    def swap_out(self):
        sys.stdin, sys.stderr, sys.stdout = self.saved

def backdoor((conn, addr), locals=None):
    host, port = addr
    print "backdoor to %s:%s" % (host, port)
    ctx = SocketConsole(conn)
    ctx.register()
    try:
        console = InteractiveConsole(locals)
        console.interact()
    finally:
        ctx.unregister()
