
    ]2                     j   d Z ddlmZ ddlZddlZddlZddlZddlZddlm	Z	m
Z
mZ ddlmZ ddlmZ ddlmZ ddlmZmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z) ddlm*Z* ddl+m,Z, dZ-d Z. G d de/      Z0 G d de/      Z1 G d de      Z2 G d de/      Z3y)aT  
Telnet server.

Example usage::

    class MyTelnetApplication(TelnetApplication):
        def client_connected(self, telnet_connection):
            # Set CLI with simple prompt.
            telnet_connection.set_application(
                telnet_connection.create_prompt_application(...))

        def handle_command(self, telnet_connection, document):
            # When the client enters a command, just reply.
            telnet_connection.send('You said: %r

' % document.text)

        ...

    a = MyTelnetApplication()
    TelnetServer(application=a, host='127.0.0.1', port=23).run()
    )unicode_literalsN)int2byte	text_typebinary_type)getincrementaldecoder)DEFAULT_BUFFER)	EventLoop)CommandLineInterfaceApplication)Size)create_prompt_application)InputStream)Vt100_Output   )logger)
IACDOLINEMODESBMODESEWILLECHONAWSSUPPRESS_GO_AHEAD)TelnetProtocolParser)TelnetApplication)TelnetServerc                    t        j                  d       | j                  t        t        z   t
        z          | j                  t        t        z   t        z          | j                  t        t        z   t
        z   t        z   t        d      z   t        z   t        z          | j                  t        t        z   t        z          | j                  t        t        z   t        z          y )NzInitializing telnet connectionr   )r   infosendr   r   r   r   r   r   r   r   r   r   r   )
connections    7lib/third_party/prompt_toolkit/contrib/telnet/server.py_initialize_telnetr$   3   s    
KK01 OOC"Hx'( OOC$J!223 OOC"Hx'$.!<sBRGH OOC$J%& OOC"HtO$    c                   "    e Zd ZdZd Zd Zd Zy)_ConnectionStdoutzk
    Wrapper around socket which provides `write` and `flush` methods for the
    Vt100_Output output.
    c                 .    || _         || _        g | _        y N)	_encoding_connection_buffer)selfr"   encodings      r#   __init__z_ConnectionStdout.__init__L   s    !%r%   c                     t        |t              sJ | j                  j                  |j	                  | j
                               | j                          y r)   )
isinstancer   r,   appendencoder*   flushr-   datas     r#   writez_ConnectionStdout.writeQ   s:    $	***DKK78

r%   c                     	 | j                   j                  dj                  | j                               g | _        y # t        j
                  $ r)}t        j
                  d|z         Y d }~g | _        y d }~ww xY w)Nr%   z"Couldn't send data over socket: %s)r+   r!   joinr,   socketerrorr   )r-   es     r#   r4   z_ConnectionStdout.flushV   sf    	C!!#((4<<"89  || 	CLL=ABB	Cs   4> A:A55A:N)__name__
__module____qualname____doc__r/   r7   r4    r%   r#   r'   r'   G   s    

