%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /lib/python3/dist-packages/twisted/protocols/__pycache__/
Upload File :
Create Path :
Current File : //lib/python3/dist-packages/twisted/protocols/__pycache__/ftp.cpython-312.pyc

�

Ϫ�f���p	�dZddlZddlZddlZddlZddlZddlZ	ddlZddlZddl
mZmZddl
mZddlmZmZmZmZddlmZmZmZmZmZddlmZmZddlmZmZm Z d	Z!d
Z"dZ#dZ$d
Z%dZ&dZ'dZ(dZ)dZ*dZ+dZ,dZ-dZ.dZ/dZ0dZ1dZ2dZ3dZ4dZ5dZ6dZ7d Z8d!Z9d"Z:d#Z;d$Z<d%Z=d&Z>d'Z?d(Z@d)ZAd*ZBd+ZCd,ZDd-ZEd.ZFd/ZGd0ZHd1ZId2ZJd3ZKd4ZLd5ZMd6ZNd7ZOd8ZPd9ZQd:ZRd;ZSd<ZTd=ZUd>ZVd?ZWd@ZXdAZYdBZZie!dC�e"dD�e#dE�e$dF�e%dG�e&dH�e'dI�e(dJ�e)dK�e*dLdMg�e+dN�e,dO�e-dP�e.dQ�e0dR�e/dS�e1dT�ie2dU�e3dV�e4dW�e5dX�e6dY�e7dZ�e8d[�e9d\�e:d]�e;d^�e<d_�e=d`�e>da�e?db�e@dc�eAdd�eBde��ieCdf�eDdg�eEdh�eFdi�eGdj�eHdk�eIdl�eJdm�eKdn�eLdo�eMdp�eNdq�eOdr�ePds�eQdt�eRdu�eSdv��eTdweVdxeWdyeUdzeXd{eYd|eZd}i�Z[Gd~�de\�Z]d��Z^d��Z_ej�d��Zad�d��ZbGd��d�e\�ZcGd��d�ec�ZdGd��d�ec�ZeGd��d�ec�ZfGd��d�ec�ZgGd��d�ec�ZhGd��d�ec�ZiGd��d�ec�ZjGd��d�ec�ZkGd��d�ec�ZlGd��d�ec�ZmGd��d�e\�ZnGd��d�e\�ZoGd��d�ec�ZpGd��d�ec�Zqd��Zrgd��Zseej��Gd��d�ej���ZvGd��d�ej��ZxGd��d��Zyeej��Gd��d���ZzGd��d�ej��Z|Gd��d�ej�ej��Z~Gd��d�ej��Z�Gd��d�e�Z�Gd��d�e�Z�Gd��d�e�Z�d��Z�d�d��Z�ee��Gd��d���Z�ee��Gd��d���Z�Gd��d�e��Z�ee��Gd��d���Z�ee�j�Gd„dë�Z�GdĄd�e��Z�GdƄd�e��Z�GdȄd�en�Z�Gdʄd�en�Z�Gd̄d�en�Z�Gd΄d�en�Z�GdЄd�en�Z�Gd҄dӫZ�GdԄd�ej��Z�Gdքd�ej��Z�ee��Gd؄d�ej���Z�dڄZ�dۄZ�d܄Z�Gd݄d�e�j4�Z�Gd߄d�ej��Z�Gd�d�ej��Z�Gd�d�e��Z�Gd�d�ej��Z�d�Z�y#e	$rdxZZY���wxYw)�z 
An FTP protocol implementation
�N)�	Interface�implementer)�	copyright)�checkers�credentials�error�portal)�deferr�
interfaces�protocol�reactor)�basic�policies)�failure�filepath�log�100�120�125�150z200.1z200.2z200.3�202z211.1z211.2�212�213�214�215z220.1z220.2z221.1z221.2�225z226.1z226.2�227�229z230.1z230.2�250z257.1z257.2z331.1z331.2�332�350z421.1z421.2�425�426�450�451�452�500�501z502.1z502.2�503�504z530.1z530.2�532z550.1z550.2z550.3z550.4z550.5z550.6z550.7�551�552�553z110 MARK yyyy-mmmmz120 service ready in %s minutesz3125 Data connection already open, starting transferz4150 File status okay; about to open data connection.z200 Command OKz200 Type set to %s.z200 PORT OKz5202 Command not implemented, superfluous at this sitez211 System status replyz
211-Features:z211 Endz212 %sz213 %sz214 help: %sz215 UNIX Type: L8z220 %sz220 Service readyz&221 Service closing control connectionz221 Goodbye.z1225 data connection open, no transfer in progressz226 Abort successfulz226 Transfer Complete.z227 Entering Passive Mode (%s).z,229 Entering Extended Passive Mode (|||%s|).z230 User logged in, proceedz2230 Anonymous login ok, access restrictions apply.z&250 Requested File Action Completed OKz257 "%s"z257 "%s" createdz331 Password required for %s.z8331 Guest login ok, type your email address as password.z332 Need account for login.z6350 Requested file action pending further information.z6421 Service not available, closing control connection.z9421 Too many users right now, try again in a few minutes.z425 Can't open data connection.z.426 Transfer aborted.  Data connection closed.z/450 Requested action aborted. File unavailable.z8451 Requested action aborted. Local error in processing.z3452 Requested action aborted. Insufficient storage.z500 Syntax error: %sz#501 syntax error in argument(s) %s.z 502 Command '%s' not implementedz 502 Option '%s' not implemented.z&503 Incorrect sequence of commands: %sz'504 Not implemented for parameter '%s'.z$530 Please login with USER and PASS.z!530 Sorry, Authentication failed.z%532 Need an account for storing filesz"550 %s: No such file or directory.z550 %s: Permission denied.z:550 Anonymous users are forbidden to change the filesystemz%550 Cannot rmd, %s is not a directoryz550 %s: File existsz550 %s: is a directoryz"550 Requested action not taken: %sz551 Page type unknownzC552 Requested file action aborted, exceeded file storage allocationz5553 Requested action not taken, file name not allowedc��eZdZdZy)�InvalidPathzL
    Internal exception used to signify an error during parsing a path.
    N)�__name__�
__module__�__qualname__�__doc__���7/usr/lib/python3/dist-packages/twisted/protocols/ftp.pyr0r0�s��r6r0c��|jd�rg}n|dd}|jd�D]V}|dk(s|dk(r�|dk(r|r|j��&t||��d|vsd|vrt||��|j	|��X|S)zn
    Normalize a path, as represented by a list of strings each
    representing one segment of the path.
    �/N�.��..�)�
startswith�split�popr0�append)�cwd�path�segs�ss    r7�
toSegmentsrF�s���
���s�����1�v��
�Z�Z��_�����8�q�B�w��
�$�Y�����
�!�#�t�,�,�
�Q�Y�#��(��c�4�(�(��K�K��N���Kr6c�:�|tjk(rtjt	|��S|tj
k(s|tjk(rtjt|��S|tjk(rtjt|��S|tjk(rtjt|��S|tjk(rtjt|��Stj�S)z?
    Map C{OSError} and C{IOError} to standard FTP errors.
    )�errno�ENOENTr
�fail�FileNotFoundError�EACCES�EPERM�PermissionDeniedError�ENOTDIR�IsNotADirectoryError�EEXIST�FileExistsError�EISDIR�IsADirectoryError)�erCs  r7�errnoToFailurerV�s���	�E�L�L���z�z�+�D�1�2�2�	
�e�l�l�	�a�5�;�;�.��z�z�/��5�6�6�	
�e�m�m�	��z�z�.�t�4�5�5�	
�e�l�l�	��z�z�/�$�/�0�0�	
�e�l�l�	��z�z�+�D�1�2�2��z�z�|�r6�TESTc�x�|sy|d}tj|�}tjd|d�}||k(ryy)a�
    Helper for checking if a FTPShell `segments` contains a wildcard Unix
    expression.

    Only filename globbing is supported.
    This means that wildcards can only be presents in the last element of
    `segments`.

    @type  segments: C{list}
    @param segments: List of path elements as used by the FTP server protocol.

    @rtype: Boolean
    @return: True if `segments` contains a globbing expression.
    F���rW�T)�fnmatch�	translate�_testTranslation�replace)�segments�
globCandidate�globTranslations�nonGlobTranslationss    r7�_isGlobbingExpressionrc�sJ�����R�L�M��(�(��7��*�2�2�6�=�!�L���.�.��r6c��eZdZdZd�Zd�Zy)�FTPCmdErrorz-
    Generic exception for FTP commands.
    c�>�tj|g|���||_y�N)�	Exception�__init__�errorMessage)�self�msgs  r7rizFTPCmdError.__init__s�����4�&�#�&���r6c�B�t|j|jzS)zA
        Generate a FTP response message for this error.
        )�RESPONSE�	errorCoderj�rks r7�responsezFTPCmdError.responses������'�$�*;�*;�;�;r6N)r1r2r3r4rirqr5r6r7rere
s��� �<r6rec��eZdZdZeZy)rKzH
    Raised when trying to access a non existent file or directory.
    N)r1r2r3r4�FILE_NOT_FOUNDror5r6r7rKrKs����Ir6rKc��eZdZdZeZy)�AnonUserDeniedErrorz[
    Raised when an anonymous user issues a command that will alter the
    filesystem
    N)r1r2r3r4�ANON_USER_DENIEDror5r6r7ruru"s���
!�Ir6ruc��eZdZdZeZy)rNz[
    Raised when access is attempted to a resource to which access is
    not allowed.
    N)r1r2r3r4�PERMISSION_DENIEDror5r6r7rNrN+s���
"�Ir6rNc��eZdZdZeZy)rPzE
    Raised when RMD is called on a path that isn't a directory.
    N)r1r2r3r4�IS_NOT_A_DIRror5r6r7rPrP4�����Ir6rPc��eZdZdZeZy)rRzA
    Raised when attempted to override an existing resource.
    N)r1r2r3r4�FILE_EXISTSror5r6r7rRrR<�����Ir6rRc��eZdZdZeZy)rTzC
    Raised when DELE is called on a path that is a directory.
    N)r1r2r3r4�IS_A_DIRror5r6r7rTrTDs����Ir6rTc��eZdZdZeZy)�CmdSyntaxErrorz0
    Raised when a command syntax is wrong.
    N)r1r2r3r4�
SYNTAX_ERRror5r6r7r�r�Ls����Ir6r�c��eZdZdZeZy)�CmdArgSyntaxErrorz^
    Raised when a command is called with wrong value or a wrong number of
    arguments.
    N)r1r2r3r4�SYNTAX_ERR_IN_ARGSror5r6r7r�r�Ts���
#�Ir6r�c��eZdZdZeZy)�CmdNotImplementedErrorzF
    Raised when an unimplemented command is given to the server.
    N)r1r2r3r4�CMD_NOT_IMPLMNTDror5r6r7r�r�]s���!�Ir6r�c��eZdZdZeZy)�CmdNotImplementedForArgErrorze
    Raised when the handling of a parameter for a command is not implemented by
    the server.
    N)r1r2r3r4�CMD_NOT_IMPLMNTD_FOR_PARAMror5r6r7r�r�es���
+�Ir6r�c��eZdZy)�FTPErrorN�r1r2r3r5r6r7r�r�n���r6r�c��eZdZy)�PortConnectionErrorNr�r5r6r7r�r�rr�r6r�c��eZdZdZeZy)�BadCmdSequenceErrorzS
    Raised when a client sends a series of commands in an illogical sequence.
    N)r1r2r3r4�BAD_CMD_SEQror5r6r7r�r�vr~r6r�c��eZdZdZeZy)�AuthorizationErrorz2
    Raised when client authentication fails.
    N)r1r2r3r4�AUTH_FAILUREror5r6r7r�r�~r{r6r�c�J�tjdt|�zd��y)NzdebugDeferred(): %sT��debug)rrl�str)rk�_s  r7�
debugDeferredr��s���G�G�!�C��F�*�$�7r6)
N�Jan�Feb�Mar�Apr�May�Jun�Jul�Aug�Sep�Oct�Nov�Decc�z�eZdZdZdZdZdZdZd�Zd�Z	d�Z
d�Zd�Zd	�Z
d
�Zd�Zd�Zd
�Zd�Zd�Zd�Zd�Zd�Zy)�DTPFN�latin-1c�j�d|_|jjjd�g|_y�NT)�isConnected�factory�deferred�callback�_bufferrps r7�connectionMadezDTP.connectionMade�s)����������&�&�t�,���r6c�b�d|_|j�|jjd�yy�NF)r��_onConnLostr��rk�reasons  r7�connectionLostzDTP.connectionLost�s/�� ������'����%�%�d�+�(r6c�@�|jj|dz�y)zv
        Send a line to data channel.

        @param line: The line to be sent.
        @type line: L{bytes}
        s
N��	transport�write�rk�lines  r7�sendLinezDTP.sendLine�s��	
�����T�G�^�,r6c	���d�}	d}
|
|xrdxsd|j�||dd|dd||	tj|��d�zj|j�}||zS)a
        Helper method to format one entry's info into a text entry like:
        'drwxrwxrwx   0 user   group   0 Jan 01  1970 filename.txt'

        @param name: C{bytes} name of the entry (file or directory or link)
        @param size: C{int} size of the entry
        @param directory: evals to C{bool} - whether the entry is a directory
        @param permissions: L{twisted.python.filepath.Permissions} object
            representing that entry's permissions
        @param hardlinks: C{int} number of hardlinks
        @param modified: C{float} - entry's last modified time in seconds
            since the epoch
        @param owner: C{str} username of the owner
        @param group: C{str} group name of the owner

        @return: C{str} in the requisite format
        c���tj�}t|j|j|j
|j|jd�}|j
|j
k7rd|zSd|zS)N)�month�day�year�hour�minutez%(month)s %(day)02d %(year)5dz+%(month)s %(day)02d %(hour)02d:%(minute)02d)�time�gmtime�_months�tm_mon�tm_mday�tm_year�tm_hour�tm_min)�mtime�now�infos   r7�
formatDatez.DTP._formatOneListResponse.<locals>.formatDate�sd���+�+�-�C� ����.��}�}��
�
��
�
��,�,��D��{�{�e�m�m�+�6��=�=�D�t�K�Kr6zY%(directory)s%(permissions)s%(hardlinks)4d %(owner)-9s %(group)-9s %(size)15d %(date)12s �d�-N�)�	directory�permissions�	hardlinks�owner�group�size�date)�	shorthandr�r��encode�	_encoding)rk�namer�r�r�r��modifiedr�r�r��formatrls            r7�_formatOneListResponsezDTP._formatOneListResponse�s���*	L�
=�	�
�&�.�3�5�#�*�4�4�6�&��r����r����"�4�;�;�x�#8�9��	
��&����
 �	��T�z�r6c�H�|j|j|g|����yrg)r�r�)rkr�rqs   r7�sendListResponsezDTP.sendListResponse�s!���
�
�1�d�1�1�$�B��B�Cr6c�:�|jj||�Srg�r��registerProducer�rk�producer�	streamings   r7r�zDTP.registerProducer�s���~�~�.�.�x��C�Cr6c�l�|jj�|jj�yrg)r��unregisterProducer�loseConnectionrps r7r�zDTP.unregisterProducer�s"�����)�)�+����%�%�'r6c�f�|jr|jj|�Std��)NzCrap damn crap damn crap damn)r�r�r�rh�rk�datas  r7r�z	DTP.write�s,������>�>�'�'��-�-��7�8�8r6c��	|jj|�y#t$r|jj	�YywxYwrg)�_consr��
BaseExceptionr��errback�rk�bytess  r7�
_conswritezDTP._conswrites:��	'��J�J���U�#���	'����$�$�&�	'�s��#A�Ac�v�|j�|j|�y|jj|�yrg)r�r�r�rAr�s  r7�dataReceivedzDTP.dataReceiveds*���:�:�!��O�O�E�"��L�L����&r6c�L�|jj�d|_|`|Srg)r�r�r��rk�ignoreds  r7�_unregConsumerzDTP._unregConsumer
s$���
�
�%�%�'���
����r6c��|j�J�||_|jj|d�|jD]}|j|��d|_|jr8tj�x|_}|j|j�|S|jj�d|_tjd�Sr�)r�r�r�r�r�r
�Deferredr��addBothrr��succeed)rk�cons�chunkr�s    r7�registerConsumerzDTP.registerConsumers����z�z�!�!�!���
��
�
�#�#�D�$�/��\�\�	#�E��O�O�E�"�	#�������#(�>�>�#3�3�D��q�
�I�I�d�)�)�*��H��J�J�)�)�+��D�J��=�=��&�&r6c�8�|jj�yrg)r��resumeProducingrps r7r
zDTP.resumeProducing#s�����&�&�(r6c�8�|jj�yrg)r��pauseProducingrps r7rzDTP.pauseProducing&������%�%�'r6c�8�|jj�yrg)r��
stopProducingrps r7rzDTP.stopProducing)s�����$�$�&r6)r1r2r3r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrr
rrr5r6r7r�r��si���K��E��K��G��I��
,�
-�4�lD�D�(�9�'�'��'� )�(�'r6r�c�n�eZdZdZe�Ze�Ze�ZeZdZ	dd�Z
d�Zd�Zd�Z
d�Zd	�Zd
�Zy)�
DTPFactorya
    Client factory for I{data transfer process} protocols.

    @ivar peerCheck: perform checks to make sure the ftp-pi's peer is the same
        as the dtp's
    @ivar pi: a reference to this factory's protocol interpreter

    @ivar _state: Indicates the current state of the DTPFactory.  Initially,
        this is L{_IN_PROGRESS}.  If the connection fails or times out, it is
        L{_FAILED}.  If the connection succeeds before the timeout, it is
        L{_FINISHED}.

    @cvar _IN_PROGRESS: Token to signal that connection is active.
    @type _IN_PROGRESS: L{object}.

    @cvar _FAILED: Token to signal that connection has failed.
    @type _FAILED: L{object}.

    @cvar _FINISHED: Token to signal that connection was successfully closed.
    @type _FINISHED: L{object}.
    FNc�~�||_||_tj�|_d|_|�ddlm}||_y)z�
        Constructor

        @param pi: this factory's protocol interpreter
        @param peerHost: if peerCheck is True, this is the tuple that the
            generated instance will use to perform security checks
        Nr�r
)	�pi�peerHostr
rr��delayedCall�twisted.internetr
�_reactor)rkrrr
s    r7rizDTPFactory.__init__Ns7����� ��
����(��
�����?�0���
r6c��tjdd��|j|jury|j|_|j�t
�}||_|j|_||j_	|S)NzDTPFactory.buildProtocolTr�)
rrl�_state�_IN_PROGRESS�	_FINISHED�
cancelTimeoutr�r�r�dtpInstance�rk�addr�ps   r7�
buildProtocolzDTPFactory.buildProtocol_sg�����*�$�7��;�;�d�/�/�/���n�n��������E����	��w�w���������r6c�R�tjdd��|j�y)NzdtpFactory.stopFactoryTr�)rrlrrps r7�stopFactoryzDTPFactory.stopFactoryms�����(��5����r6c��tjd�|j|jury|j|_|j
}d|_|j
ttjd���y)Nz$timed out waiting for DTP connectionzDTPFactory timeout)
rrlrr�_FAILEDr�r�r�r
�TimeoutError)rkr�s  r7�timeoutFactoryzDTPFactory.timeoutFactoryqs]�����6�7��;�;�d�/�/�/���l�l����M�M����
�	�	�	�%�e�&8�&8�9M�&N�O�Pr6c��|j�M|jj�r2tjdd��|jj	�yyy)Nzcancelling DTP timeoutTr�)r�activerrl�cancelrps r7rzDTPFactory.cancelTimeout{sI�����'�D�,<�,<�,C�,C�,E��G�G�,�D�9����#�#�%�-F�'r6c��tjd|z�|jj||j�|_y)Nz'DTPFactory.setTimeout set to %s seconds)rrlr�	callLaterr(r)rk�secondss  r7�
setTimeoutzDTPFactory.setTimeout�s3�����9�G�C�D��=�=�2�2�7�D�<O�<O�P��r6c��|j|jury|j|_|j}d|_|j	t|��yrg)rrr&r�r�r�)rk�	connectorr�r�s    r7�clientConnectionFailedz!DTPFactory.clientConnectionFailed�sD���;�;�d�/�/�/���l�l����M�M����
�	�	�	�%�f�-�.r6)NN)r1r2r3r4�objectrr&rr�	peerCheckrir"r$r(rr/r2r5r6r7rr-sO���,�8�L��h�G���I�
�F��I� �"��Q�&�
Q�/r6rc��eZdZd�Zd�Zy)�ASCIIConsumerWrapperc��||_|j|_|j|_tjdk(s#ttj�dk(sJd��tjdk(r|j|_yy)N�
rZz6Unsupported platform (yea right like this even exists))rr�r��os�linesep�lenr�)rkrs  r7rizASCIIConsumerWrapper.__init__�sr����	� $� 5� 5���"&�"9�"9���
�J�J�&� �C��
�
�O�q�$8�	D�C�	D�8��:�:������D�J� r6c�t�|jj|jtjd��S)Nr8)rr�r^r9r:r�s  r7r�zASCIIConsumerWrapper.write�s$���y�y���u�}�}�R�Z�Z��@�A�Ar6N)r1r2r3rir�r5r6r7r6r6�s
��
$�Br6r6c�(�eZdZdZd�Zd�Zd�Zd�Zy)�FileConsumerz�
    A consumer for FTP input that writes data to a file.

    @ivar fObj: a file object opened for writing, used to write data received.
    @type fObj: C{file}
    c��||_yrg)�fObj�rkr@s  r7rizFileConsumer.__init__�s	����	r6c��||_|sJ�yrg)r�r�s   r7r�zFileConsumer.registerProducer�s�� ��
���yr6c�F�d|_|jj�yrg)r�r@�closerps r7r�zFileConsumer.unregisterProducer�s����
��	�	���r6c�:�|jj|�yrg)r@r�r�s  r7r�zFileConsumer.write�s���	�	����r6N)r1r2r3r4rir�r�r�r5r6r7r>r>�s������r6r>c��eZdZdZdZd�Zy)�FTPOverflowProtocolz:FTP mini-protocol for when there are too many connections.r�c��|jttj|j��|j
j
�yrg)r�rn�TOO_MANY_CONNECTIONSr�r�r�r�rps r7r�z"FTPOverflowProtocol.connectionMade�s3���
�
�h�3�4�;�;�D�N�N�K�L����%�%�'r6N)r1r2r3r4r�r�r5r6r7rGrG�s��D��I�(r6rGc���eZdZdZdZed�\ZZZZ	dZ
dZdZdZ
dZdZdZddgZgd	�Zed
d�Zej*ZdZd
�Z�fd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Z d�Z!d�Z"d�Z#d�Z$d4d�Z%d�Z&d�Z'd�Z(d�Z)d�Z*d �Z+d!�Z,d"�Z-d#�Z.d$�Z/d%�Z0d&�Z1d'�Z2d(�Z3d)�Z4d*�Z5d+�Z6d,�Z7d-�Z8d.�Z9d/�Z:d0�Z;d1�Z<d2�Z=d3�Z>�xZ?S)5�FTPa;
    Protocol Interpreter for the File Transfer Protocol

    @ivar state: The current server state.  One of L{UNAUTH},
        L{INAUTH}, L{AUTHED}, L{RENAMING}.

    @ivar shell: The connected avatar
    @ivar binary: The transfer mode.  If false, ASCII.
    @ivar dtpFactory: Generates a single DTP for this session
    @ivar dtpPort: Port returned from listenTCP
    @ivar listenFactory: A callable with the signature of
        L{twisted.internet.interfaces.IReactorTCP.listenTCP} which will be used
        to create Ports for passive connections (mainly for testing).

    @ivar passivePortRange: iterator used as source of passive port numbers.
    @type passivePortRange: C{iterator}

    @cvar UNAUTH: Command channel is not yet authenticated.
    @type UNAUTH: L{int}

    @cvar INAUTH: Command channel is in the process of being authenticated.
    @type INAUTH: L{int}

    @cvar AUTHED: Command channel was successfully authenticated.
    @type AUTHED: L{int}

    @cvar RENAMING: Command channel is between the renaming command sequence.
    @type RENAMING: L{int}
    F��
NT�FEAT�QUIT)rN�MDTM�PASV�SIZEzTYPE A;IrrZr�c�>�t||z}|j|�yrg)rnr�)rk�key�argsrls    r7�replyz	FTP.reply�s���s�m�d�"���
�
�c�r6c�z��t|t�r|j|j�}t�|�|�y)za
        (Private) Encodes and sends a line

        @param line: L{bytes} or L{unicode}
        N)�
isinstancer�r�r��superr�)rkr��	__class__s  �r7r�zFTP.sendLine�s.����d�C� ��;�;�t�~�~�.�D�
����r6c��|j|_|j|j�|j	t
|jj�yrg)�UNAUTH�stater/�timeOutrV�WELCOME_MSGr��welcomeMessagerps r7r�zFTP.connectionMades5���[�[��
�������%��
�
�;���� ;� ;�<r6c��|jr|j�|jd�t|jd�r0|jj
�|jj�d|_d|_y)N�logout)�
dtpFactory�
cleanupDTPr/�hasattr�shellrbr�r�s  r7r�zFTP.connectionLosts\���?�?��O�O��������4�:�:�x�(�T�Z�Z�->�->�-J��J�J������
���r6c�8�|jj�yrg�r�r�rps r7�timeoutConnectionzFTP.timeoutConnectionr
r6c���	��j��j�ttk7r|j	�j
�}�	�fd�}�fd�}�fd�}|j
d�}|dk7r|d|�	||dzdf}n|�	d}tj�j�	g|���}|j||�|jtj�dd	lm}|j d|j"|�y)
Nc�����jt�r*�j�jj	��y�jt
�r.t
�fd�dD��r�jt��d��ytjd�tj���jtd�y)Nc3�T�K�|]}|�jjdv���!y�w)rN)�valuerU)�.0rl�errs  �r7�	<genexpr>z:FTP.lineReceived.<locals>.processFailed.<locals>.<genexpr>#s+�����.���s�y�y�~�~�a�(�(�.�s�%()z
takes exactlyzrequired positional argumentz requires an argument.zUnexpected FTP errorzinternal server error)
�checkrer�rmrq�	TypeError�anyrVr�rrlro�REQ_ACTN_NOT_TAKEN)ro�cmdrks`��r7�
processFailedz'FTP.lineReceived.<locals>.processFailed s�����y�y��%��
�
�c�i�i�0�0�2�3����9�%�#�.�L�.�+��
�
�:�#��.D�'E�F����.�/�������
�
�-�/F�Gr6c�n��t|t�r�j|�y|��j|�yyrg)rX�tuplerV��resultrks �r7�processSucceededz*FTP.lineReceived.<locals>.processSucceeded-s2����&�%�(���
�
�F�#��#��
�
�6�"�$r6c�@���js�j�yyrg)�disconnectedr
)rrks �r7�allDonez!FTP.lineReceived.<locals>.allDone3s����$�$��$�$�&�%r6� rYrZr5rr)�resetTimeoutrr�r��decoder��findr
�
maybeDeferred�processCommand�addCallbacks�
addErrbackrrorr
r-r)
rkr�rvr{r~�
spaceIndexrUr�r
rus
`        @r7�lineReceivedzFTP.lineReceiveds�������������C�<��;�;�t�~�~�.�D�	H�	#�	'��Y�Y�s�^�
�����{�
�#�C���a��)�*�,�D��C��D����� 3� 3�S�@�4�@��	���'��7�	���S�W�W��
	-�����!�Q�Y�Y��0r6c������fd�}|j�}|�jvr||�S�j�jk(r'|dk(r�j��S|dk(rt
dfStS�j�jk(r|dk(r�j��St
dfS�j�jk(r||�S�j�jk(r|dk(r�j��St
dfSy)Nc�n��t�d|zd�}|�|��Stjt|��S)N�ftp_)�getattrr
rJr�)�command�method�paramsrks  ��r7�call_ftp_commandz,FTP.processCommand.<locals>.call_ftp_commandJs;����T�6�G�#3�T�:�F��!��v��&��:�:�4�W�=�>�>r6�USER�PASSzUSER required before PASSzPASS required after USER�RNTOzRNTO required after RNFR)�upper�PUBLIC_COMMANDSr]r\�ftp_USERr��
NOT_LOGGED_IN�INAUTH�ftp_PASS�AUTHED�RENAMING�ftp_RNTO)rkrur�r�s` ` r7r�zFTP.processCommandIs����	?��i�i�k���$�&�&�&�#�C�(�(�
�Z�Z�4�;�;�
&��f�}�$�t�}�}�f�-�-����"�$?�?�?�$�$�
�Z�Z�4�;�;�
&��f�}�$�t�}�}�f�-�-�"�$>�>�>�
�Z�Z�4�;�;�
&�#�C�(�(�
�Z�Z�4�=�=�
(��f�}�$�t�}�}�f�-�-�"�$>�>�>�	)r6c���|jD]}	|j||�}|cStjdd|j����#tj$rY�TwxYw)ze
        Return a port for passive access, using C{self.passivePortRange}
        attribute.
        r;zNo port available in range )�passivePortRange�
listenFactoryr�CannotListenError)rkr��portn�dtpPorts    r7�
getDTPPortzFTP.getDTPPortls|��
�*�*�	�E�
��,�,�U�G�<����
	��%�%���4�T�5J�5J�4K�L�
�	
��	�*�*�
��
�s�A�A"�!A"c��|stjtd��S||_|j|_|jjr)|j|jjk(rtSt|fS)zc
        First part of login.  Get the username the peer wants to
        authenticate as.
        zUSER requires an argument)r
rJr��_userr�r]r��allowAnonymous�
userAnonymous�GUEST_NAME_OK_NEED_EMAIL�USR_NAME_OK_NEED_PASS)rk�usernames  r7r�zFTP.ftp_USER|sa��
��:�:�n�-H�I�J�J���
��[�[��
��<�<�&�&�4�:�:����9S�9S�+S�+�+�)�8�4�4r6c�~����jjr>�j�jjk(rt	j
�}t�n&t	j�j|�}t��`��fd�}�fd�}�jj|dt�}|j||�|S)zf
        Second part of login.  Get the password the peer wants to
        authenticate with.
        c�~��|\}}}|tusJd��|�_|�_g�_�j�_�S)NzThe realm is busted, jerk.)�	IFTPShellrfrb�workingDirectoryr�r])rz�	interface�avatarrbrVrks    ��r7�_cbLoginzFTP.ftp_PASS.<locals>._cbLogin�sI���*0�'�Y����	�)�G�+G�G�)��D�J� �D�K�$&�D�!����D�J��Lr6c���|jtjtj��j�_t�rg)�trap�
cred_error�UnauthorizedLogin�UnhandledCredentialsr\r]r�)rrks �r7�_ebLoginzFTP.ftp_PASS.<locals>._ebLogin�s0����G�L�L��5�5�z�7V�7V�W����D�J�$�$r6N)
r�r�r�r�r�	Anonymous�GUEST_LOGGED_IN_PROCEED�UsernamePassword�USR_LOGGED_IN_PROCEEDr	�loginr�r�)rk�password�credsr�r�r�rVs`     @r7r�zFTP.ftp_PASS�s����
�<�<�&�&�4�:�:����9S�9S�+S��)�)�+�E�+�E� �0�0����X�F�E�)�E��J�	�	%�

�K�K���e�T�9�5��	���x��*��r6c��|j�|j�t|��|_|jj|j�|j|j�|_|jj�j}|jj�j}|jtt||��|jjjd��S)a�
        Request for a passive connection

        from the rfc::

            This command requests the server-DTP to "listen" on a data port
            (which is not its default data port) and to wait for a connection
            rather than initiate one upon receipt of a transfer command.  The
            response to this command includes the host and port address this
            server is listening on.
        )rc��yrgr5��igns r7�<lambda>zFTP.ftp_PASV.<locals>.<lambda>���r6)rcrdrr/�
dtpTimeoutr�r�r��getHost�host�portrV�ENTERING_PASV_MODE�encodeHostPortr��addCallback)rkr�r�s   r7�ftp_PASVzFTP.ftp_PASV�s����?�?�&�
�O�O��$��-������"�"�4�?�?�3����t���7����~�~�%�%�'�,�,���|�|�#�#�%�*�*���
�
�%�~�d�D�'A�B����'�'�3�3�4D�E�Er6c��ttt|jd���}dt|dd�z}|ddz|dz}|j�|j�t
||jj�j��|_|jj|j�tj|||j�|_d�}d�}|jjj!||�S)	N�,z%d.%d.%d.%drLr��)rrc��tSrg)�ENTERING_PORT_MODE)rs r7�	connectedzFTP.ftp_PORT.<locals>.connected�s��%�%r6c�8�|jt�tSrg)r�r��CANT_OPEN_DATA_CNX�ros r7�
connFailedz FTP.ftp_PORT.<locals>.connFailed�s���H�H�(�)�%�%r6)rx�map�intr?rcrdrr��getPeerr�r/r�r
�
connectTCPr�r�r�)rk�addressr �ipr�r�r�s       r7�ftp_PORTzFTP.ftp_PORT�s����S��g�m�m�C�0�1�2��
�U�4���8�_�
,���A�w�!�|�d�1�g�%���?�?�&��O�O��$��t�~�~�7M�7M�7O�7T�7T�U������"�"�4�?�?�3��)�)�"�d�D�O�O�D���	&�	&����'�'�4�4�Y�
�K�Kr6c�H�t|t�r|jd�S|S)a�
        Encode C{name} to be sent over the wire.

        This encodes L{unicode} objects as UTF-8 and leaves L{bytes} as-is.

        As described by U{RFC 3659 section
        2.2<https://tools.ietf.org/html/rfc3659#section-2.2>}::

            Various FTP commands take pathnames as arguments, or return
            pathnames in responses. When the MLST command is supported, as
            indicated in the response to the FEAT command, pathnames are to be
            transferred in one of the following two formats.

                pathname = utf-8-name / raw
                utf-8-name = <a UTF-8 encoded Unicode string>
                raw = <any string that is not a valid UTF-8 encoding>

            Which format is used is at the option of the user-PI or server-PI
            sending the pathname.

        @param name: Name to be encoded.
        @type name: L{bytes} or L{unicode}

        @return: Wire format of C{name}.
        @rtype: L{bytes}
        zutf-8)rXr�r�)rkr�s  r7�_encodeNamezFTP._encodeName�s"��6�d�C� ��;�;�w�'�'��r6c����j��jjstjt	d��S|j�dvrd}�fd�}	t
�j|�}�jj|d�}|j|�|S#t$r!tjt|��cYSwxYw)a�This command causes a list to be sent from the server to the
        passive DTP.  If the pathname specifies a directory or other
        group of files, the server should transfer a list of files
        in the specified directory.  If the pathname specifies a
        file then the server should send current information on the
        file.  A null argument implies the user's current working or
        default directory.
        �"must send PORT or PASV before RETR)z-az-lz-laz-alr;c�����jt�|D]2\}}�j|�}�jj	||��4�jj
j
�tfSrg)rV�DATA_CNX_ALREADY_OPEN_START_XFRr�rr�r�r��TXFR_COMPLETE_OK)�resultsr��attrsrks   �r7�
gotListingz FTP.ftp_LIST.<locals>.gotListingsl����J�J�6�7�&�
?���e��'�'��-��� � �1�1�$��>�
?�
���&�&�5�5�7�$�&�&r6)r�r�r�r�r�r�r�)
rr�r
rJr��lowerrFr�r0rKrf�listr�)rkrCr�r_r�s`    r7�ftp_LISTzFTP.ftp_LIST�s�������#�4�+;�+;�+G�+G��:�:�1�2V�W�X�X��:�:�<�5�5��D�	'�	7�!�$�"7�"7��>�H�
�J�J�O�O��
�
��	
�
�
�j�!����!�	7��:�:�/��5�6�6�	7�s�B!�!'C�
Cc�����j��jjstjt	d��S	t�j|�}�fd�}�fd�}t|�r|j�}nd}�jj|�}|j||�|j|�|S#t$r!tjt|��cYSwxYw)a\
        This command causes a directory listing to be sent from the server to
        the client. The pathname should specify a directory or other
        system-specific file group descriptor. An empty path implies the
        current working directory. If the path is non-existent, send nothing.
        If the path is to a file, send only the file name.

        @type path: C{str}
        @param path: The path for which a directory listing should be returned.

        @rtype: L{Deferred}
        @return: a L{Deferred} which will be fired when the listing request
            is finished.
        Nr�c�(���jt�|D]M\}}|r|s�tj||�s�"�j|�}�jj|��O�jjj�tfS)a�
            Send, line by line, each matching file in the directory listing,
            and then close the connection.

            @type results: A C{list} of C{tuple}. The first element of each
                C{tuple} is a C{str} and the second element is a C{list}.
            @param results: The names of the files in the directory.

            @param glob: A shell-style glob through which to filter results
                (see U{http://docs.python.org/2/library/fnmatch.html}), or
                L{None} for no filtering.
            @type glob: L{str} or L{None}

            @return: A C{tuple} containing the status code for a successful
                transfer.
            @rtype: C{tuple}
            )	rVr�r[r�rr�r�r�r�)r��globr�rrks    �r7�cbListzFTP.ftp_NLST.<locals>.cbListCs~���$
�J�J�6�7�!(�
4�
��g�������t�)D��+�+�D�1�D��$�$�-�-�d�3�
4�
���&�&�5�5�7�$�&�&r6c�Z���jjj�tfS)a
            RFC 959 specifies that an NLST request may only return directory
            listings. Thus, send nothing and just close the connection.

            @type results: L{Failure}
            @param results: The L{Failure} wrapping a L{FileNotFoundError} that
                occurred while trying to list the contents of a nonexistent
                directory.

            @returns: A C{tuple} containing the status code for a successful
                transfer.
            @rtype: C{tuple}
            )rr�r�r�)r�rks �r7�listErrzFTP.ftp_NLST.<locals>.listErr]s&���
���&�&�5�5�7�$�&�&r6)rr�r
rJr�rFr�r0rKrcr@rfr�r�r�)rkrCr_r�r�r�r�s`      r7�ftp_NLSTzFTP.ftp_NLST+s���� ���#�4�+;�+;�+G�+G��:�:�1�2V�W�X�X�	7�!�$�"7�"7��>�H�	'�4	'�"!��*��<�<�>�D��D��J�J�O�O�H�%��	�
�
�f�d�#�	���W�����s�	7��:�:�/��5�6�6�	7�s�C�'C+�*C+c�����	t�j|����fd�}�jj��j|�S#t$r!tjt|��cYSwxYw)Nc� ����_tfSrg)r��REQ_FILE_ACTN_COMPLETED_OK)rzr_rks ��r7�
accessGrantedz"FTP.ftp_CWD.<locals>.accessGranted�s���$,�D�!�.�0�0r6)	rFr�r0r
rJrKrf�accessr�)rkrCr�r_s`  @r7�ftp_CWDzFTP.ftp_CWD{sg���	7�!�$�"7�"7��>�H�
	1��z�z� � ��*�6�6�}�E�E���	7��:�:�/��5�6�6�	7�s�A
�
'A4�3A4c�$�|jd�S)Nr<)r�rps r7�ftp_CDUPzFTP.ftp_CDUP�s���|�|�D�!�!r6c�J�tddj|j�zfS)Nr9)�	PWD_REPLY�joinr�rps r7�ftp_PWDzFTP.ftp_PWD�s!���3����$�*?�*?�!@�@�A�Ar6c�������	��j�td��	t�j|��	�jd��fd�}�jst�j��n�j�d��d������fd�}�	fd�}�jj�	�}|j||�|j|�|S#t$r!tjt|��cYSwxYw)a�
        This command causes the content of a file to be sent over the data
        transfer channel. If the path is to a folder, an error will be raised.

        @type path: C{str}
        @param path: The path to the file which should be transferred over the
        data transfer channel.

        @rtype: L{Deferred}
        @return: a L{Deferred} which will be fired when the transfer is done.
        Nz!PORT or PASV required before RETRc�R���j�jj�|Srg�r/r�r^rys �r7�
enableTimeoutz#FTP.ftp_RETR.<locals>.enableTimeout������O�O�D�L�L�0�0�1��Mr6c��tfSrg�r��rzs r7�cbSentzFTP.ftp_RETR.<locals>.cbSent�s��$�&�&r6c��tjd�tj|�|jt�r|St
fS)Nz7Unexpected error attempting to transmit file to client:)rrlrorqre�CNX_CLOSED_TXFR_ABORTEDr�s r7�ebSentzFTP.ftp_RETR.<locals>.ebSent�s4���G�G�M�N��G�G�C�L��y�y��%��
�+�-�-r6c�����jjr�jt�n�jt�|j��}|j
���|Srg)rr�rVr��FILE_STATUS_OK_OPEN_DATA_CNX�sendr�)�filer�rrr	rks  ����r7�cbOpenedzFTP.ftp_RETR.<locals>.cbOpened�sL������+�+��
�
�:�;��
�
�7�8��	�	�$��A�
�N�N�6�6�*��Hr6c�<��|jttt�s*t	j
d�t	j|�|jt�r'|jjdj��fStdj��fS)Nz:Unexpected error attempting to open file for transmission:r9)rqrNrKrTrrlrorermror�rs�ro�newsegss �r7�ebOpenedzFTP.ftp_RETR.<locals>.ebOpened�sp����9�9�%�'8�:K�����W�X�������y�y��%��	�	�+�+�S�X�X�g�->�?�?�"�C�H�H�W�$5�6�6r6)rr�rFr�r0r
rJrKr/�binaryr6rf�openForReadingr�r)
rkrCrrrr�rrr	rs
`     @@@@r7�ftp_RETRzFTP.ftp_RETR�s�������#�%�&I�J�J�	7� ��!6�!6��=�G�	
�����	�
�{�{�'��(8�(8�9�D��#�#�D�	'�	.�		�	7�
�J�J�%�%�g�.��	���x��*�	�	�	�-� ����o�	7��:�:�/��5�6�6�	7�s�C�'C5�4C5c������	��j�td��	t�j|��	�jd��fd�}���fd�}�	fd�}�fd��d��d���jj�	�}|j||�|j|�|S#t$r!tjt|��cYSwxYw)	a�
        STORE (STOR)

        This command causes the server-DTP to accept the data
        transferred via the data connection and to store the data as
        a file at the server site.  If the file specified in the
        pathname exists at the server site, then its contents shall
        be replaced by the data being transferred.  A new file is
        created at the server site if the file specified in the
        pathname does not already exist.
        Nz!PORT or PASV required before STORc�R���j�jj�|Srgrrys �r7rz#FTP.ftp_STOR.<locals>.enableTimeout�rr6c�����j�}|j��|j�fd��|j���|S)zx
            File was open for reading. Launch the data transfer channel via
            the file consumer.
            c�$���j�Srg)rD)rr
