aboutsummaryrefslogtreecommitdiff
path: root/karld/src/interface.rs
diff options
context:
space:
mode:
authormetamuffin <yvchraiqi@protonmail.com>2022-06-10 10:47:16 +0200
committermetamuffin <yvchraiqi@protonmail.com>2022-06-10 10:47:16 +0200
commit3238f8517097745032e19b3e26f57f0465a00b28 (patch)
tree2c712d2ab45276bed2981dbc32b7a4adeadbc878 /karld/src/interface.rs
parent829f0dc5ac68ee8a030894ce26c83b1c4eb02104 (diff)
downloadkarlender-3238f8517097745032e19b3e26f57f0465a00b28.tar
karlender-3238f8517097745032e19b3e26f57f0465a00b28.tar.bz2
karlender-3238f8517097745032e19b3e26f57f0465a00b28.tar.zst
move to workspace
Diffstat (limited to 'karld/src/interface.rs')
-rw-r--r--karld/src/interface.rs69
1 files changed, 69 insertions, 0 deletions
diff --git a/karld/src/interface.rs b/karld/src/interface.rs
new file mode 100644
index 0000000..e3d2ba3
--- /dev/null
+++ b/karld/src/interface.rs
@@ -0,0 +1,69 @@
+use super::protocol::{ClientboundPacket, ServerboundPacket};
+use crate::handle_packet;
+use log::{debug, error, info, warn};
+use std::io;
+use std::io::{BufRead, BufReader, ErrorKind, Write};
+use std::os::unix::net::{UnixListener, UnixStream};
+use std::thread;
+
+pub fn network_loop() {
+ let listener = UnixListener::bind("/run/user/1000/calendar").unwrap();
+ info!("listening.");
+ let mut id_counter = 0;
+
+ loop {
+ let (stream, addr) = listener.accept().unwrap();
+ let id = id_counter;
+ id_counter += 1;
+ thread::spawn(move || {
+ info!("client connected: {:?}", addr);
+ if let Err(err) = handle_connection(id, stream) {
+ warn!("client dropped: {:?} ({})", addr, err);
+ } else {
+ info!("client dropped: {:?}", addr);
+ }
+ });
+ }
+}
+
+fn handle_connection(id: u32, mut stream: UnixStream) -> io::Result<()> {
+ let mut reader = BufReader::new(stream.try_clone()?);
+ let (responder, responses) = crossbeam_channel::unbounded();
+ responder
+ .send(ClientboundPacket::Handshake {
+ version: env!("CARGO_PKG_VERSION").to_string(),
+ })
+ .unwrap();
+ thread::spawn(move || {
+ for m in responses {
+ debug!("{id} -> {m:?}");
+ match stream
+ .write_fmt(format_args!("{}\n", serde_json::to_string(&m).unwrap()))
+ .map_err(|e| e.kind())
+ {
+ Ok(_) => (),
+ Err(ErrorKind::BrokenPipe) => break,
+ Err(e) => error!("network error: {:?}", e),
+ }
+ }
+ });
+ {
+ let mut buf = String::new();
+ loop {
+ if reader.read_line(&mut buf)? == 0 {
+ break Ok(());
+ };
+ match serde_json::from_str::<ServerboundPacket>(buf.as_str()) {
+ Ok(packet) => {
+ debug!("{id} <- {packet:?}");
+ handle_packet(id, packet, responder.clone());
+ }
+ Err(err) => responder
+ .send(ClientboundPacket::Error(format!("{}", &err)))
+ .map_err(|_| io::Error::from(ErrorKind::InvalidInput))?,
+ }
+
+ buf.clear();
+ }
+ }
+}