From 920bd79d26b5742a0f1e0fbf42a8058c10df2760 Mon Sep 17 00:00:00 2001 From: newtoallofthis123 Date: Wed, 28 Feb 2024 00:08:55 +0530 Subject: [PATCH] refactor: New Env for swhkd --- swhkd/src/daemon.rs | 64 +++++++---------------------- swhkd/src/environ.rs | 97 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 50 deletions(-) create mode 100644 swhkd/src/environ.rs diff --git a/swhkd/src/daemon.rs b/swhkd/src/daemon.rs index af75dd4..f162862 100644 --- a/swhkd/src/daemon.rs +++ b/swhkd/src/daemon.rs @@ -1,5 +1,6 @@ use crate::config::Value; use clap::{arg, Command}; +use environ::Env; use evdev::{AttributeSet, Device, InputEventKind, Key}; use nix::{ sys::stat::{umask, Mode}, @@ -26,6 +27,7 @@ use tokio_stream::{StreamExt, StreamMap}; use tokio_udev::{AsyncMonitorSocket, EventType, MonitorBuilder}; mod config; +mod environ; mod perms; mod uinput; @@ -55,20 +57,12 @@ async fn main() -> Result<(), Box> { env_logger::init(); log::trace!("Logger initialized."); - let invoking_uid = match env::var("PKEXEC_UID") { - Ok(uid) => { - let uid = uid.parse::().unwrap(); - log::trace!("Invoking UID: {}", uid); - uid - } - Err(_) => { - log::error!("Failed to launch swhkd!!!"); - log::error!("Make sure to launch the binary with pkexec."); - exit(1); - } - }; + let env = environ::Env::contruct(); + log::trace!("Environment Aquired"); - setup_swhkd(invoking_uid); + let invoking_uid = env.pkexec_id; + + setup_swhkd(invoking_uid, env.xdg_runtime_dir.clone().to_string_lossy().to_string()); let load_config = || { // Drop privileges to the invoking user. @@ -77,7 +71,7 @@ async fn main() -> Result<(), Box> { let config_file_path: PathBuf = if args.is_present("config") { Path::new(args.value_of("config").unwrap()).to_path_buf() } else { - fetch_xdg_config_path() + fetch_xdg_config_path(&env) }; log::debug!("Using config file path: {:#?}", config_file_path); @@ -231,7 +225,7 @@ async fn main() -> Result<(), Box> { tokio::pin!(hotkey_repeat_timer); // The socket we're sending the commands to. - let socket_file_path = fetch_xdg_runtime_socket_path(); + let socket_file_path = fetch_xdg_runtime_socket_path(&env); loop { select! { _ = &mut hotkey_repeat_timer, if &last_hotkey.is_some() => { @@ -501,50 +495,20 @@ pub fn set_command_line_args() -> Command<'static> { app } -pub fn fetch_xdg_config_path() -> PathBuf { - let config_file_path: PathBuf = match env::var("XDG_CONFIG_HOME") { - Ok(val) => { - log::debug!("XDG_CONFIG_HOME exists: {:#?}", val); - Path::new(&val).join("swhkd/swhkdrc") - } - Err(_) => { - log::error!("XDG_CONFIG_HOME has not been set."); - Path::new("/etc/swhkd/swhkdrc").to_path_buf() - } - }; - config_file_path +pub fn fetch_xdg_config_path(env: &Env) -> PathBuf { + PathBuf::from(&env.xdg_config_home).join("swhkd/swhkdrc") } -pub fn fetch_xdg_runtime_socket_path() -> PathBuf { - match env::var("XDG_RUNTIME_DIR") { - Ok(val) => { - log::debug!("XDG_RUNTIME_DIR exists: {:#?}", val); - Path::new(&val).join("swhkd.sock") - } - Err(_) => { - log::error!("XDG_RUNTIME_DIR has not been set."); - Path::new(&format!("/run/user/{}/swhkd.sock", env::var("PKEXEC_UID").unwrap())) - .to_path_buf() - } - } +pub fn fetch_xdg_runtime_socket_path(env: &Env) -> PathBuf { + PathBuf::from(&env.xdg_runtime_dir).join("swhkd.sock") } -pub fn setup_swhkd(invoking_uid: u32) { +pub fn setup_swhkd(invoking_uid: u32, runtime_path: String) { // Set a sane process umask. log::trace!("Setting process umask."); umask(Mode::S_IWGRP | Mode::S_IWOTH); // Get the runtime path and create it if needed. - let runtime_path: String = match env::var("XDG_RUNTIME_DIR") { - Ok(runtime_path) => { - log::debug!("XDG_RUNTIME_DIR exists: {:#?}", runtime_path); - Path::new(&runtime_path).join("swhkd").to_str().unwrap().to_owned() - } - Err(_) => { - log::error!("XDG_RUNTIME_DIR has not been set."); - String::from("/run/swhkd/") - } - }; if !Path::new(&runtime_path).exists() { match fs::create_dir_all(Path::new(&runtime_path)) { Ok(_) => { diff --git a/swhkd/src/environ.rs b/swhkd/src/environ.rs new file mode 100644 index 0000000..35227e2 --- /dev/null +++ b/swhkd/src/environ.rs @@ -0,0 +1,97 @@ +use std::{env::VarError, path::PathBuf}; + +pub struct Env { + pub pkexec_id: u32, + pub xdg_config_home: PathBuf, + pub xdg_runtime_socket: PathBuf, + pub xdg_runtime_dir: PathBuf, +} + +#[derive(Debug)] +pub enum EnvError { + PkexecNotFound, + XdgConfigNotFound, + XdgRuntimeNotFound, + GenericError(String), +} + +impl Env { + pub fn contruct() -> Self { + let pkexec_id = match Self::get_env("PKEXEC_UID") { + Ok(val) => match val.parse::() { + Ok(val) => val, + Err(_) => { + log::error!("Failed to launch swhkd!!!"); + log::error!("Make sure to launch the binary with pkexec."); + std::process::exit(1); + } + }, + Err(_) => { + log::error!("Failed to launch swhkd!!!"); + log::error!("Make sure to launch the binary with pkexec."); + std::process::exit(1); + } + }; + + let xdg_config_home = match Self::get_env("XDG_CONFIG_HOME") { + Ok(val) => PathBuf::from(val), + Err(e) => match e { + EnvError::XdgConfigNotFound => { + log::warn!("XDG_CONFIG_HOME not found, using hardcoded /etc"); + PathBuf::from("/etc") + } + _ => { + eprintln!("Failed to get XDG_CONFIG_HOME: {:?}", e); + std::process::exit(1); + } + }, + }; + + let xdg_runtime_socket = match Self::get_env("XDG_RUNTIME_DIR") { + Ok(val) => PathBuf::from(val), + Err(e) => match e { + EnvError::XdgRuntimeNotFound => { + log::warn!("XDG_RUNTIME_DIR not found, using hardcoded /run/user"); + PathBuf::from(format!("/run/user/{}", pkexec_id)) + } + _ => { + eprintln!("Failed to get XDG_RUNTIME_DIR: {:?}", e); + std::process::exit(1); + } + }, + }; + + let xdg_runtime_dir = match Self::get_env("XDG_RUNTIME_DIR") { + Ok(val) => PathBuf::from(val), + Err(e) => match e { + EnvError::XdgRuntimeNotFound => { + log::warn!("XDG_RUNTIME_DIR not found, using hardcoded /run/swhkd"); + PathBuf::from("/run/swhkd") + } + _ => { + eprintln!("Failed to get XDG_RUNTIME_DIR: {:?}", e); + std::process::exit(1); + } + }, + }; + + Self { pkexec_id, xdg_config_home, xdg_runtime_dir, xdg_runtime_socket } + } + + fn get_env(name: &str) -> Result { + match std::env::var(name) { + Ok(val) => Ok(val), + Err(e) => match e { + VarError::NotPresent => match name { + "PKEXEC_UID" => Err(EnvError::PkexecNotFound), + "XDG_CONFIG_HOME" => Err(EnvError::XdgConfigNotFound), + "XDG_RUNTIME_DIR" => Err(EnvError::XdgRuntimeNotFound), + _ => Err(EnvError::GenericError(e.to_string())), + }, + VarError::NotUnicode(_) => { + Err(EnvError::GenericError("Not a valid unicode".to_string())) + } + }, + } + } +}