rwho: format output
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -819,6 +819,7 @@ dependencies = [
|
||||
"nix",
|
||||
"sd-notify",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"toml",
|
||||
"tracing",
|
||||
|
||||
@@ -27,7 +27,7 @@ tracing = "0.1.44"
|
||||
tracing-subscriber = { version = "0.3.22", features = ["env-filter"] }
|
||||
# onc-rpc = "0.3.2"
|
||||
sd-notify = "0.4.5"
|
||||
# serde_json = "1.0.148"
|
||||
serde_json = "1.0.148"
|
||||
uucore = { version = "0.5.0", features = ["utmpx"] }
|
||||
zlink = { version = "0.2.0", features = ["introspection"] }
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use anyhow::Context;
|
||||
use clap::Parser;
|
||||
use roowho2_lib::server::rwhod::RwhodClientProxy;
|
||||
use roowho2_lib::{proto::WhodUserEntry, server::rwhod::RwhodClientProxy};
|
||||
|
||||
/// Check who is logged in on local machines.
|
||||
///
|
||||
@@ -16,13 +17,17 @@ pub struct Args {
|
||||
#[arg(long, short)]
|
||||
all: bool,
|
||||
|
||||
/// Print the output with the old formatting
|
||||
#[arg(long, short)]
|
||||
old: bool,
|
||||
|
||||
/// Output in JSON format
|
||||
#[arg(long, short)]
|
||||
json: bool,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
let args = Args::parse();
|
||||
|
||||
let mut conn = zlink::unix::connect("/run/roowho2/roowho2.varlink")
|
||||
@@ -32,7 +37,81 @@ async fn main() {
|
||||
let reply = conn
|
||||
.rwho(args.all)
|
||||
.await
|
||||
.expect("Failed to send rwho request");
|
||||
.context("Failed to send rwho request")?
|
||||
.map_err(|e| anyhow::anyhow!("Server returned an error for rwho request: {:?}", e))?;
|
||||
|
||||
println!("{:?}", reply);
|
||||
if args.json {
|
||||
println!("{}", serde_json::to_string_pretty(&reply).unwrap());
|
||||
} else if args.old {
|
||||
old_format_user_entries(&reply)
|
||||
.iter()
|
||||
.for_each(|line| println!("{}", line));
|
||||
} else {
|
||||
old_format_user_entries(&reply)
|
||||
.iter()
|
||||
.for_each(|line| println!("{}", line));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn old_format_user_entries(entries: &[(String, WhodUserEntry)]) -> Vec<String> {
|
||||
let hostname_tty_width = entries
|
||||
.iter()
|
||||
.map(|(host, user)| host.len() + user.tty.len() + 1)
|
||||
.max()
|
||||
.unwrap_or(0);
|
||||
|
||||
let idle_time_width = entries
|
||||
.iter()
|
||||
.map(|(_, user)| user.idle_time.num_hours())
|
||||
.max()
|
||||
.map(|hours| {
|
||||
if hours >= 10 {
|
||||
5
|
||||
} else if hours > 0 {
|
||||
4
|
||||
} else {
|
||||
3
|
||||
}
|
||||
})
|
||||
.unwrap_or(0);
|
||||
|
||||
let result = entries
|
||||
.iter()
|
||||
.map(|(hostname, user)| {
|
||||
old_format_user_entry(hostname, hostname_tty_width, idle_time_width, user)
|
||||
})
|
||||
.collect();
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn old_format_user_entry(
|
||||
hostname: &str,
|
||||
hostname_tty_width: usize,
|
||||
idle_time_width: usize,
|
||||
user: &WhodUserEntry,
|
||||
) -> String {
|
||||
let idle_str = {
|
||||
let hours = user.idle_time.num_hours().min(99);
|
||||
let minutes = user.idle_time.num_minutes() % 60;
|
||||
format!(
|
||||
"{}:{:02}",
|
||||
if hours == 0 {
|
||||
"".to_string()
|
||||
} else {
|
||||
hours.to_string()
|
||||
},
|
||||
minutes
|
||||
)
|
||||
};
|
||||
|
||||
format!(
|
||||
"{:<8.8} {:<hostname_tty_width$} {:.12} {:>idle_time_width$}",
|
||||
user.user_id,
|
||||
format!("{hostname}:{}", user.tty),
|
||||
user.login_time.format("%b %d %H:%M"),
|
||||
idle_str,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ pub trait RwhodClientProxy {
|
||||
async fn rwho(
|
||||
&mut self,
|
||||
all: bool,
|
||||
) -> zlink::Result<Result<Vec<WhodUserEntry>, RwhodClientError>>;
|
||||
) -> zlink::Result<Result<Vec<(String, WhodUserEntry)>, RwhodClientError>>;
|
||||
|
||||
async fn ruptime(&mut self) -> zlink::Result<Result<Vec<WhodStatusUpdate>, RwhodClientError>>;
|
||||
}
|
||||
@@ -257,7 +257,7 @@ pub enum RwhodClientRequest {
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum RwhodClientResponse {
|
||||
Rwho(Vec<WhodUserEntry>),
|
||||
Rwho(Vec<(String, WhodUserEntry)>),
|
||||
Ruptime(Vec<WhodStatusUpdate>),
|
||||
}
|
||||
|
||||
@@ -298,7 +298,13 @@ impl zlink::Service for RwhodClientServer {
|
||||
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);
|
||||
all_user_entries.extend_from_slice(
|
||||
&status_update
|
||||
.users
|
||||
.iter()
|
||||
.map(|user| (status_update.hostname.clone(), user.clone()))
|
||||
.collect::<Vec<(String, WhodUserEntry)>>(),
|
||||
);
|
||||
}
|
||||
MethodReply::Single(Some(RwhodClientResponse::Rwho(all_user_entries)))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user