# ftp

### MODULE

ftp

### MODULE SUMMARY

A File Transfer Protocol client

### DESCRIPTION

The `ftp` module implements a client for file transfer according to a subset of the File Transfer Protocol (see RFC 959).

The following is a simple example of an ftp session, where the user `guest` with password `password` logs on to the remote host `erlang.org`, and where the file `appl.erl` is transferred from the remote to the local host. When the session is opened, the current directory at the remote host is `/home/guest`, and `/home/fred` at the local host. Before transferring the file, the current local directory is changed to `/home/eproj/examples`, and the remote directory is set to `/home/guest/appl/examples`.

    1> {ok, Pid} = ftp:open("erlang.org").
    {ok,<0.22.0>}
    2> ftp:user(Pid, "guest", "password").
    ok
    3> ftp:pwd(Pid).
    {ok, "/home/guest"}
    4> ftp:cd(Pid, "appl/examples").
    ok
    5> ftp:lpwd(Pid).
    {ok, "/home/fred"}.
    6> ftp:lcd(Pid, "/home/eproj/examples").
    ok
    7> ftp:recv(Pid, "appl.erl").
    ok
    8> ftp:close(Pid).
    ok

In addition to the ordinary functions for receiving and sending files (see `recv/2`, `recv/3`, `send/2` and `send/3`) there are functions for receiving remote files as binaries (see `recv_bin/2`) and for sending binaries to to be stored as remote files (see `send_bin/3`).

There is also a set of functions for sending and receiving contiguous parts of a file to be stored in a remote file (for send see `send_chunk_start/2`, `send_chunk/2` and `send_chunk_end/1` and for receive see `recv_chunk_start/2` and `recv_chunk/`).

The particular return values of the functions below depend very much on the implementation of the FTP server at the remote host. In particular the results from `ls` and `nlist` varies. Often real errors are not reported as errors by `ls`, even if for instance a file or directory does not exist. `nlist` is usually more strict, but some implementations have the peculiar behaviour of responding with an error, if the request is a listing of the contents of directory which exists but is empty.

### EXPORTS

`account(Pid,Account) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`Account = string()`
`Reason = eacct | econn`

If an account is needed for an operation set the account with this operation.

`append(Pid, LocalFile [, RemoteFile]) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`LocalFile = RemoteFile = string()`
`Reason = epath | elogin | econn | etnospc | epnospc | efnamena`

Transfers the file `LocalFile` to the remote server. If `RemoteFile` is specified, the name of the remote file that the file will be appended to is set to `RemoteFile`; otherwise the name is set to `LocalFile` If the file does not exists the file will be created.

`append_bin(Pid, Bin, RemoteFile) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`Bin = binary()()`
`RemoteFile = string()`
`Reason = epath | elogin | enotbinary | econn | etnospc | epnospc | efnamena`

Transfers the binary `Bin` to the remote server and append it to the file `RemoteFile`. If the file does not exists it will be created.

`append_chunk(Pid, Bin) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`Bin = binary()`
`Reason = elogin | echunk | enotbinary | econn`

Transfer the chunk `Bin` to the remote server, which append it into the file specified in the call to `append_chunk_start/2`.

Note that for some errors, e.g. file system full, it is neccessery to to call `append_chunk_end` to get the proper reason.

`append_chunk_start(Pid, File) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`File = string()`
`Reason = epath | elogin | econn`

Start the transfer of chunks for appending to the file `File` at the remote server. If the file does not exists it will be created.

`append_chunk_end(Pid) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`Reason = elogin | echunk | econn | etnospc | epnospc | efnamena`

Stops transfer of chunks for appending to the remote server. The file at the remote server, specified in the call to `append_chunk_start/2` is closed by the server.

`cd(Pid, Dir) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`Dir = string()`
`Reason = epath | elogin | econn`

Changes the working directory at the remote server to `Dir`.

`close(Pid) -> ok`

Types:

`Pid = pid()`

Ends the ftp session.

`delete(Pid, File) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`File = string()`
`Reason = epath | elogin | econn`

