
    mgj                     @   d Z ddlZddlmZmZm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ZddlZddlmZ ddlmZmZmZmZmZmZmZ ddlmZmZmZmZmZmZ ddlmZmZm Z m!Z!m"Z" dd	l#m$Z$m%Z% d
dl&m'Z'm(Z(m)Z) d
dl*m+Z+m,Z, d
dl-m.Z. d
dl/m0Z0m1Z1m2Z2m3Z3m4Z4 d
dl/m5Z5m6Z6m7Z7m8Z8 d
dl/m9Z9m:Z:m;Z; d
dl<m=Z= d
dl>m?Z?m@Z@mAZA d
dl>mBZBmCZC d
dl>mDZD  e deEeFd      ZGe!eeE   df   ZHe!eIeFej                  ee?eE   ej                  eHf   ZKe!eIeFej                  ee@eE   ej                  eHf   ZMedge2d   f   ZNdZOdZP G d de$e         ZQ G d de$      ZR G d  d!e$eG         ZSd"eeE   d#eTfd$ZU G d% d&eRee         ZV G d' d(eSe         ZW G d) d*eVe         ZX G d+ d,eVe         ZY G d- d.eWe         ZZ G d/ d0eWe         Z[ G d1 d2eVe   ej                        Z] G d3 d4eWe   ej                        Z^ G d5 d6eRee         Z_ G d7 d8eSe         Z` G d9 d:eVe         Za G d; d<eWe         Zb G d= d>eSe         Zc G d? d@eSe         Zd G dA dBe1      Ze G dC dDeeej                        Zf G dE dFe6      Zg G dG dHeAee         Zh G dI dJehe   eBe         Zi G dK dLehe   eCe         Zjy)MzSSH process handlers    N)DEVNULLPIPESTDOUT)PurePath)TracebackType)AnyAnyStr	AwaitableCallableDictGenericIO)IterableListMappingOptionalSetTextIO)TupleTypeTypeVarUnioncast)ProtocolSelf   )
SSHChannelSSHClientChannelSSHServerChannel)DEFAULT_LANGEXTENDED_DATA_STDERR)	SSHLogger)
BytesOrStrError
MaybeAwait	TermModesTermSize)ProtocolErrorRecord	open_fileset_terminal_size)BreakReceivedSignalReceivedTerminalSizeChanged)DataType)	SSHReader	SSHWriterSSHStreamSession)SSHClientStreamSessionSSHServerStreamSession)SFTPServerFactory_AnyStrContraT)contravariantz_AsyncFileProtocol[bytes]zSSHServerProcess[AnyStr]      c                   :    e Zd ZdZd	dedefdZdeddfdZd
dZy)_AsyncFileProtocolzProtocol for an async filenreturnc                    K   yw)zRead from an async fileN )selfr<   s     0lib/python3.12/site-packages/asyncssh/process.pyreadz_AsyncFileProtocol.readK           dataNc                    K   yw)zWrite to an async fileNr?   r@   rE   s     rA   writez_AsyncFileProtocol.writeN   rC   rD   c                    K   yw)zClose an async fileNr?   r@   s    rA   closez_AsyncFileProtocol.closeQ   rC   rD   )r=   N)	__name__
__module____qualname____doc__intr	   rB   rH   rK   r?       rA   r;   r;   H   s0    $&C & &% %4 %"rS   r;   c                   (    e Zd ZdZddZddZddZy)_ReaderProtocolz2A class that can be used as a reader in SSHProcessNc                      y)zPause readingNr?   rJ   s    rA   pause_readingz_ReaderProtocol.pause_readingX       rS   c                      y)zResume readingNr?   rJ   s    rA   resume_readingz_ReaderProtocol.resume_reading[   rX   rS   c                      yzStop forwarding dataNr?   rJ   s    rA   rK   z_ReaderProtocol.close^   rX   rS   rM   )rN   rO   rP   rQ   rW   rZ   rK   r?   rS   rA   rU   rU   U   s    <#rS   rU   c                   @    e Zd ZdZdeddfdZdeddfdZd
dZd
d	Z	y)_WriterProtocolz2A class that can be used as a writer in SSHProcessrE   r=   Nc                      y)z
Write dataNr?   rG   s     rA   rH   z_WriterProtocol.writee   rX   rS   excc                      y)z5Write exception (break, signal, terminal size change)Nr?   r@   r`   s     rA   write_exceptionz_WriterProtocol.write_exceptionh   s     	rS   c                      y)z)Close output when end of file is receivedNr?   rJ   s    rA   	write_eofz_WriterProtocol.write_eofm   rX   rS   c                      yr\   r?   rJ   s    rA   rK   z_WriterProtocol.closep   rX   rS   rM   )
rN   rO   rP   rQ   r6   rH   	Exceptionrc   re   rK   r?   rS   rA   r^   r^   b   s5    <- D 9  
8#rS   r^   filer=   c                     	 t        j                  t        j                  | j	                               j
                        S # t        $ r Y yw xY w)z8Return if argument is a regular file or file-like objectT)statS_ISREGosfstatfilenost_modeOSError)rh   s    rA   _is_regular_filerq   t   s=    ||BHHT[[]3;;<< s   ?A 	AAc                   `     e Zd ZdZ	 ddee   dedef fdZddedede	fd	Z
dd
ZddZ xZS )_UnicodeReaderz%Handle buffering partial Unicode dataencodingerrorstextmodec                 z    t         |           |r#|s! t        j                  |      |      | _        y d | _        y N)super__init__codecsgetincrementaldecoder_decoderr@   rt   ru   rv   	__class__s       rA   rz   z_UnicodeReader.__init__   8    H6,,X6v> M !DMrS   rE   finalr=   c                     | j                   r-	 t        t        | j                   j                  ||            }|S t        t        |      }|S # t        $ r}t        t        |            dd}~ww xY w)z5Decode Unicode bytes when reading from binary sourcesN)r}   r   r	   decodeUnicodeDecodeErrorr(   str)r@   rE   r   decoded_datar`   s        rA   r   z_UnicodeReader.decode   sl     ==8#FDMM,@,@u,MN   -L & 8#CH-478s   *A 	A/A**A/c                 (    | j                  dd       y)z1Check if there's partial Unicode data left at EOFrS   TN)r   rJ   s    rA   check_partialz_UnicodeReader.check_partial   s     	CrS   c                      y)z@Perform necessary cleanup on error (provided by derived classes)Nr?   rJ   s    rA   rK   z_UnicodeReader.close   rX   rS   FrM   )rN   rO   rP   rQ   r   r   boolrz   bytesr	   r   r   rK   __classcell__r   s   @rA   rs   rs   |   sO    / #(!# ! !!5  & 
OrS   rs   c                   J     e Zd ZdZ	 d	dee   dedef fdZdede	fdZ
 xZS )
_UnicodeWriterz.Handle encoding Unicode data before writing itrt   ru   rv   c                 z    t         |           |r#|s! t        j                  |      |      | _        y d | _        y rx   )ry   rz   r{   getincrementalencoder_encoderr~   s       rA   rz   z_UnicodeWriter.__init__   r   rS   rE   r=   c           	          | j                   rG| j                   J t        t        | j                   j                  t        t        |                  }|S t        t        |      }|S )z3Encode Unicode bytes when writing to binary targets)r   r   r   encoder   )r@   rE   encoded_datas      rA   r   z_UnicodeWriter.encode   sX     ====,,,t}}';';DdO'LML   t,LrS   r   )rN   rO   rP   rQ   r   r   r   rz   r	   r   r   r   r   s   @rA   r   r      s=    8 #(!# ! !!	6 	e 	rS   r   c                   h     e Zd ZdZdddee   dededee	   de	f fd	Z
dd
ZddZddZddZ xZS )_FileReaderzForward data from a fileprocessSSHProcess[AnyStr]rh   bufsizedatatypert   ru   c                     t         |   ||t        |d             || _        || _        || _        || _        d| _        y Nrt   F)ry   rz   hasattr_process_file_bufsize	_datatype_pausedr@   r   rh   r   r   rt   ru   r   s          rA   rz   z_FileReader.__init__   s@     	674+DE.5
!rS   c                 ^   | j                   s| j                  j                  | j                        }|r6| j                  j                  | j                  |      | j                         n6| j                          | j                  j                  | j                         y| j                   syyzFeed file dataN
r   r   rB   r   r   	feed_datar   r   r   feed_eofrG   s     rA   feedz_FileReader.feed   ss     ,,::??4==1D''D(94>>J""$&&t~~6 ,,rS   c                     d| _         yzPause reading from the fileTNr   rJ   s    rA   rW   z_FileReader.pause_reading        rS   c                 2    d| _         | j                          yzResume reading from the fileFNr   r   rJ   s    rA   rZ   z_FileReader.resume_reading        		rS   c                 8    | j                   j                          yz"Stop forwarding data from the fileN)r   rK   rJ   s    rA   rK   z_FileReader.close   s     	

rS   rM   )rN   rO   rP   rQ   r   r   rR   r/   r   r   rz   r   rW   rZ   rK   r   r   s   @rA   r   r      sV    "	 4 	BuI 		)1	#C=	25	
rS   r   c                   p     e Zd ZdZdddee   dededee	   de	f fd	Z
dd
ZddZddZddZddZ xZS )_AsyncFileReaderzForward data from an aiofiler   r   rh   r   r   rt   ru   c                     t         |   ||t        |d             |j                  j	                         | _        || _        || _        || _        || _	        d| _
        y r   )ry   rz   r   channelget_connection_connr   r   r   r   r   r   s          rA   rz   z_AsyncFileReader.__init__   sT     	674+DE__335
