moga + fmt/clippy
This commit is contained in:
+1
-1
@@ -7,4 +7,4 @@ pub(crate) async fn exec_command<S: AsRef<std::ffi::OsStr>>(
|
||||
let mut u = tokio::process::Command::new(cmd);
|
||||
u.args(args);
|
||||
u.output().await
|
||||
}
|
||||
}
|
||||
|
||||
+17
-9
@@ -20,13 +20,19 @@ pub enum Error {
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Error::DnsResolve { name, source } => write!(f, "DNS resolve failed for {name}: {source}"),
|
||||
Error::CommandFailed { cmd, args, status, stderr } => {
|
||||
let code = status.map(|c| c.to_string()).unwrap_or_else(|| "signal".into());
|
||||
write!(
|
||||
f,
|
||||
"{cmd} {args:?} failed (status: {code}): {stderr}",
|
||||
)
|
||||
Error::DnsResolve { name, source } => {
|
||||
write!(f, "DNS resolve failed for {name}: {source}")
|
||||
}
|
||||
Error::CommandFailed {
|
||||
cmd,
|
||||
args,
|
||||
status,
|
||||
stderr,
|
||||
} => {
|
||||
let code = status
|
||||
.map(|c| c.to_string())
|
||||
.unwrap_or_else(|| "signal".into());
|
||||
write!(f, "{cmd} {args:?} failed (status: {code}): {stderr}",)
|
||||
}
|
||||
Error::Io(e) => write!(f, "IO error: {e}"),
|
||||
}
|
||||
@@ -44,5 +50,7 @@ impl std::error::Error for Error {
|
||||
}
|
||||
|
||||
impl From<io::Error> for Error {
|
||||
fn from(e: io::Error) -> Self { Error::Io(e) }
|
||||
}
|
||||
fn from(e: io::Error) -> Self {
|
||||
Error::Io(e)
|
||||
}
|
||||
}
|
||||
|
||||
+5
-2
@@ -2,7 +2,10 @@
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use tokio::{net::{TcpStream, ToSocketAddrs}, time::timeout};
|
||||
use tokio::{
|
||||
net::{TcpStream, ToSocketAddrs},
|
||||
time::timeout,
|
||||
};
|
||||
|
||||
pub async fn ping_ip<T: ToSocketAddrs>(addr: T) -> bool {
|
||||
timeout(Duration::from_secs(1), TcpStream::connect(addr))
|
||||
@@ -11,4 +14,4 @@ pub async fn ping_ip<T: ToSocketAddrs>(addr: T) -> bool {
|
||||
}
|
||||
pub async fn _ping_ip_2<T: ToSocketAddrs>(_addr: T) -> bool {
|
||||
todo!("use icmp")
|
||||
}
|
||||
}
|
||||
|
||||
+51
-10
@@ -5,7 +5,11 @@ use macaddr::MacAddr;
|
||||
|
||||
use crate::{
|
||||
arpparse::{self, IpNeighLine, NUDState},
|
||||
utils::{cmd::exec_command, error::{self, Error, Result}, get_ips},
|
||||
utils::{
|
||||
cmd::exec_command,
|
||||
error::{self, Error, Result},
|
||||
get_ips,
|
||||
},
|
||||
};
|
||||
|
||||
pub async fn get_macs_2_1(machine_name: &str) -> Result<HashSet<(IpAddr, MacAddr, NUDState)>> {
|
||||
@@ -76,13 +80,8 @@ pub async fn get_macs(
|
||||
state: Option<NUDState>,
|
||||
) -> Result<Vec<IpNeighLine>> {
|
||||
// Collect IPs early (before any await) to avoid holding generics across await points
|
||||
let ip_list: Option<Vec<IpAddr>> = ips.map(|slice| {
|
||||
slice
|
||||
.iter()
|
||||
.copied()
|
||||
.map(|ip| ip.to_canonical())
|
||||
.collect()
|
||||
});
|
||||
let ip_list: Option<Vec<IpAddr>> =
|
||||
ips.map(|slice| slice.iter().copied().map(|ip| ip.to_canonical()).collect());
|
||||
|
||||
// Resolve by machine name if no IPs provided but we have a name
|
||||
let ip_list = match (ip_list, machine_name) {
|
||||
@@ -128,15 +127,57 @@ pub async fn get_macs(
|
||||
} else {
|
||||
parsed.collect()
|
||||
};
|
||||
Ok::<Vec<IpNeighLine>, error::Error>(rows)
|
||||
Ok::<Vec<IpNeighLine>, error::Error>(rows)
|
||||
};
|
||||
|
||||
// If we have specific IPs, query each; otherwise query the whole table once
|
||||
if !ip_list.is_empty() {
|
||||
let futures = ip_list.into_iter().map(|ip| run_one(Some(ip)));
|
||||
let res = futures::future::try_join_all(futures).await?;
|
||||
let res = futures::future::try_join_all(futures).await?;
|
||||
Ok(res.into_iter().flatten().collect())
|
||||
} else {
|
||||
run_one(None).await
|
||||
}
|
||||
}
|
||||
|
||||
pub mod dev {
|
||||
use std::{collections::HashSet, sync::LazyLock};
|
||||
|
||||
pub fn get_dev() -> HashSet<String> {
|
||||
// Prefer /sys/class/net, fallback to /proc/net/dev; filter out loopback
|
||||
let mut devs: HashSet<String> = HashSet::new();
|
||||
if let Ok(rd) = std::fs::read_dir("/sys/class/net") {
|
||||
for e in rd.flatten() {
|
||||
if let Ok(name) = e.file_name().into_string()
|
||||
&& name != "lo"
|
||||
&& !name.is_empty()
|
||||
{
|
||||
devs.insert(name);
|
||||
}
|
||||
}
|
||||
} else if let Ok(txt) = std::fs::read_to_string("/proc/net/dev") {
|
||||
for line in txt.lines().skip(2) {
|
||||
// skip headers
|
||||
if let Some((name, _rest)) = line.split_once(':') {
|
||||
let n = name.trim().to_string();
|
||||
if n != "lo" && !n.is_empty() {
|
||||
devs.insert(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
devs
|
||||
}
|
||||
|
||||
pub static DEVS: LazyLock<HashSet<String>> = LazyLock::new(get_dev);
|
||||
|
||||
pub fn devs_sorted() -> Vec<String> {
|
||||
let mut v: Vec<String> = DEVS.iter().cloned().collect();
|
||||
v.sort();
|
||||
v
|
||||
}
|
||||
|
||||
pub fn has_dev(name: &str) -> bool {
|
||||
DEVS.contains(name)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -2,13 +2,13 @@ use std::{io, net::IpAddr};
|
||||
|
||||
use tokio::net::UdpSocket;
|
||||
|
||||
use crate::utils::{query::get_macs_2_mac, LDA_MACS_2};
|
||||
use crate::utils::query::get_macs_2_mac;
|
||||
|
||||
pub async fn wake(machine_name: &str) -> io::Result<u32> {
|
||||
let suh = UdpSocket::bind("0.0.0.0:0").await?;
|
||||
suh.set_broadcast(true)?;
|
||||
let mut macs = get_macs_2_mac(machine_name).await.unwrap_or_default();
|
||||
macs.extend(*LDA_MACS_2);
|
||||
let /* mut */ macs = get_macs_2_mac(machine_name).await.unwrap_or_default();
|
||||
// macs.extend(*LDA_MACS_2);
|
||||
let mut sent_ok = 0;
|
||||
for mac in macs {
|
||||
let mb = mac.as_bytes();
|
||||
@@ -29,4 +29,4 @@ pub async fn wake(machine_name: &str) -> io::Result<u32> {
|
||||
}
|
||||
}
|
||||
Ok(sent_ok)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user