From 8147cd7eaed4d557c78302d8590e1cc3812076d8 Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Wed, 28 Jun 2023 22:28:58 +0100 Subject: [PATCH] Be more faithful to uname argument parsing --- 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(-) create mode 100644 pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-a.snap create mode 100644 pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-asnrvmpio.snap create mode 100644 pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn --fake.snap create mode 100644 pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn -z.snap create mode 100644 pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn oper.snap create mode 100644 pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn.snap create mode 100644 pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-snrvmpio.snap create mode 100644 pisshoff-server/src/command/uname.rs diff --git a/Cargo.lock b/Cargo.lock index 56b66b5..b7b9ab3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/pisshoff-server/Cargo.toml b/pisshoff-server/Cargo.toml index 11445b6..700c0f4 100644 --- a/pisshoff-server/Cargo.toml +++ b/pisshoff-server/Cargo.toml @@ -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" diff --git a/pisshoff-server/src/command.rs b/pisshoff-server/src/command.rs index 1f789d8..0df5a50 100644 --- a/pisshoff-server/src/command.rs +++ b/pisshoff-server/src/command.rs @@ -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" => { - // todo: move this out to its own module - 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 . -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: -Report any translation bugs to -Full documentation -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 => { // TODO: fix stderr displaying out of order @@ -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> { + 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::>(); + assert_eq!(output, expected); + } +} diff --git a/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-a.snap b/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-a.snap new file mode 100644 index 0000000..2522ec3 --- /dev/null +++ b/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-a.snap @@ -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 + diff --git a/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-asnrvmpio.snap b/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-asnrvmpio.snap new file mode 100644 index 0000000..2522ec3 --- /dev/null +++ b/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-asnrvmpio.snap @@ -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 + diff --git a/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn --fake.snap b/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn --fake.snap new file mode 100644 index 0000000..2e0640c --- /dev/null +++ b/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn --fake.snap @@ -0,0 +1,7 @@ +--- +source: pisshoff-server/src/command/uname.rs +expression: output +--- +uname: unrecognized option '--fake' +Try 'uname --help' for more information. + diff --git a/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn -z.snap b/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn -z.snap new file mode 100644 index 0000000..09e859b --- /dev/null +++ b/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn -z.snap @@ -0,0 +1,7 @@ +--- +source: pisshoff-server/src/command/uname.rs +expression: output +--- +uname: invalid option -- 'z' +Try 'uname --help' for more information. + diff --git a/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn oper.snap b/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn oper.snap new file mode 100644 index 0000000..f18ea6d --- /dev/null +++ b/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn oper.snap @@ -0,0 +1,7 @@ +--- +source: pisshoff-server/src/command/uname.rs +expression: output +--- +uname: extra operand 'oper' +Try 'uname --help' for more information. + diff --git a/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn.snap b/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn.snap new file mode 100644 index 0000000..28f09d8 --- /dev/null +++ b/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-sn.snap @@ -0,0 +1,6 @@ +--- +source: pisshoff-server/src/command/uname.rs +expression: output +--- +Linux cd5079c0d642 + diff --git a/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-snrvmpio.snap b/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-snrvmpio.snap new file mode 100644 index 0000000..f9a4deb --- /dev/null +++ b/pisshoff-server/src/command/snapshots/pisshoff_server__command__uname__test__-snrvmpio.snap @@ -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 + diff --git a/pisshoff-server/src/command/uname.rs b/pisshoff-server/src/command/uname.rs new file mode 100644 index 0000000..3563de8 --- /dev/null +++ b/pisshoff-server/src/command/uname.rs @@ -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 . +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: +Report any translation bugs to +Full documentation +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); + } +} -- libgit2 1.7.2