.5
!rS   c                 z  K   | j                   s| j                  j                  | j                         d{   }|r6| j                  j                  | j                  |      | j                         n6| j                          | j                  j                  | j                         y| j                   syy7 wr   r   rG   s     rA   _feedz_AsyncFileReader._feed   s}      ,,77D''D(94>>J""$&&t~~6 ,,7   5B;B9A>B;7B;c                 V    | j                   j                  | j                                y)zStart feeding file dataNr   create_taskr   rJ   s    rA   r   z_AsyncFileReader.feed       	

tzz|,rS   c                     d| _         yr   r   rJ   s    rA   rW   z_AsyncFileReader.pause_reading  r   rS   c                 2    d| _         | j                          yr   r   rJ   s    rA   rZ   z_AsyncFileReader.resume_reading  r   rS   c                 j    | j                   j                  | j                  j                                yr   )r   r   r   rK   rJ   s    rA   rK   z_AsyncFileReader.close  s#     	

tzz//12rS   rM   )rN   rO   rP   rQ   r;   r   rR   r/   r   r   rz   r   r   rW   rZ   rK   r   r   s   @rA   r   r      sa    & 4 )%0)1 $C= 36-

3rS   r   c                   `     e Zd ZdZdee   dedee   def fdZ	de
dd	fd
ZddZddZ xZS )_FileWriterzForward data to a filerh   needs_closert   ru   c                 X    t         |   ||t        |d             || _        || _        y )Nrt   )ry   rz   r   r   _needs_close)r@   rh   r   rt   ru   r   s        rA   rz   z_FileWriter.__init__  s*    674+DE
'rS   rE   r=   Nc                 X    | j                   j                  | j                  |             y)Write data to the fileN)r   rH   r   rG   s     rA   rH   z_FileWriter.write!  s     	

T*+rS   c                 $    | j                          yz.Close output file when end of file is receivedNrK   rJ   s    rA   re   z_FileWriter.write_eof&       	

rS   c                 R    | j                   r| j                  j                          yyz Stop forwarding data to the fileN)r   r   rK   rJ   s    rA   rK   z_FileWriter.close+  s"     JJ rS   rM   )rN   rO   rP   rQ   r   r   r   r   r   rz   r	   rH   re   rK   r   r   s   @rA   r   r     sN     (RY (T (#C=(25(,& ,T ,

rS   r   c                   v     e Zd ZdZdddee   dedee   dee	   de	f fd	Z
ddZded
dfdZddZddZ xZS )_AsyncFileWriterzForward data to an aiofiler   r   rh   r   r   rt   ru   c                 ,   t         |   ||t        |d             || _        || _        || _        || _        d| _        t        j                         | _
        |j                  j                         j                  | j                               | _        y r   )ry   rz   r   r   r   r   r   r   asyncioQueue_queuer   r   r   _writer_write_task)r@   r   rh   r   r   rt   ru   r   s          rA   rz   z_AsyncFileWriter.__init__5  sw     	674+DE.5
'!7>}}OO**,88H 	rS   r=   Nc                 B  K   	 | j                   j                          d{   }|| j                   j                          n| j                  j	                  | j                  |             d{    | j                   j                          | j                  rM| j                   j                         t        k  r,| j                  j                  | j                         d| _        | j                  r#| j                  j                          d{    yy7 7 7 
w)zProcess writes to the fileNF)r   get	task_doner   rH   r   r   qsize_QUEUE_LOW_WATERr   resume_feedingr   r   rK   rG   s     rA   r   z_AsyncFileWriter._writerC  s      **D|%%'**""4;;t#4555KK!!#|| 1 1 36F F,,T^^<$  **""$$$  + 6 %s5   DDAD0D1B!DDDDDrE   c                     | j                   j                  |       | j                  sO| j                   j                         t        k\  r-d| _        | j
                  j                  | j                         yyy)r   TNr   
put_nowaitr   r   _QUEUE_HIGH_WATERr   pause_feedingr   rG   s     rA   rH   z_AsyncFileWriter.writeW  W     	t$|| 1 1 37H HDLMM''7 !I|rS   c                 $    | j                          yr   r   rJ   s    rA   re   z_AsyncFileWriter.write_eof`  r   rS   c                     | j                   rVd| _         | j                  j                  d       | j                  j	                  | j                  j                                yyr   r   r   r   r   add_cleanup_taskjoinrJ   s    rA   rK   z_AsyncFileWriter.closee  K     #DKK""4(MM**4;;+;+;+=> rS   rM   )rN   rO   rP   rQ   r;   r   r   r   rR   r   rz   r   r	   rH   re   rK   r   r   s   @rA   r   r   2  sq    $I 4 I)%0I?CI#C=I4<SMIKNI%(8& 8T 8
?rS   r   c                        e Zd ZdZdddedee   def fdZdej                  d	d
fdZ
dee   d	d
fdZded	d
fdZddZddZddZddZ xZS )_PipeReaderzForward data from a piper   r   r   rt   ru   c                 P    t         |   ||       || _        || _        d | _        y rx   )ry   rz   r   r   
_transportr@   r   r   rt   ru   r   s        rA   rz   z_PipeReader.__init__q  s'    6*.5!;?rS   	transportr=   Nc                 B    t        t        j                  |      | _        y)Handle a newly opened pipeN)r   r   ReadTransportr   )r@   r   s     rA   connection_madez_PipeReader.connection_madey  s     w44i@rS   r`   c                 n    | j                   j                  | j                         | j                          yzHandle closing of the pipeN)r   
feed_closer   rK   rb   s     rA   connection_lostz_PipeReader.connection_lost~  s#     	  0

rS   rE   c                 n    | j                   j                  | j                  |      | j                         y)zForward data from the pipeN)r   r   r   r   rG   s     rA   data_receivedz_PipeReader.data_received  s%     	D 14>>BrS   c                 n    | j                          | j                  j                  | j                         y)zForward EOF from the pipeN)r   r   r   r   rJ   s    rA   eof_receivedz_PipeReader.eof_received  s&     	t~~.rS   c                 T    | j                   J | j                   j                          y)zPause reading from the pipeN)r   rW   rJ   s    rA   rW   z_PipeReader.pause_reading  s$     ***%%'rS   c                 T    | j                   J | j                   j                          y)zResume reading from the pipeN)r   rZ   rJ   s    rA   rZ   z_PipeReader.resume_reading  s$     ***&&(rS   c                 T    | j                   J | j                   j                          y)z"Stop forwarding data from the pipeN)r   rK   rJ   s    rA   rK   z_PipeReader.close  s$     ***rS   rM   )rN   rO   rP   rQ   r/   r   r   rz   r   BaseTransportr   rg   r   r   r   r   rW   rZ   rK   r   r   s   @rA   r   r   n  s    "@ 4 @ @#C=@25@A)>)> A4 A
8I#6 4 C% CD C
/() rS   r   c                        e Zd ZdZdddedee   def fdZdej                  d	d
fdZ
dee   d	d
fdZddZddZded	d
fdZded	d
fdZddZddZ xZS )_PipeWriterzForward data to a piper   r   r   rt   ru   c                     t         |   ||       || _        || _        d | _        d | _        t        j                         | _        y rx   )	ry   rz   r   r   r   _ttyr   Event_close_eventr   s        rA   rz   z_PipeWriter.__init__  s<    6*.5!<@"&	#MMOrS   r   r=   Nc                 
   t        t        j                  |      | _        |j	                  d      }t        | j                  t              r9|j                         r(|| _	        t        |g| j                  j                    yyy)r   pipeN)r   r   WriteTransportr   get_extra_info
