o
    ¯bð&  ã                   @   sT   d Z ddlmZ ddlmZ ddlmZ ddlmZ eej	ƒG dd„ dejƒƒZ
dS )	z‘
The parent class for all the SSH Channels.  Currently implemented channels
are session, direct-tcp, and forwarded-tcp.

Maintainer: Paul Swartz
é    )Úimplementer)Ú
interfaces)ÚLogger)Úlogc                   @   sè   e Zd ZU dZeƒ ZdZeed< 							d0dd„Z	de
fdd	„Zdefd
d„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ ZdS )1Ú
SSHChannelaº  
    A class that represents a multiplexed channel over an SSH connection.
    The channel has a local window which is the maximum amount of data it will
    receive, and a remote which is the maximum amount of data the remote side
    will accept.  There is also a maximum packet size for any individual data
    packet going each way.

    @ivar name: the name of the channel.
    @type name: L{bytes}
    @ivar localWindowSize: the maximum size of the local window in bytes.
    @type localWindowSize: L{int}
    @ivar localWindowLeft: how many bytes are left in the local window.
    @type localWindowLeft: L{int}
    @ivar localMaxPacket: the maximum size of packet we will accept in bytes.
    @type localMaxPacket: L{int}
    @ivar remoteWindowLeft: how many bytes are left in the remote window.
    @type remoteWindowLeft: L{int}
    @ivar remoteMaxPacket: the maximum size of a packet the remote side will
        accept in bytes.
    @type remoteMaxPacket: L{int}
    @ivar conn: the connection this channel is multiplexed through.
    @type conn: L{SSHConnection}
    @ivar data: any data to send to the other side when the channel is
        requested.
    @type data: L{bytes}
    @ivar avatar: an avatar for the logged-in user (if a server channel)
    @ivar localClosed: True if we aren't accepting more data.
    @type localClosed: L{bool}
    @ivar remoteClosed: True if the other side isn't accepting more data.
    @type remoteClosed: L{bool}
    NÚnamer   c                 C   sn   |pd| _ | j | _|pd| _|| _|| _d| _|| _|| _|| _d| _	d| _
g | _d| _d| _d| _d | _d S )Ni   i €  é   ó    r   )ÚlocalWindowSizeÚlocalWindowLeftÚlocalMaxPacketÚremoteWindowLeftÚremoteMaxPacketÚ
areWritingÚconnÚdataÚavatarÚspecificDataÚbufÚextBufÚclosingÚlocalClosedÚremoteClosedÚid)ÚselfÚlocalWindowr   ÚremoteWindowr   r   r   r   © r   ú;/usr/lib/python3/dist-packages/twisted/conch/ssh/channel.pyÚ__init__9   s    



zSSHChannel.__init__Úreturnc                 C   s   |   ¡  d¡S )NÚascii)Ú	__bytes__Údecode©r   r   r   r   Ú__str__T   s   zSSHChannel.__str__c                 C   s    | j }|sd}d|| j| jf S )zD
        Return a byte string representation of the channel
        s   Nones   <SSHChannel %b (lw %d rw %d)>)r   r   r   )r   r   r   r   r   r"   W   s   ýzSSHChannel.__bytes__c                 C   sL   | j d ur
t| j ƒpd}| jr| j d¡}nd}d|› d|› d| j ¡ › �S )NÚunknownr!   ÚNonezSSHChannel z (z) on )r   Ústrr   r#   r   Ú	logPrefix)r   r   r   r   r   r   r)   e   s
   zSSHChannel.logPrefixc                 C   ó   | j  d¡ dS )z²
        Called when the channel is opened.  specificData is any data that the
        other side sent us when opening the channel.

        @type specificData: L{bytes}
        zchannel openN©Ú_logÚinfo)r   r   r   r   r   ÚchannelOpenm   s   zSSHChannel.channelOpenc                 C   ó   | j jd|d� dS )zµ
        Called when the open failed for some reason.
        reason.desc is a string descrption, reason.code the SSH error code.

        @type reason: L{error.ConchError}
        z(other side refused open
reason: {reason})ÚreasonN)r,   Úerror)r   r0   r   r   r   Ú
openFailedv   ó   zSSHChannel.openFailedc                 C   sv   | j | | _ | js| jsd| _|  ¡  | jr!| j}d| _|  |¡ | jr7| j}g | _|D ]\}}|  ||¡ q,dS dS )z”
        Called when bytes are added to the remote window.  By default it clears
        the data buffers.

        @type data:    L{bytes}
        Tr	   N)r   r   r   ÚstartWritingr   Úwriter   ÚwriteExtended)r   r   ÚbÚtyper   r   r   ÚaddWindowBytes   s   
