2023-09-01 04:10:56 +00:00
|
|
|
use std::{collections::HashMap, path::PathBuf};
|
|
|
|
|
2023-08-25 06:32:21 +00:00
|
|
|
use keyfork_mnemonic_util::Mnemonic;
|
|
|
|
|
|
|
|
use tokio::io::{self, AsyncBufReadExt, BufReader};
|
|
|
|
|
|
|
|
#[cfg(feature = "tracing")]
|
|
|
|
use tracing::debug;
|
|
|
|
#[cfg(feature = "tracing")]
|
|
|
|
use tracing_subscriber::{
|
|
|
|
filter::{EnvFilter, LevelFilter},
|
|
|
|
fmt::{format::FmtSpan, layer},
|
|
|
|
prelude::*,
|
|
|
|
registry,
|
|
|
|
};
|
|
|
|
|
|
|
|
mod error;
|
|
|
|
mod server;
|
2023-08-25 07:47:54 +00:00
|
|
|
mod service;
|
2023-09-01 04:10:56 +00:00
|
|
|
use error::KeyforkdError;
|
2023-08-25 06:32:21 +00:00
|
|
|
use server::UnixServer;
|
2023-08-25 07:47:54 +00:00
|
|
|
use service::Keyforkd;
|
2023-08-25 06:32:21 +00:00
|
|
|
|
|
|
|
type Result<T, E = Box<dyn std::error::Error>> = std::result::Result<T, E>;
|
|
|
|
|
|
|
|
async fn load_mnemonic() -> Result<Mnemonic> {
|
|
|
|
let mut stdin = BufReader::new(io::stdin());
|
|
|
|
let mut line = String::new();
|
|
|
|
stdin.read_line(&mut line).await?;
|
|
|
|
Ok(line.parse()?)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "tracing")]
|
|
|
|
fn setup_registry() {
|
|
|
|
let envfilter = EnvFilter::builder()
|
|
|
|
.with_default_directive(LevelFilter::DEBUG.into())
|
|
|
|
.from_env_lossy();
|
|
|
|
registry()
|
|
|
|
.with(envfilter)
|
|
|
|
.with(layer().with_span_events(FmtSpan::CLOSE))
|
|
|
|
.with(tracing_error::ErrorLayer::default())
|
|
|
|
.init();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg_attr(feature = "multithread", tokio::main)]
|
|
|
|
#[cfg_attr(not(feature = "multithread"), tokio::main(flavor = "current_thread"))]
|
|
|
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
|
|
#[cfg(feature = "tracing")]
|
|
|
|
setup_registry();
|
|
|
|
|
|
|
|
#[cfg(feature = "tracing")]
|
|
|
|
debug!("reading mnemonic from standard input");
|
|
|
|
let mnemonic = load_mnemonic().await?;
|
|
|
|
|
|
|
|
let service = Keyforkd::new(mnemonic);
|
|
|
|
|
2023-09-01 04:10:56 +00:00
|
|
|
let runtime_vars = std::env::vars()
|
|
|
|
.filter(|(key, _)| ["XDG_RUNTIME_DIR", "KEYFORKD_SOCKET_PATH"].contains(&key.as_str()))
|
|
|
|
.collect::<HashMap<String, String>>();
|
|
|
|
let mut runtime_path: PathBuf;
|
|
|
|
#[allow(clippy::single_match_else)]
|
|
|
|
match runtime_vars.get("KEYFORKD_SOCKET_PATH") {
|
|
|
|
Some(occupied) => {
|
|
|
|
runtime_path = PathBuf::from(occupied);
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
runtime_path = PathBuf::from(
|
|
|
|
runtime_vars
|
|
|
|
.get("XDG_RUNTIME_DIR")
|
|
|
|
.ok_or(KeyforkdError::NoSocketPath)?,
|
|
|
|
);
|
|
|
|
runtime_path.push("keyforkd");
|
|
|
|
#[cfg(feature = "tracing")]
|
|
|
|
debug!("ensuring directory exists: {}", runtime_path.display());
|
|
|
|
if !runtime_path.is_dir() {
|
|
|
|
tokio::fs::create_dir(&runtime_path).await?;
|
|
|
|
}
|
|
|
|
runtime_path.push("keyforkd.sock");
|
|
|
|
}
|
2023-08-25 06:32:21 +00:00
|
|
|
}
|
2023-09-01 04:10:56 +00:00
|
|
|
|
2023-08-25 06:32:21 +00:00
|
|
|
#[cfg(feature = "tracing")]
|
|
|
|
debug!(
|
|
|
|
"binding UNIX socket in runtime dir: {}",
|
2023-09-01 04:10:56 +00:00
|
|
|
runtime_path.display()
|
2023-08-25 06:32:21 +00:00
|
|
|
);
|
|
|
|
|
2023-09-01 04:10:56 +00:00
|
|
|
let mut server = match UnixServer::bind(&runtime_path) {
|
|
|
|
Ok(s) => s,
|
|
|
|
Err(e) => {
|
|
|
|
#[cfg(feature = "tracing")]
|
|
|
|
debug!(%e, "Encountered error attempting to bind socket: {}", runtime_path.display());
|
|
|
|
return Err(e.into());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
match server.run(service).await {
|
|
|
|
Ok(_) => (),
|
|
|
|
Err(e) => {
|
|
|
|
#[cfg(feature = "tracing")]
|
|
|
|
debug!(%e, "Encountered error while running");
|
|
|
|
}
|
|
|
|
}
|
2023-08-25 06:32:21 +00:00
|
|
|
Ok(())
|
|
|
|
}
|