s �r7r�z0FTP.ftp_STOR.<locals>.cbOpened.<locals>.<lambda>�s
���$�*�*�,�r6)�receiver�r�)r
r��
cbConsumerrr	s` ���r7rzFTP.ftp_STOR.<locals>.cbOpened�s<���
����A�
�M�M�*�%�
�M�M�6�7�
�N�N�6�6�*��Hr6c����t|jt�r'|jjdj	��fStj|d�tdj	��fS)z�
            Called when failed to open the file for reading.

            For known errors, return the FTP error code.
            For all other, return a file not found error.
            r9z-Unexpected error received while opening file:)rXrmreror�rrorsrs �r7rzFTP.ftp_STOR.<locals>.ebOpenedsT����#�)�)�[�1��	�	�+�+�S�X�X�g�->�?�?��G�G�C�H�I�"�C�H�H�W�$5�6�6r6c�����jst|�}�jj|�}�jjr�jt�|S�jt�|S)z�
            Called after the file was opended for reading.

            Prepare the data transfer channel and send the response
            to the command channel.
            )rr6rrr�rVr�r)rr�rks  �r7rz FTP.ftp_STOR.<locals>.cbConsumer
se����;�;�+�D�1��� � �1�1�$�7�A����+�+��
�
�:�;��H��
�
�7�8��Hr6c��tfS)zK
            Called from data transport when transfer is done.
            rrs r7rzFTP.ftp_STOR.<locals>.cbSent!s
��%�&�&r6c�j�tj|d�|jt�r|StfS)zk
            Called from data transport when there are errors during the
            transfer.
            z*Unexpected error received during transfer:)rrorqrerr�s r7r	zFTP.ftp_STOR.<locals>.ebSent's-��

�G�G�C�E�F��y�y��%��
�+�-�-r6)
rr�rFr�r0r
rJrKr/rf�openForWritingr�r)
rkrCrrrr�rrr	rs
`     @@@@r7�ftp_STORzFTP.ftp_STOR�s�������#�%�&I�J�J�	7� ��!6�!6��=�G�	
�����	�		�
	7�	�(	'�	.�
�J�J�%�%�g�.��	���x��*�	�	�	�-� ����[�	7��:�:�/��5�6�6�	7�s�B!�!'C�
Cc���	t|j|�}d�}|jj|d�j|�S#t$r!tjt|��cYSwxYw)ab
        File SIZE

        The FTP command, SIZE OF FILE (SIZE), is used to obtain the transfer
        size of a file from the server-FTP process.  This is the exact number
        of octets (8 bit bytes) that would be transmitted over the data
        connection should that file be transmitted.  This value will change
        depending on the current STRUcture, MODE, and TYPE of the data
        connection or of a data connection that would be created were one
        created now.  Thus, the result of the SIZE command is dependent on
        the currently established STRU, MODE, and TYPE parameters.

        The SIZE command returns how many octets would be transferred if the
        file were to be transferred using the current transfer structure,
        mode, and type.  This command is normally used in conjunction with
        the RESTART (REST) command when STORing a file to a remote server in
        STREAM mode, to determine the restart point.  The server-PI might
        need to read the partially transferred file, do any appropriate
        conversion, and count the number of octets that would be generated
        when sending the file in order to correctly respond to this command.
        Estimates of the file transfer size MUST NOT be returned; only
        precise information is acceptable.

        http://tools.ietf.org/html/rfc3659
        c�,�|\}tt|�fSrg)�FILE_STATUSr�)rzr�s  r7�cbStatzFTP.ftp_SIZE.<locals>.cbStatWs���G�T���T��+�+r6)r��	rFr�r0r
rJrKrf�statr��rkrCrr%s    r7�ftp_SIZEzFTP.ftp_SIZE8sf��4	7� ��!6�!6��=�G�	,��z�z���w�	�2�>�>�v�F�F���	7��:�:�/��5�6�6�	7���A�'A0�/A0c���	t|j|�}d�}|jj|d�j|�S#t$r!tjt|��cYSwxYw)a!
        File Modification Time (MDTM)

        The FTP command, MODIFICATION TIME (MDTM), can be used to determine
        when a file in the server NVFS was last modified.  This command has
        existed in many FTP servers for many years, as an adjunct to the REST
        command for STREAM mode, thus is widely available.  However, where
        supported, the "modify" fact that can be provided in the result from
        the new MLST command is recommended as a superior alternative.

        http://tools.ietf.org/html/rfc3659
        c�h�|\}ttjdtj|��fS)Nz%Y%m%d%H%M%S)r$r��strftimer�)rzr�s  r7r%zFTP.ftp_MDTM.<locals>.cbStatos(�� �K�X�����~�t�{�{�8�?T�!U�V�Vr6)r�r&r(s    r7�ftp_MDTMzFTP.ftp_MDTM]sg��	7� ��!6�!6��=�G�	W��z�z���w�
�6�B�B�6�J�J���	7��:�:�/��5�6�6�	7�r*c��|j�}|r1t|d|dzd�}|�||dd�S|j|�StfS)a
        REPRESENTATION TYPE (TYPE)

        The argument specifies the representation type as described
        in the Section on Data Representation and Storage.  Several
        types take a second parameter.  The first parameter is
        denoted by a single Telnet character, as is the second
        Format parameter for ASCII and EBCDIC; the second parameter
        for local byte is a decimal integer to indicate Bytesize.
        The parameters are separated by a <SP> (Space, ASCII code
        32).
        �type_rNrZ)r�r��type_UNKNOWNr�)rk�typer!�fs    r7�ftp_TYPEzFTP.ftp_TYPEusU��
�J�J�L�����g��!��n�d�3�A��}���1�2��x���$�$�Q�'�'��}�r6c�v�|dk(s|dk(rd|_td|zfStjt	|��S)Nr;�NF�A�r�TYPE_SET_OKr
rJr��rk�codes  r7�type_Az
FTP.type_A�s:���2�:�����D�K���t��,�,��:�:�/��5�6�6r6c�f�|dk(rd|_tdfStjt	|��S)Nr;T�Ir8r:s  r7�type_Iz
FTP.type_I�s0���2�:��D�K���%�%��:�:�/��5�6�6r6c�>�tjt|��Srg)r
rJr�r:s  r7r1zFTP.type_UNKNOWN�s���z�z�6�t�<�=�=r6c��tSrg)�
NAME_SYS_TYPErps r7�ftp_SYSTzFTP.ftp_SYST�s���r6c�v�|j�}|dk(rtfStjt	|��S)N�F�r��CMD_OKr
rJr�)rk�	structurer!s   r7�ftp_STRUzFTP.ftp_STRU�s2���O�O�����8��9���z�z�6�y�A�B�Br6c�v�|j�}|dk(rtfStjt	|��S)N�SrF)rk�moder!s   r7�ftp_MODEzFTP.ftp_MODE�s1���J�J�L����8��9���z�z�6�t�<�=�=r6c����	t|j��}|jj|�j�fd��S#t$r!tjt���cYSwxYw)Nc���t�fSrg)�	MKD_REPLY)r�rCs �r7r�zFTP.ftp_MKD.<locals>.<lambda>�s����D�)�r6)	rFr�r0r
rJrKrf�
makeDirectoryr��rkrCrs ` r7�ftp_MKDzFTP.ftp_MKD�sg���	7� ��!6�!6��=�G��z�z�'�'��0�<�<�)�
�	
���	7��:�:�/��5�6�6�	7�s�A�'A0�/A0c���	t|j|�}|jj|�jd��S#t$r!tjt|��cYSwxYw)Nc��tfSrg�r�r�s r7r�zFTP.ftp_RMD.<locals>.<lambda>��
��3�5�r6)	rFr�r0r
rJrKrf�removeDirectoryr�rRs   r7�ftp_RMDzFTP.ftp_RMD�sf��	7� ��!6�!6��=�G��z�z�)�)�'�2�>�>�5�
�	
���	7��:�:�/��5�6�6�	7���A�'A-�,A-c���	t|j|�}|jj|�jd��S#t$r!tjt|��cYSwxYw)Nc��tfSrgrVr�s r7r�zFTP.ftp_DELE.<locals>.<lambda>�rWr6)	rFr�r0r
rJrKrf�
removeFiler�rRs   r7�ftp_DELEzFTP.ftp_DELE�sf��	7� ��!6�!6��=�G��z�z�$�$�W�-�9�9�5�
�	
���	7��:�:�/��5�6�6�	7�rZc��tfSrg)rGrps r7�ftp_NOOPzFTP.ftp_NOOP�s
���y�r6c�@�||_|j|_tfSrg)�	_fromNamer�r]�"REQ_FILE_ACTN_PENDING_FURTHER_INFO)rk�fromNames  r7�ftp_RNFRzFTP.ftp_RNFR�s��!����]�]��
�2�4�4r6c�L�|j}|`|j|_	t|j|�}t|j|�}|jj||�jd��S#t
$r!t
jt|��cYSwxYw)Nc��tfSrgrVr�s r7r�zFTP.ftp_RNTO.<locals>.<lambda>�rWr6)rbr�r]rFr�r0r
rJrKrf�renamer�)rk�toNamerd�fromsegs�tosegss     r7r�zFTP.ftp_RNTO�s����>�>���N��[�[��
�	;�!�$�"7�"7��B�H��� 5� 5�v�>�F��z�z� � ��6�2�>�>�5�
�	
���	;��:�:�/��9�:�:�	;�s�,A9�9'B#�"B#c���|jttd�|jD]}|jd|z��|jttd�y)zm
        Advertise the features supported by the server.

        http://tools.ietf.org/html/rfc2389
        rrrZN)r�rn�FEAT_OK�FEATURES)rk�features  r7�ftp_FEATzFTP.ftp_FEAT�sS��	
�
�
�h�w�'��*�+��}�}�	)�G��M�M�#��-�(�	)��
�
�h�w�'��*�+r6c�.�|jt|�S)zl
        Handle OPTS command.

        http://tools.ietf.org/html/draft-ietf-ftpext-utf-8-option-00
        )rV�OPTS_NOT_IMPLEMENTED)rk�options  r7�ftp_OPTSzFTP.ftp_OPTS�s���z�z�.��7�7r6c�p�|jt�|jj�d|_yr�)rV�GOODBYE_MSGr�r�r}rps r7�ftp_QUITzFTP.ftp_QUIT�s&���
�
�;�����%�%�'� ��r6c���tjdd��tj|j�|jdc}|_tjj|�r|j
�n:tjj|�r|j�n
Jd|����|jj�d|_	|j�d|_yy)z0
        Call when DTP connection exits
        rdTr�Nz>dtpPort should be an IListeningPort or IConnector, instead is )rrlr�r�IListeningPort�
providedBy�
stopListening�
IConnector�
disconnectrcr$r)rkr�s  r7rdzFTP.cleanupDTP�s���	����D�)�������� $���d������$�$�/�/��8��!�!�#�
�
"�
"�
-�
-�g�
6���� �
�#*�-�
�5�
	
���#�#�%�������'�#�D��(r6)r;)@r1r2r3r4r}�ranger\r�r�r�r�r	rfrcr�rrr�rnr�r
�	listenTCPr�r�rVr�r�r�rir�r�r�r�r�r�r�r�r�r�r�r�r�rr!r)r.r4r<r?r1rCrIrMrSrYr^r`rer�rprtrwrd�
__classcell__)rZs@r7rKrK�sH����<�L�(-�Q�x�$�F�F�F�H��J�
�F��E��J��G��K�
�F��v�&�O�;�H��Q��{���%�%�M��I���=�

�(�-1�^!?�F
� 
5�$�BF�4L�,�>+�ZN�`F�"�B�H�T^�@#G�JK�0�*7�7�>��C�>�
�
�
��5�

�	,�8�!�
$r6rKc�j�eZdZdZeZeZdZdZ	dZ
dej�d�Z
edd�Zd
d
�Zd�Zd�Zy	)�
FTPFactorya
    A factory for producing ftp protocol instances

    @ivar timeOut: the protocol interpreter's idle timeout time in seconds,
        default is 600 seconds.

    @ivar passivePortRange: value forwarded to C{protocol.passivePortRange}.
    @type passivePortRange: C{iterator}
    T�	anonymousiXzTwisted z FTP ServerrrZNc�.�||_||_g|_yrg)r	r��	instances)rkr	r�s   r7rizFTPFactory.__init__!s�����*�����r6c���tjj||�}|�Q|j|j_|j
