diff --git a/Cargo.lock b/Cargo.lock index ed16bef..4457b1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1278,6 +1278,7 @@ dependencies = [ "dashmap", "defguard_wireguard_rs", "derivative", + "encoding", "futures", "gethostname", "http 1.1.0", @@ -1381,6 +1382,70 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" +[[package]] +name = "encoding" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" +dependencies = [ + "encoding-index-japanese", + "encoding-index-korean", + "encoding-index-simpchinese", + "encoding-index-singlebyte", + "encoding-index-tradchinese", +] + +[[package]] +name = "encoding-index-japanese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-korean" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-simpchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-singlebyte" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-tradchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding_index_tests" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" + [[package]] name = "encoding_rs" version = "0.8.33" diff --git a/easytier/Cargo.toml b/easytier/Cargo.toml index af1a2fa..4355aaf 100644 --- a/easytier/Cargo.toml +++ b/easytier/Cargo.toml @@ -164,6 +164,7 @@ windows-sys = { version = "0.52", features = [ "Win32_Foundation", "Win32_System_IO", ] } +encoding = "0.2" [build-dependencies] tonic-build = "0.10" diff --git a/easytier/src/common/ifcfg.rs b/easytier/src/common/ifcfg.rs index aa11ea0..578e450 100644 --- a/easytier/src/common/ifcfg.rs +++ b/easytier/src/common/ifcfg.rs @@ -50,6 +50,8 @@ fn cidr_to_subnet_mask(prefix_length: u8) -> Ipv4Addr { async fn run_shell_cmd(cmd: &str) -> Result<(), Error> { let cmd_out: std::process::Output; + let stdout: String; + let stderr: String; #[cfg(target_os = "windows")] { const CREATE_NO_WINDOW: u32 = 0x08000000; @@ -58,22 +60,25 @@ async fn run_shell_cmd(cmd: &str) -> Result<(), Error> { .arg(cmd) .creation_flags(CREATE_NO_WINDOW) .output() - .await? + .await?; + stdout = crate::utils::utf8_or_gbk_to_string(cmd_out.stdout.as_slice()); + stderr = crate::utils::utf8_or_gbk_to_string(cmd_out.stderr.as_slice()); }; #[cfg(not(target_os = "windows"))] { - cmd_out = Command::new("sh").arg("-c").arg(cmd).output().await? + cmd_out = Command::new("sh").arg("-c").arg(cmd).output().await?; + stdout = String::from_utf8_lossy(cmd_out.stdout.as_slice()).to_string(); + stderr = String::from_utf8_lossy(cmd_out.stderr.as_slice()).to_string(); }; - let stdout = String::from_utf8_lossy(cmd_out.stdout.as_slice()); - let stderr = String::from_utf8_lossy(cmd_out.stderr.as_slice()); + let ec = cmd_out.status.code(); let succ = cmd_out.status.success(); tracing::info!(?cmd, ?ec, ?succ, ?stdout, ?stderr, "run shell cmd"); if !cmd_out.status.success() { return Err(Error::ShellCommandError( - stdout.to_string() + &stderr.to_string(), + stdout + &stderr, )); } Ok(()) diff --git a/easytier/src/utils.rs b/easytier/src/utils.rs index 7707e58..78fd572 100644 --- a/easytier/src/utils.rs +++ b/easytier/src/utils.rs @@ -225,6 +225,22 @@ pub fn init_logger( Ok(ret_sender) } +#[cfg(target_os = "windows")] +pub fn utf8_or_gbk_to_string(s: &[u8]) -> String { + use encoding::{all::GBK, DecoderTrap, Encoding}; + if let Ok(utf8_str) = String::from_utf8(s.to_vec()) { + utf8_str + } else { + // 如果解码失败,则尝试使用GBK解码 + if let Ok(gbk_str) = GBK.decode(&s, DecoderTrap::Strict) { + gbk_str + } else { + String::from_utf8_lossy(s).to_string() + } + } +} + + #[cfg(test)] mod tests { use crate::common::config::{self};