r%   r'   c                   <    e Zd ZdZd Zd
dZd Zd Zd Zd Z	d	 Z
y)TelnetConnectionz6
    Class that represents one Telnet connection.
    c                 ^    t        |t              sJ t        |t              sJ t        |t              sJ t        |t              sJ | _        | _        | _        d _        d _	        | _
        | _        d  _        t        dd       _        t        |        fd}t!        ||       _        t%         j"                  |d       _        t)        |       _         j-                  t/                      |j1                          d _	         j2                  j5                          y )	NFT(   O   rowscolumnsc                       j                   S r)   )sizer-   s   r#   get_sizez+TelnetConnection.__init__.<locals>.get_sizey   s    99r%   r.   )write_binary)r1   tupler   r   r   connaddrapplicationclosedhandling_commandserverr.   callbackr   rK   r$   r'   stdoutr   vt100_output_TelnetEventLoopInterface	eventloopset_applicationr   client_connectedcli_redraw)r-   rQ   rR   rS   rV   r.   rM   s   `      r#   r/   zTelnetConnection.__init__c   s   $&&&+'8999&,///(I...		& $  b"-	 	4 	'x@(hUS 36: 	689 	$$T* !&r%   Nc                     t        |t              sJ |t        |      sJ t        | j                   j
                         _        | _         j                  j                         t        j                        t         j                                gd j                  _        fd} fd}t        ||       _        y)z
        Set ``CommandLineInterface`` instance for this connection.
        (This can be replaced any time.)

        :param cli: CommandLineInterface instance.
        :param callback: Callable that takes the result of the CLI.
        N)rS   r[   outputTc                     t        | t              sJ 	 d   j                  |       }j                  |       y# t        $ r         d<   Y yw xY w)z/ TelnetProtocolParser 'data_received' callback r    N)r1   r   decodefeedUnicodeDecodeError)r6   resultinputstreamstdin_decoderstdin_decoder_clss     r#   data_receivedz7TelnetConnection.set_application.<locals>.data_received   sZ    dK000&q)006  (% #4#6a s   %; AAc                 J    t        | |      _        j                          y)z/ TelnetProtocolParser 'size_received' callback rG   N)r   rK   terminal_size_changed)rH   rI   cbr-   s     r#   size_receivedz7TelnetConnection.set_application.<locals>.size_received   s    $8DI$$&r%   )r1   r   callabler
   r[   rY   r^   rW   create_eventloop_callbacksr   feed_keyr   r.   _is_runningr   parser)	r-   apprW   rk   ro   rn   rh   ri   rj   s	   `    @@@@r#   r\   z TelnetConnection.set_application   s     #{+++8H#555'nn$$& ! XX002!"++. 2$--@*,-  $			'
 +=-Hr%   c                    t        |t              sJ | j                  j                  |       | j                  j                          | j                  j                  r-	 | j                  j                         }| j                  |       yy# t        t        f$ rC}t        j                  dt        |      j                         | j                          Y d}~yd}~ww xY w)zF
        Handler for incoming data. (Called by TelnetServer.)
        z%s, closing connection.N)r1   r   rt   re   r^   r_   is_returningreturn_valueEOFErrorKeyboardInterruptr   r    typer=   close_handle_command)r-   r6   rx   r<   s       r#   re   zTelnetConnection.feed   s     $,,, 	 88  #xx446   . ! /0 5tAw7G7GH

	s   B C9CCc                      t        j                  d        fd} fd j                  j                  |       y)zs
        Handle command. This will run in a separate thread, in order not
        to block the event loop.
        zHandle command %rc                      d_         	 j                  j                          j                  j                         y # j                  j                         w xY w)NT)rU   rW   rV   call_from_executor)commanddoner-   s   r#   in_executorz5TelnetConnection._handle_command.<locals>.in_executor   sM    $(D!5==,MM$0..t4..t4s   A A!c                  h   d _          j                  s j                  j                           j                  j                  t
           j                           j                  j                  j                           j                  j                           j                  j                          y y )NF)rU   rT   r^   resetbuffersr   renderer request_absolute_cursor_positionrY   r4   r_   rL   s   r#   r   z.TelnetConnection._handle_command.<locals>.done   sz    $)D! ;;   0668!!BBD!!'')  " r%   N)r   r    rV   run_in_executor)r-   r   r   r   s   `` @r#   r}   z TelnetConnection._handle_command   s2    
 	'1	5
	# 	##K0r%   c                     | j                   j                          | j                   j                  dd       | j                   j                          y)z&
        Erase output screen.
        r   N)rY   erase_screencursor_gotor4   rL   s    r#   r   zTelnetConnection.erase_screen   s>     	&&(%%a+!r%   c                     t        |t              sJ | j                  j                  |j	                  dd             | j                  j                          y)z*
        Send text to the client.
        
z
N)r1   r   rX   r7   replacer4   r5   s     r#   r!   zTelnetConnection.send   sC     $	***
 	$,,tV45r%   c                 |    | j                   j                  |        | j                  j                          d| _        y)z'
        Close the connection.
        TN)rS   client_leavingrQ   r|   rT   rL   s    r#   r|   zTelnetConnection.close  s-     	''-		r%   r)   )r=   r>   r?   r@   r/   r\   re   r}   r   r!   r|   rA   r%   r#   rC   rC   _   s-    &P.I`/01:"
r%   rC   c                   <    e Zd ZdZd Zd Zd Zd Zd
dZd Z	d	 Z
y)rZ   zD
    Eventloop object to be assigned to `CommandLineInterface`.
    c                     || _         y r)   )_server)r-   rV   s     r#   r/   z"_TelnetEventLoopInterface.__init__  s	    r%   c                      yz	 Ignore. NrA   rL   s    r#   r|   z_TelnetEventLoopInterface.close      r%   c                      yr   rA   rL   s    r#   stopz_TelnetEventLoopInterface.stop  r   r%   c                 :    | j                   j                  |       y r)   )r   r   r-   rW   s     r#   r   z)_TelnetEventLoopInterface.run_in_executor  s    $$X.r%   Nc                 :    | j                   j                  |       y r)   )r   r   )r-   rW   _max_postpone_untils      r#   r   z,_TelnetEventLoopInterface.call_from_executor  s    ''1r%   c                     t         r)   NotImplementedError)r-   fdrW   s      r#   
