- Rust 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
All checks were successful
Release Build / Create Release (push) Successful in 1s
Release Build / Publish to the Cargo registry (push) Successful in 42s
Release Build / Linux (binks-cli-linux-amd64) (push) Successful in 48s
Release Build / Linux (binks-cli-linux-arm64) (push) Successful in 1m21s
CI / Rust (push) Successful in 1m59s
CI / Cargo Audit (push) Successful in 25s
Reviewed-on: #2 |
||
| .cargo | ||
| .forgejo/workflows | ||
| src | ||
| tests | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CHANGELOG.md | ||
| README.md | ||
| rust-toolchain.toml | ||
binks
Command-line client for Binks: paste text, upload files of
any size (resumable, in parallel), shorten links, with passwords, end-to-end encryption, expiry
and burn-after-reading. It needs a Binks 0.9 server (api_version 2 in /api/config) and
refuses older ones; binks-cli 0.8 talks to Binks 0.8.
cargo install --path . # installs the `binks` binary
binks config set server https://binks.example # or export BINKS_URL
Usage
echo "hello" | binks # paste stdin; binary input becomes a file
binks paste "some text" -l rust # text with syntax highlighting
binks paste "see diagram" -f d.png # text with an attached file
binks upload video.mp4 -e 1w # file, expires in a week
binks shorten https://example.com/long/url
binks get https://binks.example/abc # print a text / download a file / print a link's target
binks get abc -o out.bin # save under another name
binks get abc --info # metadata only; never counts as a read
binks delete abc # uses the deletion token saved at upload
Results go to stdout and everything else to stderr, so url=$(binks upload f) just works.
--json prints machine-readable results (the server's item JSON, with the URL's #k= key and
the deletion token), -q silences status output, -c copies the URL. -l takes a
highlight.js language name such as rust, markdown or c++.
binks get reads the item's metadata first, which never counts as a read, then its content:
a text prints, a file downloads (its note, if it has one, prints first and doesn't count), and
a link prints its target. A burn-after-reading link's target counts as one of its reads, so
--info doesn't show it.
Options work before or after the command:
| Option | |
|---|---|
-e, --expiration |
1h, 1d, 1w, 1m, 1y, never |
-b, --burn-after N |
delete after N reads |
-p, --password PW / -P |
password-protect (or unlock); -P prompts instead |
--encrypted |
end-to-end encrypt; the key is appended to the URL as #k=... |
--key KEY |
encryption key to use, or to decrypt with |
--id ID |
custom ID |
--server URL |
server (also BINKS_URL, or server in the config) |
--token TOKEN |
API token (also BINKS_TOKEN) |
--connections N |
parallel connections per transfer (default: chosen from the server's latency) |
--chunk-size MIB |
upload chunk size (default: the server's) |
Encryption happens locally: the server stores ciphertext and sees neither the file name,
its type nor the paste's language. Pastes and files encrypted in the CLI open in the browser
and vice versa, as long as the URL keeps its #k= fragment.
Large files are uploaded in chunks, in parallel parts over separate connections, and large
downloads (32 MiB and up) are fetched as parallel byte ranges. A distant server (60 ms or more
away) gets more connections (8 upload parts, 4 download ranges) since one connection can't fill
a fast link over a long path; a nearby one gets 4 and 1. --connections overrides this.
Transfers ride out network drops and server restarts: a broken chunk or download resumes where
it stopped, retrying for up to about half an hour while nothing gets through. If an upload is
given up on (or you press Ctrl-C), run the same command again to resume it. A server asking
to wait longer than five minutes (a rate limit) ends the transfer instead. Downloads stream to
disk and never overwrite an existing file unless you pass --force. Burn-after-reading files
are always downloaded over one connection.
Scanning. On servers that scan uploads, new files may be unavailable for a moment;
binks get --wait waits instead of failing.
Accounts
binks login # signs in once and saves an API token for this machine
binks whoami
binks token create ci --scope upload --expires 30 # prints a token for scripts
binks token list
binks logout # revokes this machine's token
binks register # when the server allows sign-ups
Signed-in users can delete their own content without a deletion token. A saved login token is
only sent to the server it was created on (token_server in binks config).
Configuration
Settings live in ~/.config/binks/config.toml (BINKS_CLI_CONFIG overrides the path):
binks config show | get | set | unset | edit | path | reset. Keys: server, expiration,
burn_after, auto_copy, json_output, insecure, ca_cert, connections,
chunk_size_mb, token, token_server.
Deletion tokens and interrupted uploads are kept in ~/.local/state/binks/.
Shell completions: binks completions bash > ~/.local/share/bash-completion/completions/binks
(also zsh, fish, powershell, elvish).
Development
cargo fmt --check && cargo clippy --all-targets -- -D warnings
cargo test
The integration tests in tests/cli.rs run the binary against an in-process Binks server,
pulled in as a git dev-dependency (a Binks 0.9 one: the CLI refuses older servers). To test
against a local server checkout, patch it in; the patch applies once the lock names it, so
update that first (git checkout Cargo.lock undoes it):
P='patch."https://github.com/RaringM/binks".binks.path="../binks"'
cargo update --config "$P" -p binks && cargo test --config "$P"
E2EE test vectors (tests/data/e2ee-vectors.json) are shared with the server's web app.