|j_|j|j_|Srg)r�LimitTotalConnectionsFactoryr"r	�wrappedProtocolr^r�rs   r7r"zFTPFactory.buildProtocol&s\���1�1�?�?��d�K���=�'+�{�{�A���$�(,���A���%�15�1F�1F�A���.��r6c��|jD�cgc] }|j��|jd���"c}tjj|�ycc}wrg)r�r^r/rr�r$)rkr!s  r7r$zFTPFactory.stopFactory.sB��&*�^�^�M��q�y�y�7L����d�	�M��-�-�9�9�$�?��	Ns
�A�A)Nr�)r1r2r3r4rKrrG�overflowProtocolr�r�r^r�versionr`r~r�rir"r$r5r6r7r�r�sT����H�*���N��M��G��	� 1� 1�2�+�>�N��Q��{���
�@r6r�c�J�eZdZdZd�Zd�Zd�Zd�Zd�Zdd�Z	dd�Z
d	�Zd
�Zy)
r�z�
    An abstraction of the shell commands used by the FTP protocol for
    a given user account.

    All path names must be absolute.
    c��y)a
        Create a directory.

        @param path: The path, as a list of segments, to create
        @type path: C{list} of C{unicode}

        @return: A Deferred which fires when the directory has been
        created, or which fails if the directory cannot be created.
        Nr5�rCs r7rQzIFTPShell.makeDirectory@r�r6c��y)a
        Remove a directory.

        @param path: The path, as a list of segments, to remove
        @type path: C{list} of C{unicode}

        @return: A Deferred which fires when the directory has been
        removed, or which fails if the directory cannot be removed.
        Nr5r�s r7rXzIFTPShell.removeDirectoryKr�r6c��y)a

        Remove a file.

        @param path: The path, as a list of segments, to remove
        @type path: C{list} of C{unicode}

        @return: A Deferred which fires when the file has been
        removed, or which fails if the file cannot be removed.
        Nr5r�s r7r]zIFTPShell.removeFileVr�r6c��y)ax
        Rename a file or directory.

        @param fromPath: The current name of the path.
        @type fromPath: C{list} of C{unicode}

        @param toPath: The desired new name of the path.
        @type toPath: C{list} of C{unicode}

        @return: A Deferred which fires when the path has been
        renamed, or which fails if the path cannot be renamed.
        Nr5)�fromPath�toPaths  r7rhzIFTPShell.renamear�r6c��y)a
        Determine whether access to the given path is allowed.

        @param path: The path, as a list of segments

        @return: A Deferred which fires with None if access is allowed
        or which fails with a specific exception type if access is
        denied.
        Nr5r�s r7r�zIFTPShell.accessor�r6c��y)z�
        Retrieve information about the given path.

        This is like list, except it will never return results about
        child paths.
        Nr5�rC�keyss  r7r'zIFTPShell.statzr�r6c��y)ae
        Retrieve information about the given path.

        If the path represents a non-directory, the result list should
        have only one entry with information about that non-directory.
        Otherwise, the result list should have an element for each
        child of the directory.

        @param path: The path, as a list of segments, to list
        @type path: C{list} of C{unicode} or C{bytes}

        @param keys: A tuple of keys desired in the resulting
        dictionaries.

        @return: A Deferred which fires with a list of (name, list),
        where the name is the name of the entry as a unicode string or
        bytes and each list contains values corresponding to the requested
        keys.  The following are possible elements of keys, and the
        values which should be returned for them:

            - C{'size'}: size in bytes, as an integer (this is kinda required)

            - C{'directory'}: boolean indicating the type of this entry

            - C{'permissions'}: a bitvector (see os.stat(foo).st_mode)

            - C{'hardlinks'}: Number of hard links to this entry

            - C{'modified'}: number of seconds since the epoch since entry was
              modified

            - C{'owner'}: string indicating the user owner of this entry

            - C{'group'}: string indicating the group owner of this entry
        Nr5r�s  r7r�zIFTPShell.list�r�r6c��y)z�
        @param path: The path, as a list of segments, to open
        @type path: C{list} of C{unicode}

        @rtype: C{Deferred} which will fire with L{IReadFile}
        Nr5r�s r7rzIFTPShell.openForReading�r�r6c��y)z�
        @param path: The path, as a list of segments, to open
        @type path: C{list} of C{unicode}

        @rtype: C{Deferred} which will fire with L{IWriteFile}
        Nr5r�s r7r zIFTPShell.openForWriting�r�r6N�r5)
r1r2r3r4rQrXr]rhr�r'r�rr r5r6r7r�r�8s5���	�	�	��	��#�J�r6r�c��eZdZdZd�Zy)�	IReadFilez0
    A file out of which bytes may be read.
    c��y)a
        Produce the contents of the given path to the given consumer.  This
        method may only be invoked once on each provider.

        @type consumer: C{IConsumer}

        @return: A Deferred which fires when the file has been
        consumed completely.
        Nr5)�consumers r7rzIReadFile.send�r�r6N)r1r2r3r4rr5r6r7r�r��s���	r6r�c��eZdZdZd�Zd�Zy)�
IWriteFilez1
    A file into which bytes may be written.
    c��y)z�
        Create a consumer which will write to this file.  This method may
        only be invoked once on each provider.

        @rtype: C{Deferred} of C{IConsumer}
        Nr5r5r6r7rzIWriteFile.receive�r�r6c��y)ae
        Perform any post-write work that needs to be done. This method may
        only be invoked once on each provider, and will always be invoked
        after receive().

        @rtype: C{Deferred} of anything: the value is ignored. The FTP client
        will not see their upload request complete until this Deferred has
        been fired.
        Nr5r5r6r7rDzIWriteFile.close�r�r6N)r1r2r3r4rrDr5r6r7r�r��s����	r6r�c��g}tj|�}|j|j�t	j
�D]6}|j|jvs�|j|j��8|S)z_
    Return the primary and supplementary groups for the given UID.

    @type uid: C{int}
    )	�pwd�getpwuidrA�pw_gid�grp�getgrall�pw_name�gr_mem�gr_gid)�uidrz�pwent�grents    r7�
_getgroupsr��sc���F��L�L���E�
�M�M�%�,�,������(���=�=�E�L�L�(��M�M�%�,�,�'�(��Mr6c���|dk(rAtj}tj}tj}tj
}nU|dk(rAtj}tj}tj}tj}ntd|�d���d}tjj|�rn|dk(rd}nft	j|�}	||	jzr||	jk(rd}n0||	jzr|t|�vrd}n||	jzrd}|rDt	j ||�s.d}t#j$d|t	j&�fz�|S)	a�
    checks to see if uid has proper permissions to access path with mode

    @type uid: C{int}
    @param uid: numeric user id

    @type gid: C{int}
    @param gid: numeric group id

    @type spath: C{str}
    @param spath: the path on the server to test

    @type mode: C{str}
    @param mode: 'r' or 'w' (read or write)

    @rtype: C{bool}
    @return: True if the given credentials have the specified form of
        access to the given path
    �r�wz
Invalid mode z: must specify 'r' or 'w'FrTzUFilesystem grants permission to UID %d but it is inaccessible to me running as UID %d)r'�S_IRUSR�S_IRGRP�S_IROTHr9�R_OK�S_IWUSR�S_IWGRP�S_IWOTH�W_OK�
ValueErrorrC�exists�st_mode�st_uidr�r�rrl�getuid)
r��gid�spathrL�usrr��oth�amoder�rEs
          r7�_testPermissionsr��s$��(�s�{��l�l���l�l���l�l������	
����l�l���l�l���l�l�������=���0I�J�K�K�
�F�	�w�w�~�~�e���!�8��F������A��Q�Y�Y��3�!�(�(�?����q�y�y��S�J�s�O�%;����q�y�y����
��y�y���&��F��G�G�7�:=�r�y�y�{�9K�L�
��Mr6c��eZdZdZd�Zd�Zd�Zd�Zd�Zd�Z	d�Z
d	�Zd
�Zd�Z
dd�Zdd
�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zy)�FTPAnonymousShellz�
    An anonymous implementation of IFTPShell

    @type filesystemRoot: L{twisted.python.filepath.FilePath}
    @ivar filesystemRoot: The path which is considered the root of
    this shell.
    c��||_yrg)�filesystemRoot)rkr�s  r7rizFTPAnonymousShell.__init__6s
��,��r6c�8�|jj|�Srg)r��
descendant�rkrCs  r7�_pathzFTPAnonymousShell._path9s���"�"�-�-�d�3�3r6c�<�tjt��Srg�r
rJrur�s  r7rQzFTPAnonymousShell.makeDirectory<����z�z�-�/�0�0r6c�<�tjt��Srgr�r�s  r7rXz!FTPAnonymousShell.removeDirectory?r�r6c�<�tjt��Srgr�r�s  r7r]zFTPAnonymousShell.removeFileBr�r6c�<�tjt��Srgr�)rkr�r�s   r7rhzFTPAnonymousShell.renameEr�r6c�^�|j|�}tjt��Srg)r�r
rJrur�s  r7rzFTPAnonymousShell.receiveHs#���z�z�$����z�z�-�/�0�0r6c�t�|j|�}|j�rtjt	|��S	|jd�}tjt|��S#t$r }t|j|�cYd}~Sd}~wt$rtj�cYSwxYw)a�
        Open C{path} for reading.

        @param path: The path, as a list of segments, to open.
        @type path: C{list} of C{unicode}
        @return: A L{Deferred} is returned that will fire with an object
            implementing L{IReadFile} if the file is successfully opened.  If
            C{path} is a directory, or if an exception is raised while trying
            to open the file, the L{Deferred} will fire with an error.
        r�N)r��isdirr
rJrT�openr�_FileReader�OSErrorrVrHr�)rkrCr!r3rUs     r7rz FTPAnonymousShell.openForReadingLs���
�J�J�t����7�7�9��:�:�/��5�6�6�	1����s��A��=�=��Q��0�0���	1�!�!�'�'�4�0�0���	 ��:�:�<��	 ��$�A0�0	B7�9B�B7� B7�6B7c�>�tjtd��S)za
        Reject write attempts by anonymous users with
        L{PermissionDeniedError}.
        zSTOR not allowed)r
rJrNr�s  r7r z FTPAnonymousShell.openForWritinges��
�z�z�/�0B�C�D�Dr6c�`�|j|�}|j�stjt	|��S	|j�tjd�S#t$r }t|j|�cYd}~Sd}~wt$rtj�cYSwxYwrg)r�r�r
rJrK�listdirrr�rVrHr��rkrCr!rUs    r7r�zFTPAnonymousShell.accessls����J�J�t����x�x�z��:�:�/��5�6�6�	'�
�I�I�K��=�=��&�&���	1�!�!�'�'�4�0�0���	 ��:�:�<��	 ��$�A&�&	B-�/B
�B-�
 B-�,B-c�l�|j|�}|j�r(	|j||�}tj|�S|j||�jd��S#t
$r }t
|j|�cYd}~Sd}~wt$rtj�cYSwxYw)Nc��|ddS)NrrZr5)�ress r7r�z(FTPAnonymousShell.stat.<locals>.<lambda>�s���Q����r6)r�r��	_statNoder
rr�rVrHr�rJr�r�)rkrCr�r!�
statResultrUs      r7r'zFTPAnonymousShell.stat|s����J�J�t����7�7�9�
1�!�^�^�A�t�4�
��}�}�Z�0�0��9�9�T�4�(�4�4�5J�K�K���
5�%�a�g�g�t�4�4�� �
$��z�z�|�#�
$�s#�A,�,	B3�5B�
B3� B3�2B3c���|j|�}|j�r/|j�}|D�cgc]}|j|���}}nh|j	�r:tjj|j|j��g}|g}ntjt|��Sg}t||�D]?\}}g}	|j||	f�|s�	|	j|j!||���Atj*|�Scc}w#t"$r"}
t%|
j&|�cYd}
~
cSd}
~
wt($rtj�cYcSwxYw)a
        Return the list of files at given C{path}, adding C{keys} stat
        informations if specified.

        @param path: the directory or file to check.
        @type path: C{str}

        @param keys: the list of desired metadata
        @type keys: C{list} of C{str}
        N)r�r�r��child�isfiler9rCr��segmentsFromr�r
rJrK�ziprA�extendr�r�rVrHr�r)rkrCr��filePath�entriesr!�fileEntriesr��fileName�entrUs           r7r�zFTPAnonymousShell.list�s3���:�:�d�#���>�>���&�&�(�G�6=�>��8�>�>�!�,�>�K�>�
�_�_�
��w�w�|�|�X�%:�%:�4�;N�;N�%O�P�Q�G�#�*�K��:�:�/��5�6�6���"%�g�{�";�		(��H�h��C��N�N�H�c�?�+��(��J�J�t�~�~�h��=�>�		(��}�}�W�%�%��'?���=�)�!�'�'�8�<�<��$�(� �:�:�<�'�(�s)�D�&!D#�#	E.�,E	�E.�	 E.�-E.c	�r�|j�|D�cgc]}t|d|z�|���c}Scc}w)z�
        Shortcut method to get stat info on a node.

        @param filePath: the node to stat.
        @type filePath: C{filepath.FilePath}

        @param keys: the stat keys to get.
        @type keys: C{iterable}
        �_stat_)�restatr�)rkr�r��ks    r7r�zFTPAnonymousShell._statNode�s5��	����?C�D�!�+���h��l�+�H�5�D�D��Ds�4c�"�|j�S)z�
        Get the filepath's size as an int

        @param fp: L{twisted.python.filepath.FilePath}
        @return: C{int} representing the size
        )�getsize�rk�fps  r7�
_stat_sizezFTPAnonymousShell._stat_size�s���z�z�|�r6c�"�|j�S)z�
        Get the filepath's permissions object

        @param fp: L{twisted.python.filepath.FilePath}
        @return: L{twisted.python.filepath.Permissions} of C{fp}
        )�getPermissionsr�s  r7�_stat_permissionsz#FTPAnonymousShell._stat_permissions�s��� � �"�"r6c�B�	|j�S#t$rYywxYw)a�
        Get the number of hardlinks for the filepath - if the number of
        hardlinks is not yet implemented (say in Windows), just return 0 since
        stat-ing a file in Windows seems to return C{st_nlink=0}.

        (Reference:
        U{http://stackoverflow.com/questions/5275731/os-stat-on-windows})

        @param fp: L{twisted.python.filepath.FilePath}
        @return: C{int} representing the number of hardlinks
        r)�getNumberOfHardLinks�NotImplementedErrorr�s  r7�_stat_hardlinksz!FTPAnonymousShell._stat_hardlinks�s(��	��*�*�,�,��"�	��	�s��	�c�"�|j�S)z�
        Get the filepath's last modified date

        @param fp: L{twisted.python.filepath.FilePath}
        @return: C{int} as seconds since the epoch
        )�getModificationTimer�s  r7�_stat_modifiedz FTPAnonymousShell._stat_modified�s���%�%�'�'r6c���	|j�}t�	tj|�dSt	|�S#t$r
Yt	|�SwxYw#t
$rYywxYw)a�
        Get the filepath's owner's username.  If this is not implemented
        (say in Windows) return the string "0" since stat-ing a file in
        Windows seems to return C{st_uid=0}.

        (Reference:
        U{http://stackoverflow.com/questions/5275731/os-stat-on-windows})

        @param fp: L{twisted.python.filepath.FilePath}
        @return: C{str} representing the owner's username
        r�0)�	getUserIDr�r��KeyErrorr�r�)rkr��userIDs   r7�_stat_ownerzFTPAnonymousShell._stat_owner�so��
	��\�\�^�F�����<�<��/��2�2��v�;��� ����v�;����
#�	��	�� �A�<�	A�A�	A!� A!c���	|j�}t�	tj|�dSt	|�S#t$r
Yt	|�SwxYw#t
$rYywxYw)a�
        Get the filepath's owner's group.  If this is not implemented
        (say in Windows) return the string "0" since stat-ing a file in
        Windows seems to return C{st_gid=0}.

        (Reference:
        U{http://stackoverflow.com/questions/5275731/os-stat-on-windows})

        @param fp: L{twisted.python.filepath.FilePath}
        @return: C{str} representing the owner's group
        rr)�
getGroupIDr��getgrgidrr�r�)rkr��groupIDs   r7�_stat_groupzFTPAnonymousShell._stat_group�so��
	 ��m�m�o�G�����<�<��0��3�3��w�<��� ����w�<����
