CH-J Toolsupravljanje strežnikov prek SSH
Meni
Objavljen vir

CH-J Tools

Brskajte po imenikih in datotekah za določeno izdajo programa.

Prenos vir ZIP
CH-J / Server Manager 1704 datoteke
0.1.2-beta Dodano: · Zgrajena:
platform.rs Dodano: Datum, ki ni zabeležen 4,6 KB · 95 vrstice
Oznaka Prenesi datoteko
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.
4use crate::core::error::CoreResult;
5use crate::core::matrix;
6use crate::core::suggest::distribution;
7use crate::core::ssh::session::{SessionManager, SessionRecord};
8use crate::core::ssh::windows_exec::{encoded_command, parse_windows_output};
9use once_cell::sync::Lazy;
10use regex::Regex;
11use serde_json::{json, Value};
12use std::sync::Arc;
13use std::time::Duration;
15static POSIX_KERNELS: Lazy<Regex> = Lazy::new(|| Regex::new(r"^(Linux|Darwin|FreeBSD|OpenBSD|NetBSD|DragonFly|SunOS|AIX)\b").unwrap());
17pub 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()
30pub 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": kernel
77 })
78 }
79 };
80 *record.platform.lock() = Some(platform.clone());
81 Ok(platform)
84#[cfg(test)]
85mod 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 }
SHA-25648e3c7295bfc74f086d9551130df06181c4ddf12e170a6adbb6d91387b86f48d

CH-J Proprietary Software License 1.14 · Vir je na voljo pod CH-J Proprietary Software License 1.14. Njena razpoložljivost ne spreminja pogojev licence ali dodeljuje dodatnih pravic.

Arhiv SHA-256ac8fe790f4ba60fc098f8c985fc2656cfcc6cdc21fb34b30e308a2b54e62258f
Datoteke