Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added debug logging option.
Browse files Browse the repository at this point in the history
apognu committed Apr 27, 2024

Verified

This commit was signed with the committer’s verified signature.
apognu Antoine POPINEAU
1 parent f65c706 commit 6ede354
Showing 11 changed files with 284 additions and 18 deletions.
180 changes: 180 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -41,6 +41,9 @@ unic-langid = "^0.9"
zeroize = "^1.3"
uzers = "0.12"
rand = "0.8.5"
tracing-appender = "0.2.3"
tracing-subscriber = "0.3.18"
tracing = "0.1.40"

[profile.release]
lto = true
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -10,6 +10,8 @@ Usage: tuigreet [OPTIONS]
Options:
-h, --help show this usage information
-v, --version print version information
-d, --debug [FILE] enable debug logging to the provided file, or to
/tmp/tuigreet.log
-c, --cmd COMMAND command to run
-s, --sessions DIRS colon-separated list of Wayland session paths
--session-wrapper 'CMD [ARGS]...'
@@ -53,9 +55,12 @@ Options:
command to run to reboot the system
--power-no-setsid
do not prefix power commands with setsid
--kb-[command|sessions|power] [1-12]
change the default F-key keybindings to access the
command, sessions and power menus.
--kb-command [1-12]
F-key to use to open the command menu
--kb-sessions [1-12]
F-key to use to open the sessions menu
--kb-power [1-12]
F-key to use to open the power menu
```

## Usage
4 changes: 4 additions & 0 deletions contrib/man/tuigreet-1.scd
Original file line number Diff line number Diff line change
@@ -16,6 +16,10 @@ tuigreet - A graphical console greeter for greetd
*-v, --version*
Print program version and exit.

*-d, --debug [FILE]*
Enables debug logging to the provided FILE path, or to /tmp/tuigreet.log if no
file is specified.

*-c, --cmd CMD*
Specify which command to run on successful authentication. This can be
overridden by manual selection within *tuigreet*.
20 changes: 19 additions & 1 deletion src/greeter.rs
Original file line number Diff line number Diff line change
@@ -34,6 +34,7 @@ use crate::{
},
};

const DEFAULT_LOG_FILE: &str = "/tmp/tuigreet.log";
const DEFAULT_LOCALE: Locale = Locale::en_US;
const DEFAULT_ASTERISKS_CHARS: &str = "*";
// `startx` wants an absolute path to the executable as a first argument.
@@ -90,6 +91,9 @@ impl SecretDisplay {

#[derive(SmartDefault)]
pub struct Greeter {
pub debug: bool,
pub logfile: String,

#[default(DEFAULT_LOCALE)]
pub locale: Locale,
pub config: Option<Matches>,
@@ -353,6 +357,7 @@ impl Greeter {

opts.optflag("h", "help", "show this usage information");
opts.optflag("v", "version", "print version information");
opts.optflagopt("d", "debug", "enable debug logging to the provided file, or to /tmp/tuigreet.log", "FILE");
opts.optopt("c", "cmd", "command to run", "COMMAND");
opts.optopt("s", "sessions", "colon-separated list of Wayland session paths", "DIRS");
opts.optopt("", "session-wrapper", "wrapper command to initialize the non-X11 session", "'CMD [ARGS]...'");
@@ -418,6 +423,15 @@ impl Greeter {
}
}

if self.config().opt_present("debug") {
self.debug = true;

self.logfile = match self.config().opt_str("debug") {
Some(file) => file.to_string(),
None => DEFAULT_LOG_FILE.to_string(),
}
}

if self.config().opt_present("issue") && self.config().opt_present("greeting") {
eprintln!("Only one of --issue and --greeting may be used at the same time");
print_usage(opts);
@@ -454,6 +468,8 @@ impl Greeter {
let max_uid = self.config().opt_str("user-menu-max-uid").and_then(|uid| uid.parse::<u16>().ok());
let (min_uid, max_uid) = get_min_max_uids(min_uid, max_uid);

tracing::info!("min/max UIDs are {}/{}", min_uid, max_uid);

if min_uid >= max_uid {
eprintln!("Minimum UID ({min_uid}) must be less than maximum UID ({max_uid})");
process::exit(1);
@@ -463,7 +479,9 @@ impl Greeter {
title: fl!("title_users"),
options: get_users(min_uid, max_uid),
selected: 0,
}
};

tracing::info!("found {} users", self.users.options.len());
}

if self.config().opt_present("remember-session") && self.config().opt_present("remember-user-session") {
2 changes: 2 additions & 0 deletions src/info.rs
Original file line number Diff line number Diff line change
@@ -229,6 +229,8 @@ pub fn get_sessions(greeter: &Greeter) -> Result<Vec<Session>, Box<dyn Error>> {

files.sort_by(|a, b| a.name.cmp(&b.name));

tracing::info!("found {} sessions", files.len());

Ok(files)
}

19 changes: 19 additions & 0 deletions src/ipc.rs
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ use tokio::sync::{
use crate::{
event::Event,
info::{delete_last_user_session, delete_last_user_session_path, write_last_user_session, write_last_user_session_path, write_last_username},
macros::SafeDebug,
ui::sessions::{Session, SessionSource, SessionType},
AuthStatus, Greeter, Mode,
};
@@ -32,6 +33,8 @@ impl Ipc {
}

pub async fn send(&self, request: Request) {
tracing::info!("sending request to greetd: {}", request.safe_repr());

let _ = self.0.tx.read().await.send(request).await;
}

@@ -66,6 +69,8 @@ impl Ipc {
}

async fn parse_response(&mut self, greeter: &mut Greeter, response: Response) -> Result<(), Box<dyn Error>> {
tracing::info!("received greetd message: {:?}", response);

match response {
Response::AuthMessage { auth_message_type, auth_message } => match auth_message_type {
AuthMessageType::Secret => {
@@ -104,18 +109,26 @@ impl Ipc {

Response::Success => {
if greeter.done {
tracing::info!("greetd acknowledged session start, exiting");

if greeter.remember {
tracing::info!("caching last successful username");

write_last_username(&greeter.username);

if greeter.remember_user_session {
match greeter.session_source {
SessionSource::Command(ref command) => {
tracing::info!("caching last user command: {command}");

write_last_user_session(&greeter.username.value, command);
delete_last_user_session_path(&greeter.username.value);
}

SessionSource::Session(index) => {
if let Some(Session { path: Some(session_path), .. }) = greeter.sessions.options.get(index) {
tracing::info!("caching last user session: {session_path:?}");

write_last_user_session_path(&greeter.username.value, session_path);
delete_last_user_session(&greeter.username.value);
}
@@ -130,6 +143,8 @@ impl Ipc {
let _ = sender.send(Event::Exit(AuthStatus::Success)).await;
}
} else {
tracing::info!("authentication successful, starting session");

let command = greeter.session_source.command(greeter).map(str::to_string);

if let Some(command) = command {
@@ -159,6 +174,8 @@ impl Ipc {
}

Response::Error { error_type, description } => {
tracing::info!("received an error from greetd: {error_type:?} - {description}");

Ipc::cancel(greeter).await;

match error_type {
@@ -184,6 +201,8 @@ impl Ipc {
}

pub async fn cancel(greeter: &mut Greeter) {
tracing::info!("cancelling session");

let _ = Request::CancelSession.write_to(&mut *greeter.stream().await).await;
}
}
4 changes: 4 additions & 0 deletions src/keyboard.rs
Original file line number Diff line number Diff line change
@@ -365,12 +365,16 @@ async fn validate_username(greeter: &mut Greeter, ipc: &Ipc) {
if greeter.remember_user_session {
if let Ok(last_session) = get_last_user_session_path(&greeter.username.value) {
if let Some(last_session) = Session::from_path(greeter, last_session).cloned() {
tracing::info!("remembered user session is {}", last_session.name);

greeter.sessions.selected = greeter.sessions.options.iter().position(|sess| sess.path == last_session.path).unwrap_or(0);
greeter.session_source = SessionSource::Session(greeter.sessions.selected);
}
}

if let Ok(command) = get_last_user_session(&greeter.username.value) {
tracing::info!("remembered user command is {}", command);

greeter.session_source = SessionSource::Command(command);
}
}
19 changes: 18 additions & 1 deletion src/macros.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
use greetd_ipc::Request;

pub trait SafeDebug {
fn safe_repr(&self) -> String;
}

impl SafeDebug for Request {
fn safe_repr(&self) -> String {
match self {
msg @ &Request::CancelSession => format!("{:?}", msg),
msg @ &Request::CreateSession { .. } => format!("{:?}", msg),
&Request::PostAuthMessageResponse { .. } => "PostAuthMessageResponse".to_string(),
msg @ &Request::StartSession { .. } => format!("{:?}", msg),
}
}
}

macro_rules! fl {
($message_id:literal) => {{
i18n_embed_fl::fl!($crate::ui::MESSAGES, $message_id)
}};

($message_id:literal, $($args:expr),*) => {{
i18n_embed_fl::fl!($crate::ui::MESSAGES, $message_id, $($args), *)
i18n_embed_fl::fl!($crate::ui::MESSAGES, $message_id, $($args),*)
}};
}
36 changes: 23 additions & 13 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ mod keyboard;
mod power;
mod ui;

use std::{error::Error, io, process, sync::Arc};
use std::{error::Error, fs::OpenOptions, io, process, sync::Arc};

use crossterm::{
execute,
@@ -42,6 +42,22 @@ async fn run() -> Result<(), Box<dyn Error>> {
let mut greeter = Greeter::new(events.sender()).await;
let mut stdout = io::stdout();

let logfile = OpenOptions::new().write(true).create(true).append(true).clone();

let _guard = match (greeter.debug, logfile.open(&greeter.logfile)) {
(true, Ok(file)) => {
let (appender, guard) = tracing_appender::non_blocking(file);

tracing_subscriber::fmt().with_writer(appender).init();

Some(guard)
}

_ => None,
};

tracing::info!("tuigreet started");

register_panic_handler();

enable_raw_mode()?;
@@ -57,6 +73,8 @@ async fn run() -> Result<(), Box<dyn Error>> {
if greeter.remember && !greeter.username.value.is_empty() {
greeter.working = true;

tracing::info!("creating remembered session for user {}", greeter.username.value);

ipc
.send(Request::CreateSession {
username: greeter.username.value.clone(),
@@ -79,6 +97,8 @@ async fn run() -> Result<(), Box<dyn Error>> {

loop {
if let Some(status) = greeter.read().await.exit {
tracing::info!("exiting main loop");

return Err(status.into());
}

@@ -100,6 +120,8 @@ async fn run() -> Result<(), Box<dyn Error>> {
}

async fn exit(greeter: &mut Greeter, status: AuthStatus) {
tracing::info!("preparing exit with status {}", status);

match status {
AuthStatus::Success => {}
AuthStatus::Cancel | AuthStatus::Failure => Ipc::cancel(greeter).await,
@@ -132,15 +154,3 @@ pub fn clear_screen() {
let _ = terminal.clear();
}
}

#[cfg(debug_assertions)]
pub fn log(msg: &str) {
use std::io::Write;

let time = chrono::Utc::now();

let mut file = std::fs::OpenOptions::new().create(true).append(true).open("/tmp/tuigreet.log").unwrap();
file.write_all(format!("{:?} - ", time).as_ref()).unwrap();
file.write_all(msg.as_ref()).unwrap();
file.write_all("\n".as_bytes()).unwrap();
}
4 changes: 4 additions & 0 deletions src/power.rs
Original file line number Diff line number Diff line change
@@ -61,6 +61,8 @@ pub async fn power(greeter: &mut Greeter, option: PowerOption) {
}

pub async fn run(greeter: &Arc<RwLock<Greeter>>, mut command: Command) {
tracing::info!("executing power command: {:?}", command);

greeter.write().await.mode = Mode::Processing;

let message = match command.output().await {
@@ -77,6 +79,8 @@ pub async fn run(greeter: &Arc<RwLock<Greeter>>, mut command: Command) {
Err(err) => Some(format!("{}: {err}", fl!("command_failed"))),
};

tracing::info!("power command exited with: {:?}", message);

let mode = greeter.read().await.previous_mode;

let mut greeter = greeter.write().await;

0 comments on commit 6ede354

Please sign in to comment.