add_readerz$_TelnetEventLoopInterface.add_reader!      !!r%   c                     t         r)   r   )r-   r   s     r#   remove_readerz'_TelnetEventLoopInterface.remove_reader$  r   r%   r)   )r=   r>   r?   r@   r/   r|   r   r   r   r   r   rA   r%   r#   rZ   rZ     s*    /2""r%   rZ   c                   L    e Zd ZdZddZed        Zd Zd Zd Z	d Z
d	 Zd
 Zy)r   z'
    Telnet server implementation.
    Nc                    t        |t              sJ t        |t              sJ t        |t              sJ t        |t              sJ || _        || _        || _        || _        t               | _	        g | _
        t        j                         | _        t        j                  | j                  d   t        j                  t        j                          y )Nr   )r1   r   intr   hostportrS   r.   setconnections_calls_from_executorospipe_schedule_pipefcntlF_SETFL
O_NONBLOCK)r-   r   r   rS   r.   s        r#   r/   zTelnetServer.__init__,  s    $	***$$$$+'8999(I...		& 5$&! !ggiD''*EMM2==Ir%   c                    t        j                   t         j                  t         j                        }|j                  t         j                  t         j
                  d       |j                  ||f       |j                  d       |S )Nr      )r:   AF_INETSOCK_STREAM
setsockopt
SOL_SOCKETSO_REUSEADDRbindlisten)clsr   r   ss       r#   create_socketzTelnetServer.create_socket?  sZ     MM&..&*<*<=	V&&(;(;Q?	d|	r%   c                 L    t        j                  |      j                          y )N)target)	threadingThreadstartr   s     r#   r   zTelnetServer.run_in_executorI  s    )//1r%   c                     | j                   j                  |       | j                  r$t        j                  | j                  d   d       y y )Nr      x)r   r2   r   r   r7   r   s     r#   r   zTelnetServer.call_from_executorL  s=    !!((2HHT((+T2 r%   c                     t        j                  | j                  d   d       | j                  g c}| _        |D ]	  } |         y)zK
        Process callbacks from `call_from_executor` in eventloop.
        r      N)r   readr   r   )r-   calls_from_executorcs      r#   _process_callbackszTelnetServer._process_callbacksR  sE    
 	##A&- :>9R9RTV6T6$AC %r%   c                    | j                  | j                  | j                        }t        j                  d| j                  | j                         	 	 t        | j                  D cg c]  }|j                  r| c}      | _        t        | j                  D cg c]  }|j                  r| c}      }|| j                  d   g|D cg c]  }|j                   c}z   }t        j                  |g g       \  }}}|D ]M  }||k(  r| j                  |       || j                  d   k(  r| j                          =| j                  |       O c c}w c c}w c c}w # |j                          w xY w)z:
        Run the eventloop for the telnet server.
        z.Listening for telnet connections on %s port %rr   )r   r   r   r   r    r   r   rT   rU   r   rQ   select_acceptr   _handle_incoming_datar|   )r-   listen_socketr   r   	read_listr   _r   s           r#   runzTelnetServer.run^  sX    **499dii@DdiiQUQZQZ[	"#&43C3C'T3Ca1883C'T#U  "d.>.>"Y.>aFXFX1.>"YZ #D$7$7$:;%01[QVV[12  $]]9b"=
aAM)]3 d11!44//1 2215  'T #Z
 2$ !s=   E" 'E9E=E" E.E2E" E BE" "E4c                     |j                         \  }}t        ||| j                  | | j                        }| j                  j                  |       t        j                  dg|  y)z1
        Accept new incoming connection.
        rN   zNew connection %r %rN)acceptrC   rS   r.   r   addr   r    )r-   r   rQ   rR   r"   s        r#   r   zTelnetServer._accept  s[     #))+
d%dD$2B2BDSWS`S`a
Z(*2T2r%   c                     | j                   D cg c]  }|j                  |k(  s| c}d   }|j                  d      }|r|j                  |       y| j                   j	                  |       yc c}w )z1
        Handle incoming data on socket.
        r   r   N)r   rQ   recvre   remove)r-   rQ   r   r"   r6   s        r#   r   z"TelnetServer._handle_incoming_data  se     "&!1!1D!1AQVVt^a!1DQG
yyOOD!##J/ Es
   A/A/)z	127.0.0.1   Nzutf-8)r=   r>   r?   r@   r/   classmethodr   r   r   r   r   r   r   rA   r%   r#   r   r   (  s@    J&  23
$"L3	0r%   r   )4r@   
__future__r   r:   r   r   r   r   sixr   r   r   codecsr   prompt_toolkit.enumsr   prompt_toolkit.eventloop.baser	   prompt_toolkit.interfacer
   r   prompt_toolkit.layout.screenr   prompt_toolkit.shortcutsr   #prompt_toolkit.terminal.vt100_inputr   $prompt_toolkit.terminal.vt100_outputr   logr   protocolr   r   r   r   r   r   r   r   r   r   r   rS   r   __all__r$   objectr'   rC   rZ   r   rA   r%   r#   <module>r      s   ( (    	  0 0 ( / 3 F - > ; =  Z Z Z * *
%( 0lv l^"	 "4o06 o0r%   