diff --git a/Cargo.lock b/Cargo.lock index 6505209..0d346b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,6 +869,20 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "ipaddress" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957bb9f3645d6bb7f36df99d5105b4866aa79749819d7c176a170a27dc477cbf" +dependencies = [ + "lazy_static", + "libc", + "num", + "num-integer", + "num-traits", + "regex", +] + [[package]] name = "ipnet" version = "2.9.0" @@ -896,6 +910,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.155" @@ -1010,6 +1030,7 @@ version = "1.5.0" dependencies = [ "clap", "dirs", + "ipaddress", "notify-rust", "regex", "reqwest", @@ -1045,12 +1066,85 @@ dependencies = [ "zbus", ] +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "objc" version = "0.2.7" diff --git a/Cargo.toml b/Cargo.toml index 2a8668a..80b9064 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,3 +21,4 @@ reqwest = { version = "~0.12", features = ["blocking", "default"] } notify-rust = { version = "4", features = ["default"] } which = { version = "~6.0" } clap = { version = "4", features = ["derive"] } +ipaddress = "0.1.3" diff --git a/src/main.rs b/src/main.rs index 801d526..27296ec 100644 --- a/src/main.rs +++ b/src/main.rs @@ -424,7 +424,7 @@ pub struct RealCommandRunner; impl CommandRunner for RealCommandRunner { fn run_command(&self, command: &str, args: &[&str]) -> Result { - Command::new(command).args(args).output() + Command::new(command).args(args).env("LC_ALL", "C").output() } } @@ -472,6 +472,7 @@ pub fn is_known_network(ssid: &str) -> Result> } fn convert_network_strength(line: &str) -> String { + println!("{line}"); // Define the mapping for network strength symbols let strength_symbols = ["_", "▂", "▄", "▆", "█"]; diff --git a/src/tailscale.rs b/src/tailscale.rs index a49fa72..035af10 100644 --- a/src/tailscale.rs +++ b/src/tailscale.rs @@ -70,25 +70,31 @@ fn get_mullvad_actions_with_command_runner(command_runner: &dyn CommandRunner) - fn parse_mullvad_line(line: &str, regex: &Regex, active_exit_node: &str) -> String { let parts: Vec<&str> = regex.split(line).collect(); - let country = parts.get(2).unwrap_or(&""); - let node_name = parts.get(1).unwrap_or(&""); - let is_active = active_exit_node == *node_name; + let node_ip = parts.get(0).unwrap_or(&"").trim(); + let node_name = parts.get(1).unwrap_or(&"").trim(); + let country = parts.get(2).unwrap_or(&"").trim(); + let is_active = active_exit_node == node_name; format_entry( "mullvad", if is_active { "✅" } else { get_flag(country) }, - &format!("{country} - {node_name}"), + &format!("{country:<15} - {node_ip:<16} {node_name}"), ) } +fn extract_short_name(node_name: &str) -> &str { + node_name.split('.').next().unwrap_or(node_name) +} + fn parse_exit_node_line(line: &str, regex: &Regex, active_exit_node: &str) -> String { let parts: Vec<&str> = regex.split(line).collect(); let node_ip = parts.first().unwrap_or(&"").trim(); - let node_name = parts.get(1).unwrap_or(&""); - let is_active = active_exit_node == *node_name; + let node_name = parts.get(1).unwrap_or(&"").trim(); + let node_short_name = extract_short_name(node_name); + let is_active = active_exit_node == node_name; format_entry( "exit-node", if is_active { "✅" } else { "🌿" }, - &format!("{node_name} - {node_ip}"), + &format!("{node_short_name:<15} - {node_ip:<16} {node_name}"), ) } @@ -119,11 +125,14 @@ fn get_active_exit_node() -> String { } fn set_exit_node(action: &str) -> bool { - let node_name = match extract_node_name(action) { - Some(name) => name, + let node_ip = match extract_node_ip(action) { + Some(ip) => ip, None => return false, }; + #[cfg(debug_assertions)] + println!("Exit-node ip address: {node_ip}"); + if !execute_command("tailscale", &["up"]) { return false; } @@ -133,23 +142,24 @@ fn set_exit_node(action: &str) -> bool { &[ "set", "--exit-node", - node_name, + node_ip, "--exit-node-allow-lan-access=true", ], ) } -fn extract_node_name(action: &str) -> Option<&str> { - let regex = Regex::new(r" ([\w_.-]+)$").ok()?; - regex +fn extract_node_ip(action: &str) -> Option<&str> { + Regex::new(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b") + .ok()? .captures(action) - .and_then(|caps| caps.get(1)) + .and_then(|caps| caps.get(0)) .map(|m| m.as_str()) } fn execute_command(command: &str, args: &[&str]) -> bool { Command::new(command) .args(args) + .env("LC_ALL", "C") .stdout(Stdio::null()) .stderr(Stdio::null()) .status() @@ -212,7 +222,10 @@ fn get_flag(country: &str) -> &'static str { } pub fn is_exit_node_active() -> Result> { - let output = Command::new("tailscale").arg("status").output()?; + let output = Command::new("tailscale") + .arg("status") + .env("LC_ALL", "C") + .output()?; if output.status.success() { let reader = BufReader::new(output.stdout.as_slice()); @@ -242,7 +255,7 @@ impl CommandRunner for RealCommandRunner { command: &str, args: &[&str], ) -> Result { - Command::new(command).args(args).output() + Command::new(command).args(args).env("LC_ALL", "C").output() } }