chiark / gitweb /
can listen
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 21 Jul 2020 23:11:58 +0000 (00:11 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 21 Jul 2020 23:11:58 +0000 (00:11 +0100)
src/bin/server.rs
src/command.rs
src/error.rs
src/imports.rs
src/lib.rs

index 46181ebb817be8063af73a452c95b9fdf0b5e657..91b55408ca65f1c708d163bf38ca958599a17e6f 100644 (file)
@@ -68,9 +68,13 @@ fn resource(leaf : CheckedResourceLeaf) -> io::Result<NamedFile> {
   NamedFile::open(format!("{}/{}", template_dir, leaf.safe))
 }  
 
+#[throws(StartupError)]
 fn main() {
   xxx_global_setup().expect("global setup failed");
 
+  let cl = CommandListener::new()?;
+  cl.spawn()?;
+
   let helmet = SpaceHelmet::default()
     .enable(NoSniff::Enable)
     .enable(Frame::Deny)
index 7a604250ddc73f353646b29aebead6d76654fcbb..67839c4cadd77eec6ffff6117fc7d45e0898a6d8 100644 (file)
@@ -1,18 +1,20 @@
 
+#![allow(dead_code)]
+
 use crate::imports::*;
 
-use std::os::unix::prelude;
+//use std::os::unix::prelude;
 
 pub use std::os::unix::net::UnixStream;
-
 use std::os::unix::net::UnixListener;
-use uds::UnixListenerExt;
+use uds::UnixStreamExt;
+//use uds::UnixListenerExt;
 use pwd::Passwd;
 
 const SOCKET_PATH : &str = "command.socket"; // xxx
 
-struct CommandListener {
-  listener : UnixListener;
+pub struct CommandListener {
+  listener : UnixListener,
 }
 
 struct CommandStream {
@@ -20,70 +22,68 @@ struct CommandStream {
   euid : Result<u32, anyhow::Error>,
 }
 
+type CSE = anyhow::Error;
+
+impl CommandStream {
+  #[throws(CSE)]
+  pub fn mainloop(&mut self) {
+  }
+}
+
 impl CommandListener {
-  #[throws(OE)]
-  fn new() -> Self {
+  #[throws(StartupError)]
+  pub fn new() -> Self {
     let listener = UnixListener::bind(SOCKET_PATH)?;
     CommandListener { listener }
   }
-  #[throws(OE)]
-  fn process_one() -> Self {
-    let (conn, caller) = self.listener.accept()?;
-    let desc = format!("conn={:?} peer={:?}", &client, &caller);
-    eprintln!("command connection {}: accepted", client);
+
+  #[throws(StartupError)]
+  pub fn spawn(mut self) {
+    thread::spawn(move ||{
+      loop {
+        self.accept_one().unwrap_or_else(
+          |e| eprintln!("accept/spawn failed: {:?}", e)
+        );
+      }
+    })
+  }
+
+  #[throws(CSE)]
+  fn accept_one(&mut self) {
+    let (conn, caller) = self.listener.accept().context("accept")?;
+    let mut desc = format!("conn={:?} peer={:?}", &conn, &caller);
+    eprintln!("command connection {}: accepted", &desc);
     thread::spawn(move||{
-      (||{
+      match (||{
         let euid = conn.initial_peer_credentials()
-          .map_err(|e| anyhow!("initial_peer_credentials: {:?}", e))
-          .and_then(|creds| creds.euid().ok_or_else(
-            || Err(anyhow!("initial_peer_credentials no euid!"))));
-        write!(&mut desc, " user={}", (||{
-          let pwent = Passwd::from_uid(euid?)
-            .map_err(|e| format!("euid {} lookup failed {}",uid,e))?;
-          pwent.map_or_else(|p| p.name,
-                            || format!("<euid {}>", uid))
-        })().ok_or_else(|e| format!("<error: {}>", &e)));
+          .context("initial_peer_credentials")
+          .map(|creds| creds.euid());
 
-        thread::Builder::new()
-          .name(desc.clone())
-          .spawn().context
-        match euid
-          .and_then(
-            |uid| 
-              .map_err(|e| anyhow!("<euid {:?} lookup failed {}",
-                                   uid, e))
-              .and_then(|pwent| pwent.ok_or_else(
-                
-                    
-        {
-          Err(e) => 
-          Ok(u) => {
-            let pwent = Passwd::from_uid(euid);
-            
+        #[derive(Error,Debug)]
+        struct EuidLookupError(String);
+        display_as_debug!{EuidLookupError}
+        impl From<&E> for EuidLookupError where E : Display {
+          fn from(e: &E) -> Self { EuidLookupError(format!("{}",e)) }
         }
-                                                    
-        
-        let credentials_euid =
-          cred
 
- match &credentials {
-          Ok(cred) {
-            match cred.euid() {
-              None => 
-              Some(e) => Ok(e),
-              
+        let user_desc : String = (||{
+          let euid = *(euid.as_ref()?);
+          let pwent = Passwd::from_uid(euid);
+          let show_username =
+            pwent.map_or_else(|| format!("<euid {}>", euid),
+                              |p| p.name);
+          <Result<String,EuidLookupError>>::Ok(show_username)
+        })().unwrap_or_else(|e| format!("<error: {}>", e.0));
+        write!(&mut desc, " user={}", user_desc)?;
 
-          Ok(
-        };
-      })().ok_or(|e|{
-        xxx
-      });
+        let mut cs = CommandStream { conn, euid };
+        cs.mainloop()?;
+        
+        <Result<_,StartupError>>::Ok(())
+      })() {
+        Ok(()) => eprintln!("command connection {}: disconnected", &desc),
+        Err(e) => eprintln!("command connection {}: error: {:?}", &desc, e),
+      }
     });
   }
-  
-  #[throws(OE)]
-  fn process() -> Self {n
-    loop {
-      
-  }
 }
index 3d1ca07310bb6c714b7859f9b7d7e4aebb94cbe8..6769070a4633a69fd75b462f746ba320b9e2e576 100644 (file)
@@ -34,6 +34,8 @@ pub enum OnlineError {
   ServerMessagePackDecodeFail(#[from] rmp_serde::decode::Error),
 }
 
+pub type StartupError = anyhow::Error;
+
 pub use OnlineError::{NoClient,NoPlayer};
 
 use OnlineError::*;
index 2fcdea6688a6e6c84badbb1aa2a6c360709e4a18..3b811e12f4e9838ac750218e30eac2bf83d22071 100644 (file)
@@ -60,6 +60,7 @@ pub use crate::updates::*;
 pub use crate::sse;
 pub use crate::error::*;
 pub use crate::slotmap_slot_idx::*;
+pub use crate::command::*;
 
 pub type E = anyhow::Error;
 pub type AE = anyhow::Error;
index 482792f6dfe6314b7765d97fc0800177f9b003bc..789e623a2dc80349d24fb3df2eb9c8f077a45b93 100644 (file)
@@ -13,4 +13,5 @@ pub mod http;
 pub mod session;
 pub mod api;
 pub mod spec;
+pub mod command;
 #[path="slotmap-slot-idx.rs"] pub mod slotmap_slot_idx;