diff options
author | Přemysl Janouch <p@janouch.name> | 2018-09-08 16:54:17 +0200 |
---|---|---|
committer | Přemysl Janouch <p@janouch.name> | 2018-09-08 16:54:17 +0200 |
commit | 3173202cc1e08762c6e156a8fffd23269a5ddb2b (patch) | |
tree | 95c4a06f8384d41b15e9c22afac0a387de79dc51 /nexgb/auth.go | |
parent | 632b3ae494d45755525644fe5d04475c95aae364 (diff) | |
parent | 3906399e7c2a40fbaf355de572cf50a314083f64 (diff) | |
download | haven-3173202cc1e08762c6e156a8fffd23269a5ddb2b.tar.gz haven-3173202cc1e08762c6e156a8fffd23269a5ddb2b.tar.xz haven-3173202cc1e08762c6e156a8fffd23269a5ddb2b.zip |
Merge aarzilli/xgb, branch xcb1.12 as nexgb
History has been linearized and rewritten to stay under the new
subdirectory. I want to make changes incompatible to BurntSushi/xgb.
The history begs for being thrown away entirely because of its quality
and because it doesn't cover the Google period but it is still useful
for copyright tracking.
Diffstat (limited to 'nexgb/auth.go')
-rw-r--r-- | nexgb/auth.go | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/nexgb/auth.go b/nexgb/auth.go new file mode 100644 index 0000000..ec51d10 --- /dev/null +++ b/nexgb/auth.go @@ -0,0 +1,110 @@ +package xgb + +/* +auth.go contains functions to facilitate the parsing of .Xauthority files. + +It is largely unmodified from the original XGB package that I forked. +*/ + +import ( + "encoding/binary" + "errors" + "io" + "os" +) + +// readAuthority reads the X authority file for the DISPLAY. +// If hostname == "" or hostname == "localhost", +// then use the system's hostname (as returned by os.Hostname) instead. +func readAuthority(hostname, display string) ( + name string, data []byte, err error) { + + // b is a scratch buffer to use and should be at least 256 bytes long + // (i.e. it should be able to hold a hostname). + b := make([]byte, 256) + + // As per /usr/include/X11/Xauth.h. + const familyLocal = 256 + const familyWild = 65535 + + if len(hostname) == 0 || hostname == "localhost" { + hostname, err = os.Hostname() + if err != nil { + return "", nil, err + } + } + + fname := os.Getenv("XAUTHORITY") + if len(fname) == 0 { + home := os.Getenv("HOME") + if len(home) == 0 { + err = errors.New("Xauthority not found: $XAUTHORITY, $HOME not set") + return "", nil, err + } + fname = home + "/.Xauthority" + } + + r, err := os.Open(fname) + if err != nil { + return "", nil, err + } + defer r.Close() + + for { + var family uint16 + if err := binary.Read(r, binary.BigEndian, &family); err != nil { + return "", nil, err + } + + addr, err := getString(r, b) + if err != nil { + return "", nil, err + } + + disp, err := getString(r, b) + if err != nil { + return "", nil, err + } + + name0, err := getString(r, b) + if err != nil { + return "", nil, err + } + + data0, err := getBytes(r, b) + if err != nil { + return "", nil, err + } + + addrmatch := (family == familyWild) || + (family == familyLocal && addr == hostname) + dispmatch := (disp == "") || (disp == display) + + if addrmatch && dispmatch { + return name0, data0, nil + } + } + panic("unreachable") +} + +func getBytes(r io.Reader, b []byte) ([]byte, error) { + var n uint16 + if err := binary.Read(r, binary.BigEndian, &n); err != nil { + return nil, err + } else if n > uint16(len(b)) { + return nil, errors.New("bytes too long for buffer") + } + + if _, err := io.ReadFull(r, b[0:n]); err != nil { + return nil, err + } + return b[0:n], nil +} + +func getString(r io.Reader, b []byte) (string, error) { + b, err := getBytes(r, b) + if err != nil { + return "", err + } + return string(b), nil +} |