isinstancer   SSHServerProcessisattyr  r+   	term_size)r@   r   r
  s      rA   r   z_PipeWriter.connection_made  sf     w55yA''/dmm%564;;=DId=T]]%<%<= <I6rS   r`   c                 8    | j                   j                          yr   )r  setrb   s     rA   r   z_PipeWriter.connection_lost  s     	rS   c                 N    | j                   j                  | j                         y)zPause writing to the pipeNr   r   r   rJ   s    rA   pause_writingz_PipeWriter.pause_writing       	##DNN3rS   c                 N    | j                   j                  | j                         y)zResume writing to the pipeNr   r   r   rJ   s    rA   resume_writingz_PipeWriter.resume_writing       	$$T^^4rS   rE   c                 t    | j                   J | j                   j                  | j                  |             y)zWrite data to the pipeN)r   rH   r   rG   s     rA   rH   z_PipeWriter.write  s/     ***dkk$/0rS   c                     t        |t              r.| j                  r!t        | j                  g|j                    yyy)z6Write terminal size changes to the pipe if it is a TTYN)r  r.   r  r+   r  rb   s     rA   rc   z_PipeWriter.write_exception  s2     c./DIIdii8#--8 5>/rS   c                 T    | j                   J | j                   j                          y)zWrite EOF to the pipeN)r   re   rJ   s    rA   re   z_PipeWriter.write_eof  s$     ***!!#rS   c                     | j                   J | j                   j                          | j                  j                  | j                  j                                y)z Stop forwarding data to the pipeN)r   rK   r   r   r  waitrJ   s    rA   rK   z_PipeWriter.close  sE     ***&&t'8'8'='='?@rS   rM   )rN   rO   rP   rQ   r/   r   r   rz   r   r  r   rg   r   r  r  r	   rH   rc   re   rK   r   r   s   @rA   r  r    s     , 4 , ,#C=,25,	>)>)> 	>4 	> 8I#6  4  
4
5
1& 1T 199 9 9$ArS   r  c                   D     e Zd ZdZdddef fdZd	dZd	dZd	dZ xZ	S )
_ProcessReaderz%Forward data from another SSH processr   r   r   c                 >    t         |           || _        || _        y rx   ry   rz   r   r   r@   r   r   r   s      rA   rz   z_ProcessReader.__init__      .5!rS   c                 N    | j                   j                  | j                         y)z$Pause reading from the other channelNr  rJ   s    rA   rW   z_ProcessReader.pause_reading  r  rS   c                 N    | j                   j                  | j                         y)z%Resume reading from the other channelNr  rJ   s    rA   rZ   z_ProcessReader.resume_reading  r  rS   c                 N    | j                   j                  | j                         y)z+Stop forwarding data from the other channelN)r   clear_writerr   rJ   s    rA   rK   z_ProcessReader.close       	""4>>2rS   rM   )
rN   rO   rP   rQ   r/   rz   rW   rZ   rK   r   r   s   @rA   r!  r!    s)    /" 4 " "
4
5
3rS   r!  c                   \     e Zd ZdZdddef fdZdeddfd	Zd
eddfdZ	ddZ
ddZ xZS )_ProcessWriterz#Forward data to another SSH processr   r   r   c                 >    t         |           || _        || _        y rx   r#  r$  s      rA   rz   z_ProcessWriter.__init__  r%  rS   rE   r=   Nc                 P    | j                   j                  || j                         y)zWrite data to the other channelN)r   r   r   rG   s     rA   rH   z_ProcessWriter.write  s     	dnn5rS   r`   c                 V    t        t        | j                        j                  |       y)z'Write an exception to the other channelN)r   SSHClientProcessr   feed_exceptionrb   s     rA   rc   z_ProcessWriter.write_exception  s     	t}}-<<SArS   c                 N    | j                   j                  | j                         y)zWrite EOF to the other channelN)r   r   r   rJ   s    rA   re   z_ProcessWriter.write_eof  s     	t~~.rS   c                 N    | j                   j                  | j                         y)z)Stop forwarding data to the other channelN)r   clear_readerr   rJ   s    rA   rK   z_ProcessWriter.close  r*  rS   rM   )rN   rO   rP   rQ   r/   rz   r	   rH   rg   rc   re   rK   r   r   s   @rA   r,  r,    sM    -" 4 " "
6& 6T 6
B9 B B
/
3rS   r,  c                   ~     e Zd ZdZdddej
                  dededee	   de	f fd	Z
dd
ZddZddZddZddZ xZS )_StreamReaderz#Forward data from an asyncio streamr   r   readerr   r   rt   ru   c                     t         |   ||       || _        |j                  j	                         | _        || _        || _        || _        d| _	        y NF)
ry   rz   r   r   r   r   _readerr   r   r   )r@   r   r7  r   r   rt   ru   r   s          rA   rz   z_StreamReader.__init__  sK     	6*.5__335
!rS   c                 z  K   | j                   s| j                  j                  | j                         d{   }|r6| j                  j                  | j                  |      | j                         n6| j                          | j                  j                  | j                         y| j                   syy7 w)zFeed stream dataN)
r   r:  rB   r   r   r   r   r   r   r   rG   s     rA   r   z_StreamReader._feed(  s      ,,**4==99D''D(94>>J""$&&t~~6 ,,9r   c                 V    | j                   j                  | j                                y)zStart feeding stream dataNr   rJ   s    rA   r   z_StreamReader.feed5  r   rS   c                     d| _         y)zPause reading from the streamTNr   rJ   s    rA   rW   z_StreamReader.pause_reading:  r   rS   c                 2    d| _         | j                          y)zResume reading from the streamFNr   rJ   s    rA   rZ   z_StreamReader.resume_reading?  r   rS   c                      y)zAIgnore close -- the caller must clean up the associated transportNr?   rJ   s    rA   rK   z_StreamReader.closeE  rX   rS   rM   )rN   rO   rP   rQ   r   StreamReaderrR   r/   r   r   rz   r   r   rW   rZ   rK   r   r   s   @rA   r6  r6    sc    - 4  --)1 $C= 36-

PrS   r6  c                        e Zd ZdZdddej
                  dedee   dee	   de	f fd	Z
ddZded
dfdZddZddZ xZS )_StreamWriterz!Forward data to an asyncio streamr   r   writerrecv_eofr   rt   ru   c                    t         |   ||       || _        || _        || _        || _        d| _        t        j                         | _	        |j                  j                         j                  | j                               | _        y r9  )ry   rz   r   r   	_recv_eofr   r   r   r   r   r   r   r   r   r   )r@   r   rC  rD  r   rt   ru   r   s          rA   rz   z_StreamWriter.__init__L  sm     	6*.5!!7>}}OO**,88F 	rS   r=   Nc                 d  K   	 | j                   j                          d{   }|| j                   j                          n| j                  j	                  | j                  |             | j                  j                          d{    | j                   j                          | j                  rM| j                   j                         t        k  r,| j                  j                  | j                         d| _        | j                  r| j                  j                          yy7 
7 w)zFeed data to the streamNF)r   r   r   r   rH   r   drainr   r   r   r   r   r   rF  re   rG   s     rA   r   z_StreamWriter._feedZ  s      **D|%%'LLt{{401,,$$&&&KK!!#|| 1 1 36F F,,T^^<$  >>LL""$  + 's#   D0D+A(D0
D.B!D0.D0rE   c                     | j                   j                  |       | j                  sO| j                   j                         t        k\  r-d| _        | j
                  j                  | j                         yyy)zWrite data to the streamTNr   rG   s     rA   rH   z_StreamWriter.writeo  r   rS   c                 $    | j                          y)zWrite EOF to the streamNr   rJ   s    rA   re   z_StreamWriter.write_eofx  r   rS   c                     | j                   rVd| _         | j                  j                  d       | j                  j	                  | j                  j                                yy)z"Stop forwarding data to the streamNr   rJ   s    rA   rK   z_StreamWriter.close}  r   rS   rM   )rN   rO   rP   rQ   r   StreamWriterr   r   rR   r   rz   r   r	   rH   re   rK   r   r   s   @rA   rB  rB  I  sr    +G 4 G --G9=G#C=G4<SMGKNG%*8& 8T 8
