onionwire/src/main.rs

70 lines
2.2 KiB
Rust
Raw Normal View History

use onionwire::tui::AppExit;
use std::io::{self, Write};
fn print_help() {
let v = env!("CARGO_PKG_VERSION");
println!("onionwire {v} — Tor messenger (in-process Arti). Runs a TUI; no server.");
println!("Usage: onionwire [--version | --help]");
println!("Data: $ONIONWIRE_HOME or ~/.local/share/onionwire");
}
#[tokio::main]
async fn main() {
match std::env::args().nth(1).as_deref() {
Some("--version") | Some("-V") => {
println!("onionwire {}", env!("CARGO_PKG_VERSION"));
return;
}
Some("--help") | Some("-h") => {
print_help();
return;
}
Some(other) => {
eprintln!("onionwire: unknown argument {other}");
eprintln!("Try: onionwire --help");
std::process::exit(2);
}
None => {}
}
if let Err(e) = boot().await {
eprintln!("onionwire: {e}");
std::process::exit(1);
}
}
async fn boot() -> Result<(), String> {
let home = onionwire::Store::home_dir().map_err(|e| e.to_string())?;
let pass = store_passphrase()?;
eprintln!("onionwire: bootstrapping Arti…");
let node = onionwire::node::Node::start_with_passphrase(home.clone(), &pass).await?;
let handle = tokio::runtime::Handle::current();
let exit = tokio::task::spawn_blocking(move || onionwire::tui::run(node, handle))
.await
.map_err(|e| e.to_string())??;
if exit == AppExit::WipeAll {
onionwire::Store::wipe_all(&home).map_err(|e| e.to_string())?;
eprintln!("onionwire: all local data wiped");
}
Ok(())
}
fn store_passphrase() -> Result<String, String> {
match std::env::var("ONIONWIRE_STORE_PASSPHRASE") {
Ok(p) if p.is_empty() => Err("empty passphrase".into()),
Ok(p) => Ok(p),
Err(_) => {
eprint!("onionwire: store passphrase: ");
let _ = io::stderr().flush();
let mut s = String::new();
io::stdin().read_line(&mut s).map_err(|e| e.to_string())?;
let s = s.trim_end_matches(['\n', '\r']).to_string();
if s.is_empty() {
Err("empty passphrase".into())
} else {
Ok(s)
}
}
}
}