diff options
author | RaindropsSys <raindrops@equestria.dev> | 2024-03-10 16:46:07 +0100 |
---|---|---|
committer | RaindropsSys <raindrops@equestria.dev> | 2024-03-10 16:46:07 +0100 |
commit | 871329b8712a401514c51b517be38a69819c9052 (patch) | |
tree | 9df0292c1f343fadd07caafb1c65f78c8f4512f2 | |
parent | af195a544075bba6f984add9d4e1ec1c8d0b379a (diff) | |
download | where-rs-871329b8712a401514c51b517be38a69819c9052.tar.gz where-rs-871329b8712a401514c51b517be38a69819c9052.tar.bz2 where-rs-871329b8712a401514c51b517be38a69819c9052.zip |
Add UI
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Cargo.lock | 156 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | where-rs/Cargo.toml | 2 | ||||
-rw-r--r-- | where-rs/src/main.rs | 84 | ||||
-rw-r--r-- | where-shared/Cargo.toml | 2 | ||||
-rw-r--r-- | where-shared/src/error.rs | 2 | ||||
-rw-r--r-- | where-shared/src/lib.rs | 27 | ||||
-rw-r--r-- | whered/Cargo.toml | 2 | ||||
-rw-r--r-- | whered/src/main.rs | 2 |
10 files changed, 262 insertions, 19 deletions
@@ -1,2 +1,2 @@ /target -/.direnv
\ No newline at end of file +/.direnv @@ -12,6 +12,27 @@ dependencies = [ ] [[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] name = "base-x" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -35,18 +56,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" [[package]] +name = "cc" +version = "1.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" + +[[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] +name = "chrono" +version = "0.4.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets", +] + +[[package]] name = "const_fn" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" [[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] name = "coreutils_core" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -65,12 +112,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" [[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] name = "itoa" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -95,6 +174,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + +[[package]] name = "once_cell" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -423,7 +511,7 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" name = "where-rs" version = "0.1.0" dependencies = [ - "coreutils_core", + "chrono", "where-shared", ] @@ -462,3 +550,69 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +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", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" @@ -1,3 +1,3 @@ [workspace] members = [ "where-rs", "whered", "where-shared"] -resolver = "2"
\ No newline at end of file +resolver = "2" diff --git a/where-rs/Cargo.toml b/where-rs/Cargo.toml index 06cb9e1..42604ab 100644 --- a/where-rs/Cargo.toml +++ b/where-rs/Cargo.toml @@ -11,4 +11,4 @@ path = "src/main.rs" [dependencies] where-shared = { path = "../where-shared" } -coreutils_core = "0.1.1" +chrono = "0.4.35" diff --git a/where-rs/src/main.rs b/where-rs/src/main.rs index ba846a5..9bbfce5 100644 --- a/where-rs/src/main.rs +++ b/where-rs/src/main.rs @@ -1,8 +1,10 @@ +use std::cmp::max; use std::net::UdpSocket; use std::io::ErrorKind; use std::time::Duration; use where_shared::error::{WhereError, WhereResult}; use where_shared::{MAX_PAYLOAD_LENGTH, SessionCollection, WHERED_MAGIC}; +use chrono::prelude::*; pub const TIMEOUT: Duration = Duration::from_millis(2000); pub const MAX_SEND_RETRIES: usize = 3; @@ -15,7 +17,85 @@ fn main() { } fn start_client() -> WhereResult<()> { - println!("{:?}", process_server("127.0.0.1:15")?); + let servers = ["127.0.0.1:15"]; + let mut entries = vec![]; + + for server in servers { + entries.extend(process_server(server)?.into_vec()); + } + + entries.sort_by_key(|s| s.login_time); + entries.sort_by_key(|s| !s.active); + + let max_host_length = entries.iter() + .max_by_key(|s| match &s.host { + Some(remote) => remote, + None => "" + }) + .unwrap() + .host.clone().unwrap().len(); + let max_username_length = entries.iter() + .max_by_key(|s| s.user.as_str()) + .unwrap() + .user.len(); + let max_tty_length = entries.iter() + .max_by_key(|s| s.tty.as_str()) + .unwrap() + .tty.len(); + let max_pid_length = entries.iter() + .max_by_key(|s| s.pid.to_string()) + .unwrap() + .pid.to_string().len(); + let max_remote_length = entries.iter() + .max_by_key(|s| match &s.remote { + Some(remote) => remote, + None => "Local" + }) + .unwrap() + .remote.clone().unwrap_or("Local".to_string()).len(); + + let max_host_length = max(max_host_length, 4); + let max_remote_length = max(max_remote_length, 6); + let max_username_length = max(max_username_length, 4); + let max_tty_length = max(max_tty_length, 3); + let max_pid_length = max(max_pid_length, 3); + + println!("Act Host{} Source{} User{} TTY{} PID{} Since", + " ".repeat(max_host_length - 4), + " ".repeat(max_remote_length - 6), + " ".repeat(max_username_length - 4), + " ".repeat(max_tty_length - 3), + " ".repeat(max_pid_length - 3), + ); + + for session in entries { + let active_str = if session.active { + "*" + } else { + " " + }; + let host_str = session.host.unwrap_or("".to_string()); + let remote_str = session.remote.unwrap_or("Local".to_string()); + + let datetime = DateTime::from_timestamp(session.login_time, 0).unwrap(); + let time_str = datetime.format("%Y-%m-%d %H:%M:%S"); + + println!(" {} {}{} {}{} {}{} {}{} {}{} {}", + active_str, + host_str, + " ".repeat(max(max_host_length, host_str.len()) - host_str.len()), + remote_str, + " ".repeat(max(max_remote_length, remote_str.len()) - remote_str.len()), + session.user, + " ".repeat(max(max_username_length, session.user.len()) - session.user.len()), + session.tty, + " ".repeat(max(max_tty_length, session.tty.len()) - session.tty.len()), + session.pid, + " ".repeat(max(max_pid_length, session.pid.to_string().len()) - session.pid.to_string().len()), + time_str + ); + } + Ok(()) } @@ -30,7 +110,7 @@ fn process_server(server: &str) -> WhereResult<SessionCollection> { match socket.recv_from(&mut buf) { Ok(_) => { - return Ok(SessionCollection::from_udp_payload(buf)?); + return Ok(SessionCollection::from_udp_payload(buf, "My Computer")?); }, Err(e) if e.kind() == ErrorKind::TimedOut || e.kind() == ErrorKind::WouldBlock => continue, Err(e) => return Err(WhereError::from(e)), diff --git a/where-shared/Cargo.toml b/where-shared/Cargo.toml index 1f5507b..5bfeff2 100644 --- a/where-shared/Cargo.toml +++ b/where-shared/Cargo.toml @@ -6,4 +6,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -coreutils_core = "0.1.1"
\ No newline at end of file +coreutils_core = "0.1.1" diff --git a/where-shared/src/error.rs b/where-shared/src/error.rs index e94b042..5908077 100644 --- a/where-shared/src/error.rs +++ b/where-shared/src/error.rs @@ -64,4 +64,4 @@ impl Display for WhereError { Self::TimedOut(server, max_retry, timeout) => write!(f, "Timed out waiting for data from {server} after {max_retry} attempts every {} ms", timeout.as_millis()) } } -}
\ No newline at end of file +} diff --git a/where-shared/src/lib.rs b/where-shared/src/lib.rs index d64b284..06cc5ba 100644 --- a/where-shared/src/lib.rs +++ b/where-shared/src/lib.rs @@ -14,12 +14,13 @@ pub const MAX_PAYLOAD_ENTRIES: usize = MAX_PAYLOAD_LENGTH / MAX_ENTRY_LENGTH; #[derive(Debug)] pub struct Session { - user: String, - pid: i32, - tty: String, - remote: Option<String>, - active: bool, - login_time: i64 + pub host: Option<String>, + pub user: String, + pub pid: i32, + pub tty: String, + pub remote: Option<String>, + pub active: bool, + pub login_time: i64 } #[derive(Debug)] @@ -40,6 +41,10 @@ impl SessionCollection { } } + pub fn into_vec(self) -> Vec<Session> { + self.inner + } + pub fn to_udp_payload(self) -> EncodeDecodeResult<Vec<u8>> { println!("Encoding payload with {} entries", self.inner.len()); @@ -66,7 +71,7 @@ impl SessionCollection { } } - pub fn from_udp_payload(buffer: [u8; MAX_PAYLOAD_LENGTH]) -> EncodeDecodeResult<Self> { + pub fn from_udp_payload(buffer: [u8; MAX_PAYLOAD_LENGTH], host: &str) -> EncodeDecodeResult<Self> { let mut buf = Cursor::new(buffer); let mut inner = vec![]; let mut magic = [0u8; 4]; @@ -81,7 +86,7 @@ impl SessionCollection { } for _ in 0..entry_count { - inner.push(Session::from_udp_payload(&mut buf)?); + inner.push(Session::from_udp_payload(&mut buf, &host)?); } if inner.len() != entry_count as usize { @@ -95,7 +100,7 @@ impl SessionCollection { } impl Session { - pub fn from_udp_payload(cursor: &mut Cursor<[u8; MAX_PAYLOAD_LENGTH]>) -> EncodeDecodeResult<Self> { + pub fn from_udp_payload(cursor: &mut Cursor<[u8; MAX_PAYLOAD_LENGTH]>, host: &str) -> EncodeDecodeResult<Self> { let mut username_length = [0u8; 4]; let mut pid = [0u8; 4]; let mut tty_length = [0u8; 4]; @@ -162,7 +167,10 @@ impl Session { let active = active[0] == 1; let login_time = i64::from_be_bytes(login_time); + let host = Some(host.to_string()); + Ok(Self { + host, user, pid, tty, @@ -247,6 +255,7 @@ impl From<Utmpx> for Session { let login_time = utmpx.timeval().tv_sec; Self { + host: None, user, pid, tty, diff --git a/whered/Cargo.toml b/whered/Cargo.toml index 5e9d438..0bce8bf 100644 --- a/whered/Cargo.toml +++ b/whered/Cargo.toml @@ -6,4 +6,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -where-shared = { path = "../where-shared" }
\ No newline at end of file +where-shared = { path = "../where-shared" } diff --git a/whered/src/main.rs b/whered/src/main.rs index 6990dd6..47e97de 100644 --- a/whered/src/main.rs +++ b/whered/src/main.rs @@ -33,4 +33,4 @@ fn handle_request(socket: &UdpSocket) -> WhereResult<()> { println!("{src}: Completed request within {} bytes", buf.len()); Ok(()) -}
\ No newline at end of file +} |