75 lines
2.8 KiB
Markdown
75 lines
2.8 KiB
Markdown
# Memona FTP plugin
|
|
|
|
Opens an FTP or FTPS server as a folder in [Memona](https://memona.app), so
|
|
files on it are browsed, read, written and renamed like local ones, and agents
|
|
work in them.
|
|
|
|
The plugin is a WebAssembly component built against the Memona filesystem
|
|
contract, `memona:filesystem@0.1.0`. It uses only the host's sockets; it has no
|
|
ambient filesystem, environment or network access of its own.
|
|
|
|
This package requires a Memona version that supports plugin manifest schema 2.
|
|
|
|
## What it registers
|
|
|
|
One provider, `ftp`, for the `ftp` and `ftps` schemes. A connection is
|
|
configured with a server name, an optional port, a TLS toggle for FTPS, and an
|
|
optional username and password. An empty username signs in anonymously.
|
|
|
|
Public, LAN, VPN, link-local and localhost addresses work directly from the
|
|
server name; there is no separate network permission setting.
|
|
|
|
The TLS toggle currently starts TLS on the control connection only. Protected
|
|
data connections and explicit `AUTH TLS` negotiation are not implemented, so
|
|
the plugin does not yet provide a complete FTPS connection.
|
|
|
|
Listing and stat need a server that answers `MLSD` and `MLST`, the
|
|
machine-readable listing commands. A server without them reports the folder as
|
|
unsupported rather than guessing at the older, human-formatted listing or
|
|
changing its working directory to find out. FTP carries no version token,
|
|
so a conditional write is reported as unsupported rather than simulated.
|
|
|
|
## Passive mode and the port range
|
|
|
|
Transfers are passive: the plugin asks the server for a data port with `EPSV`
|
|
and connects out to it; `PASV` fallback is not implemented. The server picks a fresh port for every
|
|
transfer and announces it only as the transfer begins, so the range that has to
|
|
be reachable is wide.
|
|
|
|
The package declares socket ports 21 and 1024-65535, which Memona applies
|
|
automatically to each connection. The control port and passive data ports
|
|
must be within these ranges.
|
|
|
|
## Build
|
|
|
|
```sh
|
|
rustup target add wasm32-wasip2
|
|
cargo build --locked --release --target wasm32-wasip2
|
|
```
|
|
|
|
The component lands at
|
|
`target/wasm32-wasip2/release/memona_plugin_ftp.wasm`.
|
|
|
|
`sdk/` is a vendored copy of the Memona plugin SDK, the WIT contract plus its
|
|
generated Rust bindings, so this repository builds without the Memona repository
|
|
present.
|
|
|
|
## Package for the plugin store
|
|
|
|
Copy the component to `plugin.wasm` and ZIP it at the archive root together
|
|
with `manifest.json`, `README.md` and `LICENSE`:
|
|
|
|
```sh
|
|
cp target/wasm32-wasip2/release/memona_plugin_ftp.wasm plugin.wasm
|
|
zip memona-plugin-ftp.memona-plugin \
|
|
manifest.json plugin.wasm README.md LICENSE
|
|
```
|
|
|
|
The archive must have no wrapping directory. Memona validates the package and
|
|
its digest, and checks the component's imports against the supported WIT API,
|
|
before activation.
|
|
|
|
## License
|
|
|
|
MIT. See [LICENSE](LICENSE).
|