Foinse foilsithe
Íosluchtaigh foinse ZIP
CH-J Tools
Brabhsáil comhadlanna agus comhaid chun feidhmchlár áirithe a scaoileadh.
CH-J / Server Manager
1704 Comhaid
0.1.2-beta
Suimigh: · Tógtha:
1
//! Remote OS detection from system facts (port of `sessions/platformDetect.js`):2
//! `uname -s` for POSIX, otherwise an encoded PowerShell probe; never prompts or host names.4
use crate::core::error::CoreResult;5
use crate::core::matrix;6
use crate::core::suggest::distribution;7
use crate::core::ssh::session::{SessionManager, SessionRecord};8
use crate::core::ssh::windows_exec::{encoded_command, parse_windows_output};9
use once_cell::sync::Lazy;10
use regex::Regex;11
use serde_json::{json, Value};12
use std::sync::Arc;13
use std::time::Duration;15
static POSIX_KERNELS: Lazy<Regex> = Lazy::new(|| Regex::new(r"^(Linux|Darwin|FreeBSD|OpenBSD|NetBSD|DragonFly|SunOS|AIX)\b").unwrap());17
pub fn shell_name(default_shell: &str) -> String {18
let value = default_shell.to_lowercase();19
if value.is_empty() {20
return "cmd.exe".into();21
}22
for (pattern, name) in [(r"pwsh(\.exe)?$", "pwsh"), (r"powershell(\.exe)?$", "powershell"), (r"cmd(\.exe)?$", "cmd.exe"), (r"bash(\.exe)?$", "bash")] {23
if Regex::new(pattern).unwrap().is_match(&value) {24
return name.into();25
}26
}27
value.rsplit(['\\', '/']).next().unwrap_or("").to_string()28
}30
pub async fn detect_platform(manager: &SessionManager, record: &Arc<SessionRecord>, refresh: bool) -> CoreResult<Value> {31
if !refresh {32
if let Some(platform) = record.platform.lock().clone() {33
return Ok(platform);34
}35
}36
let probe = match manager.exec_channel(record, matrix::binding("ssh.platform.detect", "debian")?.script, Duration::from_secs(15), 512 * 1024).await {37
Ok(mut channel) => {38
channel.eof().await;39
channel.finish().await.ok()40
}41
Err(error) if error.code == "SESSION_NOT_CONNECTED" => return Err(error),42
Err(_) => None,43
};44
let stdout = probe.as_ref().map(|r| r.stdout.as_str()).unwrap_or("");45
let kernel = stdout.trim().lines().next().unwrap_or("").to_string();46
if probe.as_ref().map(|r| r.code == Some(0)).unwrap_or(false) && POSIX_KERNELS.is_match(&kernel) {47
let (release, openwrt) = stdout.split_once("@@RELEASE").map_or("", |(_, rest)| rest).split_once("@@OPENWRT").unwrap_or(("", ""));48
let system = distribution(release, openwrt);49
let platform = json!({ "os": if kernel.starts_with("Linux") { "linux" } else { "posix" }, "kernel": kernel, "detectedBy": "uname", "matrixOs": system.os, "distributionName": system.name, "distributionVersion": system.version });50
*record.platform.lock() = Some(platform.clone());51
return Ok(platform);52
}53
let mut channel = manager.exec_channel(record, &encoded_command(matrix::binding("ssh.platform.detect", "windows")?.script), Duration::from_secs(60), 512 * 1024).await?;54
channel.eof().await;55
let probe = channel.finish().await?;56
let platform = match parse_windows_output(&probe.stdout, &probe.stderr, probe.code, "PLATFORM_") {57
Err(error) => json!({ "os": "unknown", "kernel": kernel, "detectedBy": "none", "reason": error.message }),58
Ok(info) => {59
let text = |k: &str| info.get(k).map(|v| v.as_str().map(str::to_string).unwrap_or_else(|| if v.is_null() { String::new() } else { v.to_string() })).unwrap_or_default();60
json!({61
"os": "windows",62
"detectedBy": "Win32_OperatingSystem",63
"caption": text("caption"),64
"version": text("version"),65
"build": text("build"),66
"server": info.get("productType").and_then(Value::as_f64) != Some(1.0),67
"serverCore": Regex::new(r"(?i)server core").unwrap().is_match(&text("installationType")),68
"installationType": text("installationType"),69
"defaultShell": shell_name(&text("defaultShell")),70
"defaultShellPath": text("defaultShell"),71
"powershell": text("psVersion"),72
"is64BitProcess": info.get("is64BitProcess") == Some(&Value::Bool(true)),73
"languageMode": text("languageMode"),74
"localAccounts": info.get("localAccounts") == Some(&Value::Bool(true)),75
"pwsh": text("pwsh"),76
"unameOutput": kernel77
})78
}79
};80
*record.platform.lock() = Some(platform.clone());81
Ok(platform)82
}84
#[cfg(test)]85
mod tests {86
use super::*;88
#[test]89
fn shells() {90
assert_eq!(shell_name(""), "cmd.exe");91
assert_eq!(shell_name("C:\\Program Files\\PowerShell\\7\\pwsh.exe"), "pwsh");92
assert_eq!(shell_name("C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"), "powershell");93
assert_eq!(shell_name("C:\\tools\\fish.exe"), "fish.exe");94
}95
}SHA-256
48e3c7295bfc74f086d9551130df06181c4ddf12e170a6adbb6d91387b86f48dCH-J Proprietary Software License 1.14 · Tá Foinse ar fáil faoin CH-J Proprietary Software License 1.14. Ní chuireann a infhaighteacht a athrú ar na téarmaí ceadúnais nó cearta breise a dheonú.
Cartlann SHA-256
ac8fe790f4ba60fc098f8c985fc2656cfcc6cdc21fb34b30e308a2b54e62258f