Skip to content

Commit

Permalink
Works to a good extent
Browse files Browse the repository at this point in the history
  • Loading branch information
newtoallofthis123 committed Sep 8, 2024
1 parent 9858cef commit 69053a7
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 34 deletions.
71 changes: 48 additions & 23 deletions swhkd/src/daemon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ use std::{
env,
error::Error,
fs::{self, File, OpenOptions, Permissions},
io::Read,
os::unix::{fs::PermissionsExt, net::UnixListener},
hash::{DefaultHasher, Hash, Hasher},
io::{Read, Write},
os::unix::{fs::PermissionsExt, net::UnixStream},
path::{Path, PathBuf},
process::{exit, id, Command, Stdio},
sync::{Arc, Mutex},
Expand Down Expand Up @@ -92,7 +93,8 @@ async fn main() -> Result<(), Box<dyn Error>> {

log::debug!("Wating for server to start...");
// The first and the most important request for the env
let env = refresh_env(invoking_uid)?.unwrap_or(environ::Env::construct(None));
let (env, mut env_hash) = refresh_env(invoking_uid, 0)?;
let env = env.unwrap_or(environ::Env::construct(None));
log::trace!("Environment Aquired");
let log_file_name = if let Some(val) = args.log {
val
Expand Down Expand Up @@ -130,6 +132,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
// along with it, an additional 120ms is added to it, just to be safe.
let delta = (args.cooldown.unwrap_or(250) as f64 * 0.1) as u64;
let server_cooldown = args.refresh.unwrap_or(default_cooldown - delta);
let server_cooldown = 30;

// Set up a channel to communicate with the server
// The channel can have upto 100 commands in the queue
Expand All @@ -149,19 +152,22 @@ async fn main() -> Result<(), Box<dyn Error>> {
loop {
{
let mut pairs = pairs_clone.lock().unwrap();
match refresh_env(invoking_uid) {
Ok(Some(env)) => {
match refresh_env(invoking_uid, env_hash) {
Ok((Some(env), hash)) => {
pairs.clone_from(&env.pairs);
env_hash = hash;
}
Ok((None, hash)) => {
env_hash = hash;
}
Ok(None) => {}
Err(e) => {
log::error!("Error: {}", e);
_ = Command::new("notify-send").arg(format!("ERROR {}", e)).spawn();
log::warn!("Skipping refresh...");
exit(1);
}
}
}
sleep(Duration::from_millis(server_cooldown)).await;
sleep(Duration::from_secs(server_cooldown)).await;
}
});

Expand Down Expand Up @@ -632,29 +638,48 @@ fn get_file_paths(runtime_dir: &str) -> (String, String) {
}

/// Refreshes the environment variables from the server
fn refresh_env(invoking_uid: u32) -> Result<Option<environ::Env>, Box<dyn Error>> {
fn refresh_env(
invoking_uid: u32,
prev_hash: u64,
) -> Result<(Option<environ::Env>, u64), Box<dyn Error>> {
// A simple placeholder for the env that is to be refreshed
let env = environ::Env::construct(None);

let (_pid_path, sock_path) =
get_file_paths(env.xdg_runtime_dir(invoking_uid).to_str().unwrap());

if Path::new(&sock_path).exists() {
fs::remove_file(&sock_path)?;
let mut result: String = String::new();
if let Ok(mut stream) = UnixStream::connect(&sock_path) {
let n = stream.write(&[1])?;
if n != 1 {
log::error!("Failed to write to socket.");
exit(1);
}
stream.read_to_string(&mut result)?;
}
let env_hash = calculate_hash(result.clone());

let mut result: String = String::new();
let listener = UnixListener::bind(&sock_path)?;
fs::set_permissions(sock_path, fs::Permissions::from_mode(0o666))?;
for mut socket in listener.incoming().flatten() {
let mut buf = String::new();
socket.read_to_string(&mut buf)?;
// If the server doesn't return any variables, return None
if buf.is_empty() {
return Ok(None);
if env_hash == prev_hash {
log::info!("No change in env detected.");
return Ok((None, env_hash));
}

if let Ok(mut stream) = UnixStream::connect(&sock_path) {
let n = stream.write(&[2])?;
if n != 1 {
log::error!("Failed to write to socket.");
exit(1);
}
log::info!("Env refreshed from server.");
result.push_str(&buf);
log::info!("wrote get");
stream.read_to_string(&mut result)?;
log::info!("read get");
}
Ok(Some(environ::Env::construct(Some(&result))))

Ok((Some(environ::Env::construct(Some(&result))), env_hash))
}

pub fn calculate_hash(t: String) -> u64 {
let mut hasher = DefaultHasher::new();
t.hash(&mut hasher);
hasher.finish()
}
56 changes: 45 additions & 11 deletions swhks/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::error::Error;
use std::fs::Permissions;
use std::hash::{DefaultHasher, Hash, Hasher};
use std::io::Read;
use std::os::unix::net::UnixListener;
use std::{
fs::{self},
io::Write,
Expand Down Expand Up @@ -57,21 +59,53 @@ fn main() -> std::io::Result<()> {
log::info!("Started SWHKS placeholder server");

// Daemonize the process
let _ = nix::unistd::daemon(true, false);
//let _ = nix::unistd::daemon(true, false);

setup_swhks(invoking_uid, PathBuf::from(runtime_dir));
loop {
if let Ok(mut stream) = UnixStream::connect(&sock_file_path) {
// Only if the environment has changed, send it to swhkd, else do nothing.
if prev_hash != calculate_hash(get_env().unwrap()) {
log::debug!("Env changed, sending to swhkd");
let new_env = get_env().unwrap();
let _ = stream.write_all(new_env.as_bytes());
log::debug!("Sent env to swhkd");
prev_hash = calculate_hash(new_env);

if Path::new(&sock_file_path).exists() {
fs::remove_file(&sock_file_path)?;
}

let listener = UnixListener::bind(sock_file_path)?;
let mut buff = [0; 1];
println!("Listening for incoming connections...");

for stream in listener.incoming() {
match stream {
Ok(mut stream) => {
println!("Connection established!");
stream.read_exact(&mut buff)?;
println!("Received: {:?}", buff);
if buff == [1] {
log::debug!("Received VERIFY message from swhkd");
let _ = stream.write_all(prev_hash.to_string().as_bytes());
log::debug!("Sent hash to swhkd");
stream.flush()?;
continue;
}
if buff == [2] {
log::debug!("Received GET message from swhkd");
let env = get_env().unwrap();
if prev_hash == calculate_hash(env.clone()) {
log::debug!("No changes in environment variables");
} else {
log::debug!("Changes in environment variables");
}
prev_hash = calculate_hash(env.clone());
let _ = stream.write_all(env.as_bytes());
stream.flush()?;
continue;
}
}
};
Err(e) => {
log::error!("Error: {}", e);
break;
}
}
}

Ok(())
}

/// Calculates a simple hash of the string
Expand Down

0 comments on commit 69053a7

Please sign in to comment.