from __future__ import print_function
from pdb import Pdb
import socket
import logging
import sys
import errno


def cry(message, stderr=sys.__stderr__):
    logging.critical(message)
    print(message, file=stderr)


class RemotePdb(Pdb):
    """
    This will run pdb as a ephemeral telnet service. Once you connect no one
    else can connect. On construction this object will block execution till a
    client has connected.

    Based on https://github.com/tamentis/rpdb I think ...

    To use this::

        RemotePdb(4444).set_trace()

    Then run: telnet 127.0.0.1 4444
    """
    def __init__(self, host, port, patch_stdstreams=False):
        listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        listen_socket.bind((host, port))
        if not port:
            cry("RemotePdb session open at %s:%s, waiting for connection ..." % listen_socket.getsockname())
            sys.stderr.flush()
        listen_socket.listen(1)
        connection, address = listen_socket.accept()
        cry("RemotePdb accepted connection from %s." % repr(address))
        self.handle = connection.makefile('rwU')
        Pdb.__init__(self, completekey='tab', stdin=self.handle, stdout=self.handle)
        self.backup = []
        if patch_stdstreams:
            for name in (
                'stderr',
                'stdout',
                '__stderr__',
                '__stdout__',
                'stdin',
                '__stdin__',
            ):
                self.backup.append((name, getattr(sys, name)))
                setattr(sys, name, self.handle)

    def __restore(self):
        cry('Restoring streams: %s ...' % self.backup)
        for name, fh in self.backup:
            setattr(sys, name, fh)
        self.handle.close()

    #def do_continue(self, arg):
    #    self._close_session()
    #    self.set_continue()
    #    return 1
    #do_c = do_cont = do_continue

    def do_quit(self, arg):
        self.__restore()
        self.set_quit()
        return 1
    do_q = do_exit = do_quit

    def set_trace(self, frame=None):
        if frame is None:
            frame = sys._getframe(1).f_back
        try:
            Pdb.set_trace(self, frame)
        except IOError as exc:
            if exc.errno != errno.ECONNRESET:
                raise

    def set_quit(self):
        sys.settrace(None)

def set_trace(host='127.0.0.1', port=0):
    """
    Opens a remote PDB on first available port.
    """
    rdb = RemotePdb(host, port)
    rdb.set_trace()

@@ -35,35 +35,44 @@
 ion%0A
-from pdb import Pdb
+%0Aimport errno%0Aimport logging
 %0Aimport 
 sock
@@ -71,22 +71,18 @@
 ort 
-socket
+re
 %0Aimport 
 logg
@@ -69,39 +69,38 @@
 mport re%0Aimport 
-logging
+socket
 %0Aimport sys%0Aimpo
@@ -95,28 +95,35 @@
 ort sys%0A
+from pdb 
 import 
-errno
+Pdb
 %0A%0A%0Adef c
@@ -222,16 +222,606 @@
 derr)%0A%0A%0A
+class LF2CRLF_FileWrapper(object):%0A    def __init__(self, fh):%0A        self.fh = fh%0A        self.read = fh.read%0A        self.readline = fh.readline%0A        self.readlines = fh.readlines%0A        self.close = fh.close%0A        self.flush = fh.flush%0A        self.fileno = fh.fileno%0A%0A    def __iter__(self):%0A        return self.fh.__iter__()%0A%0A    def write(self, data, nl_rex=re.compile(%22%5Cr?%5Cn%22)):%0A        return self.fh.write(nl_rex.sub(%22%5Cr%5Cn%22, data))%0A%0A    def writelines(self, lines, nl_rex=re.compile(%22%5Cr?%5Cn%22)):%0A        return self.fh.writelines(nl_rex.sub(%22%5Cr%5Cn%22, line) for line in lines)%0A%0A%0A
 class Re
@@ -1775,16 +1775,36 @@
 andle = 
+LF2CRLF_FileWrapper(
 connecti
@@ -1819,13 +1819,18 @@
 ile(
-'rwU'
+bufsize=0)
 )%0A  

Convert LF to CRLF (should fix windows telnet client).