?rS   rB  c                   0    e Zd ZdZdeddfdZddZddZy)	_DevNullWriterzDiscard datarE   r=   Nc                      y)zDiscard data being writtenNr?   rG   s     rA   rH   z_DevNullWriter.write  rX   rS   c                      yzIgnore end of fileNr?   rJ   s    rA   re   z_DevNullWriter.write_eof  rX   rS   c                      yzIgnore closeNr?   rJ   s    rA   rK   z_DevNullWriter.close  rX   rS   rM   )rN   rO   rP   rQ   r	   rH   re   rK   r?   rS   rA   rN  rN    s"    )& )T )!rS   rN  c                   D     e Zd ZdZd	 fdZdeddfdZd
dZd
dZ xZ	S )_StdoutWriterz8Forward data to an SSH process' stdout instead of stderrc                 0    t         |           || _        y rx   )ry   rz   r   )r@   r   r   s     rA   rz   z_StdoutWriter.__init__  s    .5rS   rE   r=   Nc                 <    | j                   j                  |d       y)z#Pretend data was received on stdoutN)r   r   rG   s     rA   rH   z_StdoutWriter.write  s     	##D$/rS   c                      yrQ  r?   rJ   s    rA   re   z_StdoutWriter.write_eof  rX   rS   c                      yrS  r?   rJ   s    rA   rK   z_StdoutWriter.close  rX   rS   )r   r   rM   )
rN   rO   rP   rQ   rz   r	   rH   re   rK   r   r   s   @rA   rU  rU    s(    B60& 0T 0
!rS   rU  c                        e Zd ZdZdefdeeeef      dee   dee   dee   dee	ee
eef      dee   d	ed
ededef fdZ xZS )ProcessErrora>  SSH Process error

       This exception is raised when an :class:`SSHClientProcess` exits
       with a non-zero exit status and error checking is enabled. In
       addition to the usual error code, reason, and language, it
       contains the following fields:

         ============ ======================================= =================
         Field        Description                             Type
         ============ ======================================= =================
         env          The environment the client requested    `str` or `None`
                      to be set for the process
         command      The command the client requested the    `str` or `None`
                      process to execute (if any)
         subsystem    The subsystem the client requested the  `str` or `None`
                      process to open (if any)
         exit_status  The exit status returned, or -1 if an   `int` or `None`
                      exit signal is sent
         exit_signal  The exit signal sent (if any) in the    `tuple` or `None`
                      form of a tuple containing the signal
                      name, a `bool` for whether a core dump
                      occurred, a message associated with the
                      signal, and the language the message
                      was in
         returncode   The exit status returned, or negative   `int` or `None`
                      of the signal number when an exit
                      signal is sent
         stdout       The output sent by the process to       `str` or `bytes`
                      stdout (if not redirected)
         stderr       The output sent by the process to       `str` or `bytes`
                      stderr (if not redirected)
         ============ ======================================= =================

     envcommand	subsystemexit_statusexit_signal
returncodestdoutstderrreasonlangc                     || _         || _        || _        || _        || _        || _        || _        || _        |r|\  }}}}
d||rd|z   nd|rdnd}	n|rd|z  }	t        | %  |xs d|	|
       y )NzProcess exited with signal z: r\  z (core dumped)z+Process exited with non-zero exit status %sr   )
r]  r^  r_  r`  ra  rb  rc  rd  ry   rz   )r@   r]  r^  r_  r`  ra  rb  rc  rd  re  rf  signalcore_dumpedmsgr   s                 rA   rz   zProcessError.__init__  s     "&&$-8*FKds2%0!b8:F BF 	)648rS   )rN   rO   rP   rQ   r    r   r   r   rR   r   r   r#   rz   r   r   s   @rA   r[  r[    s    !P 46)9HWS#X%67 9"3-94<SM9&sm9 'uS$S-@'AB9 &c]	9 5?	9
 $9
 .19 9 9rS   r[  c                       e Zd ZdZy)TimeoutErroraG  SSH Process timeout error

       This exception is raised when a timeout occurs when calling the
       :meth:`wait <SSHClientProcess.wait>` method on :class:`SSHClientProcess`
       or the :meth:`run <SSHClientConnection.run>` method on
       :class:`SSHClientConnection`. It is a subclass of :class:`ProcessError`
       and contains all of the fields documented there, including any output
       received on stdout and stderr prior to when the timeout occurred. It
       is also a subclass of :class:`asyncio.TimeoutError`, for code that
       might be expecting that.

    N)rN   rO   rP   rQ   r?   rS   rA   rl  rl    s    rS   rl  c                       e Zd ZU dZeeeef      ed<   ee   ed<   ee   ed<   ee   ed<   ee	ee
eef      ed<   ee   ed<   ee   ed<   ee   ed	<   y
)SSHCompletedProcessa  Results from running an SSH process

       This object is returned by the :meth:`run <SSHClientConnection.run>`
       method on :class:`SSHClientConnection` when the requested command
       has finished running. It contains the following fields:

         ============ ======================================= =================
         Field        Description                             Type
         ============ ======================================= =================
         env          The environment the client requested    `dict` or `None`
                      to be set for the process
         command      The command the client requested the    `str` or `None`
                      process to execute (if any)
         subsystem    The subsystem the client requested the  `str` or `None`
                      process to open (if any)
         exit_status  The exit status returned, or -1 if an   `int`
                      exit signal is sent
         exit_signal  The exit signal sent (if any) in the    `tuple` or `None`
                      form of a tuple containing the signal
                      name, a `bool` for whether a core dump
                      occurred, a message associated with the
                      signal, and the language the message
                      was in
         returncode   The exit status returned, or negative   `int`
                      of the signal number when an exit
                      signal is sent
         stdout       The output sent by the process to       `str` or `bytes`
                      stdout (if not redirected)
         stderr       The output sent by the process to       `str` or `bytes`
                      stderr (if not redirected)
         ============ ======================================= =================

    r]  r^  r_  r`  ra  rb  rc  rd  N)rN   rO   rP   rQ   r   r   r   __annotations__rR   r   r   r#   r?   rS   rA   rn  rn    su     D 
'#s(#	$$c]}#%T3 3455Z  Z  rS   rn  c                       e Zd ZdZd4 fdZdefdZdeee	      dee	   dee
   defd	Zedee   fd
       Zedefd       Zedee   fd       Zedee   fd       Zedeeef   fd       Zd5dededefdZ	 d5dedededededdfdZ	 d5dedededededdfdZdedef fdZ def fdZ!de"ddfdZ#dee$   ddf fdZ%d ededdf fd!Z&def fd"Z'd4 fd#Z(d4 fd$Z)d ededdfd%Z*deddfd&Z+deddfd'Z,ded(e-e   ddfd)Z.deddfd*Z/deddfd+Z0d,ee1   dededdfd-Z2deddfd.Z3d(ee-e      dededdfd/Z4deddfd0Z5d4d1Z6defd2Z7d4d3Z8 xZ9S )6
SSHProcesszSSH process handlerr=   Nc                     t        |   |  g | _        i | _        i | _        i | _        i | _        t               | _        y rx   )	ry   rz   _cleanup_tasks_readers	_send_eof_writersrF  r  _paused_write_streams)r@   argsr   s     rA   rz   zSSHProcess.__init__'  s>    $57>@46FH469<"rS   c                    K   | S w)z7Allow SSHProcess to be used as an async context managerr?   rJ   s    rA   
__aenter__zSSHProcess.__aenter__4  s      s   	_exc_type
_exc_value
_tracebackc                 `   K   | j                          | j                          d{    y7 w)z<Wait for a full channel close when exiting the async contextNF)rK   wait_closed)r@   r{  r|  r}  s       rA   	__aexit__zSSHProcess.__aexit__9  s+     
 	

    	!s   $.,.c                 6    | j                   J | j                   S )z'The channel associated with the process)_chanrJ   s    rA   r   zSSHProcess.channelB  s     zz%%%zzrS   c                 J    | j                   J | j                   j                  S )z&The logger associated with the process)r  loggerrJ   s    rA   r  zSSHProcess.loggerI  s$     zz%%%zz   rS   c                 R    | j                   J | j                   j                         S )zThe command the client requested to execute, if any

           If the client did not request that a command be executed,
           this property will be set to `None`.

        )r  get_commandrJ   s    rA   r^  zSSHProcess.commandP  s'     zz%%%zz%%''rS   c                 R    | j                   J | j                   j                         S )zThe subsystem the client requested to open, if any

           If the client did not request that a subsystem be opened,
           this property will be set to `None`.

        )r  get_subsystemrJ   s    rA   r_  zSSHProcess.subsystem\  s'     zz%%%zz''))rS   c                 R    | j                   J | j                   j                         S )z6A mapping containing the environment set by the client)r  get_environmentrJ   s    rA   r]  zSSHProcess.envh  s'     zz%%%zz))++rS   namedefaultc                 V    | j                   J | j                   j                  ||      S )a5  Return additional information about this process

           This method returns extra information about the channel
           associated with this process. See :meth:`get_extra_info()
           <SSHClientChannel.get_extra_info>` on :class:`SSHClientChannel`
           for additional information.

        )r  r  )r@   r  r  s      rA   r  zSSHProcess.get_extra_infoo  s+     zz%%%zz((w77rS   sourcer   send_eofrD  r   c                    K   dt         f fd}|t        k(  rd}n|t        k(  r, j                  J  j                  j	                          d}nt        |t              rS|j                         \  }}	t        d|      }
