mod protocol;
mod server;
mod client;
mod config;
pub use protocol::{Request, Response, Operation};
pub use server::Daemon;
pub use client::DaemonClient;
pub use config::DaemonConfig;
use std::path::PathBuf;
use sha2::{Digest, Sha256};
pub const SOCKET_FILE: &str = "bd.sock";
const MAX_SOCKET_PATH_LEN: usize = 104;
pub fn get_socket_path(beads_dir: &std::path::Path) -> PathBuf {
let primary = beads_dir.join(SOCKET_FILE);
if primary.to_string_lossy().len() <= MAX_SOCKET_PATH_LEN {
primary
} else {
let mut hasher = Sha256::new();
hasher.update(beads_dir.to_string_lossy().as_bytes());
let hash = hex::encode(&hasher.finalize()[..4]);
PathBuf::from(format!("/tmp/beads-{}/{}", hash, SOCKET_FILE))
}
}
pub fn get_pid_path(beads_dir: &std::path::Path) -> PathBuf {
beads_dir.join("daemon.pid")
}
pub fn is_daemon_running(beads_dir: &std::path::Path) -> bool {
let pid_path = get_pid_path(beads_dir);
if !pid_path.exists() {
return false;
}
if let Ok(pid_str) = std::fs::read_to_string(&pid_path) {
if let Ok(pid) = pid_str.trim().parse::<u32>() {
return is_process_running(pid);
}
}
false
}
#[cfg(unix)]
fn is_process_running(pid: u32) -> bool {
unsafe {
libc::kill(pid as i32, 0) == 0
}
}
#[cfg(not(unix))]
fn is_process_running(_pid: u32) -> bool {
false
}