use std::path::PathBuf;
fn victauri_base_dir() -> PathBuf {
std::env::temp_dir().join("victauri")
}
pub fn scan_discovery_dirs_for_port() -> Option<u16> {
let servers = find_live_servers();
if servers.len() == 1 {
return Some(servers[0].port);
}
None
}
pub fn scan_discovery_dirs_for_token() -> Option<String> {
let servers = find_live_servers();
if servers.len() == 1 {
return servers[0].token.clone();
}
None
}
struct DiscoveredServer {
port: u16,
token: Option<String>,
}
fn find_live_servers() -> Vec<DiscoveredServer> {
let base = victauri_base_dir();
let Ok(entries) = std::fs::read_dir(&base) else {
return Vec::new();
};
let mut servers = Vec::new();
for entry in entries.flatten() {
let path = entry.path();
if !path.is_dir() {
continue;
}
let Some(pid_str) = path.file_name().and_then(|n| n.to_str()) else {
continue;
};
if pid_str.parse::<u32>().is_err() {
continue;
}
let port_path = path.join("port");
let Ok(port_str) = std::fs::read_to_string(&port_path) else {
continue;
};
let Ok(port) = port_str.trim().parse::<u16>() else {
continue;
};
if std::net::TcpStream::connect_timeout(
&std::net::SocketAddr::from(([127, 0, 0, 1], port)),
std::time::Duration::from_millis(100),
)
.is_err()
{
let _ = std::fs::remove_dir_all(&path);
continue;
}
let token = std::fs::read_to_string(path.join("token"))
.ok()
.map(|t| t.trim().to_string())
.filter(|t| !t.is_empty());
servers.push(DiscoveredServer { port, token });
}
servers
}