.. zsh-module-meta::
   :name: zsh/zftp
   :summary: A builtin FTP client.

The ``zsh/zftp`` module makes available one builtin command:

.. index:: single: zftp; Function

.. index:: single: FTP; Command

.. index:: single: files, transferring; Command

``zftp`` :var:`subcommand` [ :var:`args` ]
    
    The ``zsh/zftp`` module is a client for FTP (file transfer protocol).  It
    is implemented as a builtin to allow full use of shell command line
    editing, file I/O, and job control mechanisms.  Often, users will
    access it via shell functions providing a more powerful interface; a set is
    provided with the ``zsh`` distribution and is described in
    :manpage:`zshzftpsys`.
    However, the ``zftp`` command is entirely usable in its
    own right.
    
    All commands consist of the command name ``zftp`` followed by the name
    of a subcommand.  These are listed below.  The return status of each
    subcommand is supposed to reflect the success or failure of the remote
    operation.  See a description of the variable ``ZFTP_VERBOSE`` for
    more information on how responses from the server may be printed.
    

Subcommands
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. index:: single: zftp, subcommands; Command

.. index:: single: FTP, starting a session; Command

``open`` :var:`host`\[``:``:var:`port`] [ :var:`user` [ :var:`password` [ :var:`account` ] ] ]
    
    Open a new FTP session to :var:`host`, which may be the name of a TCP/IP
    connected host or an IP number in the standard dot notation.  If the
    argument is in the form :var:`host`\ ``:``:var:`port`, open a connection to
    TCP port :var:`port` instead of the standard FTP port 21.  This may be
    the name of a TCP service or a number:  see the description of
    ``ZFTP_PORT`` below for more information.
    
    If IPv6 addresses in colon format are used, the :var:`host` should be
    surrounded by quoted square brackets to distinguish it from the :var:`port`,
    for example ``'[fe80::203:baff:fe02:8b56]'``.  For consistency this is
    allowed with all forms of :var:`host`.
    
    Remaining arguments are passed to the ``login`` subcommand.  Note that
    if no arguments beyond :var:`host` are supplied, ``open`` will :emphasis:`not`
    automatically call ``login``.  If no arguments at all are supplied,
    ``open`` will use the parameters set by the ``params`` subcommand.
    
    After a successful open, the shell variables ``ZFTP_HOST``, ``ZFTP_PORT``,
    ``ZFTP_IP`` and ``ZFTP_SYSTEM`` are available; see \`Variables'
    below.
    

``login`` [ :var:`name` [ :var:`password` [ :var:`account` ] ] ]

``user`` [ :var:`name` [ :var:`password` [ :var:`account` ] ] ]
    
    Login the user :var:`name` with parameters :var:`password` and :var:`account`.
    Any of the parameters can be omitted, and will be read from standard
    input if needed (:var:`name` is always needed).  If 
    standard input is a terminal, a prompt for each one will be printed on
    standard error and :var:`password` will not be echoed.  If any of the
    parameters are not used, a warning message is printed.
    
    After a successful login, the shell variables ``ZFTP_USER``,
    ``ZFTP_ACCOUNT`` and ``ZFTP_PWD`` are available; see \`Variables'
    below.
    
    This command may be re-issued when a user is already logged in, and
    the server will first be reinitialized for a new user.
    

``params`` [ :var:`host` [ :var:`user` [ :var:`password` [ :var:`account` ] ] ] ]

``params`` ``-``
    
    Store the given parameters for a later ``open`` command with no
    arguments.  Only those given on the command line will be remembered.
    If no arguments are given, the parameters currently set are printed,
    although the password will appear as a line of stars; the return status is
    one if no parameters were set, zero otherwise.
    
    Any of the parameters may be specified as a ``?``, which
    may need to be quoted to protect it from shell expansion.  In this case,
    the appropriate parameter will be read from stdin as with the
    ``login`` subcommand, including special handling of :var:`password`.  If the
    ``?`` is followed by a string, that is used as the prompt for reading the
    parameter instead of the default message (any necessary punctuation and
    whitespace should be included at the end of the prompt).  The first letter
    of the parameter (only) may be quoted with a ``\``; hence an argument
    ``"\\$word"`` guarantees that the string from the shell parameter ``$word``
    will be treated literally, whether or not it begins with a ``?``.
    
    If instead a single ``-`` is given, the existing parameters, if any,
    are deleted.  In that case, calling ``open`` with no arguments will
    cause an error.
    
    The list of parameters is not deleted after a ``close``, however it
    will be deleted if the ``zsh/zftp`` module is unloaded.
    
    For example,
    
    
    .. code-block:: zsh
       :class: example

        zftp params ftp.elsewhere.xx juser '?Password for juser: '
    
    
    will store the host ``ftp.elsewhere.xx`` and the user ``juser`` and
    then prompt the user for the corresponding password with the given prompt.
    

