
    RSiF                         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 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 d d	lmZ d d
lmZ d dlmZ ddgZ G d de          Z G d de          ZdS )    N)_FileReadWriteError)_GiveUpOnSendfile)_RetryError)_ERRNOS_DISCONNECTED)_ERRNOS_RETRY)	AsyncChat)timer)debug)logger)strerror
DTPHandlerThrottledDTPHandlerc                       e Zd ZdZdZdZdZd Zd ZeZ	d Z
d Zd Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd ZeZd Zd Zd Zd Zd Zd ZdS )r   a*  Class handling server-data-transfer-process (server-DTP, see
    RFC-959) managing data-transfer operations involving sending
    and receiving data.

    Class attributes:

     - (int) timeout: the timeout which roughly is the maximum time we
       permit data transfers to stall for with no progress. If the
       timeout triggers, the remote client will be kicked off
       (defaults 300).

     - (int) ac_in_buffer_size: incoming data buffer size (defaults 65536)

     - (int) ac_out_buffer_size: outgoing data buffer size (defaults 65536)
    i,  i   c                 (   || _         d| _        d| _        d| _        d| _        d| _        d| _        |j        | _        |j        | _        d| _	        d| _
        d| _        t                      | _        d| _        d| _        d| _        d| _        d| _        	 t'          j        | ||j                   n# t,          $ r{}t'          j        | t/          j                    |j                   |                                  |j        t2          j        k    rY d}~dS |                                  Y d}~dS d}~ww xY w| j        s|                                  dS | j        r3| j                            | j        | j        | j                  | _        dS dS )zInitialize the command channel.

        - (instance) sock: the socket object instance of the newly
           established connection.
        - (instance) cmd_channel: the command channel class instance.
        NFr    )ioloop_errback) cmd_channelfile_objreceivetransfer_finishedtot_bytes_senttot_bytes_receivedcmdloglog_exception_data_wrapper	_lastdata_had_crr	   _start_time_resp_offset_filefd_idler_initializedr   __init__r   OSErrorsocketcloseerrnoEINVALhandle_error	connectedtimeout
call_everyhandle_timeout)selfsockr   errs       O/home/jrussi/.local/lib/python3.11/site-packages/pyftpdlib/handlers/ftp/data.pyr'   zDTPHandler.__init__/   s    '!&"#?(6! 77
!	tT+2DEEEEE 	 	 	 fmook.@    JJLLLyEL((FFFFF	 ~ 	JJLLLF< 	+00d1D<M 1  DKKK	 	s   B3 3
D8=AD3D33D8c                 Z    d| j         j        d| j                            d          dS )N<(T)as_strz)>)	__class____name__r   get_repr_infor2   s    r5   __repr__zDTPHandler.__repr__a   s9     N###**$*7777
 	
    c                     | j         j        sdS | j        t          | j        d          sdS 	 | j                                         n# t
          t          f$ r Y dS w xY w| j         j        dk    rdS dS )NFfilenoiT)r   use_sendfiler   hasattrrA   r(   
ValueError_current_typer=   s    r5   rC   zDTPHandler.use_sendfilei   s    , 	5= x(H(H 5	
 M  """"$ 	 	 	55	)S005ts   A AAc                     d| _         |                     | j        j                   | j        j        | _        t          j        | |           d S )NT)r&   modify_ioloop_eventsr   WRITE_wanted_io_eventsr   push)r2   datas     r5   rK   zDTPHandler.push}   sH     !!$+"3444!%!2tT"""""r?   c                    d| _         |                     | j        j                   | j        j        | _        |                                 ro|j                                        | _        | j	        
                                | _        	 |                                  | j        | _        d S # t          $ r Y nw xY wt          d|            t!          j        | |           d S )NTzstarting transfer using send())r&   rH   r   rI   rJ   rC   filetellr#   r   rA   r$   initiate_sendfileinitiate_sendr   r
   r   push_with_producer)r2   producers     r5   rR   zDTPHandler.push_with_producer   s     !!$+"3444!%!2 		#=--//DL=//11DL&&((( &*%;"	 %   
 	.555$T844444s   	B+ +
B87B8c                 D    t           j                            |            d S N)asynchat
async_chatclose_when_doner=   s    r5   rX   zDTPHandler.close_when_done   s    ++D11111r?   c                 D    t           j                            |            d S rU   )rV   rW   rQ   r=   s    r5   rQ   zDTPHandler.initiate_send   s    ))$/////r?   c                    	 t          j        | j        | j        | j        | j                  }|dk    r*|                                  |                                  dS | xj        |z  c_        | xj        |z  c_        dS # t          $ r}|j
        t          v s|j
        t          j        k    rY d}~dS |j
        t          v r|                                  n(| j        dk    rt          j        d           t           | Y d}~dS d}~ww xY w)zA wrapper around sendfile.r   Nz3sendfile() failed; falling back on using plain send)ossendfile_filenor$   r#   ac_out_buffer_sizediscard_buffershandle_closer   r(   r+   r   EBUSYr   r   warningr   )r2   sentr4   s      r5   rP   zDTPHandler.initiate_sendfile   s>   	,;'	 D& qyy$$&&&!!#####$##t+####'  	 	 	yM))SY%+-E-E222!!####$))I   (S0 $#####		s   +A? ?