t        t                  }|
j                  |||	       t        |
|	      }n5t        |t        j                        r&t         || j                    j"                        }nt        |t$              rt'        |d|      }nt        |t(              rt'        t%        |      d|      }nlt        |t*              rt-        j.                  |d|      }nCt        |t0        j0                        r't-        j.                  |j3                         d|      }n|}t5        |d      rqt        j6                  |j8                        st;        j<                  |j8                        r3t?         t        t@        |      | j                    j"                        }ntC        t        tD        tF           |            r:tI         t        tD        tF           |      | j                    j"                        }nkt5        |d      rt        tJ        |      jL                  } jN                  J  jN                  jQ                  ||       d{   \  }}t        t         |      } jS                  ||       t        |tH        t>        t        f      r|jU                          yt        |t              r
jW                  	       yy7 zw)	z2Create a reader to forward data to the SSH channelr=   c                  H    t         j                  j                        S )zReturn a pipe read handler)r   	_encoding_errorsr   r@   s   rA   pipe_factoryz/SSHProcess._create_reader.<locals>.pipe_factory       tXt~~t||LLrS   Nr   rb	bufferingrB   buffer),r   r   r   r  re   r  r0   get_redirect_infor   r,  r	   
set_writerr!  r   r@  r6  r  r  r   r*   r   rR   rl   fdopensocketdetachr   iscoroutinefunctionrB   inspectisgeneratorfunctionr   r;   rq   r   r   r   r   r  _loopconnect_read_pipe
set_readerr   feed_recv_buf)r@   r  r   r  rD  r   r  r7  reader_streamreader_datatypereader_processrC  rh   _protocols   `    `         rA   _create_readerzSSHProcess._create_reader|  s    
	Mk 	M
 T>04Fw::)))JJ  "F	*-3-E-E-G*M?!"6FN#F+D(;F%%fhH#NODF 4 45"4(#'>>4<<AF
 &#& AFH- VdgFFC(yyAFFMM2yy$'JtV$00;00;)$5G0N*18T^^*.,,8 "$r%y$"78$T45	4+@'%-t~~t||M 68,/66Dzz---**66|TJJ 8k84(3f{,<mLMKKM/((&A 0 Ks   KMMA;Mtargetc                    K   dt         f fd}|t        k(  rd}n.|t        k(  rt               }n|t        k(  rt               }nt        |t              rS|j                         \  }}	t        d|      }
t               }|
j                  |||	       t        t           |
|	      }nt        |t        j                        r&t!         || j"                   j$                        }n`d}t        |t&              rt)        |d|      }nt        |t*              rt)        t'        |      d|      }nt        |t,              rt/        j0                  |d||      }nZt        |t2        j2                        r<|r|j5                         n|j7                         }t/        j0                  |d||      }n|}|}t9        |d	      rrt        j:                  |j<                        st?        j@                  |j<                        r4tC         t        tD        |      | j"                   j$                        }ntG        t        tH        tJ           |            r8tM        t        tH        tJ           |      | j"                   j$                        }nt9        |d
      rt        tN        |      jP                  }|sPt/        jR                  t        tH        tJ           |      j7                               }t/        j0                  |dd      } jT                  J  jT                  jW                  ||       d{   \  }}t        t         |      } jY                  ||       |r j[                  |       yy7 @w)z4Create a writer to forward data from the SSH channelr=   c                  H    t         j                  j                        S )zReturn a pipe write handler)r  r  r  r  s   rA   r  z/SSHProcess._create_writer.<locals>.pipe_factory  r  rS   Nr   Twbr  )r  closefdrH   r  r   ).r  r   r   rN  r   rU  r  r1   r  r   r!  r  r,  r	   r   rL  rB  r  r  r   r*   r   rR   rl   r  r  r  rn   r   r  rH   r  r  r   r;   rq   r   r   r   r   r  dupr  connect_write_piper  r  )r@   r  r   r  rD  r   r  rC  writer_streamwriter_datatypewriter_processr7  r   rh   fdr  r  s   `    `           rA   _create_writerzSSHProcess._create_writer  s    
	Mk 	M
 T>8<Fw#%Fv"4(F	*-3-E-E-G*M?!"6FN#D(3F%%fhH#F+NOLF 4 45"48#'>>4<<AF K&#& AFH- VdgFFC(yy+2HFFFMM2(0V]]_fmmoyyTWhO&tW%00<00<)$148+dnndll< "$r%y$"78$T"U)T%:K$(NNDLLB 68,/66DRY 5 < < >?B99R;Dzz---**77dKK 8k84(3x0  Ls   L1M85M66AM8c                 B    || j                   v xs t        | 	  |      S )z;Return whether output is still being written to the channel)rt  ry   _should_block_drain)r@   r   r   s     rA   r  zSSHProcess._should_block_drain  s(     DMM) 6+H5	7rS   c                 N    t        | j                        xs t        |          S )z0Return whether to pause reading from the channel)r   rw  ry   _should_pause_readingr@   r   s    rA   r  z SSHProcess._should_pause_reading
  s(     D../ ,G)+	,rS   taskc                 :    | j                   j                  |       y)z(Add a task to run when the process exitsN)rs  appendr@   r  s     rA   r   zSSHProcess.add_cleanup_task  s     	""4(rS   r`   c                     t         |   |       t        | j                  j	                               D ]  }|j                           t        | j                  j	                               D ]  }|j                           i | _        i | _        y)z!Handle a close of the SSH channelN)ry   r   listrt  valuesrK   rv  )r@   r`   r7  rC  r   s       rA   r   zSSHProcess.connection_lost  sn     	$4==//12FLLN 3 4==//12FLLN 3 rS   rE   c                     | j                   j                  |      }|r|j                  |       yt        |   ||       y)z)Handle incoming data from the SSH channelN)rv  r   rH   ry   r   )r@   rE   r   rC  r   s       rA   r   zSSHProcess.data_received#  s7     ""8,LLG!$1rS   c                     t        | j                  j                               D ]%  \  }}| j                  |   s|j	                          ' t
        |          S )z3Handle an incoming end of file from the SSH channel)r  rv  itemsrF  re   ry   r   )r@   r   rC  r   s      rA   r   zSSHProcess.eof_received-  sN     !%T]]%8%8%: ;Hf~~h'  " !< w#%%rS   c                     t         |           t        | j                  j	                               D ]  }|j                           y)z$Pause forwarding data to the channelN)ry   r  r  rt  r  rW   r@   r7  r   s     rA   r  zSSHProcess.pause_writing6  s8     	4==//12F  " 3rS   c                     t         |           t        | j                  j	                               D ]  }|j                           y)z%Resume forwarding data to the channelN)ry   r  r  rt  r  rZ   r  s     rA   r  zSSHProcess.resume_writing>  s8     	 4==//12F!!# 3rS   c                 X    | j                   J | j                   j                  ||       y)zFeed data to the channelN)r  rH   )r@   rE   r   s      rA   r   zSSHProcess.feed_dataF  s(     zz%%%

