diff options
-rw-r--r-- | Cargo.lock | 2 | ||||
-rw-r--r-- | karlc/Cargo.toml | 4 | ||||
-rw-r--r-- | karlc/src/client.rs | 42 | ||||
-rw-r--r-- | karlc/src/main.rs | 60 | ||||
-rw-r--r-- | karlc/src/pretty.rs | 2 | ||||
-rw-r--r-- | karlcommon/src/lib.rs | 15 | ||||
-rw-r--r-- | karlcommon/src/protocol.rs | 1 | ||||
-rw-r--r-- | karld/src/interface.rs | 4 | ||||
-rw-r--r-- | karld/src/main.rs | 10 |
9 files changed, 126 insertions, 14 deletions
@@ -179,10 +179,12 @@ name = "karlc" version = "0.1.0" dependencies = [ "clap", + "crossbeam-channel", "env_logger", "karlcommon", "log", "serde", + "serde_json", ] [[package]] diff --git a/karlc/Cargo.toml b/karlc/Cargo.toml index e37abfb..c49ecfe 100644 --- a/karlc/Cargo.toml +++ b/karlc/Cargo.toml @@ -6,7 +6,9 @@ edition = "2021" [dependencies] karlcommon = { path = "../karlcommon" } -serde = { version = "1.0.137", features = ["derive"] } clap = { version = "3.1.18", features = ["derive"] } +serde = { version = "1.0.137", features = ["derive"] } +serde_json = "1.0.81" env_logger = "0.9.0" log = "0.4.17" +crossbeam-channel = "0.5.4" diff --git a/karlc/src/client.rs b/karlc/src/client.rs new file mode 100644 index 0000000..6420da0 --- /dev/null +++ b/karlc/src/client.rs @@ -0,0 +1,42 @@ +use std::{ + io::{BufRead, BufReader, Write}, + os::unix::net::UnixStream, + thread, +}; + +use crossbeam_channel::Receiver; +use karlcommon::{ClientboundPacket, ServerboundPacket}; +use log::debug; + +pub struct Client { + socket: UnixStream, + pub receiver: Receiver<ClientboundPacket>, +} + +impl Client { + pub fn new(socket: UnixStream) -> Self { + let (sender, receiver) = crossbeam_channel::unbounded(); + let mut reader = BufReader::new(socket.try_clone().unwrap()); + thread::spawn(move || { + loop { + let mut buf = String::new(); + reader.read_line(&mut buf).unwrap(); + let p: ClientboundPacket = serde_json::from_str(buf.as_str()).unwrap(); + debug!("<- {:?}", p); + sender.send(p).unwrap(); + } + }); + let mut c = Self { receiver, socket }; + c.send(ServerboundPacket::Handshake { + version: env!("CARGO_PKG_VERSION").to_owned(), + }); + return c; + } + + pub fn send(&mut self, p: ServerboundPacket) { + debug!("-> {:?}", p); + self.socket + .write_fmt(format_args!("{}\n", serde_json::to_string(&p).unwrap())) + .unwrap() + } +} diff --git a/karlc/src/main.rs b/karlc/src/main.rs index 8db8d18..bfd433e 100644 --- a/karlc/src/main.rs +++ b/karlc/src/main.rs @@ -1,18 +1,64 @@ -use std::os::unix::net::UnixStream; +pub mod client; +pub mod pretty; -use clap::Parser; -use karlcommon::socket_path; +use std::{os::unix::net::UnixStream, process::exit}; + +use clap::{Parser, Subcommand}; +use client::Client; +use karlcommon::{socket_path, version, ClientboundPacket, ServerboundPacket}; +use log::{error, info}; /// CLI interface for karld #[derive(Parser)] #[clap(about, author, version)] -struct Args {} +struct Args { + #[clap(subcommand)] + action: Action, +} + +#[derive(Subcommand)] +pub enum Action { + /// Show version of the client and daemon + Version, + /// List all taskss + ListTasks, +} fn main() { - let _args = Args::parse(); + env_logger::init(); + let args = Args::parse(); - let socket = UnixStream::connect(socket_path()).unwrap(); + let socket = match UnixStream::connect(socket_path()) { + Ok(s) => s, + Err(e) => { + error!("failed to connect to socket: {}", e); + exit(1); + } + }; - + let mut client = Client::new(socket); + info!("connected"); + let handshake = client.receiver.recv().unwrap(); + match args.action { + Action::Version => { + if let ClientboundPacket::Handshake { + version: daemon_version, + } = handshake + { + println!("{}", version!()); + println!("{daemon_version}"); + } else { + error!("handshake is not the first packet") + } + } + Action::ListTasks => { + client.send(ServerboundPacket::Download); + if let ClientboundPacket::DownloadResponse(tasks) = client.receiver.recv().unwrap() { + for t in tasks { + println!("{:?}", t) + } + } + } + } } diff --git a/karlc/src/pretty.rs b/karlc/src/pretty.rs new file mode 100644 index 0000000..139597f --- /dev/null +++ b/karlc/src/pretty.rs @@ -0,0 +1,2 @@ + + diff --git a/karlcommon/src/lib.rs b/karlcommon/src/lib.rs index 8e7694b..66df90d 100644 --- a/karlcommon/src/lib.rs +++ b/karlcommon/src/lib.rs @@ -14,3 +14,18 @@ pub fn socket_path() -> PathBuf { fn getuid() -> u32 { std::fs::metadata("/proc/self").unwrap().uid() } + +#[macro_export] +macro_rules! version { + () => { + format!( + "{} {} (lib{})", + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_VERSION"), + karlcommon::own_version() + ) + }; +} +pub fn own_version() -> String { + format!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")) +} diff --git a/karlcommon/src/protocol.rs b/karlcommon/src/protocol.rs index 74559bf..55dda06 100644 --- a/karlcommon/src/protocol.rs +++ b/karlcommon/src/protocol.rs @@ -12,6 +12,7 @@ pub enum ClientboundPacket { #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(tag = "type", content = "data", rename_all = "snake_case")] pub enum ServerboundPacket { + Handshake { version: String }, Download, UpdateTask(Task), RemoveTask(u64), diff --git a/karld/src/interface.rs b/karld/src/interface.rs index 99ef594..127c0db 100644 --- a/karld/src/interface.rs +++ b/karld/src/interface.rs @@ -1,5 +1,5 @@ use crate::handle_packet; -use karlcommon::{socket_path, ClientboundPacket, ServerboundPacket}; +use karlcommon::{socket_path, version, ClientboundPacket, ServerboundPacket}; use log::{debug, error, info, warn}; use std::io; use std::io::{BufRead, BufReader, ErrorKind, Write}; @@ -31,7 +31,7 @@ fn handle_connection(id: u32, mut stream: UnixStream) -> io::Result<()> { let (responder, responses) = crossbeam_channel::unbounded(); responder .send(ClientboundPacket::Handshake { - version: env!("CARGO_PKG_VERSION").to_string(), + version: version!(), }) .unwrap(); thread::spawn(move || { diff --git a/karld/src/main.rs b/karld/src/main.rs index 7fa47e2..f70b7e7 100644 --- a/karld/src/main.rs +++ b/karld/src/main.rs @@ -1,11 +1,11 @@ pub mod condition; pub mod interface; -use std::{collections::HashMap, sync::RwLock}; use crossbeam_channel::Sender; use interface::network_loop; -use karlcommon::{Task, Condition, Property, ServerboundPacket, ClientboundPacket}; -use log::info; +use karlcommon::{ClientboundPacket, Condition, Property, ServerboundPacket, Task}; +use log::{debug, info}; +use std::{collections::HashMap, sync::RwLock}; fn main() { env_logger::init(); @@ -43,7 +43,6 @@ lazy_static::lazy_static! { } pub fn handle_packet(client: u32, packet: ServerboundPacket, responder: Sender<ClientboundPacket>) { - println!("{:?}, {:?}, {:?}", client, packet, responder); match packet { ServerboundPacket::Download => { let _ = responder.send(ClientboundPacket::DownloadResponse( @@ -56,5 +55,8 @@ pub fn handle_packet(client: u32, packet: ServerboundPacket, responder: Sender<C ServerboundPacket::RemoveTask(i) => { TASKS.write().unwrap().remove(&i); } + ServerboundPacket::Handshake { version } => { + debug!("{client}: version {version}"); + } } } |