123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- use std::borrow::Cow;
- /// 给clash内核的tun模式授权
- #[cfg(any(target_os = "macos", target_os = "linux"))]
- pub fn grant_permission(core: String) -> anyhow::Result<()> {
- use std::process::Command;
- use tauri::utils::platform::current_exe;
- let path = current_exe()?.with_file_name(core).canonicalize()?;
- let path = path.display().to_string();
- log::debug!("grant_permission path: {path}");
- #[cfg(target_os = "macos")]
- let output = {
- // the path of clash /Applications/Clash Verge.app/Contents/MacOS/clash
- // https://apple.stackexchange.com/questions/82967/problem-with-empty-spaces-when-executing-shell-commands-in-applescript
- let path = escape(&path);
- let shell = format!("chown root:admin {path}\nchmod +sx {path}");
- let command = format!(r#"do shell script "{shell}" with administrator privileges"#);
- Command::new("osascript")
- .args(vec!["-e", &command])
- .output()?
- };
- #[cfg(target_os = "linux")]
- let output = {
- let path = path.replace(' ', "\\ "); // 避免路径中有空格
- let shell = format!("setcap cap_net_bind_service,cap_net_admin=+ep {path}");
- Command::new("sudo")
- .arg("sh")
- .arg("-c")
- .arg(shell)
- .output()?
- };
- if output.status.success() {
- Ok(())
- } else {
- let stderr = std::str::from_utf8(&output.stderr).unwrap_or("");
- anyhow::bail!("{stderr}");
- }
- }
- pub fn escape<'a>(text: &'a str) -> Cow<'a, str> {
- let bytes = text.as_bytes();
- let mut owned = None;
- for pos in 0..bytes.len() {
- let special = match bytes[pos] {
- b' ' => Some(b' '),
- _ => None,
- };
- if let Some(s) = special {
- if owned.is_none() {
- owned = Some(bytes[0..pos].to_owned());
- }
- owned.as_mut().unwrap().push(b'\\');
- owned.as_mut().unwrap().push(b'\\');
- owned.as_mut().unwrap().push(s);
- } else if let Some(owned) = owned.as_mut() {
- owned.push(bytes[pos]);
- }
- }
- if let Some(owned) = owned {
- unsafe { Cow::Owned(String::from_utf8_unchecked(owned)) }
- } else {
- unsafe { Cow::Borrowed(std::str::from_utf8_unchecked(bytes)) }
- }
- }
|