
    =*fq,                         S r  SSKrSSKJr   " S S\R                  5      r " S S	5      rS
 r	g! \ a	    SSKJr   N7f = f)a  A class supporting chat-style (command/response) protocols.

This class adds support for 'chat' style protocols - where one side
sends a 'command', and the other sends a response (examples would be
the common internet protocols - smtp, nntp, ftp, etc..).

The handle_read() method looks at the input stream for the current
'terminator' (usually '\r\n' for single-line responses, '\r\n.\r\n'
for multi-line output), calling self.found_terminator() on its
receipt.

for example:
Say you build an async nntp client using this class.  At the start
of the connection, you'll have self.terminator set to '\r\n', in
order to process the single-line greeting.  Just before issuing a
'LIST' command you'll set it to '\r\n.\r\n'.  The output of the LIST
command will be accumulated (using your own 'collect_incoming_data'
method) up to the terminator, and then control will be returned to
you - by calling your self.found_terminator() method.
    N   )asyncore)dequec                       \ rS rSrSrSrSrSrSrSS jr	S r
S	 rS
 rS rS rS rS rS rS rS rS rS rS rS rS rS rSrg)
async_chat7   zThis is an abstract class.  You must derive from this class, and add
the two methods collect_incoming_data() and found_terminator()i   r   zlatin-1Nc                 ~    SU l         / U l        [        5       U l        [        R
                  R                  XU5        g N    )ac_in_bufferincomingr   producer_fifor   
dispatcher__init__)selfsockmaps      :/usr/lib/python3/dist-packages/fail2ban/compat/asynchat.pyr   async_chat.__init__F   s5    
  #W$$T5r   c                     [        S5      eNzmust be implemented in subclassNotImplementedErrorr   datas     r   collect_incoming_data async_chat.collect_incoming_dataT       !"CDDr   c                 :    U R                   R                  U5        g N)r   appendr   s     r   _collect_incoming_data!async_chat._collect_incoming_dataW   s    T"r   c                 Z    SR                  U R                  5      nU R                  S S 2	 U$ r
   )joinr   )r   ds     r   	_get_dataasync_chat._get_dataZ   s%    HHT]]#MM!r   c                     [        S5      er   r   r   s    r   found_terminatorasync_chat.found_terminator_   r   r   c                     [        U[        5      (       a'  U R                  (       a  [        XR                  5      nO&[        U[
        5      (       a  US:  a  [        S5      eXl        g)zTSet the input delimiter.

Can be a fixed string of any length, an integer, or None.
r   z-the number of received bytes must be positiveN)
isinstancestruse_encodingbytesencodingint
ValueError
terminator)r   terms     r   set_terminatorasync_chat.set_terminatorb   sK    
 dC  T%6%6}}-Dc""taxLMMr   c                     U R                   $ r    )r5   r*   s    r   get_terminatorasync_chat.get_terminatorm   s    r   c                 D    U R                  U R                  5      n[        U[        5      (       a+  U R                  (       a  [        [        U R                  5      nU R                  U-   U l
        U R                  (       Ga  [        U R                  5      nU R                  5       nU(       d$  U R                  U R                  5        SU l
        GO[        U[        5      (       a  UnX$:  a8  U R                  U R                  5        SU l
        U R                  U-
  U l        GO:U R                  U R                  S U 5        U R                  US  U l
        SU l        U R!                  5         O[        U5      nU R                  R#                  U5      nUS:w  aK  US:  a  U R                  U R                  S U 5        U R                  Xe-   S  U l
        U R!                  5         Oy[%        U R                  U5      nU(       a:  Xb:w  a4  U R                  U R                  S U*  5        U R                  U* S  U l
        g U R                  U R                  5        SU l
        U R                  (       a  GM  g g ! [         a     g [         a    U R	                  5          g f = f)Nr   r   )recvac_in_buffer_sizeBlockingIOErrorOSErrorhandle_errorr.   r/   r0   r1   r2   r   lenr:   r   r3   r5   r+   findfind_prefix_at_end)r   r   lbr5   nterminator_lenindexs          r   handle_readasync_chat.handle_readu   sD   	99T334D dC  T%6%6dmm,D --4 T&&'B,,.J**4+<+<=$'!J,,6..t/@/@A(+D%&*oo&:DO..t/@/@!/DE(,(9(9!"(=D%&'DO))+ "%Z))..z:B;qy 2243D3DVe3LM(,(9(9%:N:O(PD% ))+ /t/@/@*ME ; 66t7H7H5&7QR040A0A5&'0JD- 2243D3DE,/)g   	 		s   I7 7
JJJc                 $    U R                  5         g r    )initiate_sendr*   s    r   handle_writeasync_chat.handle_write   s    r   c                 $    U R                  5         g r    )closer*   s    r   handle_closeasync_chat.handle_close   s    

r   c                 t   [        U[        [        [        45      (       d  [	        S[        U5      5      eU R                  n[        U5      U:  a=  [        S[        U5      U5       H"  nU R                  R                  XX2-    5        M$     OU R                  R                  U5        U R                  5         g )Nz#data argument must be byte-ish (%r)r   )r.   r1   	bytearray
memoryview	TypeErrortypeac_out_buffer_sizerC   ranger   r!   rM   )r   r   sabsis       r   pushasync_chat.push   s    $	: >??A J( (&&t9t1c$i.""))$.9 / %%d+r   c                 Z    U R                   R                  U5        U R                  5         g r    )r   r!   rM   )r   producers     r   push_with_producerasync_chat.push_with_producer   s"    !!(+r   c                     g)z4predicate for inclusion in the readable for select()r    r*   s    r   readableasync_chat.readable   s     r   c                 J    U R                   =(       d    U R                  (       + $ )z4predicate for inclusion in the writable for select())r   	connectedr*   s    r   writableasync_chat.writable   s    !!9$..&89r   c                 :    U R                   R                  S5        g)zAautomatically close this channel once the outgoing queue is emptyN)r   r!   r*   s    r   close_when_doneasync_chat.close_when_done   s    !!$'r   c                    U R                   (       a  U R                  (       a  U R                   S   nU(       d!  U R                   S	 Uc  U R                  5         g U R                  n US U n[        U[        5      (       a&  U R                  (       a  [        X0R                  5      n U R                  U5      nU(       a=  U[        U5      :  d  U[        U5      :  a  XS  U R                   S'   g U R                   S	 g g g ! [         aE    UR                  5       nU(       a  U R                   R                  U5        OU R                   S	  GMM  f = f! [         a    U R                  5          g f = f)Nr   )r   rh   rR   rY   rW   more
appendleftr.   r/   r0   r1   r2   sendrA   rB   rC   )r   firstobsr   num_sents        r   rM   async_chat.initiate_send   sO     T^^&&q)E&&q)=%%' ))CTc{ $$$):):T==199T?
 c$i'3U+;,1),<D&&q)  **1-K &4   zz|&&11$7**1-  !!#s%   'D  (E  A
EEE/.E/c                 d    SU l         U R                  S S 2	 U R                  R                  5         g r
   )r   r   r   clearr*   s    r   discard_buffersasync_chat.discard_buffers  s(    MM!  "r   )r   r   r   r5   )NN)__name__
__module____qualname____firstlineno____doc__r?   rY   r0   r2   r   r   r"   r'   r+   r7   r:   rJ   rN   rR   r]   ra   re   ri   rl   rM   rx   __static_attributes__rd   r   r   r   r   7   s|    F
 
 LH6E#
E	F0P
:(&P#r   r   c                   $    \ rS rSrSS jrS rSrg)simple_produceri  c                     Xl         X l        g r    )r   buffer_size)r   r   r   s      r   r   simple_producer.__init__  s    	&r   c                     [        U R                  5      U R                  :  a9  U R                  S U R                   nU R                  U R                  S  U l        U$ U R                  nSU l        U$ r
   )rC   r   r   )r   results     r   ro   simple_producer.more  sb    tyy>D,,,YY0 0 01F		$"2"2"34DIMYYFDIMr   )r   r   N)i   )rz   r{   r|   r}   r   ro   r   rd   r   r   r   r     s    'r   r   c                     [        U5      S-
  nU(       a@  U R                  US U 5      (       d'  US-  nU(       a  U R                  US U 5      (       d  M'  U$ )Nr   )rC   endswith)haystackneedlels      r   rE   rE   2  sQ    FaA
H%%fRaj11	Q H%%fRaj11Hr   )
r~   r   ImportError collectionsr   r   r   r   rE   rd   r   r   <module>r      sQ   8( X#$$ X#v @A  s   1 A A 