Skip to content

Commit

Permalink
refactor: New Env for swhkd
Browse files Browse the repository at this point in the history
  • Loading branch information
newtoallofthis123 committed Feb 27, 2024
1 parent 994b74f commit 920bd79
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 50 deletions.
64 changes: 14 additions & 50 deletions swhkd/src/daemon.rs
Original file line number Diff line number Diff line change
@@ -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},
Expand All @@ -26,6 +27,7 @@ use tokio_stream::{StreamExt, StreamMap};
use tokio_udev::{AsyncMonitorSocket, EventType, MonitorBuilder};

mod config;
mod environ;
mod perms;
mod uinput;

Expand Down Expand Up @@ -55,20 +57,12 @@ async fn main() -> Result<(), Box<dyn Error>> {
env_logger::init();
log::trace!("Logger initialized.");

let invoking_uid = match env::var("PKEXEC_UID") {
Ok(uid) => {
let uid = uid.parse::<u32>().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.
Expand All @@ -77,7 +71,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
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);
Expand Down Expand Up @@ -231,7 +225,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
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() => {
Expand Down Expand Up @@ -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(_) => {
Expand Down
97 changes: 97 additions & 0 deletions swhkd/src/environ.rs
Original file line number Diff line number Diff line change
@@ -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::<u32>() {
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<String, EnvError> {
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()))
}
},
}
}
}

0 comments on commit 920bd79

Please sign in to comment.