üzSSHChannel.addWindowBytesc                 C   sB   |  dd¡ d¡}t| d| dƒ}|r||ƒS | jjd|d� dS )	aJ  
        Called when a request is sent to this channel.  By default it delegates
        to self.request_<requestType>.
        If this function returns true, the request succeeded, otherwise it
        failed.

        @type requestType:  L{bytes}
        @type data:         L{bytes}
        @rtype:             L{bool}
        ó   -ó   _r!   Úrequest_Nz#unhandled request for {requestType})ÚrequestTyper   )Úreplacer#   Úgetattrr,   r-   )r   r=   r   ÚfooÚfr   r   r   ÚrequestReceived”   s   zSSHChannel.requestReceivedc                 C   r/   )zL
        Called when we receive data.

        @type data: L{bytes}
        zgot data {data})r   N©r,   Údebug©r   r   r   r   r   ÚdataReceived¦   s   zSSHChannel.dataReceivedc                 C   s   | j jd||d� dS )z�
        Called when we receive extended data (usually standard error).

        @type dataType: L{int}
        @type data:     L{str}
        z%got extended data {dataType} {data!r})ÚdataTyper   NrC   ©r   rG   r   r   r   r   ÚextReceived®   s   
ÿzSSHChannel.extReceivedc                 C   r*   )zD
        Called when the other side will send no more data.
        z
remote eofNr+   r$   r   r   r   ÚeofReceived¹   s   zSSHChannel.eofReceivedc                 C   s   | j  d¡ |  ¡  dS )zD
        Called when the other side has closed the channel.
        zremote closeN)r,   r-   ÚloseConnectionr$   r   r   r   ÚcloseReceived¿   s   zSSHChannel.closeReceivedc                 C   r*   )zˆ
        Called when the channel is closed.  This means that both our side and
        the remote side have closed the channel.
        ÚclosedNr+   r$   r   r   r   rM   Æ   s   zSSHChannel.closedc                 C   sÆ   | j r|  j |7  _ dS t|ƒ}|| jkr/|d| j… || jd… }| _ d| _|  ¡  | j}| j}| jj}td||ƒ}|D ]}|| |||| … ƒ q>|  j|8  _| j	r_| j sa|  
¡  dS dS dS )zõ
        Write some data to the channel.  If there is not enough remote window
        available, buffer until it is.  Otherwise, split the data into
        packets of length remoteMaxPacket and send them.

        @type data: L{bytes}
        Nr   )r   Úlenr   r   ÚstopWritingr   r   ÚsendDataÚranger   rK   )r   r   ÚtopÚrmpr5   ÚrÚoffsetr   r   r   r5   Í   s(   
þÿzSSHChannel.writec                 C   s  | j r#| j d d |kr| j d d  |7  < dS | j  ||g¡ dS t|ƒ| jkrD|d| j… ||| jd… gg}| _ d| _|  ¡  t|ƒ| jkrn| j | ||d| j… ¡ || jd… }|  j| j8  _t|ƒ| jksK|r�| j | ||¡ |  jt|ƒ8  _| j	rŠ|  
¡  dS dS )a  
        Send extended data to this channel.  If there is not enough remote
        window available, buffer until there is.  Otherwise, split the data
        into packets of length remoteMaxPacket and send them.

        @type dataType: L{int}
        @type data:     L{bytes}
        éÿÿÿÿr   r   N)r   ÚappendrN   r   r   rO   r   r   ÚsendExtendedDatar   rK   rH   r   r   r   r6   ê   s.   	ÿþýÿzSSHChannel.writeExtendedc                 C   s   |   d |¡¡ dS )zŠ
        Part of the Transport interface.  Write a list of strings to the
        channel.

        @type data: C{list} of L{str}
        r	   N)r5   ÚjoinrE   r   r   r   ÚwriteSequence
  r3   zSSHChannel.writeSequencec                 C   s*   d| _ | js| js| j | ¡ dS dS dS )zr
        Close the channel if there is no buferred data.  Otherwise, note the
        request and return.
        r   N)r   r   r   r   Ú	sendCloser$   r   r   r   rK     s   ÿzSSHChannel.loseConnectionc                 C   ó   | j j ¡ S )z�
        See: L{ITransport.getPeer}

        @return: The remote address of this connection.
        @rtype: L{SSHTransportAddress}.
        )r   Ú	transportÚgetPeerr$   r   r   r   r^     ó   zSSHChannel.getPeerc                 C   r\   )z™
        See: L{ITransport.getHost}

        @return: An address describing this side of the connection.
        @rtype: L{SSHTransportAddress}.
        )r   r]   ÚgetHostr$   r   r   r   r`   %  r_   zSSHChannel.getHostc                 C   ó   dS )z‡
        Called when the remote buffer is full, as a hint to stop writing.
        This can be ignored, but it can be helpful.
        Nr   r$   r   r   r   rO   .  ó    zSSHChannel.stopWritingc                 C   ra   )ze
        Called when the remote buffer has more room, as a hint to continue
        writing.
        Nr   r$   r   r   r   r4   4  rb   zSSHChannel.startWriting)r   r   r   r   NNN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r,   r   ÚbytesÚ__annotations__r   r(   r%   r"   r)   r.   r2   r9   rB   rF   rI   rJ   rL   rM   r5   r6   rZ   rK   r^   r`   rO   r4   r   r   r   r   r      s@   
  
ø		 				r   N)rf   Úzope.interfacer   Útwisted.internetr   Útwisted.loggerr   Útwisted.pythonr   Ú
ITransportr   r   r   r   r   Ú<module>   s   