#�	��	�r
c�"�|j�S)z�
        Get whether the filepath is a directory

        @param fp: L{twisted.python.filepath.FilePath}
        @return: C{bool}
        )r�r�s  r7�_stat_directoryz!FTPAnonymousShell._stat_directorys���x�x�z�r6Nr�)r1r2r3r4rir�rQrXr]rhrrr r�r'r�r�r�r�rrr	rrr5r6r7r�r�,so���-�4�1�1�1�1�1�1�2E�'� L�!&�FE��#��"(��0 �0r6r�c��eZdZd�Zd�Zd�Zy)r�c� �||_d|_yr�)r@�_sendrAs  r7riz_FileReader.__init__"s����	���
r6c�H�d|_|jj�|Sr�)rr@rD)rk�passthroughs  r7�_closez_FileReader._close&s����
��	�	�����r6c���|jrJd��d|_tj�j|j|�}|j|j�|S)Nz0Can only call IReadFile.send *once* per instanceT)rr�
FileSender�beginFileTransferr@rr)rkr�r�s   r7rz_FileReader.send+sO���:�:�Q�Q�Q�~���
�����0�0����H�E��	�	�	�$�+�+���r6N)r1r2r3rirrr5r6r7r�r� s����
r6r�c�.�eZdZdZd�Zd�Zd�Zd�Zd�Zy)�FTPShellz:
    An authenticated implementation of L{IFTPShell}.
    c��|j|�}	|j�tjd�S#t$r }t|j|�cYd}~Sd}~wt$rtj�cYSwxYwrg)	r��makedirsr
rr�rVrHr�rJr�s    r7rQzFTPShell.makeDirectory8sf���J�J�t���	'�
�J�J�L��=�=��&�&���	1�!�!�'�'�4�0�0���	 ��:�:�<��	 �s!�8�	A?�A�A?� A?�>A?c�~�|j|�}|j�rtjt	|��S	tj|j�tjd�S#t$r }t|j|�cYd}~Sd}~wt$rtj�cYSwxYwrg)
r�r�r
rJrPr9�rmdirrCrr�rVrHr�r�s    r7rXzFTPShell.removeDirectoryCs����J�J�t����8�8�:��:�:�2�4�8�9�9�	'��H�H�Q�V�V���=�=��&�&���	1�!�!�'�'�4�0�0���	 ��:�:�<��	 �s$�A5�5	B<�>B�B<� B<�;B<c�`�|j|�}|j�rtjt	|��S	|j�tjd�S#t$r }t|j|�cYd}~Sd}~wt$rtj�cYSwxYwrg)r�r�r
rJrT�removerr�rVrHr�r�s    r7r]zFTPShell.removeFileSs����J�J�t����7�7�9��:�:�/��5�6�6�	'�
�H�H�J��=�=��&�&���	1�!�!�'�'�4�0�0���	 ��:�:�<��	 �r�c�Z�|j|�}|j|�}	tj|j|j�t	j
d�S#t$r }t|j|�cYd}~Sd}~wt$rt	j�cYSwxYwrg)r�r9rhrCr
rr�rVrHr�rJ)rkr�r�r��tprUs      r7rhzFTPShell.renamecs���
�Z�Z��
!��
�Z�Z��
��	'��I�I�b�g�g�r�w�w�'��=�=��&�&���	5�!�!�'�'�8�4�4���	 ��:�:�<��	 �s#�*A#�#	B*�,B�B*� B*�)B*c�t�|j|�}|j�rtjt	|��S	|jd�}tjt|��S#t$r }t|j|�cYd}~Sd}~wt$rtj�cYSwxYw)a�
        Open C{path} for writing.

        @param path: The path, as a list of segments, to open.
        @type path: C{list} of C{unicode}
        @return: A L{Deferred} is returned that will fire with an object
            implementing L{IWriteFile} if the file is successfully opened.  If
            C{path} is a directory, or if an exception is raised while trying
            to open the file, the L{Deferred} will fire with an error.
        r�N)r�r�r
rJrTr�r�rVrHr�r�_FileWriter)rkrCr!r@rUs     r7r zFTPShell.openForWritingos���
�J�J�t����7�7�9��:�:�/��5�6�6�	 ��6�6�#�;�D�
�}�}�[��.�/�/��	�	1�!�!�'�'�4�0�0���	 ��:�:�<��	 �r�N)	r1r2r3r4rQrXr]rhr r5r6r7rr3s ���	'�'� '� 
'�0r6rc��eZdZd�Zd�Zd�Zy)r&c� �||_d|_yr�)r@�_receiverAs  r7riz_FileWriter.__init__�s����	���
r6c��|jrJd��d|_tjt|j��S)Nz4Can only call IWriteFile.receive *once* per instanceT)r)r
rr>r@rps r7rz_FileWriter.receive�s4���=�=�X�"X�X� ���
��}�}�\�$�)�)�4�5�5r6c�,�tjd�Srg)r
rrps r7rDz_FileWriter.close�s���}�}�T�"�"r6N)r1r2r3rirrDr5r6r7r&r&�s���6�#r6r&c�"�eZdZdZd�Zd�Zd�Zy)�BaseFTPRealmz{
    Base class for simple FTP realms which provides an easy hook for specifying
    the home directory for each user.
    c�8�tj|�|_yrg)r�FilePath�
anonymousRoot)rkr0s  r7rizBaseFTPRealm.__init__�s��%�.�.�}�=��r6c�2�t|j�d���)a
        Return a L{FilePath} representing the home directory of the given
        avatar.  Override this in a subclass.

        @param avatarId: A user identifier returned from a credentials checker.
        @type avatarId: C{str}

        @rtype: L{FilePath}
        z" did not override getHomeDirectory)r�rZ�rk�avatarIds  r7�getHomeDirectoryzBaseFTPRealm.getHomeDirectory�s!��"��~�~� � B�C�
�	
r6c���|D]c}|tus�|tjurt|j�}nt|j
|��}t|t|dd��fcStd��)Nrbc��yrgr5r5r6r7r�z,BaseFTPRealm.requestAvatar.<locals>.<lambda>�r�r6z3Only IFTPShell interface is supported by this realm)	r�r�	ANONYMOUSr�r0rr4r�r�)rkr3�mindr�ifacer�s      r7�
requestAvatarzBaseFTPRealm.requestAvatar�sr���	T�E��	�!��x�1�1�1�.�t�/A�/A�B�F�%�d�&;�&;�H�&E�F�F�!�6�7�6�8�\�+R�S�S�
	T�"�"W�X�Xr6N)r1r2r3r4rir4r:r5r6r7r-r-�s���
>�
�Yr6r-c��eZdZdZdd�Zd�Zy)�FTPRealma"
    @type anonymousRoot: L{twisted.python.filepath.FilePath}
    @ivar anonymousRoot: Root of the filesystem to which anonymous
        users will be granted access.

    @type userHome: L{filepath.FilePath}
    @ivar userHome: Root of the filesystem containing user home directories.
    c�d�tj||�tj|�|_yrg)r-rirr/�userHome)rkr0r>s   r7rizFTPRealm.__init__�s$�����d�M�2� �)�)�(�3��
r6c�8�|jj|�S)z�
        Use C{avatarId} as a single path segment to construct a child of
        C{self.userHome} and return that child.
        )r>r�r2s  r7r4zFTPRealm.getHomeDirectory�s��
�}�}�"�"�8�,�,r6N)z/home)r1r2r3r4rir4r5r6r7r<r<�s���4�-r6r<c��eZdZdZd�Zy)�SystemFTPRealmz�
    L{SystemFTPRealm} uses system user account information to decide what the
    home directory for a particular avatarId is.

    This works on POSIX but probably is not reliable on Windows.
    c��tjjd|z�}|jd�rt	j
��t
j|�S)zx
        Return the system-defined home directory of the system user account
        with the name C{avatarId}.
        �~)r9rC�
expanduserr>r�r�rr/)rkr3rCs   r7r4zSystemFTPRealm.getHomeDirectory�sH��
�w�w�!�!�#��.�1���?�?�3���.�.�0�0�� � ��&�&r6N)r1r2r3r4r4r5r6r7rArA�s���'r6rAc��eZdZy)�ConnectionLostNr�r5r6r7rFrF�r�r6rFc��eZdZy)�
CommandFailedNr�r5r6r7rHrH�r�r6rHc��eZdZy)�BadResponseNr�r5r6r7rJrJ�r�r6rJc��eZdZy)�UnexpectedResponseNr�r5r6r7rLrL	r�r6rLc��eZdZy)�UnexpectedDataNr�r5r6r7rNrN	r�r6rNc��eZdZdd�Zd�Zy)�
FTPCommandNc�n�||_tj�|_d|_||_d|_y)NrZ)�textr
rr��ready�public�transferDeferred)rkrRrTs   r7rizFTPCommand.__init__	s-����	����(��
���
���� $��r6c�T�|jr|jj|�yyrg)rTr�r�)rkrs  r7rJzFTPCommand.fail	s ���;�;��M�M�!�!�'�*�r6�Nr)r1r2r3rirJr5r6r7rPrP
	s��%�+r6rPc�$�eZdZd�Zd�Zd�Zd�Zy)�ProtocolWrapperc� �||_||_yrg)�originalr�)rkr[r�s   r7rizProtocolWrapper.__init__	s�� ��
� ��
r6c�:�|jj|�yrg)r[�makeConnection�rkr�s  r7r]zProtocolWrapper.makeConnection	s���
�
�$�$�Y�/r6c�:�|jj|�yrg)r[r�r�s  r7r�zProtocolWrapper.dataReceived	s���
�
�"�"�4�(r6c�p�|jj|�|jjd�yrg)r[r�r�r�r�s  r7r�zProtocolWrapper.connectionLost"	s&���
�
�$�$�V�,��
�
���t�$r6N)r1r2r3rir]r�r�r5r6r7rYrY	s��!�0�)�%r6rYc��eZdZdZd�Zy)�IFinishableConsumerzA
    A Consumer for producers that finish.

    @since: 11.0
    c��y)z6
        The producer has finished producing.
        Nr5r5r6r7�finishzIFinishableConsumer.finish/	r�r6N)r1r2r3r4rdr5r6r7rbrb(	s���r6rbc�<�eZdZd�Zd�Zd�Zd�Zd�Zd�Zd�Z	d�Z
y	)
�SenderProtocolc�h�tj�|_tj�|_yrg)r
r�connectedDeferredr�rps r7rizSenderProtocol.__init__7	s!��!&���!1������(��
r6c��td��)Nz<Received data from the server on a send-only data-connection)rNr�s  r7r�zSenderProtocol.dataReceived?	s���M�
�	
r6c�z�tjj||�|jj	|�yrg)r�Protocolr]rhr�r^s  r7r]zSenderProtocol.makeConnectionD	s,�����(�(��y�9����'�'��-r6c��|jtj�r|jj	d�y|jj|�y)Nzconnection done)rqr�ConnectionDoner�r�r�r�s  r7r�zSenderProtocol.connectionLostH	s9���<�<��,�,�-��M�M�"�"�#4�5��M�M�!�!�&�)r6c�:�|jj|�yrgr�r�s  r7r�zSenderProtocol.writeO	s�������T�"r6c�<�|jj||�y)zA
        Register the given producer with our transport.
        Nr�r�s   r7r�zSenderProtocol.registerProducerR	s��	
���'�'��)�<r6c�8�|jj�y)z@
        Unregister the previously registered producer.
        N)r�r�rps r7r�z!SenderProtocol.unregisterProducerX	s��	
���)�)�+r6c�8�|jj�yrgrhrps r7rdzSenderProtocol.finish^	r
r6N)r1r2r3rir�r]r�r�r�r�rdr5r6r7rfrf5	s*��)�
�
.�*�#�=�,�(r6rfc�H�tjdd|�}|jd�D�cgc]}t|j	����}}|D]}|dks|dkDs�td||��|\}}}}}	}
|�d|�d|�d|��}t|	�dzt|
�z}||fScc}w)	ze
    Decode an FTP response specifying a host and port.

    @return: a 2-tuple of (host, port).
    z[^0-9, ]r;r�r�zOut of ranger:r�)�re�subr?r��stripr�)
r��abcdefr!�parsed�x�a�b�cr�rUr3r�r�s
             r7�decodeHostPortr}b	s����V�V�J��D�
)�F�&,�l�l�3�&7�
8��c�!�'�'�)�n�
8�F�
8�
�6���q�5�A��G��^�T�1�5�5�6���A�q�!�Q��1��S��!��A�a�S��!���D���F�a�K�3�q�6�!�D���:���9s� Bc��|jd�t|dz	�t|dz�gz}dj|�S)Nr:r��r�)r?r�r�)r�r��numberss   r7r�r�s	s8���j�j��o��T�Q�Y���T�C�Z�� A�A�G��8�8�G��r6c�n�|jtj�|jjSrg)r�r
�
FirstErrorrm�
subFailure)rs r7�_unwrapFirstErrorr�x	s&���G�L�L��!�!�"��=�=�#�#�#r6c��eZdZdZdZd�Zy)�FTPDataPortFactoryz_
    Factory for data connections that use the PORT command

    (i.e. "active" transfers)
    Fc�p�||j_|jj�|jSrg)rr�r�r�)rkr s  r7r"z FTPDataPortFactory.buildProtocol�	s*��
!%��
�
���	�	� � �"��}�}�r6N)r1r2r3r4�noisyr"r5r6r7r�r�}	s���
�E�r6r�c�b�eZdZdZdZdZd�Zd�Zd�Zd�Z	d�Z
d	�Zd
�Zdd�Z
d�Zd
�Zd�Zd�Zy)�FTPClientBasicz'
    Foundations of an FTP client.
    Fr�c���g|_d|_tj�j	|j
�|_|jj|j�g|_	d|_
yrW)�actionQueue�greetingr
rr��_cb_greeting�nextDeferredr�rJrq�_failedrps r7rizFTPClientBasic.__init__�	sW�������
�!�N�N�,�8�8��9J�9J�K������$�$�T�Y�Y�/���
���r6c�&�|j|�y)z8
        Give an error to any queued deferreds.
        N��_fail�rkrs  r7rJzFTPClientBasic.fail�	s��	
�
�
�5�r6c	�j�|jr|Sd|_|jr9	|jjtjtd|���|jD]0}|jtjtd|����2|S#tj$rY�VwxYw)z/
        Errback all queued deferreds.
        rZzFTP connection lost)
