diff --git a/build-linux.sh b/build-linux.sh new file mode 100644 index 0000000..1de5d00 --- /dev/null +++ b/build-linux.sh @@ -0,0 +1,58 @@ +#!/bin/bash +echo "Building HeaderAnalyzer for Linux..." + +# Check for required dependencies +echo "Checking system dependencies..." + +# Check for pkg-config +if ! command -v pkg-config >/dev/null 2>&1; then + echo "Error: pkg-config not found." + echo "Installing required dependencies for systray..." + + # Detect package manager and install dependencies + if command -v apt-get >/dev/null 2>&1; then + echo "Using apt-get to install dependencies..." + sudo apt-get update + sudo apt-get install -y pkg-config libgtk-3-dev libayatana-appindicator3-dev + elif command -v yum >/dev/null 2>&1; then + echo "Using yum to install dependencies..." + sudo yum install -y pkgconfig gtk3-devel libayatana-appindicator-gtk3-devel + elif command -v dnf >/dev/null 2>&1; then + echo "Using dnf to install dependencies..." + sudo dnf install -y pkgconfig gtk3-devel libayatana-appindicator-gtk3-devel + elif command -v pacman >/dev/null 2>&1; then + echo "Using pacman to install dependencies..." + sudo pacman -S --noconfirm pkg-config gtk3 libayatana-appindicator + elif command -v zypper >/dev/null 2>&1; then + echo "Using zypper to install dependencies..." + sudo zypper install -y pkg-config gtk3-devel libayatana-appindicator-devel + else + echo "Could not detect package manager. Please install manually:" + echo "Ubuntu/Debian: sudo apt-get install pkg-config libgtk-3-dev libayatana-appindicator3-dev" + echo "CentOS/RHEL: sudo yum install pkgconfig gtk3-devel libayatana-appindicator-gtk3-devel" + echo "Fedora: sudo dnf install pkgconfig gtk3-devel libayatana-appindicator-gtk3-devel" + echo "Arch: sudo pacman -S pkg-config gtk3 libayatana-appindicator" + echo "openSUSE: sudo zypper install pkg-config gtk3-devel libayatana-appindicator-devel" + exit 1 + fi +fi + +# Verify GTK libraries are available +if ! pkg-config --exists gtk+-3.0; then + echo "Error: GTK 3 development libraries not found." + echo "Please install GTK 3 development packages for your distribution." + exit 1 +fi + +echo "All dependencies satisfied. Building application..." + +# Build the Go application +go build -o headeranalyzer + +if [ $? -eq 0 ]; then + echo "Build successful! Executable: ./headeranalyzer" + echo "Run with: ./headeranalyzer" +else + echo "Build failed!" + exit 1 +fi diff --git a/build-resource.sh b/build-resource.sh index 9426440..da1bfcc 100644 --- a/build-resource.sh +++ b/build-resource.sh @@ -1,4 +1,48 @@ #!/bin/bash +echo "Checking system dependencies..." + +# Check if we're on Linux and need systray dependencies +if [[ "$OSTYPE" == "linux-gnu"* ]]; then + echo "Linux detected - checking systray dependencies..." + + # Check for pkg-config + if ! command -v pkg-config >/dev/null 2>&1; then + echo "Error: pkg-config not found." + echo "Installing required dependencies for systray..." + + # Detect package manager and install dependencies + if command -v apt-get >/dev/null 2>&1; then + echo "Using apt-get to install dependencies..." + sudo apt-get update + sudo apt-get install -y pkg-config libgtk-3-dev libayatana-appindicator3-dev + elif command -v yum >/dev/null 2>&1; then + echo "Using yum to install dependencies..." + sudo yum install -y pkgconfig gtk3-devel libayatana-appindicator-gtk3-devel + elif command -v dnf >/dev/null 2>&1; then + echo "Using dnf to install dependencies..." + sudo dnf install -y pkgconfig gtk3-devel libayatana-appindicator-gtk3-devel + elif command -v pacman >/dev/null 2>&1; then + echo "Using pacman to install dependencies..." + sudo pacman -S --noconfirm pkg-config gtk3 libayatana-appindicator + else + echo "Could not detect package manager. Please install manually:" + echo " - pkg-config" + echo " - GTK 3 development libraries" + echo " - libayatana-appindicator development libraries" + exit 1 + fi + fi + + # Verify GTK libraries are available + if ! pkg-config --exists gtk+-3.0; then + echo "Error: GTK 3 development libraries not found." + echo "Please install GTK 3 development packages for your distribution." + exit 1 + fi + + echo "All Linux systray dependencies are satisfied." +fi + echo "Compiling Windows resource file..." # Check if x86_64-w64-mingw32-windres is available (for cross-compilation) diff --git a/main.go b/main.go index 72189b5..377f2fc 100644 --- a/main.go +++ b/main.go @@ -11,9 +11,12 @@ import ( "io/fs" "log" "net/http" + "os" "os/exec" + "os/signal" "runtime" "strings" + "syscall" "time" "headeranalyzer/parser" @@ -24,8 +27,9 @@ import ( ) var ( - addr = flag.String("host", "127.0.0.1", "IP to bind") - port = flag.Int("port", 5555, "Port to run on") + addr = flag.String("host", "127.0.0.1", "IP to bind") + port = flag.Int("port", 5555, "Port to run on") + headless = flag.Bool("headless", false, "Force headless mode (disable system tray)") ) //go:embed web/* @@ -83,6 +87,43 @@ func openBrowser(url string) { } } +// isHeadless checks if the system is running in a headless environment +func isHeadless() bool { + // Check for common headless indicators + if runtime.GOOS == "windows" { + // On Windows, assume GUI is available + return false + } + + // Check if DISPLAY is set (X11) + if display := os.Getenv("DISPLAY"); display != "" { + return false + } + + // Check if WAYLAND_DISPLAY is set (Wayland) + if waylandDisplay := os.Getenv("WAYLAND_DISPLAY"); waylandDisplay != "" { + return false + } + + // Check if XDG_SESSION_TYPE indicates a graphical session + if sessionType := os.Getenv("XDG_SESSION_TYPE"); sessionType == "x11" || sessionType == "wayland" { + return false + } + + // Check if we're in SSH session + if os.Getenv("SSH_CONNECTION") != "" || os.Getenv("SSH_CLIENT") != "" || os.Getenv("SSH_TTY") != "" { + return true + } + + // Check if TERM indicates we're in a terminal + if term := os.Getenv("TERM"); term == "linux" || strings.Contains(term, "tty") { + return true + } + + // If none of the above, assume headless on Linux/Unix + return runtime.GOOS == "linux" +} + func main() { flag.Parse() @@ -538,10 +579,34 @@ func main() { log.Fatal(srv.ListenAndServe()) }() - systray.Run(func() { onReady(addrPort, shutdownCh) }, func() {}) + // Check if we're in a headless environment + if *headless || isHeadless() { + if *headless { + fmt.Println("Headless mode forced via command line flag.") + } else { + fmt.Println("Headless environment detected. System tray disabled.") + } + fmt.Printf("Access the web interface at: http://%s\n", addrPort) + fmt.Println("Press Ctrl+C to stop the server.") - <-shutdownCh - ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) - defer cancel() - srv.Shutdown(ctx) + // Set up signal handling for graceful shutdown + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) + + // Wait for interrupt signal + <-sigChan + fmt.Println("\nShutting down server...") + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + srv.Shutdown(ctx) + } else { + fmt.Println("GUI environment detected. Starting system tray...") + systray.Run(func() { onReady(addrPort, shutdownCh) }, func() {}) + + <-shutdownCh + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + srv.Shutdown(ctx) + } }