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() }