Deletes the file `File` at the remote server.

`formaterror(Tag) -> string()`

Types:

`Tag = {error, atom()} | atom()`

Given an error return value `{error, Reason}`, this function returns a readable string describing the error.

`lcd(Pid, Dir) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`Dir = string()`
`Reason = epath`

Changes the working directory to `Dir` for the local client.

`lpwd(Pid) -> {ok, Dir}`

Types:

`Pid = pid()`

Returns the current working directory at the local client.

`ls(Pid [, Dir]) -> {ok, Listing} | {error, Reason}`

Types:

`Pid = pid()`
`Dir = string()`
`Listing = string()`
`Reason = epath | elogin | econn`

Returns a listing of the contents of the remote current directory (`ls/1`) or the specified directory (`ls/2`). The format of `Listing` is operating system dependent (on UNIX it is typically produced from the output of the `ls -l` shell command).

`mkdir(Pid, Dir) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`Dir = string()`
`Reason = epath | elogin | econn`

Creates the directory `Dir` at the remote server.

`nlist(Pid [, Dir]) -> {ok, Listing} | {error, Reason}`

Types:

`Pid = pid()`
`Dir = string()`
`Listing = string()`
`Reason = epath | elogin | econn`

Returns a listing of the contents of the remote current directory (`nlist/1`) or the specified directory (`nlist/2`). The format of `Listing` is a stream of file names, where each name is separated by <CRLF> or <NL>. Contrary to the `ls` function, the purpose of `nlist` is to make it possible for a program to automatically process file name information.

`open(Host [, Port] [, Flags]) -> {ok, Pid} | {error, Reason}`
`open({option_list,Option_list}) -> {ok, Pid} | {error, Reason}`

Types:

`Host = string() | ip_address()`
`ip_address() = {byte(), byte(), byte(), byte()}`
`byte() = 0 | 1 | ... | 255`
`Port = integer()`
`Flags = [Flag]`
`Flag = verbose | debug`
`Pid = pid()`
`Reason = ehost`
`Option_list=[Options]`
`Options={host,Host}|{port,Port}|{flags,Flags}|{timeout,Timeout}`
`Timeout=integer()`

Opens a session with the ftp server at `Host`. The argument `Host` is either the name of the host, its IP address in dotted decimal notation (e.g. `"150.236.14.136"`), or a tuple of arity 4 (e.g. `{150, 236, 14, 136}`).

If `Port` is supplied, a connection is attempted using this port number instead of the default (21).

If the atom `verbose` is included in `Flags`, response messages from the remote server will be written to standard output.

The file transfer type is set to `binary` when the session is opened.

The current local working directory (cf. `lpwd/1`) is set to the value reported by `file:get_cwd/1`. the wanted local directory.

The timeout value is default set to 60000 milliseconds.

The return value `Pid` is used as a reference to the newly created ftp client in all other functions. The ftp client process is linked to the caller.

`pwd(Pid) -> {ok, Dir} | {error, Reason}`

Types:

`Pid = pid()`
`Reason = elogin | econn`

Returns the current working directory at the remote server.

`recv(Pid, RemoteFile [, LocalFile]) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`RemoteFile = LocalFile = string()`
`Reason = epath | elogin | econn`

Transfer the file `RemoteFile` from the remote server to the the file system of the local client. If `LocalFile` is specified, the local file will be `LocalFile`; otherwise it will be `RemoteFile`.

`recv_bin(Pid, RemoteFile) -> {ok, Bin} | {error, Reason}`

Types:

`Pid = pid()`
`Bin = binary()`
`RemoteFile = string()`
`Reason = epath | elogin | econn`

Transfers the file `RemoteFile` from the remote server and receives it as a binary.

`recv_chunk_start(Pid, RemoteFile) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`RemoteFile = string()`
`Reason = epath | elogin | econn`

