Be more faithful to uname argument parsing
Diff
Cargo.lock | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
pisshoff-server/Cargo.toml | 5 ++-
pisshoff-server/src/command.rs | 90 +++++++++++++------------------
pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-a.snap | 6 ++-
pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-asnrvmpio.snap | 6 ++-
pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn --fake.snap | 7 ++-
pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn -z.snap | 7 ++-
pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn oper.snap | 7 ++-
pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn.snap | 6 ++-
pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-snrvmpio.snap | 6 ++-
pisshoff-server/src/command/uname.rs | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
11 files changed, 452 insertions(+), 74 deletions(-)
@@ -66,7 +66,7 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
dependencies = [
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@@ -76,7 +76,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188"
dependencies = [
"anstyle",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@@ -138,6 +138,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42"
[[package]]
name = "block-buffer"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -243,7 +249,7 @@ checksum = "9a78fbdd3cc2914ddf37ba444114bc7765bbdcb55ec9cbe6fa054f0137400717"
dependencies = [
"anstream",
"anstyle",
"bitflags",
"bitflags 1.3.2",
"clap_lex",
"once_cell",
"strsim",
@@ -274,6 +280,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "console"
version = "0.15.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
"windows-sys 0.45.0",
]
[[package]]
name = "cpufeatures"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -419,6 +437,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "equivalent"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -432,7 +456,7 @@ checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
dependencies = [
"errno-dragonfly",
"libc",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@@ -665,6 +689,19 @@ dependencies = [
]
[[package]]
name = "insta"
version = "1.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28491f7753051e5704d4d0ae7860d45fae3238d7d235bc4289dcd45c48d3cec3"
dependencies = [
"console",
"lazy_static",
"linked-hash-map",
"similar",
"yaml-rust",
]
[[package]]
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -681,7 +718,7 @@ checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
dependencies = [
"hermit-abi 0.3.1",
"libc",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@@ -693,7 +730,7 @@ dependencies = [
"hermit-abi 0.3.1",
"io-lifetimes",
"rustix",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@@ -736,6 +773,12 @@ dependencies = [
]
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "linux-raw-sys"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -813,7 +856,7 @@ checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
dependencies = [
"libc",
"wasi",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@@ -822,7 +865,7 @@ version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"cfg-if",
"libc",
"memoffset",
@@ -918,7 +961,7 @@ dependencies = [
"libc",
"redox_syscall 0.3.5",
"smallvec",
"windows-targets",
"windows-targets 0.48.0",
]
[[package]]
@@ -995,9 +1038,11 @@ name = "pisshoff-server"
version = "0.1.0"
dependencies = [
"anyhow",
"bitflags 2.3.3",
"clap",
"fastrand",
"futures",
"insta",
"itertools",
"nix",
"parking_lot",
@@ -1005,6 +1050,7 @@ dependencies = [
"serde",
"serde_json",
"shlex",
"test-case",
"thrussh",
"thrussh-keys",
"tokio",
@@ -1090,6 +1136,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn 1.0.109",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1143,7 +1213,7 @@ version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags",
"bitflags 1.3.2",
]
[[package]]
@@ -1152,7 +1222,7 @@ version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
dependencies = [
"bitflags",
"bitflags 1.3.2",
]
[[package]]
@@ -1255,12 +1325,12 @@ version = "0.37.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@@ -1379,6 +1449,12 @@ dependencies = [
]
[[package]]
name = "similar"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf"
[[package]]
name = "siphasher"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1416,7 +1492,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877"
dependencies = [
"libc",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@@ -1492,6 +1568,41 @@ dependencies = [
]
[[package]]
name = "test-case"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a1d6e7bde536b0412f20765b76e921028059adfd1b90d8974d33fd3c91b25df"
dependencies = [
"test-case-macros",
]
[[package]]
name = "test-case-core"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d10394d5d1e27794f772b6fc854c7e91a2dc26e2cbf807ad523370c2a59c0cee"
dependencies = [
"cfg-if",
"proc-macro-error",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "test-case-macros"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eeb9a44b1c6a54c1ba58b152797739dba2a83ca74e18168a68c980eb142f9404"
dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn 1.0.109",
"test-case-core",
]
[[package]]
name = "thiserror"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1526,7 +1637,7 @@ name = "thrussh"
version = "0.34.0"
source = "git+https://github.com/JordanForks/thrussh#5b7232db70817c3519d191d1c4440da933f28563"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"byteorder",
"cryptovec",
"digest 0.9.0",
@@ -1644,7 +1755,7 @@ dependencies = [
"signal-hook-registry",
"socket2 0.4.9",
"tokio-macros",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@@ -1924,11 +2035,35 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
"windows-targets 0.42.2",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets",
"windows-targets 0.48.0",
]
[[package]]
name = "windows-targets"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
dependencies = [
"windows_aarch64_gnullvm 0.42.2",
"windows_aarch64_msvc 0.42.2",
"windows_i686_gnu 0.42.2",
"windows_i686_msvc 0.42.2",
"windows_x86_64_gnu 0.42.2",
"windows_x86_64_gnullvm 0.42.2",
"windows_x86_64_msvc 0.42.2",
]
[[package]]
@@ -1937,53 +2072,95 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
"windows_aarch64_gnullvm 0.48.0",
"windows_aarch64_msvc 0.48.0",
"windows_i686_gnu 0.48.0",
"windows_i686_msvc 0.48.0",
"windows_x86_64_gnu 0.48.0",
"windows_x86_64_gnullvm 0.48.0",
"windows_x86_64_msvc 0.48.0",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_gnu"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_i686_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
@@ -1998,6 +2175,15 @@ dependencies = [
]
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]
[[package]]
name = "yasna"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -9,6 +9,7 @@ edition = "2021"
pisshoff-types = { path = "../pisshoff-types" }
anyhow = "1.0"
bitflags = "2.3"
clap = { version = "4.3", features = ["derive", "env", "cargo"] }
futures = "0.3"
parking_lot = "0.12"
@@ -25,3 +26,7 @@ toml = "0.7"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
uuid = { version = "1.3", features = ["v4", "serde"] }
[dev-dependencies]
insta = "1.29"
test-case = "3.1"
@@ -1,5 +1,7 @@
use itertools::Itertools;
use std::{borrow::Cow, f32, str::FromStr, time::Duration};
pub mod uname;
use itertools::{Either, Itertools};
use std::{f32, str::FromStr, time::Duration};
use thrussh::{server::Session, ChannelId};
pub async fn run_command(args: &[String], channel: ChannelId, session: &mut Session) {
@@ -41,54 +43,8 @@ pub async fn run_command(args: &[String], channel: ChannelId, session: &mut Sess
}
}
"uname" => {
let out: Cow<'static, str> = match args.get(1).map(String::as_str) {
None | Some("-s" | "--kernel-name") => "Linux\n".into(),
Some("-a" | "--all") => "Linux cd5079c0d642 5.15.49 #1 SMP PREEMPT Tue Sep 13 07:51:32 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux\n".into(),
Some("-n" | "--nodename") => "cd5079c0d642\n".into(),
Some("-r" | "--kernel-release") => "5.15.49\n".into(),
Some("-v" | "--kernel-version") => "#1 SMP PREEMPT Tue Sep 13 07:51:32 UTC 2022\n".into(),
Some("-m" | "--machine" | "-p" | "--processor" | "-i" | "--hardware-platform") => "x86_64\n".into(),
Some("-o" | "--operating-system") => "GNU/Linux\n".into(),
Some("--version") => "uname (GNU coreutils) 8.32
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https:This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by David MacKenzie.\n".into(),
Some("--help") => "Usage: uname [OPTION]...
Print certain system information. With no OPTION, same as -s.
-a, --all print all information, in the following order,
except omit -p and -i if unknown:
-s, --kernel-name print the kernel name
-n, --nodename print the network node hostname
-r, --kernel-release print the kernel release
-v, --kernel-version print the kernel version
-m, --machine print the machine hardware name
-p, --processor print the processor type (non-portable)
-i, --hardware-platform print the hardware platform (non-portable)
-o, --operating-system print the operating system
--help display this help and exit
--version output version information and exit
GNU coreutils online help: <https:Report any translation bugs to <https:Full documentation <https:or available locally via: info '(coreutils) uname invocation'\n".into(),
Some("-") => "uname: extra operand '-'\nTry 'uname --help' for more information.\n".into(),
Some(v) => format!(
"uname: invalid option -- '{}'\nTry 'uname --help' for more information.\n",
if v.starts_with('-') && !v.starts_with("--") {
&v[1..]
} else {
v
}
).into(),
};
session.data(channel, out.into_owned().into());
let out = uname::execute(&args[1..]);
session.data(channel, out.into());
}
other => {
@@ -99,3 +55,37 @@ or available locally via: info '(coreutils) uname invocation'\n".into(),
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Arg<'a> {
Operand(&'a str),
Long(&'a str),
Short(char),
}
fn argparse(args: &[String]) -> impl Iterator<Item = Arg<'_>> {
args.iter().flat_map(|rest| {
if let Some(rest) = rest.strip_prefix("--") {
Either::Left(std::iter::once(Arg::Long(rest)))
} else if let Some(rest) = rest.strip_prefix('-').filter(|v| !v.is_empty()) {
Either::Right(rest.chars().map(Arg::Short))
} else {
Either::Left(std::iter::once(Arg::Operand(rest)))
}
})
}
#[cfg(test)]
mod test {
use super::Arg;
use test_case::test_case;
#[test_case("-a", &[Arg::Short('a')]; "single short parameter")]
#[test_case("-abc", &[Arg::Short('a'), Arg::Short('b'), Arg::Short('c')]; "multiple short parameter")]
#[test_case("-a --long operand -b -", &[Arg::Short('a'), Arg::Long("long"), Arg::Operand("operand"), Arg::Short('b'), Arg::Operand("-")]; "full hit")]
fn argparse(input: &str, expected: &[Arg<'static>]) {
let input = shlex::split(input).unwrap();
let output = super::argparse(&input).collect::<Vec<_>>();
assert_eq!(output, expected);
}
}
@@ -0,0 +1,6 @@
---
source: pisshoff-server/src/command/uname.rs
expression: output
---
Linux cd5079c0d642 5.15.49 #1 SMP PREEMPT Tue Sep 13 07:51:32 UTC 2022 x86_64 GNU/Linux
@@ -0,0 +1,6 @@
---
source: pisshoff-server/src/command/uname.rs
expression: output
---
Linux cd5079c0d642 5.15.49 #1 SMP PREEMPT Tue Sep 13 07:51:32 UTC 2022 x86_64 GNU/Linux
@@ -0,0 +1,7 @@
---
source: pisshoff-server/src/command/uname.rs
expression: output
---
uname: unrecognized option '--fake'
Try 'uname --help' for more information.
@@ -0,0 +1,7 @@
---
source: pisshoff-server/src/command/uname.rs
expression: output
---
uname: invalid option -- 'z'
Try 'uname --help' for more information.
@@ -0,0 +1,7 @@
---
source: pisshoff-server/src/command/uname.rs
expression: output
---
uname: extra operand 'oper'
Try 'uname --help' for more information.
@@ -0,0 +1,6 @@
---
source: pisshoff-server/src/command/uname.rs
expression: output
---
Linux cd5079c0d642
@@ -0,0 +1,6 @@
---
source: pisshoff-server/src/command/uname.rs
expression: output
---
Linux cd5079c0d642 5.15.49 #1 SMP PREEMPT Tue Sep 13 07:51:32 UTC 2022 x86_64 unknown unknown GNU/Linux
@@ -0,0 +1,152 @@
use crate::command::Arg;
use bitflags::bitflags;
bitflags! {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
struct ToPrint: u8 {
const KERNEL_NAME = 0b0000_0001;
const NODE_NAME = 0b0000_0010;
const KERNEL_RELEASE = 0b0000_0100;
const KERNEL_VERSION = 0b0000_1000;
const MACHINE = 0b0001_0000;
const PROCESSOR = 0b0010_0000;
const PLATFORM = 0b0100_0000;
const OPERATING_SYSTEM = 0b1000_0000;
}
}
const VERSION_STRING: &str = "uname (GNU coreutils) 8.32
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https:This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by David MacKenzie.
";
pub const HELP_STRING: &str = "Usage: uname [OPTION]...
Print certain system information. With no OPTION, same as -s.
-a, --all print all information, in the following order,
except omit -p and -i if unknown:
-s, --kernel-name print the kernel name
-n, --nodename print the network node hostname
-r, --kernel-release print the kernel release
-v, --kernel-version print the kernel version
-m, --machine print the machine hardware name
-p, --processor print the processor type (non-portable)
-i, --hardware-platform print the hardware platform (non-portable)
-o, --operating-system print the operating system
--help display this help and exit
--version output version information and exit
GNU coreutils online help: <https:Report any translation bugs to <https:Full documentation <https:or available locally via: info '(coreutils) uname invocation'
";
pub fn execute(params: &[String]) -> String {
let mut to_print = ToPrint::empty();
let mut filter_unknown = false;
for param in super::argparse(params) {
to_print |= match param {
Arg::Short('a') | Arg::Long("all") => {
filter_unknown = true;
ToPrint::all()
}
Arg::Short('s') | Arg::Long("kernel-name") => ToPrint::KERNEL_NAME,
Arg::Short('n') | Arg::Long("nodename") => ToPrint::NODE_NAME,
Arg::Short('r') | Arg::Long("kernel-release") => ToPrint::KERNEL_RELEASE,
Arg::Short('v') | Arg::Long("kernel-version") => ToPrint::KERNEL_VERSION,
Arg::Short('m') | Arg::Long("machine") => ToPrint::MACHINE,
Arg::Short('p') | Arg::Long("processor") => ToPrint::PROCESSOR,
Arg::Short('i') | Arg::Long("hardware-platform") => ToPrint::PLATFORM,
Arg::Short('o') | Arg::Long("operating-system") => ToPrint::OPERATING_SYSTEM,
Arg::Long("help") => return HELP_STRING.to_string(),
Arg::Long("version") => return VERSION_STRING.to_string(),
Arg::Operand(operand) => {
return format!(
"uname: extra operand '{operand}'\nTry 'uname --help' for more information.\n"
);
}
Arg::Short(s) => {
return format!(
"uname: invalid option -- '{s}'\nTry 'uname --help' for more information.\n"
);
}
Arg::Long(s) => return format!(
"uname: unrecognized option '--{s}'\nTry 'uname --help' for more information.\n"
),
};
}
let mut out = String::with_capacity(105);
macro_rules! write {
($v:expr) => {
if !out.is_empty() {
out.push(' ');
}
out.push_str($v);
};
}
if to_print.contains(ToPrint::KERNEL_NAME) {
write!("Linux");
}
if to_print.contains(ToPrint::NODE_NAME) {
write!("cd5079c0d642");
}
if to_print.contains(ToPrint::KERNEL_RELEASE) {
write!("5.15.49");
}
if to_print.contains(ToPrint::KERNEL_VERSION) {
write!("#1 SMP PREEMPT Tue Sep 13 07:51:32 UTC 2022");
}
if to_print.contains(ToPrint::MACHINE) {
write!("x86_64");
}
if to_print.contains(ToPrint::PROCESSOR) && !filter_unknown {
write!("unknown");
}
if to_print.contains(ToPrint::PLATFORM) && !filter_unknown {
write!("unknown");
}
if to_print.contains(ToPrint::OPERATING_SYSTEM) {
write!("GNU/Linux");
}
out.push('\n');
out
}
#[cfg(test)]
mod test {
use crate::command::uname::execute;
use test_case::test_case;
#[test_case("-a"; "all")]
#[test_case("-snrvmpio"; "all separate")]
#[test_case("-asnrvmpio"; "all separate with all")]
#[test_case("-sn"; "subset")]
#[test_case("-sn --fake"; "unknown long arg param")]
#[test_case("-sn -z"; "unknown short arg param")]
#[test_case("-sn oper"; "unknown operand")]
fn snapshot(input: &str) {
let input_parsed = shlex::split(input).unwrap();
let output = execute(&input_parsed);
insta::assert_display_snapshot!(input, output);
}
}