linux.rs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. use crate::ResultType;
  2. lazy_static::lazy_static! {
  3. pub static ref DISTRO: Disto = Disto::new();
  4. }
  5. pub struct Disto {
  6. pub name: String,
  7. pub version_id: String,
  8. }
  9. impl Disto {
  10. fn new() -> Self {
  11. let name = run_cmds("awk -F'=' '/^NAME=/ {print $2}' /etc/os-release".to_owned())
  12. .unwrap_or_default()
  13. .trim()
  14. .trim_matches('"')
  15. .to_string();
  16. let version_id =
  17. run_cmds("awk -F'=' '/^VERSION_ID=/ {print $2}' /etc/os-release".to_owned())
  18. .unwrap_or_default()
  19. .trim()
  20. .trim_matches('"')
  21. .to_string();
  22. Self { name, version_id }
  23. }
  24. }
  25. pub fn get_display_server() -> String {
  26. let mut session = get_values_of_seat0([0].to_vec())[0].clone();
  27. if session.is_empty() {
  28. // loginctl has not given the expected output. try something else.
  29. if let Ok(sid) = std::env::var("XDG_SESSION_ID") {
  30. // could also execute "cat /proc/self/sessionid"
  31. session = sid;
  32. }
  33. if session.is_empty() {
  34. session = run_cmds("cat /proc/self/sessionid".to_owned()).unwrap_or_default();
  35. }
  36. }
  37. get_display_server_of_session(&session)
  38. }
  39. fn get_display_server_of_session(session: &str) -> String {
  40. let mut display_server = if let Ok(output) =
  41. run_loginctl(Some(vec!["show-session", "-p", "Type", session]))
  42. // Check session type of the session
  43. {
  44. let display_server = String::from_utf8_lossy(&output.stdout)
  45. .replace("Type=", "")
  46. .trim_end()
  47. .into();
  48. if display_server == "tty" {
  49. // If the type is tty...
  50. if let Ok(output) = run_loginctl(Some(vec!["show-session", "-p", "TTY", session]))
  51. // Get the tty number
  52. {
  53. let tty: String = String::from_utf8_lossy(&output.stdout)
  54. .replace("TTY=", "")
  55. .trim_end()
  56. .into();
  57. if let Ok(xorg_results) = run_cmds(format!("ps -e | grep \"{}.\\\\+Xorg\"", tty))
  58. // And check if Xorg is running on that tty
  59. {
  60. if xorg_results.trim_end() != "" {
  61. // If it is, manually return "x11", otherwise return tty
  62. return "x11".to_owned();
  63. }
  64. }
  65. }
  66. }
  67. display_server
  68. } else {
  69. "".to_owned()
  70. };
  71. if display_server.is_empty() {
  72. // loginctl has not given the expected output. try something else.
  73. if let Ok(sestype) = std::env::var("XDG_SESSION_TYPE") {
  74. display_server = sestype;
  75. }
  76. }
  77. // If the session is not a tty, then just return the type as usual
  78. display_server
  79. }
  80. pub fn get_values_of_seat0(indices: Vec<usize>) -> Vec<String> {
  81. if let Ok(output) = run_loginctl(None) {
  82. for line in String::from_utf8_lossy(&output.stdout).lines() {
  83. if line.contains("seat0") {
  84. if let Some(sid) = line.split_whitespace().next() {
  85. if is_active(sid) {
  86. return indices
  87. .into_iter()
  88. .map(|idx| line.split_whitespace().nth(idx).unwrap_or("").to_owned())
  89. .collect::<Vec<String>>();
  90. }
  91. }
  92. }
  93. }
  94. }
  95. // some case, there is no seat0 https://github.com/rustdesk/rustdesk/issues/73
  96. if let Ok(output) = run_loginctl(None) {
  97. for line in String::from_utf8_lossy(&output.stdout).lines() {
  98. if let Some(sid) = line.split_whitespace().next() {
  99. let d = get_display_server_of_session(sid);
  100. if is_active(sid) && d != "tty" {
  101. return indices
  102. .into_iter()
  103. .map(|idx| line.split_whitespace().nth(idx).unwrap_or("").to_owned())
  104. .collect::<Vec<String>>();
  105. }
  106. }
  107. }
  108. }
  109. return indices
  110. .iter()
  111. .map(|_x| "".to_owned())
  112. .collect::<Vec<String>>();
  113. }
  114. fn is_active(sid: &str) -> bool {
  115. if let Ok(output) = run_loginctl(Some(vec!["show-session", "-p", "State", sid])) {
  116. String::from_utf8_lossy(&output.stdout).contains("active")
  117. } else {
  118. false
  119. }
  120. }
  121. pub fn run_cmds(cmds: String) -> ResultType<String> {
  122. let output = std::process::Command::new("sh")
  123. .args(vec!["-c", &cmds])
  124. .output()?;
  125. Ok(String::from_utf8_lossy(&output.stdout).to_string())
  126. }
  127. #[cfg(not(feature = "flatpak"))]
  128. fn run_loginctl(args: Option<Vec<&str>>) -> std::io::Result<std::process::Output> {
  129. let mut cmd = std::process::Command::new("loginctl");
  130. if let Some(a) = args {
  131. return cmd.args(a).output();
  132. }
  133. cmd.output()
  134. }
  135. #[cfg(feature = "flatpak")]
  136. fn run_loginctl(args: Option<Vec<&str>>) -> std::io::Result<std::process::Output> {
  137. let mut l_args = String::from("loginctl");
  138. if let Some(a) = args {
  139. l_args = format!("{} {}", l_args, a.join(" "));
  140. }
  141. std::process::Command::new("flatpak-spawn")
  142. .args(vec![String::from("--host"), l_args])
  143. .output()
  144. }