diff --git a/README.md b/README.md index 83f8430..4429ad2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,34 @@ # cosmic-greeter libcosmic greeter for greetd, which can be run inside cosmic-comp + +## Development + +This project uses [just](https://github.com/casey/just) as a command runner. + +### Available Commands + +#### Building +- `just build-debug` - Compile with debug profile +- `just build-release` - Compile with release profile (default) +- `just build-vendored` - Compile release profile with vendored dependencies + +#### Testing & Development +- `just mock` - Run greeter in a windowed compositor for quick testing (builds and runs the mock server example) +- `just run` - Run with debug logs (`RUST_LOG=debug` and `RUST_BACKTRACE=full`) + +#### Code Quality +- `just check` - Run clippy linter with pedantic warnings +- `just check-json` - Run clippy with JSON output format + +#### Installation +- `just install` - Install all files (binary, daemon, D-Bus config, systemd files) +- `just install-debian` - Install only Debian package required files +- `just uninstall` - Remove all installed files + +#### Cleanup +- `just clean` - Run `cargo clean` +- `just clean-dist` - Run `cargo clean` and remove vendored dependencies + +#### Vendoring +- `just vendor` - Vendor dependencies locally and create vendor.tar +- `just vendor-extract` - Extract vendored dependencies from vendor.tar diff --git a/examples/server.rs b/examples/server.rs index 71c82eb..5aaa01c 100644 --- a/examples/server.rs +++ b/examples/server.rs @@ -2,67 +2,74 @@ use greetd_ipc::{AuthMessageType, ErrorType, Request, Response, codec::TokioCode use std::{env, fs, io, thread}; use tokio::net::UnixListener; -#[tokio::main] -async fn main() { +fn main() { let greetd_sock = env::current_dir().unwrap().join("socket"); if greetd_sock.exists() { fs::remove_file(&greetd_sock).unwrap(); } - let listener = UnixListener::bind(&greetd_sock).unwrap(); - println!("listening at {:?}", greetd_sock); + // Set up the socket environment variable before spawning greeter unsafe { env::set_var("GREETD_SOCK", &greetd_sock) }; - thread::spawn(|| { - cosmic_greeter::greeter::main().unwrap(); + + // Spawn the mock greetd server in a background thread + thread::spawn(move || { + let rt = tokio::runtime::Runtime::new().unwrap(); + rt.block_on(async { + let listener = UnixListener::bind(&greetd_sock).unwrap(); + println!("listening at {:?}", greetd_sock); + + loop { + let (socket, _addr) = listener.accept().await.unwrap(); + println!("new connection"); + + loop { + let request = { + socket.readable().await.unwrap(); + + let mut bytes = Vec::with_capacity(4096); + match socket.try_read_buf(&mut bytes) { + Ok(0) => break, + Ok(count) => { + println!("read {} bytes", count); + } + Err(err) => match err.kind() { + io::ErrorKind::WouldBlock => continue, + _ => { + println!("failed to read socket: {:?}", err); + break; + } + }, + } + + let mut cursor = io::Cursor::new(bytes); + Request::read_from(&mut cursor).await.unwrap() + }; + println!("{:?}", request); + + let response = match request { + Request::CreateSession { .. } => Response::AuthMessage { + auth_message_type: AuthMessageType::Secret, + auth_message: "MOCKING:".to_string(), + }, + Request::PostAuthMessageResponse { response } => match response.as_deref() { + Some("password") => Response::Success, + _ => Response::Error { + error_type: ErrorType::AuthError, + description: "AUTH_ERR".to_string(), + }, + }, + Request::StartSession { .. } => Response::Success, + Request::CancelSession => Response::Success, + }; + + let mut bytes = Vec::with_capacity(4096); + response.write_to(&mut bytes).await.unwrap(); + socket.try_write(&bytes).unwrap(); + } + } + }); }); - loop { - let (socket, _addr) = listener.accept().await.unwrap(); - println!("new connection"); - - loop { - let request = { - socket.readable().await.unwrap(); - - let mut bytes = Vec::with_capacity(4096); - match socket.try_read_buf(&mut bytes) { - Ok(0) => break, - Ok(count) => { - println!("read {} bytes", count); - } - Err(err) => match err.kind() { - io::ErrorKind::WouldBlock => continue, - _ => { - println!("failed to read socket: {:?}", err); - break; - } - }, - } - - let mut cursor = io::Cursor::new(bytes); - Request::read_from(&mut cursor).await.unwrap() - }; - println!("{:?}", request); - - let response = match request { - Request::CreateSession { .. } => Response::AuthMessage { - auth_message_type: AuthMessageType::Secret, - auth_message: "MOCKING:".to_string(), - }, - Request::PostAuthMessageResponse { response } => match response.as_deref() { - Some("password") => Response::Success, - _ => Response::Error { - error_type: ErrorType::AuthError, - description: "pam_authenticate: AUTH_ERR".to_string(), - }, - }, - Request::StartSession { .. } => Response::Success, - Request::CancelSession => Response::Success, - }; - - let mut bytes = Vec::with_capacity(4096); - response.write_to(&mut bytes).await.unwrap(); - socket.try_write(&bytes).unwrap(); - } - } + // Run greeter on main thread (required for winit event loop) + cosmic_greeter::greeter::main().unwrap(); }