diff --git a/dialog-gtk3/src/main.rs b/dialog-gtk3/src/main.rs index 2c83d60..a49f81e 100644 --- a/dialog-gtk3/src/main.rs +++ b/dialog-gtk3/src/main.rs @@ -4,9 +4,9 @@ use gethostname::gethostname; use glib::{GString, clone, SourceId}; use gtk::{prelude::*, Button, Entry, Label, Plug, Window}; use log::{debug, error, warn}; -use std::{io::{self, Write}, process::exit, thread, time::Duration}; +use std::{io::{self, Write}, thread, time::Duration}; -use bscreensaver_util::{init_logging, settings::Configuration, desktop::NewLoginCommand}; +use bscreensaver_util::{init_logging, DialogExitStatus, settings::Configuration, desktop::NewLoginCommand}; const DIALOG_UPDATE_INTERVAL: Duration = Duration::from_millis(100); const DIALOG_TIMEOUT: Duration = Duration::from_secs(60); @@ -70,7 +70,7 @@ fn main() -> anyhow::Result<()> { let plug_window = match plug.window().unwrap().downcast::() { Err(err) => { error!("Failed to find XID of unlock dialog window: {}", err); - exit(2); + DialogExitStatus::OtherError.exit(); }, Ok(w) => w, }; @@ -85,7 +85,7 @@ fn main() -> anyhow::Result<()> { let mut out_locked = out.lock(); if let Err(err) = out_locked.write_all(&xid_buf).and_then(|_| out_locked.flush()) { error!("Failed to write XID to stdout: {}", err); - exit(2); + DialogExitStatus::OtherError.exit(); }; }); @@ -102,7 +102,7 @@ fn main() -> anyhow::Result<()> { // an examination of the gtk source suggesting that the header should send // a delete-event to the toplevel (which should be the plug) when the close // button is clicked. For some reason, though, we never get the delete-event. - dialog.connect_delete_event(|_, _| exit(1)); + dialog.connect_delete_event(|_, _| DialogExitStatus::AuthCanceled.exit()); dialog.connect_realize(|_| debug!("DIALOG REALIZED")); dialog.connect_map(|_| debug!("DIALOG MAPPED")); dialog.connect_unmap(|_| debug!("DIALOG UNMAPPED")); @@ -164,14 +164,14 @@ fn main() -> anyhow::Result<()> { .build(); vbox.pack_start(&auth_status_label, false, false, 0); - rx.attach(None, clone!(@strong auth_status_label => move |(exit_status, auth_dots_id): (i32, SourceId)| { + rx.attach(None, clone!(@strong auth_status_label => move |(exit_status, auth_dots_id): (DialogExitStatus, SourceId)| { auth_dots_id.remove(); - if exit_status != 0 { + if exit_status != DialogExitStatus::AuthSucceeded { auth_status_label.set_label("Authentication Failed!"); auth_status_label.set_opacity(1.0); - glib::timeout_add_seconds_local_once(1, move || exit(exit_status)); + glib::timeout_add_seconds_local_once(1, move || exit_status.exit()); } else { - exit(exit_status); + exit_status.exit(); } glib::Continue(true) })); @@ -232,7 +232,7 @@ fn main() -> anyhow::Result<()> { hbox.pack_start(&password_box, true, true, 8); password_box.connect_key_press_event(|_, ev| { if ev.keyval().name() == Some(GString::from("Escape")) { - exit(1); + DialogExitStatus::AuthCanceled.exit(); } gtk::Inhibit(false) }); @@ -254,7 +254,7 @@ fn main() -> anyhow::Result<()> { if let Err(err) = new_login_command.run() { warn!("Failed to run new login command: {}", err); } else { - exit(1); + DialogExitStatus::OtherError.exit(); } }); }); @@ -282,13 +282,13 @@ fn main() -> anyhow::Result<()> { let tx = tx.clone(); thread::spawn(move || { let status = if authenticate(&username, &password) { - 0 + DialogExitStatus::AuthSucceeded } else { - -1 + DialogExitStatus::AuthFailed }; if let Err(err) = tx.send((status, auth_dots_id)) { error!("Failed to send exit status to main thread: {}", err); - exit(2); + DialogExitStatus::OtherError.exit(); } }); })); @@ -309,7 +309,7 @@ fn main() -> anyhow::Result<()> { glib::timeout_add_local(DIALOG_UPDATE_INTERVAL, clone!(@strong timer => move || { let new_fraction = timer.fraction() - delta; if new_fraction <= 0.0 { - exit(1); + DialogExitStatus::AuthTimedOut.exit(); } timer.set_fraction(new_fraction); Continue(true) diff --git a/util/src/lib.rs b/util/src/lib.rs index f8c3091..7ecb590 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -6,6 +6,22 @@ pub mod settings; pub const BSCREENSAVER_WM_CLASS: &[u8] = b"bscreensaver\0Bscreensaver\0"; +#[repr(i32)] +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum DialogExitStatus { + AuthFailed = -1, + AuthSucceeded = 0, + AuthCanceled = 1, + AuthTimedOut = 2, + OtherError = 3, +} + +impl DialogExitStatus { + pub fn exit(&self) -> ! { + std::process::exit(*self as i32); + } +} + pub fn init_logging(env_name: &str) { env_logger::builder() .format_timestamp_millis()