r�r�r�r�FailurerFr
�AlreadyCalledErrorr�rJ)rkr�
ftpCommands   r7r�zFTPClientBasic._fail�	s����<�<��L�������
��!�!�)�)��O�O�N�3H�%�$P�Q��
�*�*�	�J��O�O�����/D�e� L�M�
�	����
�+�+�
��
�s�8B�B2�1B2c��||_yrg)r�)rkr�s  r7r�zFTPClientBasic._cb_greeting�	s	�� ��
r6c��|�yt|t�r|j|j�}tj
j
||�y)z�
        Sends a line, unless line is None.

        @param line: Line to send
        @type line: L{bytes} or L{unicode}
        N)rXr�r�r�r�LineReceiverr�r�s  r7r�zFTPClientBasic.sendLine�	s>���<��
��c�
"��;�;�t�~�~�.�D�
���#�#�D�$�/r6c���|j�}|�d|_y|jsD|jj	d|�tjd|j�d|_y|jdk(r|j|�|jr"tjd|jz�|j|_|j|j�y)zD
        (Private) Processes the next command in the queue.
        Nrg�?�PORTz<-- %s)�popCommandQueuer�rSr��insertr
r-�sendNextCommandrR�generatePortCommandr�rrlr�r��rkr�s  r7r�zFTPClientBasic.sendNextCommand�	s����)�)�+�
��� $�D���������#�#�A�z�2����c�4�#7�#7�8� $�D����?�?�f�$��$�$�Z�0��:�:��G�G�H�z���.�/�&�/�/����
�
�j�o�o�&r6c��|jj|�t|j�dk(r+|j�|j�|j�yyyy)a
        Add an FTPCommand object to the queue.

        If it's the only thing in the queue, and we are connected and we aren't
        waiting for a response of an earlier command, the command will be sent
        immediately.

        @param ftpCommand: an L{FTPCommand}
        rZN)r�rAr;r�r�r�r�s  r7�queueCommandzFTPClientBasic.queueCommand�	s\��	
�����
�+��� � �!�Q�&����*��!�!�)�� � �"�*�+�
'r6c�T�t||�}|j|�|jS)au
        Queues a string to be issued as an FTP command

        @param command: string of an FTP command to queue
        @param public: a flag intended for internal use by FTPClient.  Don't
            change it unless you know what you're doing.

        @return: a L{Deferred} that will be called when the response to the
            command has been received.
        )rPr�r�)rkr�rTr�s    r7�queueStringCommandz!FTPClientBasic.queueStringCommand�	s*�� ���0�
����*�%��"�"�"r6c�R�|jr|jjd�Sy)zR
        Return the front element of the command queue, or None if empty.
        rN)r�r@rps r7r�zFTPClientBasic.popCommandQueue
s'������#�#�'�'��*�*�r6c�l���g}�jd|zd��}|j|�|�Std|zd����j��|j�j���fd�}|j|�|D]/}|j
�j�|j
d���1y)a
        Login: send the username, send the password.

        If the password is L{None}, the PASS command won't be sent.  Also, if
        the response to the USER command has a response code of 230 (User
        logged in), then PASS won't be sent either.
        zUSER r�rTNzPASS c�f��|djd�r�jj��|S)Nr�230)r>r�r")rq�passwordCmdrks ��r7�cancelPasswordIfNotNeededz<FTPClientBasic.queueLogin.<locals>.cancelPasswordIfNotNeeded"
s.����A�;�)�)�%�0��$�$�+�+�K�8��r6c��yrgr5�rys r7r�z+FTPClientBasic.queueLogin.<locals>.<lambda>/
r�r6)r�rArPr�r�r�r�rJ)rkr�r��	deferreds�userDeferredr�r�r�s`      @r7�
queueLoginzFTPClientBasic.queueLogin
s�����	��.�.�w��/A�!�.�L������&���$�W�x�%7��B�K����k�*����[�1�1�2�
 �
�$�$�%>�?�"�	0�H�����	�	�*�����/�		0r6c�*�ttk7r|j|j�}|jrtjd|z�|jj|�tjd|�}|sy|dd}|ddk(ry|j�%|jt|j��y|j}g|_|ddvr|jj|�n�|ddvr8|jjt!j"t%|���nOtjd	|���|jjt!j"t'|���|j)�y)
zM
        (Private) Parses the response messages from the FTP server.
        z--> %sz\d{3} Nr��1)�2�3)�4�5z"Server sent invalid response code )r�r�r�r�r�rrlrqrArt�matchr�rJrLr�r�rr�rHrJr�)rkr��codeIsValidr;rqs     r7r�zFTPClientBasic.lineReceived1
sH��
�C�<��;�;�t�~�~�.�D��:�:��G�G�H�t�O�$��
�
���T�"��h�h�y�$�/�����A�a�y����7�c�>�����$��I�I�(����7�8���=�=����
���7�j� ����&�&�x�0�
�!�W�
�
"����%�%�g�o�o�m�H�6M�&N�O�
�G�G�8���?�@����%�%�g�o�o�k�(�6K�&L�M�	
���r6c�&�|j|�yrgr�r�s  r7r�zFTPClientBasic.connectionLosta
s���
�
�6�r6N)rZ)r1r2r3r4r�r�rirJr�r�r�r�r�r�r�r�r�r�r5r6r7r�r��	sQ���
�E��I����*!�0�'�0#�$
#��"0�H.�`r6r�c�"�eZdZdZd�Zd�Zd�Zy)�_PassiveConnectionFactoryFc��||_yrg)�
protoInstance)rkr�s  r7riz"_PassiveConnectionFactory.__init__h
s
��*��r6c�<�||j_|jSrg)r�r�r�s  r7r"z'_PassiveConnectionFactory.buildProtocolk
s��%)����"��!�!�!r6c�f�td|�}|jjj|�y)NzConnection Failed)r�r�r�r�)rkr1r�rUs    r7r2z0_PassiveConnectionFactory.clientConnectionFailedo
s)���(�&�1�����#�#�+�+�A�.r6N)r1r2r3r�rir"r2r5r6r7r�r�e
s���E�+�"�/r6r�c��eZdZdZej
Z	dd�Zd�Zd�Z	d�Z
d�Zd�Zd�Z
d	�Zdd
�ZeZdd�ZeZd�Zd
�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zy)�	FTPClientaI
    L{FTPClient} is a client implementation of the FTP protocol which
    exposes FTP commands as methods which return L{Deferred}s.

    Each command method returns a L{Deferred} which is called back when a
    successful response code (2xx or 3xx) is received from the server or
    which is error backed if an error response code (4xx or 5xx) is received
    from the server or if a protocol violation occurs.  If an error response
    code is received, the L{Deferred} fires with a L{Failure} wrapping a
    L{CommandFailed} instance.  The L{CommandFailed} instance is created
    with a list of the response lines received from the server.

    See U{RFC 959<http://www.ietf.org/rfc/rfc959.txt>} for error code
    definitions.

    Both active and passive transfers are supported.

    @ivar passive: See description in __init__.
    c�`�tj|�|j||�||_y)ay
        Constructor.

        I will login as soon as I receive the welcome message from the server.

        @param username: FTP username
        @param password: FTP password
        @param passive: flag that controls if I use active or passive data
            connections.  You can also change this after construction by
            assigning to C{self.passive}.
        N)r�rir��passive)rkr�r�r�s    r7rizFTPClient.__init__�
s'��	����%�����(�+���r6c�Z�|jj�|j|�y)zM
        Disconnect, and also give an error to any queued deferreds.
        N)r�r�r�r�s  r7rJzFTPClient.fail�
s ��	
���%�%�'��
�
�5�r6c��tj|�}t|tj��}|j||�S)a�
        Retrieves a file or listing generated by the given command,
        feeding it to the given protocol.

        @param commands: list of strings of FTP commands to execute then
            receive the results of (e.g. C{LIST}, C{RETR})
        @param protocol: A L{Protocol} B{instance} e.g. an
            L{FTPFileListProtocol}, or something that can be adapted to one.
            Typically this will be an L{IConsumer} implementation.

        @return: L{Deferred}.
        )r�	IProtocolrYr
r�_openDataConnection)rk�commandsr�wrappers    r7�receiveFromConnectionzFTPClient.receiveFromConnection�
s:���'�'��1��!�(�E�N�N�,<�=���'�'��'�:�:r6c��tj|||�|jdd��}|j|j�|jd��y)zg
        Login: send the username, send the password, and
        set retrieval mode to binary
        zTYPE Irr�c��yrgr5r�s r7r�z&FTPClient.queueLogin.<locals>.<lambda>�
r�r6N)r�r�r�r�rJ)rkr�r�r�s    r7r�zFTPClient.queueLogin�
sG��
	�!�!�$��(�;��#�#�H�Q�#�7��	���T�Y�Y��	���^�$r6c�V�t�}|j||�}|j|fS)aQ
        XXX

        @return: A tuple of two L{Deferred}s:
                  - L{Deferred} L{IFinishableConsumer}. You must call
                    the C{finish} method on the IFinishableConsumer when the
                    file is completely transferred.
                  - L{Deferred} list of control-connection responses.
        )rfr�rh)rkr�rEr�s    r7�sendToConnectionzFTPClient.sendToConnection�
s/��
����$�$�X�q�1���#�#�Q�'�'r6c�.���
�|D�cgc]}t|d����}}tj|D�cgc]}|j��c}dd��}|j	t
��jr�dg�
�
��fd�}td�}�j|�|jj|�j	�j�||j�jg}	tj|	dd��}
|
j	t
��
fd�}|
j|�n�td	�}�j|_�|_|jj	|jj��j|�d
�|_d�|_	|j	|fd��||j|jg}	tj|	dd��}
|
j	t
�|D]}�j|��|
Scc}wcc}w)
z5
        This method returns a DeferredList.
        rZr�T)�fireOnOneErrback�
consumeErrorsNc�p��t|ddd�\}}t��}�j|||��d<y)z5Connect to the port specified in the response to PASVrYrLNr)r}r��connectFactory)rqr�r�r3�_mutablerrks    ���r7�	doPassivez0FTPClient._openDataConnection.<locals>.doPassive�
s>���+�H�R�L���,<�=�
��d�-�h�7��"�1�1�$��a�@���r6rQc�:�|dxr|dj�|SrW)r})ry�ms  r7rDz,FTPClient._openDataConnection.<locals>.close�
s���!��*��1����*���r6r�c��|Srgr5rs r7r�z/FTPClient._openDataConnection.<locals>.<lambda>	s��F�r6c��|Srgr5)rs r7r�z/FTPClient._openDataConnection.<locals>.<lambda>
s���r6c�,�|j|�xs|Srg)rJ)rU�pcs  r7r�z/FTPClient._openDataConnection.<locals>.<lambda>
s��"�'�'�!�*�/��r6)rPr
�DeferredListr�r�r�r�r�r�rJrrUrr�r�)rkr�rr��cmdsru�cmdsDeferredr��pasvCmdr�r�rD�portCmdr�s` `          @r7r�zFTPClient._openDataConnection�
s����>F�F�'�
�7�1�-�F��F��)�)�%)�*�c�S�\�\�*�T�QU�
��	��� 1�2��<�<��v�H�
A�!��(�G����g�&����(�(��3�>�>�t�y�y�I�#�W�%5�%5�x�7H�7H�I�G��"�"�7�T�QU�V�A�
�L�L�*�+�$�
�
�I�I�e��
!��(�G�(0�'8�'8�G�$�'�G�����'�'��(@�(@�(H�(H�I����g�&�
&;�G�"�.�G�L�
�#�#��$I�J�#�W�%5�%5�w�7O�7O�P�G��"�"�7�T�QU�V�A�
�L�L�*�+��	#�C����c�"�	#����CG��*s
�H
�Hc�0�t�}|j|_tjd|�}||_|fd�}||_|jj�j}|j�j}dt||�z|_
y)zG
        (Private) Generates the text of a given PORT command.
        rc�>�|jr|j�|Srg)r�r�)r�listeners  r7�listenerFailz3FTPClient.generatePortCommand.<locals>.listenerFail.s���!�!��'�'�)��Lr6zPORT N)r�rr
rr�rJr�r�r�r�rR)rkr�r�r�r�r�r�s       r7r�zFTPClient.generatePortCommands���"%�&��"�+�+����$�$�Q��0�����*2�	�
$����~�~�%�%�'�,�,�����!�&�&�����d�!;�;��r6c�&�|jdd�S)zK
        Returns a FTP escaped path (replace newlines with nulls).
        �
r=)r^r�s  r7�
escapePathzFTPClient.escapePath:s��
�|�|�D�$�'�'r6c��d|j|�zg}|r|jddt|�z�|j||�S)a�
        Retrieve a file from the given path

        This method issues the 'RETR' FTP command.

        The file is fed into the given Protocol instance.  The data connection
        will be passive if self.passive is set.

        @param path: path to file that you wish to receive.
        @param protocol: a L{Protocol} instance.
        @param offset: offset to start downloading from

        @return: L{Deferred}
        zRETR r�REST )r�r�r�r�)rkrCr�offsetr�s     r7�retrieveFilezFTPClient.retrieveFileAsG���$�/�/�$�/�/�0����K�K��G�c�&�k�1�3��)�)�$��9�9r6c��d|j|�zg}|r|jddt|�z�|j|�S)a�
        Store a file at the given path.

        This method issues the 'STOR' FTP command.

        @return: A tuple of two L{Deferred}s:
                  - L{Deferred} L{IFinishableConsumer}. You must call
                    the C{finish} method on the IFinishableConsumer when the
                    file is completely transferred.
                  - L{Deferred} list of control-connection responses.
        zSTOR rr�)r�r�r�r�)rkrCr�r�s    r7�	storeFilezFTPClient.storeFileWsE���$�/�/�$�/�/�0����K�K��G�c�&�k�1�3��$�$�T�*�*r6c�R�����jd�j|�z�}�jd�j|�z�}g�tj���j	�fd����fd�}|j�j|�|j���S)a]
        Rename a file.

        This method issues the I{RNFR}/I{RNTO} command sequence to rename
        C{pathFrom} to C{pathTo}.

        @param pathFrom: the absolute path to the file to be renamed
        @type pathFrom: C{str}

        @param pathTo: the absolute path to rename the file to.
        @type pathTo: C{str}

        @return: A L{Deferred} which fires when the rename operation has
            succeeded or failed.  If it succeeds, the L{Deferred} is called
            back with a two-tuple of lists.  The first list contains the
            responses to the I{RNFR} command.  The second list contains the
            responses to the I{RNTO} command.  If either I{RNFR} or I{RNTO}
            fails, the L{Deferred} is errbacked with L{CommandFailed} or
            L{BadResponse}.
        @rtype: L{Deferred}

        @since: 8.2
        zRNFR zRNTO c����|fSrgr5)�
toResponse�fromResponses �r7r�z"FTPClient.rename.<locals>.<lambda>�s���|�Z�.H�r6c�H���j��j|�yrg)r�r�)rrzrks ��r7�ebFromz FTPClient.rename.<locals>.ebFrom�s���� � �"��N�N�7�#r6)r�r�r
rr�r�r��
chainDeferred)rk�pathFrom�pathTo�
renameFrom�renameTor�r�rzs`     @@r7rhzFTPClient.renamejs����0�,�,�W�t���x�7P�-P�Q�
��*�*�7�T�_�_�V�5L�+L�M�������!�����H�I�	$�	���� 3� 3�V�<�	���v�&��
r6c�T�|�d}|jd|j|�zg|�S)a|
        Retrieve a file listing into the given protocol instance.

        This method issues the 'LIST' FTP command.

        @param path: path to get a file listing for.
        @param protocol: a L{Protocol} instance, probably a
            L{FTPFileListProtocol} instance.  It can cope with most common file
            listing formats.

        @return: L{Deferred}
        r;zLIST �r�r��rkrCrs   r7r�zFTPClient.list�s2���<��D��)�)�7�T�_�_�T�5J�+J�*K�X�V�Vr6c�T�|�d}|jd|j|�zg|�S)a1
        Retrieve a short file listing into the given protocol instance.

        This method issues the 'NLST' FTP command.

        NLST (should) return a list of filenames, one per line.

        @param path: path to get short file listing for.
        @param protocol: a L{Protocol} instance.
        r;zNLST r�r�s   r7�nlstzFTPClient.nlst�s2���<��D��)�)�7�T�_�_�T�5J�+J�*K�X�V�Vr6c�H�|jd|j|�z�S)z�
        Issues the CWD (Change Working Directory) command.

        @return: a L{Deferred} that will be called when done.
        zCWD �r�r�r�s  r7rBz
