#![feature(fn_traits)] use jsonrpc_core::Result; use jsonrpc_derive::rpc; use std::io::prelude::*; use std::{ os::unix::net::{ UnixStream, UnixListener, }, env, fs, path::Path, process::{exit, id}, collections::HashMap, }; use sysinfo::{ProcessExt, System, SystemExt}; #[rpc] pub trait Rpc { #[rpc(name = "test")] fn test(&self) -> Result<()>; #[rpc(name = "next")] fn next(&self, attrs: HashMap) -> Result; #[rpc(name = "changeMode")] fn change_mode(&self, mode: String) -> Result; } fn set_mode(mode: &String) -> std::io::Result<()> { println!("Treying to write to socket!"); let mut stream = UnixStream::connect("/tmp/odilia-mode.sock")?; stream.write_all(mode.as_bytes())?; println!("Wrote to socket!"); Ok(()) } pub struct RpcImpl; impl Rpc for RpcImpl { fn change_mode(&self, mode: String) -> Result { // change mode internally let ret = set_mode(&mode); match ret { Ok(_) => println!("Success writing to socket!"), Err(e) => println!("Error writing to socket: {:?}", e), } println!("MODE: {}", mode); Ok(true) } fn test(&self) -> Result<()> { println!("TEST IS RUN!"); Ok(()) } fn next(&self, attrs: HashMap) -> Result { for (key, val) in attrs.iter() { println!("{}={}", key, val); } Ok("next where ^^".to_owned()) } } fn main() -> std::io::Result<()> { let mut io = jsonrpc_core::IoHandler::new(); io.extend_with(RpcImpl.to_delegate()); env::set_var("RUST_LOG", "swhks=trace"); env_logger::init(); let pidfile: String = String::from("/tmp/odilia-recv.pid"); let sockfile: String = String::from("/tmp/odilia-ctrl.sock"); if Path::new(&pidfile).exists() { log::trace!("Reading {} file and checking for running instances.", pidfile); let swhkd_pid = match fs::read_to_string(&pidfile) { Ok(swhkd_pid) => swhkd_pid, Err(e) => { log::error!("Unable to read {} to check all running instances", e); exit(1); } }; log::debug!("Previous PID: {}", swhkd_pid); let mut sys = System::new_all(); sys.refresh_all(); for (pid, process) in sys.processes() { if pid.to_string() == swhkd_pid && process.exe() == env::current_exe().unwrap() { log::error!("Server is already running!"); exit(1); } } } if Path::new(&sockfile).exists() { log::trace!("Sockfile exists, attempting to remove it."); match fs::remove_file(&sockfile) { Ok(_) => { log::debug!("Removed old socket file"); } Err(e) => { log::error!("Error removing the socket file!: {}", e); log::error!("You can manually remove the socket file: {}", sockfile); exit(1); } }; } match fs::write(&pidfile, id().to_string()) { Ok(_) => {} Err(e) => { log::error!("Unable to write to {}: {}", pidfile, e); exit(1); } } let listener = UnixListener::bind(sockfile)?; loop { match listener.accept() { Ok((mut socket, addr)) => { let mut response = String::new(); socket.read_to_string(&mut response)?; println!("RESP: {}", io.handle_request_sync(&response).expect("Could not unwrap")); println!("{}", &response); //run_system_command(&response); log::debug!("Socket: {:?} Address: {:?} Response: {}", socket, addr, response); } Err(e) => log::error!("accept function failed: {:?}", e), } } }