D	#D2ADDc                     | j         rd|z   }|                    d          rd| _         |dd         }nd| _         |                    dt          t          j        d                    S )zThe data wrapper used for receiving data in ASCII mode on
        systems using a single line terminator, handling those cases
        where CRLF ('
') gets delivered in two chunks.
           TNFs   
ascii)r    endswithreplacebytesr[   linesep)r2   chunks     r5   _posix_ascii_data_wrapperz$DTPHandler._posix_ascii_data_wrapper   sh    
 < 	"EME>>%   	!DL#2#JEE DL}}WeBJ&@&@AAAr?   c                     d| _         |                     | j        j                   | j        j        | _        || _        |dk    r%t          j        dk    rd| _        n*| j	        | _        n|dk    rd| _        nt          d          d| _        dS )zEnable receiving of data over the channel. Depending on the
        TYPE currently in use it creates an appropriate wrapper for the
        incoming data.

         - (str) type: current transfer type, 'a' (ASCII) or 'i' (binary).
        Taz
NrB   zunsupported type)r&   rH   r   READrJ   r   r[   rk   r   rm   	TypeErrorr   )r2   typer   s      r5   enable_receivingzDTPHandler.enable_receiving   s     !!!$+"2333!%!13;;zV##%)""%)%C""S[[!%D.///r?   c                      | j         | j        z   S )z'Return the number of transmitted bytes.)r   r   r=   s    r5   get_transmitted_bytesz DTPHandler.get_transmitted_bytes   s    "T%<<<r?   c                 .    t                      | j        z
  S )z,Return the transfer elapsed time in seconds.)r	   r!   r=   s    r5   get_elapsed_timezDTPHandler.get_elapsed_time   s    ww)))r?   c                 2    |                                  dk    S )z5Return True if a transfer is in progress, else False.r   )ru   r=   s    r5   transfer_in_progresszDTPHandler.transfer_in_progress   s    ))++q00r?   c                 P    t          j        | |          }| xj        |z  c_        |S rU   )r   sendr   )r2   rL   results      r5   r{   zDTPHandler.send   s,    d++v%r?   c                    	 t          | j                  r| j                                        }|6| j        s-| j                                         |                                  dS t          |t                    r+| j                                         | xj        |z  c_        dS |                                }|r| xj        |z  c_        dS | j                                         ndS )zOverridden as a fix around https://bugs.python.org/issue1740572
        (when the producer is consumed, close() was called instead of
        handle_close()).
        TN)	lenproducer_fifofirstac_out_bufferpopr`   
isinstancestrmore)r2   prL   s      r5   refill_bufferzDTPHandler.refill_buffer   s    
	4%&& &,,.. 9- ,*..000))+++F3'' &**,,,&&!+&&Fvvxx -&&$.&&F&**,,,,-	r?   c                    	 |                      | j                  }| xj        t          |          z  c_        |s	d| _        dS | j        |                     |          }	 | j                            |           dS # t          $ r}t          |          |d}~ww xY w# t          $ r Y dS t          $ r |                                  Y dS w xY w)z-Called when there is data waiting to be read.TN)recvac_in_buffer_sizer   r~   r   r   r   writer(   r   r   r-   )r2   rl   r4   s      r5   handle_readzDTPHandler.handle_read  s	   	8IId455E ##s5zz1## )-&!-**5118##E***** 8 8 8)#..C78  	 	 	DD 	  	  	 	 s/   B !A= =
BBB
C,CCc                 T    | j         s| j        s|                                 S | j         S )z5Predicate for inclusion in the readable for select().)r   r&   r*   r=   s    r5   readablezDTPHandler.readable'  s.     | 	 D$5 	 ::<<|r?   c                 P    | j          ot          j                            |           S )z5Predicate for inclusion in the writable for select().)r   rV   rW   writabler=   s    r5   r   zDTPHandler.writable4  s#    <FH$7$@$@$F$FFr?   c                     |                                  | j        k    r|                                  | _        dS d}d|z   t          j        f| _        |                                  | j                                         dS )zCalled cyclically to check if data transfer is stalling with
        no progress in which case the client is kicked off.
        zData connection timed out.z421 N)ru   r   r   infor"   r*   r   rX   )r2   msgs     r5   r1   zDTPHandler.handle_timeout8  ss     %%''$.88!7799DNNN.C 3,4DJJJLLL,,.....r?   c                 h   	  # t           $ r}t          |j                  }Y d}~n*d}~wt          $ r |                     |            d}Y nw xY w	 d| dt
          j        f| _        |                                  dS # t          $ r) t          j	        t          j                               Y dS w xY w)z=Called when an exception is raised and not otherwise handled.NzInternal errorz426 z; transfer aborted.)r   r   r+   	Exceptionr   r   rb   r"   r*   critical	traceback
format_exc)r2   r4   errors      r5   r-   zDTPHandler.handle_errorD  s    
	% # 	( 	( 	(SY''EEEEEE 	% 	% 	% t$$$$EEE		%
	4;;;;V^LDJJJLLLLL 	4 	4 	4OI022333333	4s*    
A&$AA+A> >/B10B1c                 r   | j         s| j        rd| _        nt          | j                  dk    | _        	 | j        rdt
          j        f| _        n8|                                 }dt          |           dt
          j        f| _        | 
                                 dS # | 
                                 w xY wdS )z!Called when the socket is closed.Tr   z226 Transfer complete.z426 Transfer aborted; z bytes transmitted.N)_closedr   r   r~   r   r   r
   r"   ru   intr*   )r2   	tot_bytess     r5   r`   zDTPHandler.handle_closeW  s     | 	| F)-&&),T-?)@)@A)E&) 
