Architecture
etrans is two crates in one workspace.
etrans-core
Everything that is not drawing, and has no UI dependency:
| Module | |
|---|---|
ssh |
Connecting: TCP or a tunnel through a jump host, the host key check, and the login (agent, keys, password, keyboard-interactive). Anything that needs a person is put to an Asker, and the connection waits for the answer. |
known_hosts |
~/.ssh/known_hosts read as OpenSSH reads it: patterns, negation, hashed names, @revoked and @cert-authority, and host certificates checked against it. |
ssh_config |
The parts of ~/.ssh/config etrans uses. |
sftp |
The remote filesystem over an SFTP channel. |
local |
The local filesystem, listed the same way, plus keys in ~/.ssh and user and group names. |
transfer |
The transfer queue: planning, copying with partial files and resume, retries, conflicts. |
forward |
Local, remote and SOCKS5 forwarding. |
shell |
An interactive shell in a pseudo-terminal. |
site, settings, secrets, import, accounts |
Saved servers, settings, Keychain, importing, owners by name. |
runtime |
The tokio runtime the SSH work runs on. |
SSH and SFTP are russh and russh-sftp.
russh needs tokio, and gpui has its own executor, so the two meet in
runtime: work is spawned onto a runtime that lives for the whole process,
and the caller gets back a plain future any executor can wait on. Dropping that
future stops the work, which is how cancelling a connection really cancels it.
etrans
The app, on GPUI:
| Module | |
|---|---|
browser |
The main window: connecting and reconnecting, the server list, dialogs, the right-click menu, the transfer drawer, port forwarding, Get Info, About and the update strip. |
pane |
One file pane: listing, selection, navigation, drag and drop. |
terminal |
A shell window: alacritty's emulator fed from the SSH channel, drawn cell by cell. |
preferences |
Settings as the app holds them, and the Settings window. |
update |
The updater: the feed, the download, the signature check and the swap. |
text_input, ui, theme, actions, keys |
Text fields, shared controls, colours, actions and their keys, and keystrokes to terminal bytes. |
Two things worth knowing
Questions from the background. A connection that meets an unknown host key,
or needs a password, does not know about windows. It calls an Asker — a
function from a Question to a future answer — and waits. The window turns the
question into a sheet and sends the answer back over a oneshot channel. A
reconnect wraps the asker in one that answers passwords typed earlier from
memory.
Partial files are named for their source. A transfer writes
.<name>.<size>-<mtime>.etrans-part beside the destination and renames it into
place when it is whole. Resuming is looking for that exact name: if the source
changed, the name changed, and the copy starts over instead of continuing a
different file.