``test``
    
    Test the connection; if the server has reported
    that it has closed the connection (maybe due to a timeout), return
    status 2; if no connection was open anyway, return status 1; else
    return status 0.  The ``test`` subcommand is
    silent, apart from messages printed by the ``$ZFTP_VERBOSE``
    mechanism, or error messages if the connection closes.  There is no
    network overhead for this test.
    
    The test is only supported on systems with either the
    ``select(2)`` or
    ``poll(2)`` system calls; otherwise the message ``not
    supported on this system`` is printed instead.
    
    The ``test`` subcommand will automatically be called at the start of any
    other subcommand for the current session when a connection is open.
    

``cd`` :var:`directory`
    
    Change the remote directory to :var:`directory`.  Also alters the shell
    variable ``ZFTP_PWD``.
    

``cdup``
    
    Change the remote directory to the one higher in the directory tree.
    Note that ``cd ..`` will also work correctly on non-UNIX systems.
    

``dir`` [ :var:`arg` ... ]
    
    Give a (verbose) listing of the remote directory.  The :var:`arg`\s are
    passed directly to the server. The command's behaviour is implementation
    dependent, but a UNIX server will typically interpret :var:`arg`\s as
    arguments to the ``ls`` command and with no arguments return the
    result of ``ls -l``. The directory is listed to standard output.
    

``ls`` [ :var:`arg` ... ]
    
    Give a (short) listing of the remote directory.  With no :var:`arg`,
    produces a raw list of the files in the directory, one per line.
    Otherwise, up to vagaries of the server implementation, behaves
    similar to ``dir``.
    

``type`` [ :var:`type` ]
    
    Change the type for the transfer to :var:`type`, or print the current type
    if :var:`type` is absent.  The allowed values are ``A`` (ASCII),
    ``I`` (Image, i.e. binary), or ``B`` (a synonym for ``I``).
    
    The FTP default for a transfer is ASCII.  However, if ``zftp`` finds
    that the remote host is a UNIX machine with 8-bit byes, it will
    automatically switch to using binary for file transfers upon
    ``open``.  This can subsequently be overridden.
    
    The transfer type is only passed to the remote host when a data
    connection is established; this command involves no network overhead.
    

``ascii``
    
    The same as ``type A``.
    

``binary``
    
    The same as ``type I``.
    

``mode`` [ ``S`` | ``B`` ]
    
    Set the mode type to stream (``S``) or block (``B``).  Stream mode is
    the default; block mode is not widely supported.
    

``remote`` :var:`file` ...

