# `Sidereon.GNSS.FtpClient`
[🔗](https://github.com/neilberkman/sidereon-ex/blob/main/lib/sidereon/gnss/ftp_client.ex#L1)

Minimal anonymous-FTP client implementation over `:gen_tcp`.

Replaces Erlang/OTP's legacy `:ftp` application (removed in OTP 30) for
retrieving open GNSS archive files and listings over FTP.

## Test Seams

  * `:ftp_port` - Configured via `Application.get_env(:sidereon, :ftp_port, 21)`.
    Allows overriding the default control port (21) for local test servers.

# `host`

```elixir
@type host() :: charlist() | String.t() | :inet.ip_address()
```

# `opt`

```elixir
@type opt() :: {:timeout, pos_integer()} | {:mode, :passive | :active}
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `close`

```elixir
@spec close(pid()) :: :ok
```

Closes the FTP connection.

# `ls`

```elixir
@spec ls(pid(), charlist() | String.t()) ::
  {:ok, binary()} | {:error, :epath} | {:error, term()}
```

Lists contents of a directory.

# `open`

```elixir
@spec open(host(), [opt()]) :: {:ok, pid()} | {:error, term()}
```

Opens an FTP control connection to `host`.

# `recv_chunk`

```elixir
@spec recv_chunk(pid()) :: :ok | {:ok, binary()} | {:error, :epath} | {:error, term()}
```

Retrieves the next chunk of the file or signals EOF (`:ok`).

# `recv_chunk_start`

```elixir
@spec recv_chunk_start(pid(), charlist() | String.t()) ::
  :ok | {:error, :epath} | {:error, term()}
```

Starts retrieving a file.

# `type`

```elixir
@spec type(pid(), :binary | :ascii) :: :ok | {:error, :epath} | {:error, term()}
```

Sets transfer mode (e.g. `:binary` for `TYPE I`).

# `user`

```elixir
@spec user(pid(), charlist() | String.t(), charlist() | String.t()) ::
  :ok | {:error, :epath} | {:error, term()}
```

Authenticates with the FTP server (typically anonymous).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
