From 1995f9fa4ee88a30ab78cfb1d3da55b55259f360 Mon Sep 17 00:00:00 2001 From: chenbaiyu Date: Thu, 13 Jan 2022 16:06:51 +0800 Subject: [PATCH] Revert "temp commit" This reverts commit 88f0f67ee321429c94f3fc2419edd537382917de. --- libs/hbb_common/src/config.rs | 203 +++++++++++++--------------------- src/ipc.rs | 83 +++++--------- src/platform/macos.rs | 1 - src/server.rs | 159 +++++++++++--------------- 4 files changed, 174 insertions(+), 272 deletions(-) diff --git a/libs/hbb_common/src/config.rs b/libs/hbb_common/src/config.rs index cb52f8708..e9df2f15c 100644 --- a/libs/hbb_common/src/config.rs +++ b/libs/hbb_common/src/config.rs @@ -11,6 +11,7 @@ use std::{ sync::{Arc, Mutex, RwLock}, time::SystemTime, }; +use std::borrow::Borrow; pub const APP_NAME: &str = "RustDesk"; pub const RENDEZVOUS_TIMEOUT: u64 = 12_000; @@ -162,28 +163,28 @@ pub struct PeerInfoSerde { fn patch(path: PathBuf) -> PathBuf { if let Some(_tmp) = path.to_str() { #[cfg(windows)] - return _tmp + return _tmp .replace( "system32\\config\\systemprofile", "ServiceProfiles\\LocalService", ) .into(); #[cfg(target_os = "macos")] - return _tmp.replace("Application Support", "Preferences").into(); + return _tmp.replace("Application Support", "Preferences").into(); #[cfg(target_os = "linux")] - { - if _tmp == "/root" { - if let Ok(output) = std::process::Command::new("whoami").output() { - let user = String::from_utf8_lossy(&output.stdout) - .to_string() - .trim() - .to_owned(); - if user != "root" { - return format!("/home/{}", user).into(); + { + if _tmp == "/root" { + if let Ok(output) = std::process::Command::new("whoami").output() { + let user = String::from_utf8_lossy(&output.stdout) + .to_string() + .trim() + .to_owned(); + if user != "root" { + return format!("/home/{}", user).into(); + } } } } - } } path } @@ -275,7 +276,7 @@ impl Config { pub fn get_home() -> PathBuf { #[cfg(any(target_os = "android", target_os = "ios"))] - return Self::path(""); + return Self::path(""); if let Some(path) = dirs_next::home_dir() { patch(path) } else if let Ok(path) = std::env::current_dir() { @@ -287,15 +288,15 @@ impl Config { pub fn path>(p: P) -> PathBuf { #[cfg(any(target_os = "android", target_os = "ios"))] - { - let mut path: PathBuf = APP_DIR.read().unwrap().clone().into(); - path.push(p); - return path; - } + { + let mut path: PathBuf = APP_DIR.read().unwrap().clone().into(); + path.push(p); + return path; + } #[cfg(not(target_os = "macos"))] - let org = ""; + let org = ""; #[cfg(target_os = "macos")] - let org = ORG; + let org = ORG; // /var/root for root if let Some(project) = ProjectDirs::from("", org, APP_NAME) { let mut path = patch(project.config_dir().to_path_buf()); @@ -308,19 +309,19 @@ impl Config { #[allow(unreachable_code)] pub fn log_path() -> PathBuf { #[cfg(target_os = "macos")] - { - if let Some(path) = dirs_next::home_dir().as_mut() { - path.push(format!("Library/Logs/{}", APP_NAME)); - return path.clone(); + { + if let Some(path) = dirs_next::home_dir().as_mut() { + path.push(format!("Library/Logs/{}", APP_NAME)); + return path.clone(); + } } - } #[cfg(target_os = "linux")] - { - let mut path = Self::get_home(); - path.push(format!(".local/share/logs/{}", APP_NAME)); - std::fs::create_dir_all(&path).ok(); - return path; - } + { + let mut path = Self::get_home(); + path.push(format!(".local/share/logs/{}", APP_NAME)); + std::fs::create_dir_all(&path).ok(); + return path; + } if let Some(path) = Self::path("").parent() { let mut path: PathBuf = path.into(); path.push("log"); @@ -331,21 +332,21 @@ impl Config { pub fn ipc_path(postfix: &str) -> String { #[cfg(windows)] - { - // \\ServerName\pipe\PipeName - // where ServerName is either the name of a remote computer or a period, to specify the local computer. - // https://docs.microsoft.com/en-us/windows/win32/ipc/pipe-names - format!("\\\\.\\pipe\\{}\\query{}", APP_NAME, postfix) - } + { + // \\ServerName\pipe\PipeName + // where ServerName is either the name of a remote computer or a period, to specify the local computer. + // https://docs.microsoft.com/en-us/windows/win32/ipc/pipe-names + format!("\\\\.\\pipe\\{}\\query{}", APP_NAME, postfix) + } #[cfg(not(windows))] - { - use std::os::unix::fs::PermissionsExt; - let mut path: PathBuf = format!("/tmp/{}", APP_NAME).into(); - fs::create_dir(&path).ok(); - fs::set_permissions(&path, fs::Permissions::from_mode(0o0777)).ok(); - path.push(format!("ipc{}", postfix)); - path.to_str().unwrap_or("").to_owned() - } + { + use std::os::unix::fs::PermissionsExt; + let mut path: PathBuf = format!("/tmp/{}", APP_NAME).into(); + fs::create_dir(&path).ok(); + fs::set_permissions(&path, fs::Permissions::from_mode(0o0777)).ok(); + path.push(format!("ipc{}", postfix)); + path.to_str().unwrap_or("").to_owned() + } } pub fn icon_path() -> PathBuf { @@ -459,7 +460,7 @@ impl Config { fn get_auto_id() -> Option { #[cfg(any(target_os = "android", target_os = "ios"))] - return None; + return None; let mut id = 0u32; #[cfg(not(any(target_os = "android", target_os = "ios")))] if let Ok(Some(ma)) = mac_address::get_mac_address() { @@ -673,91 +674,43 @@ impl Config { } } - pub fn sync_config_to_user>(target_username: String, to_dir: P) -> bool { - let config1_root_file_path = Config::file_(""); - let config1_filename = config1_root_file_path.file_name(); + pub fn copy_and_reload_config_dir>( + target_username: String, + from: P, + ) -> Result { + let to = Self::path(""); + let to_parent = to.parent().unwrap(); - let config2_root_file_path = Config::file_("2"); - let config2_filename = config2_root_file_path.file_name(); + let mut options = fs_extra::dir::CopyOptions::new(); + options.overwrite = true; + options.copy_inside = true; - let config1_to_file_path = to_dir - .as_ref() - .join(PathBuf::from(&config1_filename.unwrap())); - let config2_to_file_path = to_dir - .as_ref() - .join(PathBuf::from(&config2_filename.unwrap())); + let mut f = from.as_ref(); - log::info!( - "config1_root_path:{}", - &config1_root_file_path.as_path().to_str().unwrap() - ); - log::info!( - "config2_root_path:{}", - &config2_root_file_path.as_path().to_str().unwrap() - ); - log::info!( - "config1_to_path:{}", - &config1_to_file_path.as_path().to_str().unwrap() - ); - log::info!( - "config2_to_path:{}", - &config2_to_file_path.as_path().to_str().unwrap() - ); + return match fs_extra::dir::copy(f, to_parent, &options) { + Ok(count) => { + if count > 0 { + log::info!("{}",target_username); + log::info!("{}",f.to_str().unwrap().to_string()); + log::info!("{}",to.to_str().unwrap().to_string()); - match std::fs::copy(&config1_root_file_path, &config1_to_file_path) { - Err(e) => log::error!( - "copy config {} to user failed: {}", - config1_filename.unwrap().to_str().unwrap(), - e - ), - _ => {} - } + std::process::Command::new("chown") + .arg("-R") + .arg(target_username) + .arg(to.to_str().unwrap().to_string()) + .spawn(); - match std::fs::copy(&config2_root_file_path, &config2_to_file_path) { - Err(e) => log::error!( - "copy config {} to user failed: {}", - config2_filename.unwrap().to_str().unwrap(), - e - ), - _ => {} - } - - let success = std::process::Command::new("chown") - .arg(&target_username.to_string()) - .arg(&config1_to_file_path.to_str().unwrap().to_string()) - .arg(&config2_to_file_path.to_str().unwrap().to_string()) - .spawn() - .is_ok(); - - if success { - CONFIG.write().unwrap().reload(); - CONFIG2.write().unwrap().reload(); - } - - return success; - } - - pub fn sync_config_to_root>(from_file_path: P) -> bool { - if let Some(filename) = from_file_path.as_ref().file_name() { - let to = Config::path(filename); - return match std::fs::copy(from_file_path, &to) { - Ok(count) => { - if count > 0 { - return std::process::Command::new("chown") - .arg("root") - .arg(&to.to_str().unwrap().to_string()) - .spawn() - .is_ok(); - } - false + CONFIG.write().unwrap().reload(); + CONFIG2.write().unwrap().reload(); } - Err(e) => { - log::error!("sync_config_to_root failed: {}", e); - false - } - }; - } - false + + Ok(count > 0) + } + Err(e) => { + log::error!("config copy failed: {}", e); + Err(e) + } + }; } } diff --git a/src/ipc.rs b/src/ipc.rs index 59e406430..bbfc40a31 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -1,20 +1,10 @@ -use hbb_common::log::info; -use hbb_common::{ - allow_err, bail, bytes, - bytes_codec::BytesCodec, - config::{self, Config}, - futures::StreamExt as _, - futures_util::sink::SinkExt, - log, timeout, tokio, - tokio::io::{AsyncRead, AsyncWrite}, - tokio_util::codec::Framed, - ResultType, -}; +use hbb_common::{allow_err, bail, bytes, bytes_codec::BytesCodec, config::{self, Config}, futures::StreamExt as _, futures_util::sink::SinkExt, log, timeout, tokio, tokio::io::{AsyncRead, AsyncWrite}, tokio_util::codec::Framed, ResultType}; use parity_tokio_ipc::{ Connection as Conn, ConnectionClient as ConnClient, Endpoint, Incoming, SecurityAttributes, }; use serde_derive::{Deserialize, Serialize}; use std::collections::HashMap; +use std::path::PathBuf; #[cfg(not(windows))] use std::{fs::File, io::prelude::*}; @@ -93,22 +83,17 @@ pub enum Data { Socks(Option), FS(FS), Test, - SyncConfigToRootReq { - from: String, + ConfigCopyReq { + target_username: String, + dir_path: String, }, - SyncConfigToRootResp(bool), - SyncConfigToUserReq { - username: String, - to: String, - }, - SyncConfigToUserResp(bool), + ConfigCopyResp(Option), } #[tokio::main(flavor = "current_thread")] pub async fn start(postfix: &str) -> ResultType<()> { let mut incoming = new_listener(postfix).await?; loop { - log::info!("begin loop"); if let Some(result) = incoming.next().await { match result { Ok(stream) => { @@ -116,16 +101,13 @@ pub async fn start(postfix: &str) -> ResultType<()> { let postfix = postfix.to_owned(); tokio::spawn(async move { loop { - log::info!("begin loop"); match stream.next().await { Err(err) => { log::trace!("ipc{} connection closed: {}", postfix, err); break; } Ok(Some(data)) => { - log::info!("begin handle"); handle(data, &mut stream).await; - log::info!("end handle"); } _ => {} } @@ -143,7 +125,7 @@ pub async fn start(postfix: &str) -> ResultType<()> { pub async fn new_listener(postfix: &str) -> ResultType { let path = Config::ipc_path(postfix); #[cfg(not(windows))] - check_pid(postfix).await; + check_pid(postfix).await; let mut endpoint = Endpoint::new(path.clone()); match SecurityAttributes::allow_everyone_create() { Ok(attr) => endpoint.set_security_attributes(attr), @@ -153,11 +135,11 @@ pub async fn new_listener(postfix: &str) -> ResultType { Ok(incoming) => { log::info!("Started ipc{} server at path: {}", postfix, &path); #[cfg(not(windows))] - { - use std::os::unix::fs::PermissionsExt; - std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o0777)).ok(); - write_pid(postfix); - } + { + use std::os::unix::fs::PermissionsExt; + std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o0777)).ok(); + write_pid(postfix); + } Ok(incoming) } Err(err) => { @@ -266,27 +248,22 @@ async fn handle(data: Data, stream: &mut Connection) { let t = Config::get_nat_type(); allow_err!(stream.send(&Data::NatType(Some(t))).await); } - Data::SyncConfigToRootReq { from } => { - info!("begin SyncConfigToRootReq, {}", from); - allow_err!( - stream - .send(&Data::SyncConfigToRootResp(Config::sync_config_to_root( - from - ))) - .await - ); - info!("begin SyncConfigToRootReq end"); - } - Data::SyncConfigToUserReq { username, to } => { - info!("begin SyncConfigToUserReq,{},{}", username, to); - allow_err!( - stream - .send(&Data::SyncConfigToUserResp(Config::sync_config_to_user( - username, to - ))) - .await - ); - info!("begin SyncConfigToUserReq end"); + Data::ConfigCopyReq { target_username, dir_path } => { + let from = PathBuf::from(dir_path); + if !from.exists() { + allow_err!(stream.send(&Data::ConfigCopyResp(None)).await); + return; + } + + match Config::copy_and_reload_config_dir(target_username, from) { + Ok(result) => { + allow_err!(stream.send(&Data::ConfigCopyResp(Some(result))).await); + } + Err(e) => { + log::error!("copy_and_reload_config_dir failed: {:?}",e); + allow_err!(stream.send(&Data::ConfigCopyResp(Some(false))).await); + } + } } _ => {} } @@ -348,8 +325,8 @@ pub struct ConnectionTmpl { pub type Connection = ConnectionTmpl; impl ConnectionTmpl -where - T: AsyncRead + AsyncWrite + std::marker::Unpin, + where + T: AsyncRead + AsyncWrite + std::marker::Unpin, { pub fn new(conn: T) -> Self { Self { diff --git a/src/platform/macos.rs b/src/platform/macos.rs index f278fdf9c..a79094172 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -335,7 +335,6 @@ pub fn is_installed() -> bool { } pub fn start_daemon(){ - log::info!("{}",crate::username()); if let Err(err) = crate::ipc::start("_daemon") { log::error!("Failed to start ipc_daemon: {}", err); std::process::exit(-1); diff --git a/src/server.rs b/src/server.rs index 38da11b5c..27cf0061a 100644 --- a/src/server.rs +++ b/src/server.rs @@ -14,7 +14,7 @@ use hbb_common::{ timeout, tokio, ResultType, Stream, }; use service::{GenericService, Service, ServiceTmpl, Subscriber}; -use std::path::PathBuf; +use std::sync::mpsc::RecvError; use std::time::Duration; use std::{ collections::HashMap, @@ -22,6 +22,7 @@ use std::{ sync::{Arc, Mutex, RwLock, Weak}, }; +use hbb_common::log::info; #[cfg(target_os = "macos")] use notify::{watcher, RecursiveMode, Watcher}; use parity_tokio_ipc::ConnectionClient; @@ -171,7 +172,7 @@ pub async fn create_relay_connection( secure: bool, ) { if let Err(err) = - create_relay_connection_(server, relay_server, uuid.clone(), peer_addr, secure).await + create_relay_connection_(server, relay_server, uuid.clone(), peer_addr, secure).await { log::error!( "Failed to create relay connection for {} with uuid {}: {}", @@ -194,7 +195,7 @@ async fn create_relay_connection_( Config::get_any_listen_addr(), CONNECT_TIMEOUT, ) - .await?; + .await?; let mut msg_out = RendezvousMessage::new(); msg_out.set_request_relay(RequestRelay { uuid, @@ -269,14 +270,12 @@ pub fn check_zombie() { #[tokio::main] pub async fn start_server(is_server: bool, _tray: bool) { #[cfg(target_os = "linux")] - { - log::info!("DISPLAY={:?}", std::env::var("DISPLAY")); - log::info!("XAUTHORITY={:?}", std::env::var("XAUTHORITY")); - } + { + log::info!("DISPLAY={:?}", std::env::var("DISPLAY")); + log::info!("XAUTHORITY={:?}", std::env::var("XAUTHORITY")); + } - tokio::spawn(async { sync_and_watch_config_dir().await }); - - log::info!("enter server"); + sync_and_watch_config_dir().await; if is_server { std::thread::spawn(move || { @@ -308,7 +307,7 @@ pub async fn start_server(is_server: bool, _tray: bool) { } else { allow_err!(conn.send(&Data::ConfirmedKey(None)).await); if let Ok(Some(Data::ConfirmedKey(Some(pair)))) = - conn.next_timeout(1000).await + conn.next_timeout(1000).await { Config::set_key_pair(pair); Config::set_key_confirmed(true); @@ -328,94 +327,68 @@ pub async fn start_server(is_server: bool, _tray: bool) { } } -async fn sync_and_watch_config_dir() { - if crate::username() == "root"{ - return; - } +async fn sync_and_watch_config_dir() -> ResultType<()> { + let mut conn = crate::ipc::connect(1000, "_daemon").await?; - match crate::ipc::connect(1000, "_daemon").await { - Ok(mut conn) => { - sync_config_to_user(&mut conn).await; + sync_config_dir(&mut conn, "/var/root/Library/Preferences/com.carriez.RustDesk/".to_string()).await?; - log::info!( - "watching config dir: {}", - Config::path("").to_str().unwrap().to_string() - ); + tokio::spawn(async move { + log::info!( + "watching config dir: {}", + Config::path("").to_str().unwrap().to_string() + ); - let (tx, rx) = std::sync::mpsc::channel(); - let mut watcher = watcher(tx, Duration::from_secs(2)).unwrap(); - watcher - .watch(Config::path("").as_path(), RecursiveMode::Recursive) - .unwrap(); + let (tx, rx) = std::sync::mpsc::channel(); + let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap(); + watcher + .watch(Config::path("").as_path(), RecursiveMode::Recursive) + .unwrap(); - loop { - let ev = rx.recv(); - match ev { - Ok(event) => match event { - notify::DebouncedEvent::Write(path) => { - log::info!( - "config file changed, call ipc_daemon to sync: {}", - path.to_str().unwrap().to_string() - ); - sync_config_to_root(&mut conn, path).await; - log::info!("sync end"); - } - x => { - log::info!("another {:?}", x) - } - }, - Err(e) => println!("watch error: {:?}", e), + loop { + let ev = rx.recv(); + match ev { + Ok(event) => match event { + notify::DebouncedEvent::Write(path) => { + log::info!( + "config file changed, call ipc_daemon to sync: {}", + path.to_str().unwrap().to_string() + ); + sync_config_dir(&mut conn, Config::path("").to_str().unwrap().to_string()).await; + } + x => { + log::info!("another {:?}", x) + } + }, + Err(e) => println!("watch error: {:?}", e), + } + } + }); + + Ok(()) +} + +async fn sync_config_dir(conn: &mut ConnectionTmpl, path: String) -> ResultType<()> { + allow_err!( + conn.send(&Data::ConfigCopyReq { + target_username: crate::username(), + dir_path: path + }) + .await + ); + if let Ok(Some(data)) = conn.next_timeout(1000).await { + match data { + Data::ConfigCopyResp(result) => match result { + Some(success) => { + if success { + log::info!("copy and reload config dir success"); + } else { + log::info!("copy config dir failed. may be first running"); + } } - } - } - Err(e) => { - log::info!("connect ipc_daemon failed, skip config sync"); - return; - } - } -} - -async fn sync_config_to_user(conn: &mut ConnectionTmpl) -> ResultType<()> { - allow_err!( - conn.send(&Data::SyncConfigToUserReq { - username: crate::username(), - to: Config::path("").to_str().unwrap().to_string(), - }) - .await - ); - - if let Some(data) = conn.next_timeout(2000).await? { - match data { - Data::SyncConfigToUserResp(success) => { - log::info!("copy and reload config dir success: {:?}", success); - } + None => {} + }, x => { - log::info!("receive another {:?}", x) - } - }; - }; - - Ok(()) -} - -async fn sync_config_to_root( - conn: &mut ConnectionTmpl, - from: PathBuf, -) -> ResultType<()> { - allow_err!( - conn.send(&Data::SyncConfigToRootReq { - from: from.to_str().unwrap().to_string() - }) - .await - ); - - if let Some(data) = conn.next_timeout(2000).await? { - match data { - Data::SyncConfigToRootResp(success) => { - log::info!("copy config to root dir success: {:?}", success); - } - x => { - log::info!("receive another {:?}", x) + log::info!("receive another {:?}",x) } }; };