Start transfer of the file `RemoteFile` from the remote server.

`recv_chunk(Pid) -> ok | {ok, Bin} | {error, Reason}`

Types:

`Pid = pid()`
`Bin = binary()`
`Reason = epath | eclosed | econn`

Receive a chunk of the remote file (`RemoteFile` of `recv_chunk_start`). The return values has the following meaning:

- `ok` the transfer is complete.
- `{ok, Bin}` just another chunk of the file.
- `{error, Reason}` transfer failed.

`rename(Pid, Old, New) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`CurrFile = NewFile = string()`
`Reason = epath | elogin | econn`

Renames `Old` to `New` at the remote server.

`rmdir(Pid, Dir) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`Dir = string()`
`Reason = epath | elogin | econn`

Removes directory `Dir` at the remote server.

`send(Pid, LocalFile [, RemoteFile]) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`LocalFile = RemoteFile = string()`
`Reason = epath | elogin | econn | etnospc | epnospc | efnamena`

Transfers the file `LocalFile` to the remote server. If `RemoteFile` is specified, the name of the remote file is set to `RemoteFile`; otherwise the name is set to `LocalFile`.

`send_bin(Pid, Bin, RemoteFile) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`Bin = binary()()`
`RemoteFile = string()`
`Reason = epath | elogin | enotbinary | econn | etnospc | epnospc | efnamena`

Transfers the binary `Bin` into the file `RemoteFile` at the remote server.

`send_chunk(Pid, Bin) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`Bin = binary()`
`Reason = elogin | echunk | enotbinary | econn`

Transfer the chunk `Bin` to the remote server, which writes it into the file specified in the call to `send_chunk_start/2`.

Note that for some errors, e.g. file system full, it is neccessery to to call `send_chunk_end` to get the proper reason.

`send_chunk_start(Pid, File) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`File = string()`
`Reason = epath | elogin | econn`

Start transfer of chunks into the file `File` at the remote server.

`send_chunk_end(Pid) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`Reason = elogin | echunk | econn | etnospc | epnospc | efnamena`

Stops transfer of chunks to the remote server. The file at the remote server, specified in the call to `send_chunk_start/2` is closed by the server.

`type(Pid, Type) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`Type = ascii | binary`
`Reason = etype | elogin | econn`

Sets the file transfer type to `ascii` or `binary`. When an ftp session is opened, the transfer type is set to `binary`.

`user(Pid, User, Password) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`User = Password = string()`
`Reason = euser | econn`

Performs login of `User` with `Password`.

`user(Pid, User, Password,Account) -> ok | {error, Reason}`

Types:

`Pid = pid()`
`User = Password = string()`
`Reason = euser | econn`

Performs login of `User` with `Password`to the acccount specified by `Account` .

### ERRORS

The possible error reasons and the corresponding diagnostic strings returned by `formaterror/1` are as follows:

`echunk`
  Synchronisation error during chunk sending.
  A call has been made to `send_chunk/2` or `send_chunk_end/1`, before a call to `send_chunk_start/2`; or a call has been made to another transfer function during chunk sending, i.e. before a call to `send_chunk_end/1`.
`eclosed`
  The session has been closed.
`econn`
  Connection to remote server prematurely closed.
`ehost`
  Host not found, FTP server not found, or connection rejected by FTP server.
`elogin`
  User not logged in.
`enotbinary`
  Term is not a binary.
`epath`
  No such file or directory, or directory already exists, or permission denied.
`etype`
  No such type.
`euser`
  User name or password not valid.
`etnospc`
  Insufficient storage space in system [452].
`epnospc`
  Exceeded storage allocation (for current directory or dataset) [552].
`efnamena`
  File name not allowed [553].

### SEE ALSO

file, filename, J. Postel and J. Reynolds: File Transfer Protocol (RFC 959).

### AUTHORS

Peter Högfeldt - support@erlang.ericsson.se

inets 3.0.6
Copyright © 1991-2003 Ericsson Utvecklings AB