Files
X11Proxy/main.go
2025-08-03 11:32:44 -04:00

132 lines
3.0 KiB
Go

package main
import (
"flag"
"fmt"
"log"
"os"
"strings"
"time"
"x11proxy/x11probe"
)
const version = "0.2"
var (
overrideDisplay = flag.String("display", "", "Override DISPLAY")
overrideSocket = flag.String("proxy-socket", "/tmp/.X11-unix/X5", "Proxy socket path")
showVersion = flag.Bool("version", false, "Show version and exit")
)
func init() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n\n", os.Args[0])
flag.PrintDefaults()
}
}
func main() {
flag.Parse()
if *showVersion {
fmt.Printf("X11Proxy version %s\n", version)
return
}
fmt.Printf("version %s\n", version)
display := os.Getenv("DISPLAY")
if *overrideDisplay != "" {
display = *overrideDisplay
}
if display == "" {
log.Fatalf("No DISPLAY environment variable set and no override provided. Please set DISPLAY or use --display.")
}
connType, target := resolveDisplay(display)
fmt.Printf("Proxying to %s (%s)\n", target, connTypeString(connType))
timeout := 10 * time.Second
status, err := x11probe.ProbeX11Socket(connType, target, timeout)
if err != nil {
log.Fatalf("Connection probe error: %v", err)
}
if status == x11probe.X11TemporarilyUnavailable {
//retry 1x, but change display if :0/:1 assuming wayland dead socket
if display == ":1" && x11probe.CheckDisplay(display) {
log.Printf("is wayland scoket wrong? try :0")
display = ":0"
connType, target = resolveDisplay(display)
fmt.Printf("Proxying to %s (%s)\n", target, connTypeString(connType))
} else {
if display == ":0" && x11probe.CheckDisplay(display) {
log.Printf("is wayland scoket wrong? try :1")
display = ":1"
connType, target = resolveDisplay(display)
fmt.Printf("Proxying to %s (%s)\n", target, connTypeString(connType))
}
}
status, err = x11probe.ProbeX11Socket(connType, target, timeout)
if err != nil {
log.Fatalf("Connection probe error: %v", err)
}
}
switch status {
case x11probe.X11TemporarilyUnavailable:
log.Fatalf("Target connection is temporarily unavalible, is X11 running?")
case x11probe.X11Live:
log.Println("X11 socket is live and accepting connections")
case x11probe.X11AuthRequired:
log.Println("X11 socket is live but requires authentication")
case x11probe.X11Dead:
log.Fatalf("Target connection is dead or unreachable")
}
err2 := StartProxy(*overrideSocket, target, connType, display)
if err2 != nil {
log.Fatalf("Proxy error: %v", err2)
}
}
func connTypeString(t x11probe.ConnType) string {
if t == x11probe.Unix {
return "Unix socket"
}
return "TCP"
}
func hexDump(buf []byte) string {
var out strings.Builder
for i := 0; i < len(buf); i += 16 {
line := fmt.Sprintf("%08x ", i)
for j := 0; j < 16; j++ {
if i+j < len(buf) {
line += fmt.Sprintf("%02x ", buf[i+j])
} else {
line += " "
}
if j == 7 {
line += " "
}
}
line += " |"
for j := 0; j < 16 && i+j < len(buf); j++ {
b := buf[i+j]
if b >= 32 && b <= 126 {
line += string(b)
} else {
line += "."
}
}
line += "|\n"
out.WriteString(line)
}
return out.String()
}