Without them the Connections page showed no pairing code (or QR code) on Arch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Showing 1 changed file with 23 additions and 3 deletions.
| @@ -463,9 +463,29 @@ pub fn with_port(address: &str) -> String { | ||
| 463 | 463 | |
| 464 | 464 | /// This machine's IPv4 addresses on the network, for showing where to connect. |
| 465 | 465 | pub fn local_addresses() -> Vec<String> { |
| 466 | - let output = std::process::Command::new("hostname").arg("-I").stderr(std::process::Stdio::null()).output(); | |
| 467 | - let text = output.map(|output| String::from_utf8_lossy(&output.stdout).to_string()).unwrap_or_default(); | |
| 468 | - text.split_whitespace().filter(|address| address.parse::<std::net::Ipv4Addr>().is_ok()).map(str::to_string).collect() | |
| 466 | + let run = |program: &str, args: &[&str]| { | |
| 467 | + let output = std::process::Command::new(program).args(args).stderr(std::process::Stdio::null()).output(); | |
| 468 | + output.map(|output| String::from_utf8_lossy(&output.stdout).to_string()).unwrap_or_default() | |
| 469 | + }; | |
| 470 | + let ipv4 = |address: &str| address.parse::<std::net::Ipv4Addr>().ok().filter(|address| !address.is_loopback()); | |
| 471 | + let addresses: Vec<String> = | |
| 472 | + run("hostname", &["-I"]).split_whitespace().filter_map(ipv4).map(|address| address.to_string()).collect(); | |
| 473 | + if !addresses.is_empty() { | |
| 474 | + return addresses; | |
| 475 | + } | |
| 476 | + // inetutils' hostname has no -I (Arch and its derivatives); ask iproute2, | |
| 477 | + // leaving out container bridges. | |
| 478 | + run("ip", &["-4", "-o", "addr", "show", "scope", "global"]) | |
| 479 | + .lines() | |
| 480 | + .filter_map(|line| { | |
| 481 | + let mut fields = line.split_whitespace().skip(1); | |
| 482 | + let interface = fields.next()?; | |
| 483 | + let address = fields.skip_while(|field| *field != "inet").nth(1)?.split('/').next()?; | |
| 484 | + let bridge = ["docker", "br-", "veth", "virbr"].iter().any(|prefix| interface.starts_with(prefix)); | |
| 485 | + (!bridge).then(|| ipv4(address)).flatten() | |
| 486 | + }) | |
| 487 | + .map(|address| address.to_string()) | |
| 488 | + .collect() | |
| 469 | 489 | } |
| 470 | 490 | |
| 471 | 491 | #[cfg(test)] |