From 30c396ab9ef604c78732409e21c2e4fc18678171 Mon Sep 17 00:00:00 2001 From: Zane Walker Date: Sat, 18 Jul 2026 21:00:02 +0530 Subject: [PATCH] (Fix): replaced hardcoded `C.__uint32_t` / `C.__int32_t` casts with a C helper function (`auth/utmpx_time.h`) that lets the compiler handle type conversion. --- .gitignore | 4 +++- CHANGELOG.md | 37 +++++++++++++++++++++++++++++++++++++ Makefile | 18 +++++++++++++++++- README.md | 23 +++++------------------ src/auth/utmpx.go | 7 ++++--- src/auth/utmpx_time.h | 9 +++++++++ 6 files changed, 75 insertions(+), 23 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 src/auth/utmpx_time.h diff --git a/.gitignore b/.gitignore index bac2414..c29a0a4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ go_project_build_documentation.md documentation.md session.md -build/* \ No newline at end of file +build/* +examples/* +things_todo.md \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..6339099 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,37 @@ +# Changelog + +## 0.1.0 — Unreleased + +first public release + +### What's In + +- tui login screen with username/password fields, session switcher, and status messages +- supports x11, wayland, and tty sessions +- pam authentication via cgo (thread-locked for safety) +- faillock integration — detects lockouts, shows remaining attempts, admin bypass via ctrl+u +- conway's game of life background rendered at 30 fps with unicode half-block characters +- spring animation on switcher transitions +- shake animation on failed login +- caps lock indicator via ioctl +- configurable power controls (shutdown/reboot on f1/f2 by default) +- toml configuration with `$VARIABLE` substitution +- preview mode (`--preview`) to test the login screen without leaving your session +- utmpx user accounting (glibc only) +- x11 session setup — xauthority cookies, sigusr1 handshake, server timeout +- privilege dropping for child processes +- log piping with 64 mb cap + +### Recent Fixes + +- **utmpx time field portability** — replaced hardcoded `C.__uint32_t` / `C.__int32_t` casts with a C helper function (`auth/utmpx_time.h`) that lets the compiler handle type conversion. fixes build failure on systems where `ut_tv` uses `struct timeval` instead of the 32/64 compat struct +- **makefile `deps` target** — added `make deps` to automatically install `libpam0g-dev` and `build-essential`, and verify go is present +- **readme overhaul** — rewrote for clarity: added "what problem does this solve", "how it works", known issues, simpler install instructions, and proper dependency listing + +### What's Missing + +- no tests +- session spawning uses `ForkExec` which is less clean than the original fork-then-exec model +- not all config options affect the rendering yet +- occasional terminal state corruption on abrupt exit +- automata background can flicker on rapid terminal resizes diff --git a/Makefile b/Makefile index 76736dd..c85fb4c 100644 --- a/Makefile +++ b/Makefile @@ -33,9 +33,25 @@ RST := \033[0m ## ─── targets ──────────────────────────────────────────────── -.PHONY: all build install uninstall clean test lint fmt vet \ +.PHONY: all deps build install uninstall clean test lint fmt vet \ run-preview release help +deps: ## install system dependencies + @printf " $(BLUE)%-10s$(RST) checking dependencies...\n" "DEPS" + @if ! dpkg -s libpam0g-dev >/dev/null 2>&1; then \ + printf " $(YELLOW)%-10s$(RST) sudo apt install -y libpam0g-dev\n" ""; \ + sudo apt install -y libpam0g-dev; \ + fi + @if ! dpkg -s build-essential >/dev/null 2>&1; then \ + printf " $(YELLOW)%-10s$(RST) sudo apt install -y build-essential\n" ""; \ + sudo apt install -y build-essential; \ + fi + @if ! command -v go >/dev/null 2>&1; then \ + printf " $(RED)%-10s$(RST) go not found — install go 1.22+\n" ""; \ + exit 1; \ + fi + @printf " $(GREEN)%-10s$(RST) dependencies ok\n" "DEPS" + all: build ## build the release binary build: $(BUILD_DIR)/$(BINARY) ## compile latchd diff --git a/README.md b/README.md index f242987..77e5359 100644 --- a/README.md +++ b/README.md @@ -44,31 +44,18 @@ This project is a work in progress. here's what you should know: ### from source -you need go 1.22 or later and `libpam-dev` (or your distro's equivalent). +you need go 1.22 or later, `libpam0g-dev` (debian/ubuntu) or `pam-devel` (rhel/fedora) or `pam` (arch), and a c compiler (`build-essential`). ```bash -# clone and build -cd src -go build -ldflags="-s -w" -o latchd . -sudo cp latchd /usr/bin/ - -# set up config and session directories -sudo mkdir -p /etc/latchd/wms /etc/latchd/wayland /var/log /var/cache -sudo cp ../extra/config.toml /etc/latchd/config.toml -sudo cp ../extra/xsetup.sh /etc/latchd/xsetup.sh -sudo cp ../extra/lemurs.pam /etc/pam.d/latchd -sudo cp ../extra/lemurs.service /etc/systemd/system/latchd.service - -# enable the service +make deps # install system dependencies +sudo make install # build, install binary + configs + systemd unit sudo systemctl enable latchd ``` -you can also use the makefile: +to test without rebooting: ```bash -make build # compile to build/latchd -sudo make install # install to /usr/bin and set up systemd -make run-preview # test the login screen in your current terminal +make run-preview ``` ### arch diff --git a/src/auth/utmpx.go b/src/auth/utmpx.go index 5e5637a..d9dc146 100644 --- a/src/auth/utmpx.go +++ b/src/auth/utmpx.go @@ -6,8 +6,10 @@ package auth /* #include #include -#include #include +#include + +#include "utmpx_time.h" */ import "C" import ( @@ -49,8 +51,7 @@ func AddUtmpx(user string, tty uint8, pid uint32) *UtmpxSession { ut.ut_id[0] = C.char(ttyCh) us := time.Now().UnixMicro() - ut.ut_tv.tv_sec = C.__uint32_t(us / 1_000_000) - ut.ut_tv.tv_usec = C.__int32_t(us % 1_000_000) + C.latchd_set_utmpx_time(&ut, C.int64_t(us/1_000_000), C.int32_t(us%1_000_000)) C.setutxent() C.pututxline(&ut) diff --git a/src/auth/utmpx_time.h b/src/auth/utmpx_time.h new file mode 100644 index 0000000..ccee120 --- /dev/null +++ b/src/auth/utmpx_time.h @@ -0,0 +1,9 @@ +// Helper: assign seconds + microseconds to utmpx's ut_tv field. +// The C compiler handles the type conversion, so this works whether +// ut_tv is struct timeval (long tv_sec/tv_usec) or the compat struct +// (__uint32_t tv_sec / __int32_t tv_usec). + +static inline void latchd_set_utmpx_time(struct utmpx *ut, int64_t sec, int32_t usec) { + ut->ut_tv.tv_sec = sec; + ut->ut_tv.tv_usec = usec; +}