x(rS   c                     | j                   |   r(| j                  J | j                  j                          | j                  |   j	                          | j                  |       y)zFeed EOF to the channelN)ru  r  re   rt  rK   r4  r@   r   s     rA   r   zSSHProcess.feed_eofL  sS     >>(#::)))JJ  "h%%'(#rS   c                 D    || j                   v r| j                  |       yy)zFeed pipe close to the channelN)rt  r   r  s     rA   r   zSSHProcess.feed_closeV  s!     t}}$MM(# %rS   rC  c                 `   | j                   |   D ]S  }t        |t              r|j                  |       %|j	                  |       | xj
                  t        |      z  c_        U | j                   |   j                          | j                  r|j                          | j                          y)z1Feed current receive buffer to a newly set writerN)	_recv_bufr  rg   rc   rH   _recv_buf_lenlenclear_eof_receivedre   _maybe_resume_reading)r@   r   rC  bufs       rA   r  zSSHProcess.feed_recv_buf\  s     >>(+C#y)&&s+S!""c#h." , 	x &&(""$rS   c                 Z    | j                   j                  |       | j                          y)z#Pause feeding data from the channelN)rw  add_maybe_pause_readingr  s     rA   r   zSSHProcess.pause_feedingn  s$     	""&&x0!!#rS   c                 Z    | j                   j                  |       | j                          y)z$Resume feeding data from the channelN)rw  remover  r  s     rA   r   zSSHProcess.resume_feedingt  s$     	""))(3""$rS   r7  c                    | j                   j                  |      }|r|j                          |r<|| j                   |<   || j                  |<   | j                  r|j                          yy|r| j                  |       yy)z0Set a reader used to forward data to the channelN)rt  r   rK   ru  _write_pausedrW   r4  )r@   r7  r  r   
old_readers        rA   r  zSSHProcess.set_readerz  sv     ]]&&x0
&,DMM(#'/DNN8$!!$$& "h' rS   c                 Z    | j                   |= | j                  |= | j                  |       y)z-Clear a reader forwarding data to the channelN)rt  ru  _unblock_drainr  s     rA   r4  zSSHProcess.clear_reader  s*     MM(#NN8$H%rS   c                     | j                   j                  |      }|r!|j                          | j                  |       |r|| j                   |<   || j                  |<   yy)z2Set a writer used to forward data from the channelN)rv  r   rK   r)  rF  )r@   rC  rD  r   
old_writers        rA   r  zSSHProcess.set_writer  sY     ]]&&x0
h'&,DMM(#'/DNN8$ rS   c                 \    || j                   v r| j                  |       | j                  |= y)z/Clear a writer forwarding data from the channelN)rw  r   rv  r  s     rA   r)  zSSHProcess.clear_writer  s,     t111)MM(#rS   c                 T    | j                   J | j                   j                          y)zShut down the processN)r  rK   rJ   s    rA   rK   zSSHProcess.close  s$     zz%%%

rS   c                 R    | j                   J | j                   j                         S )z-Return if the channel is closing or is closed)r  
is_closingrJ   s    rA   r  zSSHProcess.is_closing  s'     zz%%%zz$$&&rS   c                    K   | j                   J | j                   j                          d{    | j                  D ]  }| d{     y7  7 	w)z,Wait for the process to finish shutting downN)r  r  rs  r  s     rA   r  zSSHProcess.wait_closed  sP      zz%%%jj$$&&&''DJJ ( 	' s!   ,AAAAAArM   rx   ):rN   rO   rP   rQ   rz   r   rz  r   r   BaseExceptionr   r   r  propertyr   r	   r   r"   r  r   r^  r_  r   r]  r   r  ProcessSourcerR   r/   r  ProcessTargetr  r  r  r
   r   rg   r   r   r   r  r  r   r   r   r^   r  r   r   rU   r  r4  r  r)  rK   r  r  r   r   s   @rA   rq  rq  $  s   ?$ 
$}2E)F $,]$;$,]$;@D F+   !	 ! ! 	(# 	( 	( 	*8C= 	* 	* ,WS#X& , ,83 8 8 8 37?B= ?B3 ?B'+?B7;?B'/?B;??BF 37E1= E13 E1'+E17;E1'/E1;?E1N7H 7 7,t ,)Y )4 )
8I#6 4 2& 2H 2 2&d &#$)f ) )T )$ $d $$8 $ $%h %-f5%:>%$$h $4 $%x %D %(/!: (!(-5(:>($&X &$ &0/&*A!B 0!0-50:>0$X $$ $'D 'rS   rq  c                       e Zd ZU dZee   ed<   ee   ed<   d0 fdZd1dedefdZ	d0d	Z
edee   fd
       Zedeeeeeef      fd       Zedee   fd       Zedee   fd       Zedee   fd       Zedee   fd       ZdeddfdZdddej8                  ddfdee   dee   dee   dedededdfdZej8                  dfdedededdfdZ ej8                  dfdedededdfdZ!ej8                  dfdedededdfdZ"deeef   fdZ#d1d ee   deeef   fd!Z$	 d2d"ed#ed$ed%eddf
d&Z%d'eddfd(Z&d)eddfd*Z'd0d+Z(d0d,Z)	 	 d3d-ed.ee*   de+fd/Z, xZ-S )4r0  zSSH client process handlerr  r   r=   Nc                 L    t         |           d | _        d | _        d | _        y rx   )ry   rz   _stdin_stdout_stderrr  s    rA   rz   zSSHClientProcess.__init__  s#    374848rS   r   c                 "   | j                   |   }|r,t        |d   t              r|dd |dd c}| j                   |<   ng | j                   |<   t        t        | j
                  rdnd      }|j                  t        t        t           |            S )zReturn output from the processrL   Nr\  rS   )r  r  rg   r   r	   r  r   r   )r@   r   recv_bufr  s       rA   _collect_outputz SSHClientProcess._collect_output  s     >>(+
8B<;19#2.HdnnX.')DNN8$62S9xxXf-x899rS   c                     t        t           | | j                        | _        t	        t           | | j                        | _        t	        t           | | j                  t              | _        y)z4Start a process for this newly opened client channelN)r1   r	   r  r  r0   r  r!   r  rJ   s    rA   session_startedz SSHClientProcess.session_started  sL      'djj9 (tzz: (tzz;OPrS   c                 6    | j                   j                         S )zThe exit status of the process)r  get_exit_statusrJ   s    rA   r`  zSSHClientProcess.exit_status       zz))++rS   c                 6    | j                   j                         S )z'Exit signal information for the process)r  get_exit_signalrJ   s    rA   ra  zSSHClientProcess.exit_signal  r  rS   c                 6    | j                   j                         S )z>The exit status or negative exit signal number for the process)r  get_returncoderJ   s    rA   rb  zSSHClientProcess.returncode  s     zz((**rS   c                 6    | j                   J | j                   S )z>The :class:`SSHWriter` to use to write to stdin of the processr  rJ   s    rA   stdinzSSHClientProcess.stdin       {{&&&{{rS   c                 6    | j                   J | j                   S )z@The :class:`SSHReader` to use to read from stdout of the processr  rJ   s    rA   rc  zSSHClientProcess.stdout       ||'''||rS   c                 6    | j                   J | j                   S )z@The :class:`SSHReader` to use to read from stderr of the processr  rJ   s    rA   rd  zSSHClientProcess.stderr   r  rS   r`   c                    t        |t              rG| j                  j                  |j                  |j
                  |j                  |j                         yt        |t              r&| j                  j                  |j                         yt        |t              r&| j                  j                  |j                         yy)zFeed exception to the channelN)r  r.   r  change_terminal_sizewidthheightpixwidth	pixheightr,   
send_breakmsecr-   send_signalrh  rb   s     rA   r1  zSSHClientProcess.feed_exception  s     c./JJ++CIIszz,/LL#--I]+JJ!!#((+^,JJ""3::. -rS   Tr  rc  rd  r   r  rD  c                    K   |r| j                  ||||       d{    |r| j                  ||||       d{    |r"| j                  ||||t               d{    yy7 G7 +7 
w)a  Perform I/O redirection for the process

           This method redirects data going to or from any or all of
           standard input, standard output, and standard error for
           the process.

           The `stdin` argument can be any of the following:

               * An :class:`SSHReader` object
               * An :class:`asyncio.StreamReader` object
               * A file object open for read
               * An `int` file descriptor open for read
               * A connected socket object
               * A string or :class:`PurePath <pathlib.PurePath>` containing
                 the name of a file or device to open
               * `DEVNULL` to provide no input to standard input
               * `PIPE` to interactively write standard input

           The `stdout` and `stderr` arguments can be any of the following:

               * An :class:`SSHWriter` object
               * An :class:`asyncio.StreamWriter` object
               * A file object open for write
               * An `int` file descriptor open for write
               * A connected socket object
               * A string or :class:`PurePath <pathlib.PurePath>` containing
                 the name of a file or device to open
               * `DEVNULL` to discard standard error output
               * `PIPE` to interactively read standard error output

           The `stderr` argument also accepts the value `STDOUT` to
           request that standard error output be delivered to stdout.

           File objects passed in can be associated with plain files, pipes,
           sockets, or ttys.

           The default value of `None` means to not change redirection
           for that stream.

           .. note:: While it is legal to use buffered I/O streams such
                     as sys.stdin, sys.stdout, and sys.stderr as redirect
                     targets, you must make sure buffers are flushed
                     before redirection begins and that these streams
                     are put back into blocking mode before attempting
                     to go back using buffered I/O again. Also, no buffered
                     I/O should be performed while redirection is active.

           .. note:: When passing in asyncio streams, it is the responsibility
                     of the caller to close the associated transport when it
                     is no longer needed.

           :param stdin:
               Source of data to feed to standard input
           :param stdout:
               Target to feed data from standard output to
           :param stderr:
               Target to feed data from standard error to
           :param bufsize:
               Buffer size to use when forwarding data from a file
           :param send_eof:
               Whether or not to send EOF to the channel when EOF is
               received from stdin, defaulting to `True`. If set to `False`,
               the channel will remain open after EOF is received on stdin,
               and multiple sources can be redirected to the channel.
           :param recv_eof:
               Whether or not to send EOF to stdout and stderr when EOF is
               received from the channel, defaulting to `True`. If set to
               `False`, the redirect targets of stdout and stderr will remain
               open after EOF is received on the channel and can be used for
               multiple redirects.
           :type bufsize: `int`
           :type send_eof: `bool`
           :type recv_eof: `bool`

        N)r  r  r!   r@   r  rc  rd  r   r  rD  s          rA   redirectzSSHClientProcess.redirect  s     b %%eWhIII%%fgxJJJ%%fgx&:< < <  J K<1   A*A$A*A&"A*A(A*&A*(A*r  c                 L   K   | j                  |dd||d       d{    y7 wz&Redirect standard input of the processNTr  r@   r  r   r  s       rA   redirect_stdinzSSHClientProcess.redirect_stdinm  s$     
 mmFD$4HHH   $"$r  c                 L   K   | j                  d|d|d|       d{    y7 wz'Redirect standard output of the processNTr  r@   r  r   rD  s       rA   redirect_stdoutz SSHClientProcess.redirect_stdoutt  s$     
 mmD&$xHHHr  c                 L   K   | j                  dd||d|       d{    y7 wz&Redirect standard error of the processNTr  r  s       rA   redirect_stderrz SSHClientProcess.redirect_stderr{  s$     
 mmD$xHHHr  c                 L    | j                         | j                  t              fS )a  Collect output from the process without blocking

           This method returns a tuple of the output that the process
           has written to stdout and stderr which has not yet been read.
           It is intended to be called instead of read() by callers
           that want to collect received data without blocking.

           :returns: A tuple of output to stdout and stderr

        )r  r!   rJ   s    rA   collect_outputzSSHClientProcess.collect_output  s)     $$&$$%9:< 	<rS   inputc                    K   d| _         | j                          |r5| j                  j                  |       | j                  j	                          | j                          d{    | j                         S 7 w)a  Send input to and/or collect output from the process

           This method is a coroutine which optionally provides input
           to the process and then waits for the process to exit,
           returning a tuple of the data written to stdout and stderr.

           :param input:
               Input data to feed to standard input of the process. Data
               should be a `str` if encoding is set, or `bytes` if not.
           :type input: `str` or `bytes`

           :returns: A tuple of output to stdout and stderr

        r   N)_limitr  r  rH   re   r  r!  )r@   r"  s     rA   communicatezSSHClientProcess.communicate  sf     " ""$JJU#JJ  "   ""$$ 	!s   A"A;$A9%A;r  r	  r
  r  c                 @    | j                   j                  ||||       y)a  Change the terminal window size for this process

           This method changes the width and height of the terminal
           associated with this process.

           :param width:
               The width of the terminal in characters
           :param height:
               The height of the terminal in characters
           :param pixwidth: (optional)
               The width of the terminal in pixels
           :param pixheight: (optional)
               The height of the terminal in pixels
           :type width: `int`
           :type height: `int`
           :type pixwidth: `int`
           :type pixheight: `int`

           :raises: :exc:`OSError` if the SSH channel is not open

        N)r  r  )r@   r  r	  r
  r  s        rA   r  z%SSHClientProcess.change_terminal_size  s    0 	