FTPClient.cwd�s#���&�&�v�����0E�'E�F�Fr6c�H�|jd|j|�z�S)a@
        Make a directory

        This method issues the MKD command.

        @param path: The path to the directory to create.
        @type path: C{str}

        @return: A L{Deferred} which fires when the server responds.  If the
            directory is created, the L{Deferred} is called back with the
            server response.  If the server response indicates the directory
            was not created, the L{Deferred} is errbacked with a L{Failure}
            wrapping L{CommandFailed} or L{BadResponse}.
        @rtype: L{Deferred}

        @since: 8.2
        zMKD rr�s  r7rQzFTPClient.makeDirectory��#��$�&�&�v�����0E�'E�F�Fr6c�H�|jd|j|�z�S)a^
        Delete a file on the server.

        L{removeFile} issues a I{DELE} command to the server to remove the
        indicated file.  Note that this command cannot remove a directory.

        @param path: The path to the file to delete. May be relative to the
            current dir.
        @type path: C{str}

        @return: A L{Deferred} which fires when the server responds.  On error,
            it is errbacked with either L{CommandFailed} or L{BadResponse}.  On
            success, it is called back with a list of response lines.
        @rtype: L{Deferred}

        @since: 8.2
        zDELE rr�s  r7r]zFTPClient.removeFile�s#��$�&�&�w�����1F�'F�G�Gr6c�H�|jd|j|�z�S)a`
        Delete a directory on the server.

        L{removeDirectory} issues a I{RMD} command to the server to remove the
        indicated directory. Described in RFC959.

        @param path: The path to the directory to delete. May be relative to
            the current working directory.
        @type path: C{str}

        @return: A L{Deferred} which fires when the server responds. On error,
            it is errbacked with either L{CommandFailed} or L{BadResponse}. On
            success, it is called back with a list of response lines.
        @rtype: L{Deferred}

        @since: 11.1
        zRMD rr�s  r7rXzFTPClient.removeDirectory�rr6c�$�|jd�S)z
        Issues the CDUP (Change Directory UP) command.

        @return: a L{Deferred} that will be called when done.
        �CDUP�r�rps r7�cdupzFTPClient.cdup�s���&�&�v�.�.r6c�$�|jd�S)ah
        Issues the PWD (Print Working Directory) command.

        The L{getDirectory} does the same job but automatically parses the
        result.

        @return: a L{Deferred} that will be called when done.  It is up to the
            caller to interpret the response, but the L{parsePWDResponse}
            method in this module should work.
        �PWDr	rps r7r�z
FTPClient.pwds���&�&�u�-�-r6c�F�d�}|j�j|�S)a
        Returns the current remote directory.

        @return: a L{Deferred} that will be called back with a C{str} giving
            the remote directory or which will errback with L{CommandFailed}
            if an error response is returned.
        c� �	t|djdd�d�dk7rt�	t|d�}|�t	j
t
|��S|S#ttf$r!t	j
t
|��cYSwxYw)NrrrZi)r�r?r��
IndexErrorrr�rH�parsePWDResponse)rzrCs  r7�cbParsez'FTPClient.getDirectory.<locals>.cbParses���
>��v�a�y���s�A�.�q�1�2�c�9�$�$�:�$�F�1�I�.�D��|����}�V�'<�=�=��K���
�+�
>����}�V�'<�=�=�
>�s�*A�-B
�B
)r�r�)rkrs  r7�getDirectoryzFTPClient.getDirectorys ��
	��x�x�z�%�%�g�.�.r6c�$�|jd�S)z�
        Issues the I{QUIT} command.

        @return: A L{Deferred} that fires when the server acknowledges the
            I{QUIT} command.  The transport should not be disconnected until
            this L{Deferred} fires.
        rOr	rps r7�quitzFTPClient.quit*s���&�&�v�.�.r6N)r�ztwisted@twistedmatrix.comrZ)r)r1r2r3r4r
r�r�rirJr�r�r�r�r�r�r��retrr��storrhr�rrBrQr]rXr
r�rrr5r6r7r�r�t
s����(�'�'�N�ST��&�;�"
%�(�E�N!<�F(�:�(�D�+�"�D�.�`W�"
W�G�G�(H�(G�(/�.�/�./r6r�c�Z�eZdZdZej
d�ZdZdZd�Z	d�Z
d�Zd�Zd	�Z
y
)�FTPFileListProtocola�
    Parser for standard FTP file listings

    This is the evil required to match::

        -rw-r--r--   1 root     other        531 Jan 29 03:26 README

    If you need different evil for a wacky FTP server, you can
    override either C{fileLinePattern} or C{parseDirectoryLine()}.

    It populates the instance attribute self.files, which is a list containing
    dicts with the following keys (examples from the above line):
        - filetype:   e.g. 'd' for directories, or '-' for an ordinary file
        - perms:      e.g. 'rw-r--r--'
        - nlinks:     e.g. 1
        - owner:      e.g. 'root'
        - group:      e.g. 'other'
        - size:       e.g. 531
        - date:       e.g. 'Jan 29 03:26'
        - filename:   e.g. 'README'
        - linktarget: e.g. 'some/file'

    Note that the 'date' value will be formatted differently depending on the
    date.  Check U{http://cr.yp.to/ftp.html} if you really want to try to parse
    it.

    It also matches the following::
        -rw-r--r--   1 root     other        531 Jan 29 03:26 I HAVE\ SPACE
           - filename:   e.g. 'I HAVE SPACE'

        -rw-r--r--   1 root     other        531 Jan 29 03:26 LINK -> TARGET
           - filename:   e.g. 'LINK'
           - linktarget: e.g. 'TARGET'

        -rw-r--r--   1 root     other        531 Jan 29 03:26 N S -> L S
           - filename:   e.g. 'N S'
           - linktarget: e.g. 'L S'

    @ivar files: list of dicts describing the files in this listing
    z�^(?P<filetype>.)(?P<perms>.{9})\s+(?P<nlinks>\d*)\s*(?P<owner>\S+)\s+(?P<group>\S+)\s+(?P<size>\d+)\s+(?P<date>...\s+\d+\s+[\d:]+)\s+(?P<filename>.{1,}?)( -> (?P<linktarget>[^\r]*))?\r?$�
r�c��g|_yrg)�filesrps r7rizFTPFileListProtocol.__init__hs	����
r6c��ttk7r|j|j�}|j	|�}|�|j|�y|j
|�yrg)r�r�r�r��parseDirectoryLine�unknownLine�addFile)rkr�r�s   r7r�z FTPFileListProtocol.lineReceivedksI���C�<��;�;�t�~�~�.�D��#�#�D�)���9����T�"��L�L��Or6c��|jj|�}|�y|j�}|djdd�|d<t	|d�|d<t	|d�|d<|dr|djdd�|d<|S)z�
        Return a dictionary of fields, or None if line cannot be parsed.

        @param line: line of text expected to contain a directory entry
        @type line: str

        @return: dict
        N�filenamez\ r�nlinksr��
linktarget)�fileLinePatternr��	groupdictr^r�)rkr�r�r�s    r7rz&FTPFileListProtocol.parseDirectoryLinets����$�$�*�*�4�0���=�����!�A��j�M�1�1�%��=�A�j�M��a��k�*�A�h�K��A�f�I��A�f�I����"#�L�/�"9�"9�%��"E��,���Hr6c�:�|jj|�y)a�
        Append file information dictionary to the list of known files.

        Subclasses can override or extend this method to handle file
        information differently without affecting the parsing of data
        from the server.

        @param info: dictionary containing the parsed representation
                     of the file information
        @type info: dict
        N)rrA)rkr�s  r7rzFTPFileListProtocol.addFile�s��	
�
�
���$�r6c��y)a
        Deal with received lines which could not be parsed as file
        information.

        Subclasses can override this to perform any special processing
        needed.

        @param line: unparsable line as received
        @type line: str
        Nr5r�s  r7rzFTPFileListProtocol.unknownLine�s��	
r6N)r1r2r3r4rt�compiler$�	delimiterr�rir�rrrr5r6r7rr5sD��'�R!�b�j�j�	-��O��I��I����* �
r6rc�Z�tjd|�}|r|j�dSy)z�
    Returns the path from a response to a PWD command.

    Responses typically look like::

        257 "/home/andrew" is current directory.

    For this example, I will return C{'/home/andrew'}.

    If I can't find the path, I return L{None}.
    z"(.*)"rN)rt�search�groups)rqr�s  r7rr�s+��
�I�I�h��)�E���|�|�~�a� � �r6rg)r�)�r4rHr[r9rtr'r�r�r��ImportError�zope.interfacerr�twistedr�twisted.credrrrr�r	rr
rrr
�twisted.protocolsrr�twisted.pythonrrr�RESTART_MARKER_REPLY�SERVICE_READY_IN_N_MINUTESr�rrGr9r��CMD_NOT_IMPLMNTD_SUPERFLUOUS�SYS_STATUS_OR_HELP_REPLYrm�
DIR_STATUSr$�HELP_MSGrB�SVC_READY_FOR_NEW_USERr_�SVC_CLOSING_CTRL_CNXrv� DATA_CNX_OPEN_NO_XFR_IN_PROGRESS�CLOSING_DATA_CNXr�r��ENTERING_EPSV_MODEr�r�r�r�rPr�r��NEED_ACCT_FOR_LOGINrc�SVC_NOT_AVAIL_CLOSING_CTRL_CNXrIr�r�REQ_ACTN_ABRTD_FILE_UNAVAIL�REQ_ACTN_ABRTD_LOCAL_ERR�REQ_ACTN_ABRTD_INSUFF_STORAGEr�r�r�rrr�r�r�r��NEED_ACCT_FOR_STORrsrxrvrzrtr}r��
PAGE_TYPE_UNK�EXCEEDED_STORAGE_ALLOC�FILENAME_NOT_ALLOWEDrnrhr0rFrVr\r]rcrerKrurNrPrRrTr�r�r�r�r�r�r�r�r�r��	IConsumerrkr��
ClientFactoryrr6r>r�rG�TimeoutMixinrKr�r�r�r�r�r�r�r�r�rr&�IRealmr-r<rArFrHrJrLrNrPrYrbrfr}r�r��
ServerFactoryr�r�r�r�rrr5r6r7�<module>rLs���
�
��
�	������2��K�K�H�H�-�1�1�
��"��"'��$��	������$��"��
��
�
������
� ��������#(� �����������!��"���	��	���"����%*�"�!(��������#�� �� %��
�
���������"���
��������������������
�����N��.�N�� A�	N�
$�&�N�!�#�N���N��&�N��
�N�!�#�N��7�N� �o�y�
)�!N�"��#N�$��%N�&
�n�'N�(�&�)N�*��+N�,�/�-N�.�E�/N�0��1N�2%�'�3N�6�,�7N�8�.�9N�:�9�;N�>�I�?N�@�8�AN�B�T�CN�F� K�GN�H�z�IN�J�!�KN�N�:�ON�P��QN�T�6�UN�V'�)�WN�\#�%�]N�`��aN�d�9�eN�f�P�gN�h �!U�iN�j�!�kN�n"�$�oN�t�&�uN�v�=�wN�x�8�yN�z�<�{N�|�<�}N�~� L�N�@�9�AN�B�5�CN�D�B�EN�F�8�GN�H�3�IN�J�U�KN�L�<��&��&��<��*��'��T�[N��b�)���2�$%�7�$�$�V�,���B
<�)�
<� ���!�+�!�"�K�"��;���k������[��#��#�!�[�!�+�;�+�	�y�	�	�)�	��+�����8���"
�Z�
!�
!�"�K'�(�
�
�K'�#�K'�\]/��'�'�]/�FB�B�"
�Z�
!�
!�"���#��.(�%�,�,�(�F
$�%�
�
�h�3�3�F
$�R&@��6�6�&@�X}�	�}�@�	��"���2�$5�p
�Y��p�p��p�f
�Y������$R0� �R0�j
�Z��#�#��#�
�V�]�]��Y�Y��Y�D-�|�-�,'�\�'�J	�X�	�	�H�	�	�(�	�	��	�	�X�	�
+�
+�%�h�'�'�%�"
�*�.�.�
�
�
 �!�)(�X�&�&�)(�"�)(�X�"�
$�
��/�/��&R�U�'�'�R�j/�� 6� 6�/�~/��~/�Bm
�%�,�,�m
�`��ad����C�#��s�R(�(	R5�4R5

Zerion Mini Shell 1.0