":FL!IDJJ $ : : < <I,S^^ , , , "DJ 



%	 	s   AB B4c           	         t          d|            | j        st          j        |            | j        %| j        j        s| j                                         | j        r2| j                            | j        d         | j        d                    | j	        %| j	        j
        s| j	                                         | j        | j        j        }t          |                                 d          }| j                            | j        | j        j        | j        | j        ||                                            | j        r=| j        r| j                            |           nW| j                            |           n<| j        r| j                            |           n| j                            |           | j                                         dS dS )	zUClose the data channel, first attempting to close any remaining
        file handles.zcall: close())instNr      )logfun   )r   filenamer   	completedelapsedrj   )r
   r   r   r*   r   closedr"   r   respondr%   	cancelledcancelnameroundrw   log_transferr   r   r   ru   on_file_receivedon_file_senton_incomplete_file_receivedon_incomplete_file_sent_on_dtp_close)r2   r   elapsed_times      r5   r*   zDTPHandler.closes  s    	oD))))| !	-OD!!! }(1E(##%%%z N ((Atz!}(MMM{&t{/D&""$$$}(=-$T%:%:%<%<a@@ --!]/ L"4(4466 .    ) G| @(99(CCCC(55h????\ G$@@JJJJ$<<XFFF**,,,,,C!	- !	-r?   N)r;   
__module____qualname____doc__r/   r   r^   r'   r>   __str__rC   rK   rR   rX   rQ   rP   rm   rs   ru   rw   ry   r{   r   r   handle_read_eventr   r   r1   r-   r`   r*   r   r?   r5   r   r      s          G0 0 0d
 
 
 G  (# # #5 5 5"2 2 20 0 0, , ,@B B B   ,= = =* * *1 1 1  
  :8 8 8* $  G G G
/ 
/ 
/4 4 4&  8%- %- %- %- %-r?   c                   d     e Zd ZdZdZdZdZ fdZd Zd Z	 fdZ
 fdZd	 Zd
 Z fdZ xZS )r   a  A DTPHandler subclass which wraps sending and receiving in a data
    counter and temporarily "sleeps" the channel so that you burst to no
    more than x Kb/sec average.

     - (int) read_limit: the maximum number of bytes to read (receive)
       in one second (defaults to 0 == no limit).

     - (int) write_limit: the maximum number of bytes to write (send)
       in one second (defaults to 0 == no limit).

     - (bool) auto_sized_buffers: this option only applies when read
       and/or write limits are specified. When enabled it bumps down
       the data buffer sizes so that they are never greater than read
       and write limits which results in a less bursty and smoother
       throughput (default: True).
    r   Tc                    t                                          ||           d| _        d| _        d| _        d | _        | j        rn| j        r0| j        | j        k    r | xj        dz  c_        | j        | j        k     | j	        r0| j
        | j	        k    r | xj
        dz  c_
        | j
        | j	        k     t          | j                  | _        t          | j
                  | _
        d S )Nr   F   )superr'   	_timenext
