~ knotless Search/
↑↓ move↵ open⇧↵ all results
0
0
main
67 lines · 1.5 KB Raw History
package busdial

import (
	"context"
	"fmt"
	"os"
	"strconv"

	sd "github.com/coreos/go-systemd/v22/dbus"
	"github.com/godbus/dbus/v5"
)

func PrivatePath() string {
	return os.Getenv("XDG_RUNTIME_DIR") + "/systemd/private"
}

func RawPrivate(ctx context.Context, path string) (*dbus.Conn, error) {
	c, err := dbus.Dial("unix:path="+path, dbus.WithContext(ctx))
	if err != nil {
		return nil, err
	}
	if err := c.Auth([]dbus.Auth{dbus.AuthExternal(strconv.Itoa(os.Getuid()))}); err != nil {
		c.Close()
		return nil, err
	}
	return c, nil
}

func RawSession(ctx context.Context, addr string) (*dbus.Conn, error) {
	c, err := dbus.Dial(addr, dbus.WithContext(ctx))
	if err != nil {
		return nil, err
	}
	if err := c.Auth([]dbus.Auth{dbus.AuthExternal(strconv.Itoa(os.Getuid()))}); err != nil {
		c.Close()
		return nil, err
	}
	if err := c.Hello(); err != nil {
		c.Close()
		return nil, err
	}
	return c, nil
}

func Raw(ctx context.Context, mode, path string) (*dbus.Conn, error) {
	switch mode {
	case "private":
		if path == "" {
			path = PrivatePath()
		}
		return RawPrivate(ctx, path)
	case "session":
		addr := os.Getenv("DBUS_SESSION_BUS_ADDRESS")
		if path != "" {
			addr = "unix:path=" + path
		}
		return RawSession(ctx, addr)
	}
	return nil, fmt.Errorf("unknown mode %q", mode)
}

func Systemd(ctx context.Context, mode, path string) (*sd.Conn, error) {
	if mode == "session" && path == "" {
		return sd.NewUserConnectionContext(ctx)
	}
	return sd.NewConnection(func() (*dbus.Conn, error) { return Raw(ctx, mode, path) })
}