''vxKrS   r  c                 :    | j                   j                  |       y)zSend a break to the process

           :param msec:
               The duration of the break in milliseconds
           :type msec: `int`

           :raises: :exc:`OSError` if the SSH channel is not open

        N)r  r  )r@   r  s     rA   r  zSSHClientProcess.send_break  s     	

d#rS   rh  c                 :    | j                   j                  |       y)zSend a signal to the process

           :param signal:
               The signal to deliver
           :type signal: `str`

           :raises: :exc:`OSError` if the SSH channel is not open

        N)r  r  )r@   rh  s     rA   r  zSSHClientProcess.send_signal  s     	

v&rS   c                 8    | j                   j                          y)zbTerminate the process

           :raises: :exc:`OSError` if the SSH channel is not open

        N)r  	terminaterJ   s    rA   r*  zSSHClientProcess.terminate  s     	

rS   c                 8    | j                   j                          y)zfForcibly kill the process

           :raises: :exc:`OSError` if the SSH channel is not open

        N)r  killrJ   s    rA   r,  zSSHClientProcess.kill  s     	

rS   checktimeoutc                   K   	 t        j                  | j                         |       d{   \  }}|rZ| j                  rNt        | j
                  | j                  | j                  | j                  | j                  | j                  ||      t        | j
                  | j                  | j                  | j                  | j                  | j                  ||      S 7 # t         j                  $ rc | j	                         \  }}t        | j
                  | j                  | j                  | j                  | j                  | j                  ||      dw xY ww)a2  Wait for process to exit

           This method is a coroutine which waits for the process to
           exit. It returns an :class:`SSHCompletedProcess` object with
           the exit status or signal information and the output sent
           to stdout and stderr if those are redirected to pipes.

           If the check argument is set to `True`, a non-zero exit
           status from the process with trigger the :exc:`ProcessError`
           exception to be raised.

           If a timeout is specified and it expires before the process
           exits, the :exc:`TimeoutError` exception will be raised. By
           default, no timeout is set and this call will wait indefinitely.

           :param check:
               Whether or not to raise an error on non-zero exit status
           :param timeout:
               Amount of time in seconds to wait for process to exit, or
               `None` to wait indefinitely
           :type check: `bool`
           :type timeout: `int`, `float`, or `None`

           :returns: :class:`SSHCompletedProcess`

           :raises: | :exc:`ProcessError` if check is set to `True`
                      and the process returns a non-zero exit status
                    | :exc:`TimeoutError` if the timeout expires
                      before the process exits

        N)r   wait_forr%  rl  r!  r]  r^  r_  r`  ra  rb  r[  rn  )r@   r-  r.  stdout_datastderr_datas        rA   r  zSSHClientProcess.wait  s'    D		6&&t'7'7'97CC %K T%%txxt~~#//1A1A#[J J 'txxt~~'+'7'79I9I'+'24 4 D## 	6'+':':'<$Ktxxt~~#//1A1A#*, 266	6s-   E'C CC B*EC A6EErM   rx   )r   r   )FN).rN   rO   rP   rQ   r   r	   ro  rz   r/   r  r  r  r   rR   r`  r   r   r   ra  rb  r1   r  r0   rc  rd  rg   r1  ioDEFAULT_BUFFER_SIZEr  r  r  r  r  r  r!  r%  r  r  r  r*  r,  floatrn  r  r   r   s   @rA   r0  r0    s   $F##f%%9: :F :Q ,Xc] , ,
 ,XeCsC,?&@A , ,
 +HSM + +
 y(   	&)   	&)  	/) 	/ 	/ ?C9=9=%'%;%;(,t	Y<H]$; Y<'6Y<'6Y< !$Y< "&	Y< 9=	Y< IM	Y<x -/,B,B.2I= I&)I'+I7;I .0-C-C/3IM I'*I(,I8<I .0-C-C/3IM I'*I(,I8<I<ffn 5 < %x'7 %&&.!%< BCL# Ls L'*L;>LGKL4$s $t $'# '$ ' (-.254 54$UO547J54rS   r0  c                       e Zd ZU dZee   ed<   ee   ed<   dedee	   de
def fdZd	ee   d
ee   dee   ded   fdZedee   fd       Zedefd       Zedefd       Zedee   fd       Zedee   fd       Zedee   fd       Zdeddf fdZdddej<                  ddfd	ee   d
ee    dee    de
dededdfdZ!ej<                  dfdede
deddfdZ"ej<                  dfde de
deddfdZ#ej<                  dfde de
deddfd Z$dee   fd!Z%de&e
e
e
e
f   fd"Z'd#e
dee
   fd$Z(d%e
ddfd&Z)d'd(e*fd)ed*ed+ed,eddf
d-Z+ xZ,S ).r  zSSH server process handlerr  r   process_factorysftp_factorysftp_version	allow_scpc                 v    t         |   | j                  |||       || _        d | _        d | _        d | _        y rx   )ry   rz   _start_process_process_factoryr  r  r  )r@   r7  r8  r9  r:  r   s        rA   rz   zSSHServerProcess.__init__3  s@     	,,l%y	2 !0374848rS   r  rc  rd  r=   Nc                 N    || _         || _        || _        | j                  |       S )zStart a new server process)r  r  r  r=  )r@   r  rc  rd  s       rA   r<  zSSHServerProcess._start_process?  s*    
 $$T**rS   c                 6    | j                   j                         S )zThe terminal type set by the client

           If the client didn't request a pseudo-terminal, this
           property will be set to `None`.

        )r  get_terminal_typerJ   s    rA   	term_typezSSHServerProcess.term_typeJ  s     zz++--rS   c                 6    | j                   j                         S )ai  The terminal size set by the client

           This property contains a tuple of four `int` values
           representing the width and height of the terminal in
           characters followed by the width and height of the
           terminal in pixels. If the client hasn't set terminal
           size information, the values will be set to zero.

        )r  get_terminal_sizerJ   s    rA   r  zSSHServerProcess.term_sizeU  s     zz++--rS   c                 6    | j                   j                         S )zA mapping containing the TTY modes set by the client

           If the client didn't request a pseudo-terminal, this
           property will be set to an empty mapping.

        )r  get_terminal_modesrJ   s    rA   
