a
   d)(e                
   @   s   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\ZZzd dlZW n( eyp Z	 ze	ZW Y dZ	[	n
dZ	[	0 0 d dl
mZ d dlmZ G dd deZdS )    N)select)NN)ProxyCommandFailure)ClosingContextManagerc                   @   sP   e Zd ZdZdd Zdd Zdd Zdd	 Zed
d Z	edd Z
dd ZdS )ProxyCommanda  
    Wraps a subprocess running ProxyCommand-driven programs.

    This class implements a the socket-like interface needed by the
    `.Transport` and `.Packetizer` classes. Using this class instead of a
    regular socket makes it possible to talk with a Popen'd command that will
    proxy traffic between the client and a server hosted in another machine.

    Instances of this class may be used as context managers.
    c                 C   s@   t du rtt|| _t j| jt jt jt jdd| _d| _dS )a  
        Create a new CommandProxy instance. The instance created by this
        class can be passed as an argument to the `.Transport` class.

        :param str command_line:
            the command that should be executed and used as the proxy.
        Nr   )stdinstdoutstderrbufsize)	
subprocesssubprocess_import_errorshlexsplitcmdPopenPIPEprocesstimeout)selfZcommand_line r   2/usr/lib/python3.9/site-packages/paramiko/proxy.py__init__3   s    zProxyCommand.__init__c              
   C   sT   z| j j| W n8 tyJ } z td| j|jW Y d}~n
d}~0 0 t|S )z
        Write the content received from the SSH client to the standard
        input of the forked command.

        :param str content: string to be sent to the forked command
         N)	r   r   writeIOErrorr   joinr   strerrorlen)r   Zcontenter   r   r   sendG   s
    *zProxyCommand.sendc           
   
   C   s  zd}t   }t||k rd}| jdurPt   | }|| jkrFt | j| }t| jjgg g |\}}}|r|d | jjkr|t| jj	 |t| 7 }q|W S  tjy   |r| Y S  Y n: t
 y }	 z td| j|	jW Y d}	~	n
d}	~	0 0 dS )z
        Read from the standard output of the forked program.

        :param int size: how many chars should be read

        :return: the string of bytes read, which may be shorter than requested
            Nr   r   )timer   r   socketr   r   r   osreadfilenor   r   r   r   r   )
r   sizebufferstartZselect_timeoutelapsedrwxr   r   r   r   recvX   s,    


zProxyCommand.recvc                 C   s   t | jjtj d S N)r"   killr   pidsignalSIGTERMr   r   r   r   closey   s    zProxyCommand.closec                 C   s   | j jd uS r-   )r   
returncoder2   r   r   r   closed|   s    zProxyCommand.closedc                 C   s   | j S r-   )r5   r2   r   r   r   _closed   s    zProxyCommand._closedc                 C   s
   || _ d S r-   )r   )r   r   r   r   r   
settimeout   s    zProxyCommand.settimeoutN)__name__
__module____qualname____doc__r   r   r,   r3   propertyr5   r6   r7   r   r   r   r   r   '   s   !

r   )r"   r   r0   r   r!   r    r
   r   ImportErrorr   Zparamiko.ssh_exceptionr   Zparamiko.utilr   r   r   r   r   r   <module>   s   