``local`` [ :var:`file` ... ]
    
    Print the size and last modification time of the remote or local
    files.  If there is more than one item on the list, the name of the
    file is printed first.  The first number is the file size, the second
    is the last modification time of the file in the format
    ``CCYYMMDDhhmmSS`` consisting of year, month, date, hour, minutes and
    seconds in GMT.  Note that this format, including the length, is
    guaranteed, so that time strings can be directly compared via the
    ``[[`` builtin's ``<`` and ``>`` operators, even if they are too long
    to be represented as integers.
    
    Not all servers support the commands for retrieving this information.
    In that case, the ``remote`` command will print nothing and return
    status 2, compared with status 1 for a file not found.
    
    The ``local`` command (but not ``remote``) may be used with no
    arguments, in which case the information comes from examining file
    descriptor zero.  This is the same file as seen by a ``put`` command
    with no further redirection.
    

``get`` :var:`file` ...
    
    Retrieve all :var:`file`\s from the server, concatenating them
    and sending them to standard output.
    

``put`` :var:`file` ...
    
    For each :var:`file`, read a file from standard input and send that to
    the remote host with the given name.
    

``append`` :var:`file` ...
    
    As ``put``, but if the remote :var:`file` already exists, data is
    appended to it instead of overwriting it.
    

``getat`` :var:`file` :var:`point`

``putat`` :var:`file` :var:`point`

``appendat`` :var:`file` :var:`point`
    
    Versions of ``get``, ``put`` and ``append`` which will start the
    transfer at the given :var:`point` in the remote :var:`file`.  This is
    useful for appending to an incomplete local file.  However, note that
    this ability is not universally supported by servers (and is not quite
    the behaviour specified by the standard).
    

``delete`` :var:`file` ...
    
    Delete the list of files on the server.
    

``mkdir`` :var:`directory`
    
    Create a new directory :var:`directory` on the server.
    

``rmdir`` :var:`directory`
    
    Delete the directory :var:`directory`  on the server.
    

``rename`` :var:`old-name` :var:`new-name`
    
    Rename file :var:`old-name` to :var:`new-name` on the server.
    

``site`` :var:`arg` ...
    
    Send a host-specific command to the server.  You will probably
    only need this if instructed by the server to use it.
    

``quote`` :var:`arg` ...
    
    Send the raw FTP command sequence to the server.  You should be
    familiar with the FTP command set as defined in RFC959 before doing
    this.  Useful commands may include ``STAT`` and ``HELP``.  Note also
    the mechanism for returning messages as described for the variable
    ``ZFTP_VERBOSE`` below, in particular that all messages from the
    control connection are sent to standard error.
    

``close``

``quit``
    
    Close the current data connection.  This unsets the shell parameters
    ``ZFTP_HOST``, ``ZFTP_PORT``, ``ZFTP_IP``, ``ZFTP_SYSTEM``, ``ZFTP_USER``,
    ``ZFTP_ACCOUNT``, ``ZFTP_PWD``, ``ZFTP_TYPE`` and ``ZFTP_MODE``.
    

``session`` [ :var:`sessname` ]
    
    Allows multiple FTP sessions to be used at once.  The name of the session
    is an arbitrary string of characters; the default session is called
    ``default``.  If this command is called without an argument, it will list
    all the current sessions; with an argument, it will either switch to the
    existing session called :var:`sessname`, or create a new session of that name.
    
    Each session remembers the status of the connection, the set of
    connection-specific shell parameters (the same set as are unset when a
    connection closes, as given in the description of ``close``), and any user
    parameters specified with the ``params`` subcommand.  Changing to a
    previous session restores those values; changing to a new session
    initialises them in the same way as if ``zftp`` had just been loaded.  The
    name of the current session is given by the parameter ``ZFTP_SESSION``.
    

``rmsession`` [ :var:`sessname` ]
    
    Delete a session; if a name is not given, the current session is deleted.
    If the current session is deleted, the earliest existing session becomes
    the new current session, otherwise the current session is not changed.
    If the session being deleted is the only one, a new session called
    ``default`` is created and becomes the current session; note that this is
    a new session even if the session being deleted is also called
    ``default``. It is recommended that sessions not be deleted while
    background commands which use ``zftp`` are still active.
    

Parameters
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. index:: single: zftp, parameters; Command

The following shell parameters are used by ``zftp``.  Currently none
of them are special.

.. index:: single: ZFTP_TMOUT; Variable

``ZFTP_TMOUT``
    
    Integer.  The time in seconds to wait for a network operation to
    complete before returning an error.  If this is not set when the
    module is loaded, it will be given the default value 60.  A value of
    zero turns off timeouts.  If a timeout occurs on the control
    connection it will be closed.  Use a larger value if this occurs too
    frequently.
    

.. index:: single: ZFTP_IP; Variable

``ZFTP_IP``
    
    Readonly.  The IP address of the current connection in dot notation.
    

.. index:: single: ZFTP_HOST; Variable

``ZFTP_HOST``
    
    Readonly.  The hostname of the current remote server.  If the host was
    opened as an IP number, ``ZFTP_HOST`` contains that instead; this
    saves the overhead for a name lookup, as IP numbers are most commonly
    used when a nameserver is unavailable.
    

.. index:: single: ZFTP_PORT; Variable

``ZFTP_PORT``
    
    Readonly.  The number of the remote TCP port to which the connection is
    open (even if the port was originally specified as a named service).
    Usually this is the standard FTP port, 21.
    
    In the unlikely event that your system does not have the appropriate
    conversion functions, this appears in network byte order.  If your
    system is little-endian, the port then consists of two swapped bytes and the
    standard port will be reported as 5376.  In that case, numeric ports passed
    to ``zftp open`` will also need to be in this format.
    

.. index:: single: ZFTP_SYSTEM; Variable

``ZFTP_SYSTEM``
    
    Readonly.  The system type string returned by the server in response
    to an FTP ``SYST`` request.  The most interesting case is a string
    beginning ``"UNIX Type: L8"``, which ensures maximum compatibility
    with a local UNIX host.
    

.. index:: single: ZFTP_TYPE; Variable

``ZFTP_TYPE``
    
    Readonly.  The type to be used for data transfers , either ``A`` or
    ``I``.   Use the ``type`` subcommand to change this.
    

.. index:: single: ZFTP_USER; Variable

``ZFTP_USER``
    
    Readonly.  The username currently logged in, if any.
    

.. index:: single: ZFTP_ACCOUNT; Variable

``ZFTP_ACCOUNT``
    
    Readonly.  The account name of the current user, if any.  Most servers
    do not require an account name.
    

.. index:: single: ZFTP_PWD; Variable

``ZFTP_PWD``
    
    Readonly.  The current directory on the server.
    

.. index:: single: ZFTP_CODE; Variable

``ZFTP_CODE``
    
    Readonly.  The three digit code of the last FTP reply from the server
    as a string.  This can still be read after the connection is closed, and
    is not changed when the current session changes.
    

.. index:: single: ZFTP_REPLY; Variable

``ZFTP_REPLY``
    
    Readonly.  The last line of the last reply sent by the server.  This
    can still be read after the connection is closed, and is not changed when
    the current session changes.
    

.. index:: single: ZFTP_SESSION; Variable

``ZFTP_SESSION``
    
    Readonly.  The name of the current FTP session; see the description of the
    ``session`` subcommand.
    

.. index:: single: ZFTP_PREFS; Variable

``ZFTP_PREFS``
    
    A string of preferences for altering aspects of ``zftp``'s behaviour.
    Each preference is a single character.  The following are defined:
    
    
    ``P``
        
        Passive:  attempt to make the remote server initiate data transfers.
        This is slightly more efficient than sendport mode.  If the letter
        ``S`` occurs later in the string, ``zftp`` will use sendport mode if
        passive mode is not available.
        
    
    ``S``
        
        Sendport:  initiate transfers by the FTP ``PORT`` command.  If this
        occurs before any ``P`` in the string, passive mode will never be
        attempted.
        
    
    ``D``
        
        Dumb:  use only the bare minimum of FTP commands.  This prevents
        the variables ``ZFTP_SYSTEM`` and ``ZFTP_PWD`` from being set, and
        will mean all connections default to ASCII type.  It may prevent
        ``ZFTP_SIZE`` from being set during a transfer if the server
        does not send it anyway (many servers do).
        
    
    
    
    If ``ZFTP_PREFS`` is not set when ``zftp`` is loaded, it will be set to a
    default of ``PS``, i.e. use passive mode if available, otherwise
    fall back to sendport mode.
    

.. index:: single: ZFTP_VERBOSE; Variable

``ZFTP_VERBOSE``
    
    A string of digits between 0 and 5 inclusive, specifying which
    responses from the server should be printed.  All responses go to
    standard error.  If any of the numbers 1 to 5 appear in the string,
    raw responses from the server with reply codes beginning with that
    digit will be printed to standard error.  The first digit of the three
    digit reply code is defined by RFC959 to correspond to:
    
    
    1.
        
        A positive preliminary reply.
        
    
    2.
        
        A positive completion reply.
        
    
    3.
        
        A positive intermediate reply.
        
    
    4.
        
        A transient negative completion reply.
        
    
    5.
        
        A permanent negative completion reply.
        
    
    
    
    It should be noted that, for unknown reasons, the reply \`Service not
    available', which forces termination of a connection, is classified as
    421, i.e. \`transient negative', an interesting interpretation of the word
    \`transient'.
    
    The code 0 is special:  it indicates that all but the last line of
    multiline replies read from the server will be printed to standard
    error in a processed format.  By convention, servers use this
    mechanism for sending information for the user to read.  The
    appropriate reply code, if it matches the same response, takes
    priority.
    
    If ``ZFTP_VERBOSE`` is not set when ``zftp`` is loaded, it will be
    set to the default value ``450``, i.e., messages destined for the user
    and all errors will be printed.  A null string is valid and
    specifies that no messages should be printed.
    

Functions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. index:: single: zftp, functions; Command

.. index:: single: zftp_chpwd, specification; Function

``zftp_chpwd``
    
    If this function is set by the user, it is called every time the
    directory changes on the server, including when a user is logged
    in, or when a connection is closed.  In the last case, ``$ZFTP_PWD``
    will be unset; otherwise it will reflect the new directory.
    

.. index:: single: zftp_progress, specification; Function

``zftp_progress``
    
    If this function is set by the user, it will be called during
    a ``get``, ``put`` or ``append`` operation each time sufficient data
    has been received from the host.  During a ``get``, the data is sent
    to standard output, so it is vital that this function should write
    to standard error or directly to the terminal, :emphasis:`not` to standard
    output.
    
    When it is called with a transfer in progress, the following
    additional shell parameters are set:
    
    
    .. index:: single: ZFTP_FILE; Variable
    
    
    ``ZFTP_FILE``
        
        The name of the remote file being transferred from or to.
        
    
    .. index:: single: ZFTP_TRANSFER; Variable
    
    
    ``ZFTP_TRANSFER``
        
        A ``G`` for a ``get`` operation and a ``P`` for a ``put`` operation.
        
    
    .. index:: single: ZFTP_SIZE; Variable
    
    
    ``ZFTP_SIZE``
        
        The total size of the complete file being transferred:
        the same as the first value provided by the
        ``remote`` and ``local`` subcommands for a particular file.
        If the server cannot supply this value for a remote file being
        retrieved, it will not be set.  If input is from a pipe the value may
        be incorrect and correspond simply to a full pipe buffer.
        
    
    .. index:: single: ZFTP_COUNT; Variable
    
    
    ``ZFTP_COUNT``
        
        The amount of data so far transferred; a number between zero and
        ``$ZFTP_SIZE``, if that is set.  This number is always available.
        
    
    
    
    The function is initially called with ``ZFTP_TRANSFER`` set
    appropriately and ``ZFTP_COUNT`` set to zero.  After the transfer is
    finished, the function will be called one more time with
    ``ZFTP_TRANSFER`` set to ``GF`` or ``PF``, in case it wishes to tidy
    up.  It is otherwise never called twice with the same value of
    ``ZFTP_COUNT``.
    
    Sometimes the progress meter may cause disruption.  It is up to the
    user to decide whether the function should be defined and to use
    ``unfunction`` when necessary.
    

Problems
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. index:: single: zftp, problems; Command

A connection may not be opened in the left hand side of a pipe as this
occurs in a subshell and the file information is not updated in the main
shell.  In the case of type or mode changes or closing the connection in a
subshell, the information is returned but variables are not updated until
the next call to ``zftp``.  Other status changes in subshells will not be
reflected by changes to the variables (but should be otherwise harmless).

Deleting sessions while a ``zftp`` command is active in the background can
have unexpected effects, even if it does not use the session being deleted.
This is because all shell subprocesses share information on the state of
all connections, and deleting a session changes the ordering of that
information.

On some operating systems, the control connection is not valid after a
fork(), so that operations in subshells, on the left hand side
of a pipeline, or in the background are not possible, as they should be.
This is presumably a bug in the operating system.
