From 0cd3fe9d0ab8aad466a9f823a20b8de8d538bca4 Mon Sep 17 00:00:00 2001 From: newtoallofthis123 Date: Mon, 26 Feb 2024 14:19:38 +0530 Subject: [PATCH 1/5] Refactor file path handling and environment variable initialization --- .gitignore | 2 +- swhks/src/environ.rs | 84 ++++++++++++++++++++++++++++++++++++++++++++ swhks/src/main.rs | 63 +++++++++------------------------ 3 files changed, 102 insertions(+), 47 deletions(-) create mode 100644 swhks/src/environ.rs diff --git a/.gitignore b/.gitignore index e5a7404..6aaf6b8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,5 @@ target *.gz *.out com.github.swhkd.pkexec.policy -*rc +# *rc .direnv diff --git a/swhks/src/environ.rs b/swhks/src/environ.rs new file mode 100644 index 0000000..5361ea3 --- /dev/null +++ b/swhks/src/environ.rs @@ -0,0 +1,84 @@ +//! Environ.rs +//! Defines modules and structs for handling environment variables and paths. + +use std::{path::PathBuf, env::VarError}; + +use nix::unistd; + +// The main struct for handling environment variables. +// Contains the values of the environment variables in the form of PathBuffers. +pub struct Env { + pub data_home: PathBuf, + pub home: PathBuf, + pub runtime_dir: PathBuf, +} + +/// Error type for the Env struct. +/// Contains all the possible errors that can occur when trying to get an environment variable. +#[derive(Debug)] +pub enum EnvError { + DataHomeNotSet, + HomeNotSet, + RuntimeDirNotSet, + GenericError(String), +} + +impl Env { + /// Constructs a new Env struct. + /// This function is called only once and the result is stored in a static variable. + pub fn construct() -> Self { + let home = match Self::get_env("HOME") { + Ok(val) => val, + Err(_) => { + eprintln!("HOME Variable is not set, cannot fall back on hardcoded path for XDG_DATA_HOME."); + std::process::exit(1); + } + }; + + let data_home = match Self::get_env("XDG_DATA_HOME") { + Ok(val) => val, + Err(e) => match e { + EnvError::DataHomeNotSet => { + log::warn!("XDG_DATA_HOME Variable is not set, falling back on hardcoded path."); + home.join(".local/share") + }, + _ => panic!("Unexpected error: {:#?}", e), + }, + }; + + let runtime_dir = match Self::get_env("XDG_RUNTIME_DIR") { + Ok(val) => val, + Err(e) => match e { + EnvError::RuntimeDirNotSet => { + log::warn!("XDG_RUNTIME_DIR Variable is not set, falling back on hardcoded path."); + PathBuf::from(format!("/run/user/{}", unistd::Uid::current())) + }, + _ => panic!("Unexpected error: {:#?}", e), + }, + }; + + Self { + data_home, + home, + runtime_dir, + } + } + + /// Actual interface to get the environment variable. + fn get_env(name: &str) -> Result { + match std::env::var(name) { + Ok(val) => Ok(PathBuf::from(val)), + Err(e) => match e { + VarError::NotPresent => match name { + "XDG_DATA_HOME" => Err(EnvError::DataHomeNotSet), + "HOME" => Err(EnvError::HomeNotSet), + "XDG_RUNTIME_DIR" => Err(EnvError::RuntimeDirNotSet), + _ => Err(EnvError::GenericError(format!("{} not set", name))), + }, + VarError::NotUnicode(_) => { + Err(EnvError::GenericError(format!("{} not unicode", name))) + } + }, + } + } +} diff --git a/swhks/src/main.rs b/swhks/src/main.rs index 77d0911..8304986 100644 --- a/swhks/src/main.rs +++ b/swhks/src/main.rs @@ -1,7 +1,7 @@ use clap::arg; +use environ::Env; use nix::{ sys::stat::{umask, Mode}, - unistd, unistd::daemon, }; use std::{ @@ -11,10 +11,12 @@ use std::{ os::unix::net::UnixListener, path::Path, process::{exit, id, Command, Stdio}, - time::{SystemTime, UNIX_EPOCH}, + time::{SystemTime, UNIX_EPOCH}, sync::OnceLock, }; use sysinfo::{ProcessExt, System, SystemExt}; +mod environ; + fn main() -> std::io::Result<()> { let app = clap::Command::new("swhks") .version(env!("CARGO_PKG_VERSION")) @@ -38,7 +40,14 @@ fn main() -> std::io::Result<()> { log::trace!("Setting process umask."); umask(Mode::S_IWGRP | Mode::S_IWOTH); - let (pid_file_path, sock_file_path) = get_file_paths(); + // This is used to initialize the environment variables only once + // then lock it so that it cannot be modified. + // This ensures that even if the environment variables are modified + // at run time, it doesn't cause weird issues with the server already running. + static ENV: OnceLock = OnceLock::new(); + ENV.get_or_init(Env::construct); + + let (pid_file_path, sock_file_path) = get_file_paths(ENV.get().unwrap()); let log_file_name = if let Some(val) = args.value_of("log") { val.to_string() @@ -51,29 +60,7 @@ fn main() -> std::io::Result<()> { } }; - match env::var("XDG_DATA_HOME") { - Ok(val) => { - log::info!( - "XDG_DATA_HOME Variable is present, using it's value for default file path." - ); - format!("{}/swhks/swhks-{}.log", val, time) - } - Err(e) => { - log::trace!( - "XDG_DATA_HOME Variable is not set, falling back on hardcoded path.\nError: {:#?}", - e - ); - match env::var("HOME") { - Ok(val) => format!("{}/.local/share/swhks/swhks-{}.log", val, time), - Err(_) => { - log::error!( - "HOME Variable is not set, cannot fall back on hardcoded path for XDG_DATA_HOME." - ); - exit(1); - } - } - } - } + format!("{}/swhks/swhks-{}.log", ENV.get().unwrap().data_home.to_string_lossy(), time) }; let log_path = Path::new(&log_file_name); @@ -142,27 +129,11 @@ fn main() -> std::io::Result<()> { } } -fn get_file_paths() -> (String, String) { - match env::var("XDG_RUNTIME_DIR") { - Ok(val) => { - log::info!( - "XDG_RUNTIME_DIR Variable is present, using it's value as default file path." - ); - - let pid_file_path = format!("{}/swhks.pid", val); - let sock_file_path = format!("{}/swhkd.sock", val); +fn get_file_paths(env: &Env) -> (String, String) { + let pid_file_path = format!("{}/swhks.pid", env.runtime_dir.to_string_lossy()); + let sock_file_path = format!("{}/swhkd.sock", env.runtime_dir.to_string_lossy()); - (pid_file_path, sock_file_path) - } - Err(e) => { - log::trace!("XDG_RUNTIME_DIR Variable is not set, falling back on hardcoded path.\nError: {:#?}", e); - - let pid_file_path = format!("/run/user/{}/swhks.pid", unistd::Uid::current()); - let sock_file_path = format!("/run/user/{}/swhkd.sock", unistd::Uid::current()); - - (pid_file_path, sock_file_path) - } - } + (pid_file_path, sock_file_path) } fn run_system_command(command: &str, log_path: &Path) { From 1cc3a1f7dfef251abc38c6f0f59c5bc7b0ead76b Mon Sep 17 00:00:00 2001 From: newtoallofthis123 Date: Mon, 26 Feb 2024 14:31:48 +0530 Subject: [PATCH 2/5] Run File Check --- swhks/src/environ.rs | 20 ++++++++++---------- swhks/src/main.rs | 3 ++- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/swhks/src/environ.rs b/swhks/src/environ.rs index 5361ea3..cef57ea 100644 --- a/swhks/src/environ.rs +++ b/swhks/src/environ.rs @@ -1,7 +1,7 @@ //! Environ.rs //! Defines modules and structs for handling environment variables and paths. -use std::{path::PathBuf, env::VarError}; +use std::{env::VarError, path::PathBuf}; use nix::unistd; @@ -39,9 +39,11 @@ impl Env { Ok(val) => val, Err(e) => match e { EnvError::DataHomeNotSet => { - log::warn!("XDG_DATA_HOME Variable is not set, falling back on hardcoded path."); + log::warn!( + "XDG_DATA_HOME Variable is not set, falling back on hardcoded path." + ); home.join(".local/share") - }, + } _ => panic!("Unexpected error: {:#?}", e), }, }; @@ -50,18 +52,16 @@ impl Env { Ok(val) => val, Err(e) => match e { EnvError::RuntimeDirNotSet => { - log::warn!("XDG_RUNTIME_DIR Variable is not set, falling back on hardcoded path."); + log::warn!( + "XDG_RUNTIME_DIR Variable is not set, falling back on hardcoded path." + ); PathBuf::from(format!("/run/user/{}", unistd::Uid::current())) - }, + } _ => panic!("Unexpected error: {:#?}", e), }, }; - Self { - data_home, - home, - runtime_dir, - } + Self { data_home, home, runtime_dir } } /// Actual interface to get the environment variable. diff --git a/swhks/src/main.rs b/swhks/src/main.rs index 8304986..b40a27b 100644 --- a/swhks/src/main.rs +++ b/swhks/src/main.rs @@ -11,7 +11,8 @@ use std::{ os::unix::net::UnixListener, path::Path, process::{exit, id, Command, Stdio}, - time::{SystemTime, UNIX_EPOCH}, sync::OnceLock, + sync::OnceLock, + time::{SystemTime, UNIX_EPOCH}, }; use sysinfo::{ProcessExt, System, SystemExt}; From 49098780f413f173827151b0290994f016d8c40b Mon Sep 17 00:00:00 2001 From: newtoallofthis123 Date: Mon, 26 Feb 2024 18:22:32 +0530 Subject: [PATCH 3/5] Remove OnceLock --- swhks/src/main.rs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/swhks/src/main.rs b/swhks/src/main.rs index b40a27b..f74fd92 100644 --- a/swhks/src/main.rs +++ b/swhks/src/main.rs @@ -1,3 +1,4 @@ +use std::io::Read; use clap::arg; use environ::Env; use nix::{ @@ -7,13 +8,11 @@ use nix::{ use std::{ env, fs, fs::OpenOptions, - io::prelude::*, os::unix::net::UnixListener, path::Path, process::{exit, id, Command, Stdio}, - sync::OnceLock, - time::{SystemTime, UNIX_EPOCH}, }; +use std::time::{SystemTime, UNIX_EPOCH}; use sysinfo::{ProcessExt, System, SystemExt}; mod environ; @@ -42,13 +41,9 @@ fn main() -> std::io::Result<()> { umask(Mode::S_IWGRP | Mode::S_IWOTH); // This is used to initialize the environment variables only once - // then lock it so that it cannot be modified. - // This ensures that even if the environment variables are modified - // at run time, it doesn't cause weird issues with the server already running. - static ENV: OnceLock = OnceLock::new(); - ENV.get_or_init(Env::construct); + let environment = environ::Env::construct(); - let (pid_file_path, sock_file_path) = get_file_paths(ENV.get().unwrap()); + let (pid_file_path, sock_file_path) = get_file_paths(&environment); let log_file_name = if let Some(val) = args.value_of("log") { val.to_string() @@ -61,7 +56,7 @@ fn main() -> std::io::Result<()> { } }; - format!("{}/swhks/swhks-{}.log", ENV.get().unwrap().data_home.to_string_lossy(), time) + format!("{}/swhks/swhks-{}.log", environment.data_home.to_string_lossy(), time) }; let log_path = Path::new(&log_file_name); From d67a55078cf7711bf57f2335b8a3f1989c75d33a Mon Sep 17 00:00:00 2001 From: newtoallofthis123 Date: Tue, 27 Feb 2024 19:42:29 +0530 Subject: [PATCH 4/5] Run Code Format --- swhks/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swhks/src/main.rs b/swhks/src/main.rs index f74fd92..3de2eae 100644 --- a/swhks/src/main.rs +++ b/swhks/src/main.rs @@ -1,10 +1,11 @@ -use std::io::Read; use clap::arg; use environ::Env; use nix::{ sys::stat::{umask, Mode}, unistd::daemon, }; +use std::io::Read; +use std::time::{SystemTime, UNIX_EPOCH}; use std::{ env, fs, fs::OpenOptions, @@ -12,7 +13,6 @@ use std::{ path::Path, process::{exit, id, Command, Stdio}, }; -use std::time::{SystemTime, UNIX_EPOCH}; use sysinfo::{ProcessExt, System, SystemExt}; mod environ; From 5c609a97abd23accdd09c16c3b1733a25f878f88 Mon Sep 17 00:00:00 2001 From: Ishan Joshi <78465651+newtoallofthis123@users.noreply.github.com> Date: Tue, 27 Feb 2024 19:48:33 +0530 Subject: [PATCH 5/5] Discard changes to .gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6aaf6b8..c65e36a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,6 @@ target *.gz *.out com.github.swhkd.pkexec.policy -# *rc +*rc +!*rc/ .direnv