M Cargo.toml => Cargo.toml +0 -4
@@ 6,7 6,3 @@ edition = "2021"
authors = ["Knut Magnus Aasrud <km@aasrud.com>"]
homepage = "https://git.sr.ht/~kmaasrud/toe"
license = "MIT"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
A README.md => README.md +18 -0
@@ 0,0 1,18 @@
+# toe
+
+To run the daemon:
+
+```
+$ cargo run --bin toed
+```
+
+This will start the daemon process, which listens on a TCP socket at
+`127.0.0.1:1702`. You can then query information with the client:
+
+```
+$ cargo run --bin toenail [request]
+```
+
+Replace `[request]` with the request you want to send to the server. The default
+(and currently only) request is "user", which returns the name of the user
+running the daemon process.
A src/bin/toed.rs => src/bin/toed.rs +61 -0
@@ 0,0 1,61 @@
+use std::env;
+use std::error::Error;
+use std::io::{BufRead, BufReader, Write};
+use std::net::{TcpListener, TcpStream};
+use std::process;
+use std::thread;
+
+fn main() -> Result<(), Box<dyn Error>> {
+ let listener = TcpListener::bind("127.0.0.1:1702")?;
+
+ for stream in listener.incoming() {
+ match stream {
+ Ok(stream) => {
+ println!("New connection: {}", stream.peer_addr().unwrap());
+ thread::spawn(move || {
+ handle_client(stream).unwrap();
+ });
+ }
+ Err(e) => {
+ println!("Error: {}", e);
+ }
+ }
+ }
+
+ Ok(())
+}
+
+fn handle_client(mut stream: TcpStream) -> Result<(), Box<dyn Error>> {
+ let buf_reader = BufReader::new(&mut stream);
+ let request: Vec<String> = buf_reader
+ .lines()
+ .map(|result| result.unwrap())
+ .take_while(|line| !line.is_empty())
+ .collect();
+
+ if let Some(request) = request.get(0) {
+ match request.as_str() {
+ "user" => {
+ writeln!(stream, "Daemon host user: {}", get_user().unwrap())?;
+ stream.flush()?;
+ }
+ _ => writeln!(stream, "Unknown request: {request}").unwrap(),
+ }
+ }
+
+ Ok(())
+}
+
+fn get_user() -> Option<String> {
+ if let Some(user) = env::var_os("USER") {
+ return Some(user.into_string().unwrap());
+ }
+
+ if let Ok(output) = process::Command::new("id").arg("-un").output() {
+ if output.status.success() {
+ return Some(String::from_utf8(output.stdout).ok()?);
+ }
+ }
+
+ None
+}
A src/bin/toenail.rs => src/bin/toenail.rs +21 -0
@@ 0,0 1,21 @@
+use std::io::{prelude::*, BufRead, BufReader};
+use std::net::TcpStream;
+
+fn main() {
+ let request = std::env::args().nth(1).unwrap_or("user".to_string());
+
+ match TcpStream::connect("127.0.0.1:1702") {
+ Ok(mut stream) => {
+ write!(stream, "{request}\n\n").unwrap();
+ stream.flush().unwrap();
+
+ let buf_reader = BufReader::new(&mut stream);
+ for line in buf_reader.lines() {
+ if let Ok(line) = line {
+ println!("{}", line);
+ }
+ }
+ }
+ Err(e) => eprintln!("{e}"),
+ }
+}
D src/main.rs => src/main.rs +0 -3
@@ 1,3 0,0 @@
-fn main() {
- println!("Hello from toe!");
-}