server/rwhod: varlink shenanigans
This commit is contained in:
305
Cargo.lock
generated
305
Cargo.lock
generated
@@ -76,6 +76,48 @@ version = "1.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
|
||||
|
||||
[[package]]
|
||||
name = "async-broadcast"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532"
|
||||
dependencies = [
|
||||
"event-listener",
|
||||
"event-listener-strategy",
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-channel"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2"
|
||||
dependencies = [
|
||||
"concurrent-queue",
|
||||
"event-listener-strategy",
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-io"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
"futures-io",
|
||||
"futures-lite",
|
||||
"parking",
|
||||
"polling",
|
||||
"rustix",
|
||||
"slab",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.5.0"
|
||||
@@ -183,12 +225,27 @@ version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||
|
||||
[[package]]
|
||||
name = "concurrent-queue"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.5.5"
|
||||
@@ -231,6 +288,33 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "event-listener"
|
||||
version = "5.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab"
|
||||
dependencies = [
|
||||
"concurrent-queue",
|
||||
"parking",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "event-listener-strategy"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
|
||||
dependencies = [
|
||||
"event-listener",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.6"
|
||||
@@ -282,6 +366,68 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
|
||||
|
||||
[[package]]
|
||||
name = "futures-lite"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"parking",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-macro",
|
||||
"futures-task",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.3"
|
||||
@@ -294,6 +440,12 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.64"
|
||||
@@ -526,6 +678,12 @@ dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.13.1"
|
||||
@@ -551,6 +709,26 @@ version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "polling"
|
||||
version = "3.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
"hermit-abi",
|
||||
"pin-project-lite",
|
||||
"rustix",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.13.0"
|
||||
@@ -615,11 +793,14 @@ dependencies = [
|
||||
"bytes",
|
||||
"chrono",
|
||||
"clap",
|
||||
"futures-util",
|
||||
"nix",
|
||||
"serde",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"uucore",
|
||||
"zlink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -647,6 +828,12 @@ version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984"
|
||||
|
||||
[[package]]
|
||||
name = "self_cell"
|
||||
version = "1.2.2"
|
||||
@@ -683,6 +870,19 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.148"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.7"
|
||||
@@ -714,6 +914,12 @@ version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.15.1"
|
||||
@@ -836,12 +1042,14 @@ version = "1.49.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"tracing",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
@@ -856,6 +1064,31 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-stream"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.44"
|
||||
@@ -1218,3 +1451,75 @@ dependencies = [
|
||||
"serde",
|
||||
"zerofrom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zlink"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04baab6c44f6c5f33dd26dffabe2c6473d9a93a080c3424865df068d4e76f58a"
|
||||
dependencies = [
|
||||
"zlink-smol",
|
||||
"zlink-tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zlink-core"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "487e09febc08bcbac32cee2c26e85779351f711146db0176a3f61a3fea1c955f"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"itoa",
|
||||
"libc",
|
||||
"pin-project-lite",
|
||||
"rustix",
|
||||
"ryu",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tracing",
|
||||
"zlink-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zlink-macros"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6a10a1ed09222634dde2db7055226eafae571389ce57dae3707bd2a76f6dc7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zlink-smol"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72ec157812fcde1a3f45fea27db5a6fa1868ecbf5e11644166ab4caf5e3546dd"
|
||||
dependencies = [
|
||||
"async-broadcast",
|
||||
"async-channel",
|
||||
"async-io",
|
||||
"futures-lite",
|
||||
"futures-util",
|
||||
"pin-project-lite",
|
||||
"zlink-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zlink-tokio"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ab6f490a817bcbbc67d82b22427f1fafd9764da04a6b9499cf73e7ef68f4482"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"zlink-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30e0d8dffbae3d840f64bda38e28391faef673a7b5a6017840f2a106c8145868"
|
||||
|
||||
@@ -18,15 +18,17 @@ anyhow = "1.0.100"
|
||||
bytes = "1.11.0"
|
||||
chrono = { version = "0.4.42", features = ["serde"] }
|
||||
clap = { version = "4.5.53", features = ["derive"] }
|
||||
futures-util = "0.3.31"
|
||||
nix = { version = "0.30.1", features = ["hostname", "net"] }
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
tokio = { version = "1.49.0", features = ["macros", "net", "rt-multi-thread", "signal", "sync", "time"] }
|
||||
tracing = "0.1.44"
|
||||
tracing-subscriber = { version = "0.3.22", features = ["env-filter"] }
|
||||
# onc-rpc = "0.3.2"
|
||||
# sd-notify = "0.4.5"
|
||||
# serde = { version = "1.0.228", features = ["derive"] }
|
||||
# serde_json = "1.0.148"
|
||||
uucore = { version = "0.5.0", features = ["utmpx"] }
|
||||
zlink = { version = "0.2.0", features = ["introspection"] }
|
||||
|
||||
[lib]
|
||||
name = "roowho2_lib"
|
||||
|
||||
@@ -4,8 +4,10 @@ use std::{
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use anyhow::Context;
|
||||
use roowho2_lib::server::rwhod::{
|
||||
RWHOD_BROADCAST_PORT, rwhod_packet_receiver_task, rwhod_packet_sender_task,
|
||||
RWHOD_BROADCAST_PORT, rwhod_client_server_task, rwhod_packet_receiver_task,
|
||||
rwhod_packet_sender_task,
|
||||
};
|
||||
use tokio::sync::RwLock;
|
||||
use tracing_subscriber::{EnvFilter, fmt, layer::SubscriberExt, util::SubscriberInitExt};
|
||||
@@ -18,15 +20,26 @@ async fn main() -> anyhow::Result<()> {
|
||||
.init();
|
||||
|
||||
let addr = SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, RWHOD_BROADCAST_PORT);
|
||||
tracing::info!("Binding RWHOD socket to {}", addr);
|
||||
let socket = Arc::new(tokio::net::UdpSocket::bind(addr).await?);
|
||||
socket.set_broadcast(true)?;
|
||||
tracing::debug!("Binding RWHOD socket to {}", addr);
|
||||
let socket = tokio::net::UdpSocket::bind(addr)
|
||||
.await
|
||||
.context("Failed to bind RWHOD UDP socket")
|
||||
.and_then(|socket| {
|
||||
socket.set_broadcast(true)?;
|
||||
Ok(socket)
|
||||
})
|
||||
.context("Failed to enable broadcast on RWHOD UDP socket")
|
||||
.map(Arc::new)?;
|
||||
|
||||
let interfaces = roowho2_lib::server::rwhod::determine_relevant_interfaces()?;
|
||||
let sender_task = rwhod_packet_sender_task(socket.clone(), interfaces);
|
||||
|
||||
let status_store = Arc::new(RwLock::new(HashMap::new()));
|
||||
let receiver_task = rwhod_packet_receiver_task(socket.clone(), status_store);
|
||||
let receiver_task = rwhod_packet_receiver_task(socket.clone(), status_store.clone());
|
||||
|
||||
tracing::debug!("Binding RWHOD client-server socket at /run/roowho2/rwhod.socket");
|
||||
let client_server_socket = zlink::unix::bind("/run/roowho2/rwhod.varlink")?;
|
||||
let client_server_task = rwhod_client_server_task(client_server_socket, status_store.clone());
|
||||
|
||||
tokio::select! {
|
||||
res = sender_task => {
|
||||
@@ -39,6 +52,11 @@ async fn main() -> anyhow::Result<()> {
|
||||
eprintln!("RWHOD receiver task error: {}", err);
|
||||
}
|
||||
}
|
||||
res = client_server_task => {
|
||||
if let Err(err) = res {
|
||||
eprintln!("RWHOD client-server task error: {}", err);
|
||||
}
|
||||
}
|
||||
_ = tokio::signal::ctrl_c() => {
|
||||
println!("Received Ctrl-C, shutting down.");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use clap::Parser;
|
||||
use roowho2_lib::server::rwhod::RwhodClientProxy;
|
||||
|
||||
/// Check who is logged in on local machines.
|
||||
///
|
||||
@@ -20,7 +21,18 @@ pub struct Args {
|
||||
json: bool,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _args = Args::parse();
|
||||
unimplemented!()
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let args = Args::parse();
|
||||
|
||||
let mut conn = zlink::unix::connect("/run/roowho2/rwhod.varlink")
|
||||
.await
|
||||
.expect("Failed to connect to rwhod server");
|
||||
|
||||
let reply = conn
|
||||
.rwho(args.all)
|
||||
.await
|
||||
.expect("Failed to send rwho request");
|
||||
|
||||
println!("{:?}", reply);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::array;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use bytes::{Buf, BufMut, BytesMut};
|
||||
use chrono::{DateTime, Duration, Utc};
|
||||
|
||||
@@ -239,7 +240,7 @@ pub type LoadAverage = (i32, i32, i32);
|
||||
///
|
||||
/// This struct is intended for easier use in Rust code, with proper types and dynamic arrays.
|
||||
/// It can be converted to and from the low-level [`Whod`] struct used for network transmission.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct WhodStatusUpdate {
|
||||
// NOTE: there is only one defined packet type, so we just omit it here
|
||||
/// Timestamp by sender
|
||||
@@ -285,7 +286,7 @@ impl WhodStatusUpdate {
|
||||
///
|
||||
/// This struct is intended for easier use in Rust code, with proper types.
|
||||
/// It can be converted to and from the low-level [`Whoent`] struct used for network transmission.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct WhodUserEntry {
|
||||
/// TTY name (max 8 characters)
|
||||
pub tty: String,
|
||||
|
||||
@@ -8,7 +8,9 @@ use std::{
|
||||
use anyhow::Context;
|
||||
use chrono::{DateTime, Duration, Timelike, Utc};
|
||||
use nix::{ifaddrs::getifaddrs, net::if_::InterfaceFlags, sys::stat::stat};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uucore::utmpx::Utmpx;
|
||||
use zlink::{ReplyError, service::MethodReply};
|
||||
|
||||
use crate::proto::{Whod, WhodStatusUpdate, WhodUserEntry};
|
||||
|
||||
@@ -229,4 +231,100 @@ pub async fn rwhod_packet_sender_task(
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement protocol for cli - daemon communication
|
||||
#[zlink::proxy("no.ntnu.pvv.roowho2.rwhod")]
|
||||
pub trait RwhodClientProxy {
|
||||
async fn rwho(
|
||||
&mut self,
|
||||
all: bool,
|
||||
) -> zlink::Result<Result<Vec<WhodUserEntry>, RwhodClientError>>;
|
||||
|
||||
async fn ruptime(&mut self) -> zlink::Result<Result<Vec<WhodStatusUpdate>, RwhodClientError>>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(tag = "method", content = "parameters")]
|
||||
pub enum RwhodClientRequest {
|
||||
#[serde(rename = "no.ntnu.pvv.roowho2.rwhod.Rwho")]
|
||||
Rwho {
|
||||
/// Retrieve all users, even those that have been idle for a long time.
|
||||
all: bool,
|
||||
},
|
||||
|
||||
#[serde(rename = "no.ntnu.pvv.roowho2.rwhod.Ruptime")]
|
||||
Ruptime,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum RwhodClientResponse {
|
||||
Rwho(Vec<WhodUserEntry>),
|
||||
Ruptime(Vec<WhodStatusUpdate>),
|
||||
}
|
||||
|
||||
#[derive(Debug, ReplyError)]
|
||||
#[zlink(interface = "no.ntnu.pvv.roowho2.rwhod")]
|
||||
pub enum RwhodClientError {
|
||||
InvalidRequest,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RwhodClientServer {
|
||||
whod_status_store: Arc<tokio::sync::RwLock<HashMap<IpAddr, WhodStatusUpdate>>>,
|
||||
}
|
||||
|
||||
impl<'a> RwhodClientServer {
|
||||
pub fn new(
|
||||
whod_status_store: Arc<tokio::sync::RwLock<HashMap<IpAddr, WhodStatusUpdate>>>,
|
||||
) -> Self {
|
||||
Self { whod_status_store }
|
||||
}
|
||||
}
|
||||
|
||||
impl zlink::Service for RwhodClientServer {
|
||||
type MethodCall<'de> = RwhodClientRequest;
|
||||
type ReplyParams<'se> = RwhodClientResponse;
|
||||
type ReplyStreamParams = ();
|
||||
type ReplyStream = futures_util::stream::Empty<zlink::Reply<()>>;
|
||||
type ReplyError<'se> = RwhodClientError;
|
||||
|
||||
async fn handle<'ser, 'de: 'ser, Sock: zlink::connection::Socket>(
|
||||
&'ser mut self,
|
||||
call: zlink::Call<Self::MethodCall<'de>>,
|
||||
_conn: &mut zlink::Connection<Sock>,
|
||||
) -> MethodReply<Self::ReplyParams<'ser>, Self::ReplyStream, Self::ReplyError<'ser>> {
|
||||
match call.method() {
|
||||
// TODO: handle 'all' parameter
|
||||
RwhodClientRequest::Rwho { .. } => {
|
||||
let store = self.whod_status_store.read().await;
|
||||
let mut all_user_entries = Vec::new();
|
||||
for status_update in store.values() {
|
||||
all_user_entries.extend_from_slice(&status_update.users);
|
||||
}
|
||||
MethodReply::Single(Some(RwhodClientResponse::Rwho(all_user_entries)))
|
||||
}
|
||||
RwhodClientRequest::Ruptime => {
|
||||
let store = self.whod_status_store.read().await;
|
||||
let all_status_updates = store.values().cloned().collect();
|
||||
MethodReply::Single(Some(RwhodClientResponse::Ruptime(all_status_updates)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn rwhod_client_server_task(
|
||||
socket: zlink::unix::Listener,
|
||||
whod_status_store: Arc<tokio::sync::RwLock<HashMap<IpAddr, WhodStatusUpdate>>>,
|
||||
) -> anyhow::Result<()> {
|
||||
let service = RwhodClientServer::new(whod_status_store);
|
||||
|
||||
let server = zlink::Server::new(socket, service);
|
||||
|
||||
tracing::info!("Starting Rwhod client API server");
|
||||
|
||||
server
|
||||
.run()
|
||||
.await
|
||||
.context("Rwhod client API server failed")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user