_datacountsleeping
_throttlerauto_sized_buffers
read_limitr   write_limitr^   r   )r2   r3   r   r:   s      r5   r'   zThrottledDTPHandler.__init__  s    {+++" 	1 0,t>>**a/** ,t>> 1-0@@@++q0++ -0@@@!$T%;!<!<"%d&=">">r?   c                 6    t                               |           S rU   )r   r>   r=   s    r5   r>   zThrottledDTPHandler.__repr__  s    ""4(((r?   c                     dS )NFr   r=   s    r5   rC   z ThrottledDTPHandler.use_sendfile  s    ur?   c                     t                                          |          }| j        r(|                     t	          |          | j                   |S rU   )r   r   r   _throttle_bandwidthr~   )r2   buffer_sizerl   r:   s      r5   r   zThrottledDTPHandler.recv  sF    [))? 	B$$SZZAAAr?   c                     t                                          |          }| j        r|                     || j                   |S rU   )r   r{   r   r   )r2   rL   num_sentr:   s      r5   r{   zThrottledDTPHandler.send  sB    77<<%% 	A$$Xt/?@@@r?   c                 f    | j         '| j         j        s| j                                          d S d S d S rU   )r   r   r   r=   s    r5   _cancel_throttlerz%ThrottledDTPHandler._cancel_throttler  s<    ?&t/H&O""$$$$$ '&&&r?   c                 N     xj         |z  c_          j         |k    rd _         t                      } j        |z
  dz  }|dk    rT fd}                                                                     j                            || j                   _        |dz    _        dS dS )zkA method which counts data transmitted so that you burst to
        no more than x Kb/sec average.
        r   r   c                  t    j         rj        j        } nj        j        }                     |            d S )N)events)r   r   rp   rI   add_channel)eventr2   s    r5   unsleepz8ThrottledDTPHandler._throttle_bandwidth.<locals>.unsleep  s@    | 2 $ 0 $ 1$$E$22222r?   r   r   N)	r   r	   r   del_channelr   r   
call_laterr-   r   )r2   	len_chunk	max_speednowsleepforr   s   `     r5   r   z'ThrottledDTPHandler._throttle_bandwidth  s     	9$?i''DO''C,1H!||3 3 3 3 3   """&&((("&+"8"8g0A #9 # # !1WDNNN% ('r?   c                 p    |                                   t                                                       d S rU   )r   r   r*   )r2   r:   s    r5   r*   zThrottledDTPHandler.close  s*       r?   )r;   r   r   r   r   r   r   r'   r>   rC   r   r{   r   r   r*   __classcell__)r:   s   @r5   r   r     s         " JK? ? ? ? ? ) ) )          % % %% % %2        r?   )rV   r+   r[   r)   r   pyftpdlib.exceptionsr   r   r   pyftpdlib.ioloopr   r   r   r	   pyftpdlib.logr
   r   pyftpdlib.utilsr   __all__r   r   r   r?   r5   <module>r      sg     				      4 4 4 4 4 4 2 2 2 2 2 2 , , , , , , 1 1 1 1 1 1 * * * * * * & & & & & & " " " " " "                   $ $ $ $ $ $.
/~- ~- ~- ~- ~- ~- ~- ~-BW W W W W* W W W W Wr?   