term_modeszSSHServerProcess.term_modesc  s     zz,,..rS   c                 6    | j                   J | j                   S )z?The :class:`SSHReader` to use to read from stdin of the processr  rJ   s    rA   r  zSSHServerProcess.stdinn  r   rS   c                 6    | j                   J | j                   S )z?The :class:`SSHWriter` to use to write to stdout of the processr  rJ   s    rA   rc  zSSHServerProcess.stdoutu  r  rS   c                 6    | j                   J | j                   S )z?The :class:`SSHWriter` to use to write to stderr of the processr  rJ   s    rA   rd  zSSHServerProcess.stderr|  r  rS   r`   c                     | j                   j                  d      }|r|j                  |       yt        |   |       y)z+Handle an incoming exception on the channelN)rv  r   rc   ry   exception_received)r@   r`   rC  r   s      rA   rK  z#SSHServerProcess.exception_received  s7     ""4(""3'G&s+rS   Tr   r  rD  c                    K   |r| j                  ||||       d{    |r| j                  ||||       d{    |r"| j                  ||||t               d{    yy7 G7 +7 
w)a^  Perform I/O redirection for the process

           This method redirects data going to or from any or all of
           standard input, standard output, and standard error for
           the process.

           The `stdin` argument can be any of the following:

               * An :class:`SSHWriter` object
               * An :class:`asyncio.StreamWriter` object
               * A file object open for write
               * An `int` file descriptor open for write
               * A connected socket object
               * A string or :class:`PurePath <pathlib.PurePath>` containing
                 the name of a file or device to open
               * `DEVNULL` to discard standard error output
               * `PIPE` to interactively read standard error output

           The `stdout` and `stderr` arguments can be any of the following:

               * An :class:`SSHReader` object
               * An :class:`asyncio.StreamReader` object
               * A file object open for read
               * An `int` file descriptor open for read
               * A connected socket object
               * A string or :class:`PurePath <pathlib.PurePath>` containing
                 the name of a file or device to open
               * `DEVNULL` to provide no input to standard input
               * `PIPE` to interactively write standard input

           File objects passed in can be associated with plain files, pipes,
           sockets, or ttys.

           The default value of `None` means to not change redirection
           for that stream.

           .. note:: When passing in asyncio streams, it is the responsibility
                     of the caller to close the associated transport when it
                     is no longer needed.

           :param stdin:
               Target to feed data from standard input to
           :param stdout:
               Source of data to feed to standard output
           :param stderr:
               Source of data to feed to standard error
           :param bufsize:
               Buffer size to use when forwarding data from a file
           :param send_eof:
               Whether or not to send EOF to the channel when EOF is
               received from stdout or stderr, defaulting to `True`. If
               set to `False`, the channel will remain open after EOF is
               received on stdout or stderr, and multiple sources can be
               redirected to the channel.
           :param recv_eof:
               Whether or not to send EOF to stdin when EOF is received
               on the channel, defaulting to `True`. If set to `False`,
               the redirect target of stdin will remain open after EOF
               is received on the channel and can be used for multiple
               redirects.
           :type bufsize: `int`
           :type send_eof: `bool`
           :type recv_eof: `bool`

        N)r  r  r!   r  s          rA   r  zSSHServerProcess.redirect  s     N %%eWhIII%%fgxJJJ%%fgx&:< < <  J K<r  r  c                 L   K   | j                  |dd|d|       d{    y7 wr  r  r  s       rA   r  zSSHServerProcess.redirect_stdin  s$     
 mmFD$xHHHr  r  c                 L   K   | j                  d|d||d       d{    y7 wr  r  r  s       rA   r  z SSHServerProcess.redirect_stdout  s$     
 mmD&$4HHHr  c                 L   K   | j                  dd|||d       d{    y7 wr  r  r  s       rA   r  z SSHServerProcess.redirect_stderr  s$     
 mmD$4HHHr  c                     | j                   S )a  Return the terminal type set by the client for the process

           This method returns the terminal type set by the client
           when the process was started. If the client didn't request
           a pseudo-terminal, this method will return `None`.

           :returns: A `str` containing the terminal type or `None` if
                     no pseudo-terminal was requested

        )rA  rJ   s    rA   r@  z"SSHServerProcess.get_terminal_type  s     ~~rS   c                     | j                   S )a  Return the terminal size set by the client for the process

           This method returns the latest terminal size information set
           by the client. If the client didn't set any terminal size
           information, all values returned will be zero.

           :returns: A tuple of four `int` values containing the width and
                     height of the terminal in characters and the width
                     and height of the terminal in pixels

        )r  rJ   s    rA   rC  z"SSHServerProcess.get_terminal_size  s     ~~rS   modec                 8    | j                   j                  |      S )a  Return the requested TTY mode for this session

           This method looks up the value of a POSIX terminal mode
           set by the client when the process was started. If the client
           didn't request a pseudo-terminal or didn't set the requested
           TTY mode opcode, this method will return `None`.

           :param mode:
               POSIX terminal mode taken from :ref:`POSIX terminal modes
               <PTYModes>` to look up
           :type mode: `int`

           :returns: An `int` containing the value of the requested
                     POSIX terminal mode or `None` if the requested
                     mode was not set

        )rF  r   )r@   rR  s     rA   get_terminal_modez"SSHServerProcess.get_terminal_mode  s    & ""4((rS   statusc                 :    | j                   j                  |       y)a%  Send exit status and close the channel

           This method can be called to report an exit status for the
           process back to the client and close the channel.

           :param status:
               The exit status to report to the client
           :type status: `int`

        N)r  exit)r@   rU  s     rA   rW  zSSHServerProcess.exit%  s     	

rS   Fr\  rh  ri  rj  rf  c                 >    | j                   j                  ||||      S )aG  Send exit signal and close the channel

           This method can be called to report that the process
           terminated abnormslly with a signal. A more detailed
           error message may also provided, along with an indication
           of whether or not the process dumped core. After
           reporting the signal, the channel is closed.

           :param signal:
               The signal which caused the process to exit
           :param core_dumped: (optional)
               Whether or not the process dumped core
           :param msg: (optional)
               Details about what error occurred
           :param lang: (optional)
               The language the error message is in
           :type signal: `str`
           :type core_dumped: `bool`
           :type msg: `str`
           :type lang: `str`

        )r  exit_with_signal)r@   rh  ri  rj  rf  s        rA   rY  z!SSHServerProcess.exit_with_signal3  s    2 zz**6;TJJrS   )-rN   rO   rP   rQ   r   r	   ro  SSHServerProcessFactoryr   r5   rR   r   rz   r0   r1   r%   r<  r  r   rA  r'   r  r&   rF  r  rc  rd  rg   rK  r3  r4  r  r  r  r  r  r  r@  r   rC  rT  rW  r    rY  r   r   s   @rA   r  r  -  s   $F##f%%
9(? 
9'(9:
9"
9/3
9	+If$5 	+(0	+(0	+5?5E	+ .8C= . . .8 . . /I / / y(   	&)   	&)  ,i ,D , ?C9=9=&(&<&<(,t	O<H]$; O<'6O<'6O< !$O< "&	O< 9=	O< IM	O<d -/,B,B.2I= I&)I'+I7;I .0-C-C/3IM I'*I(,I8<I .0-C-C/3IM I'*I(,I8<I8C= 5c3);#< )c )hsm )* 3  4   AF$&LKs K K!K.1KEIKrS   r  )krQ   r   asyncio.subprocessr   r   r   r{   r  r3  rl   pathlibr   r  rj   typesr   typingr   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   typing_extensionsr   r   r   r   r   r   	constantsr    r!   loggingr"   miscr#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   sessionr/   streamr0   r1   r2   r3   r4   r5   r   r   r6   _FilerR   r@  r  rL  r  rZ  r   r   r;   rU   r^   r   rq   rs   r   r   r   r   r   BaseProtocolr   r  r!  r,  r6  rB  rN  rU  r[  rl  rn  rq  r0  r  r?   rS   rA   <module>rg     s  *   4 4   	 	     F F F A A 4 4 , C C 9  D D E E D D  : : B %4Hbi445c3x59I**E2 3 c3x59I**E2 3 #$>#?#-d#3$4 5    
"&) 
"
#h 
##h}- #$2e9   O_gfo  OF_V, 2).( )X03~f- 03f.( 69?~f- 9?x1 .('*>*> 1 h>A.('*>*> >AB3_gfo 303_V, 3:.PN6* .Pb:?N6* :?z
_V, 
OF+ &=95 =9B<!5!5  *!& *!ZX!76? Xvk4z&)+A&+I k4\_Kz&)+A&+I _KrS   