allow checking multiple interfaces

This commit is contained in:
Robin Appelman 2020-04-27 15:33:32 +02:00
commit bfa79a65a3

View file

@ -10,26 +10,36 @@ use std::sync::Arc;
use std::str::FromStr; use std::str::FromStr;
struct WifiLister { struct WifiLister {
session: Session command: String,
session: Session,
} }
impl WifiLister { impl WifiLister {
pub fn new<A: ToSocketAddrs, S: AsRef<OsStr> + ?Sized>(addr: A, keyfile: &S) -> Result<Self, MainError> { pub fn new<A: ToSocketAddrs, Priv: AsRef<OsStr>, Pub: AsRef<OsStr>>(addr: A, keyfile: Priv, pubkey: Pub, interfaces: &[&str]) -> Result<Self, MainError> {
let tcp = TcpStream::connect(addr)?; let tcp = TcpStream::connect(addr)?;
let mut session = Session::new()?; let mut session = Session::new()?;
session.set_tcp_stream(tcp); session.set_tcp_stream(tcp);
session.handshake()?; session.handshake()?;
let key_file = Path::new(keyfile); let keyfile = Path::new(keyfile.as_ref());
session.userauth_pubkey_file("admin", None, &key_file, None)?; let pubkey = Path::new(pubkey.as_ref());
session.userauth_pubkey_file("admin", Some(pubkey), keyfile, None)?;
let command = if interfaces.is_empty() {
"wl assoclist".to_string()
} else {
let commands: Vec<String> = interfaces.iter().map(|interface| format!("wl -a {} assoclist", interface)).collect();
commands.join(" && ")
};
Ok(WifiLister { Ok(WifiLister {
session session,
command,
}) })
} }
pub fn list_connected_devices(&self) -> Result<Vec<String>, MainError> { pub fn list_connected_devices(&self) -> Result<Vec<String>, MainError> {
let mut channel = self.session.channel_session()?; let mut channel = self.session.channel_session()?;
channel.exec("wl assoclist")?; channel.exec(&self.command)?;
let mut s = String::new(); let mut s = String::new();
channel.read_to_string(&mut s)?; channel.read_to_string(&mut s)?;
channel.wait_close()?; channel.wait_close()?;
@ -43,9 +53,11 @@ async fn main() -> Result<(), MainError> {
let mut env: HashMap<String, String> = dotenv::vars().collect(); let mut env: HashMap<String, String> = dotenv::vars().collect();
let addr = env.remove("ADDR").ok_or("No ADDR set")?; let addr = env.remove("ADDR").ok_or("No ADDR set")?;
let keyfile = env.remove("KEYFILE").ok_or("No KEYFILE set")?; let keyfile = env.remove("KEYFILE").ok_or("No KEYFILE set")?;
let pubfile = env.remove("PUBFILE").ok_or("No PUBFILE set")?;
let port = env.get("PORT").and_then(|s| u16::from_str(s).ok()).unwrap_or(80); let port = env.get("PORT").and_then(|s| u16::from_str(s).ok()).unwrap_or(80);
let interfaces: Vec<&str> = env.get("INTERFACES").map(|interfaces| interfaces.split(' ').collect()).unwrap_or_default();
let wifi_listener = Arc::new(WifiLister::new(addr, &keyfile)?); let wifi_listener = Arc::new(WifiLister::new(addr, &keyfile, &pubfile, &interfaces)?);
// GET /hello/warp => 200 OK with body "Hello, warp!" // GET /hello/warp => 200 OK with body "Hello, warp!"
let metrics = warp::path!("metrics") let metrics = warp::path!("metrics")