From cca18ac6d3cfda60df6443ecd7f7785280851755 Mon Sep 17 00:00:00 2001 From: "Daniel P. Smith" Date: Mon, 6 Apr 2026 14:47:25 +0000 Subject: [PATCH 1/3] db: uprev godbus and new packege file A simple commit that uprevs godbus to latest version compatible with the go version openxt-go is pinned to in go.mod. It also adds db.go that provides a location to hold the top level package documentation. Place the package global variable PathDelimiter in db.go and document it. Signed-off-by: Daniel P. Smith --- db/db.go | 13 +++++++++++++ go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 db/db.go diff --git a/db/db.go b/db/db.go new file mode 100644 index 0000000..74091b1 --- /dev/null +++ b/db/db.go @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright 2026 Apertus Soutions, LLC +// + +/* +Package db implements an client and server for OpenXT db. +*/ +package db + +// PathDelimiter allows specifying the delimiter used for path element +// separation. +var PathDelimiter string = "/" diff --git a/go.mod b/go.mod index 9de977f..19788df 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,6 @@ module github.com/openxt/openxt-go go 1.12 require ( - github.com/godbus/dbus/v5 v5.0.3 + github.com/godbus/dbus/v5 v5.1.0 github.com/spf13/pflag v1.0.5 ) diff --git a/go.sum b/go.sum index 9ae06e1..74d827f 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,4 @@ -github.com/godbus/dbus/v5 v5.0.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME= -github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= From 050ac2bdf9dcc5e0849d7448f079fd20a9b54e27 Mon Sep 17 00:00:00 2001 From: "Daniel P. Smith" Date: Sun, 8 Mar 2026 15:43:56 -0400 Subject: [PATCH 2/3] db: replace with generated dbus bindings This replaces the existing db client code with the generated dbus bindings. In the process rename the file to client.go to reflect this is the client code. Update dbdcmd to work with the new db client code. Signed-off-by: Daniel P. Smith --- cmd/dbdcmd/main.go | 9 ++- db/client.go | 77 +++++++++++++++++++++++++ db/dbd.go | 137 --------------------------------------------- 3 files changed, 83 insertions(+), 140 deletions(-) create mode 100644 db/client.go delete mode 100644 db/dbd.go diff --git a/cmd/dbdcmd/main.go b/cmd/dbdcmd/main.go index 5f206e7..dda4b28 100644 --- a/cmd/dbdcmd/main.go +++ b/cmd/dbdcmd/main.go @@ -9,6 +9,7 @@ import ( "fmt" "os" + "github.com/godbus/dbus/v5" "github.com/openxt/openxt-go/db" ) @@ -36,11 +37,13 @@ func main() { usage() } - db, err := dbd.NewClient() - + conn, err := dbus.SystemBus() if err != nil { - die("DB connection error: %v", err) + die("Error connecting to system bus: %v\n", err) } + defer conn.Close() + + db := db.NewDbClient(conn, db.DbServiceName, "/") operation := os.Args[1] diff --git a/db/client.go b/db/client.go new file mode 100644 index 0000000..c173a83 --- /dev/null +++ b/db/client.go @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright 2026 Apertus Soutions, LLC +// + +package db + +import ( + "github.com/godbus/dbus/v5" +) + +const DbServiceName = "com.citrix.xenclient.db" + +type DbClient struct { + dbus.BusObject +} + +func NewDbClient(conn *dbus.Conn, dest, path string) *DbClient { + return &DbClient{conn.Object(dest, dbus.ObjectPath(path))} +} + +/* Interface com.citrix.xenclient.db */ +func (d *DbClient) Dump(path string) (value string, err error) { + + err = d.Call("com.citrix.xenclient.db.dump", 0, path).Store(&value) + + return +} + +func (d *DbClient) Exists(path string) (ex bool, err error) { + + err = d.Call("com.citrix.xenclient.db.exists", 0, path).Store(&ex) + + return +} + +func (d *DbClient) Inject(path string, value string) error { + + call := d.Call("com.citrix.xenclient.db.inject", 0, path, value) + + return call.Err +} + +func (d *DbClient) List(path string) (value []string, err error) { + + err = d.Call("com.citrix.xenclient.db.list", 0, path).Store(&value) + + return +} + +func (d *DbClient) Read(path string) (value string, err error) { + + err = d.Call("com.citrix.xenclient.db.read", 0, path).Store(&value) + + return +} + +func (d *DbClient) ReadBinary(path string) (value []byte, err error) { + + err = d.Call("com.citrix.xenclient.db.read_binary", 0, path).Store(&value) + + return +} + +func (d *DbClient) Rm(path string) error { + + call := d.Call("com.citrix.xenclient.db.rm", 0, path) + + return call.Err +} + +func (d *DbClient) Write(path string, value string) error { + + call := d.Call("com.citrix.xenclient.db.write", 0, path, value) + + return call.Err +} diff --git a/db/dbd.go b/db/dbd.go deleted file mode 100644 index c0bdb46..0000000 --- a/db/dbd.go +++ /dev/null @@ -1,137 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// -// Copyright 2026 Apertus Soutions, LLC -// - - -package dbd - -import ( - "github.com/godbus/dbus/v5" -) - -type Client interface { - Read(path string) (string, error) - ReadBinary(path string) ([]byte, error) - Write(path string, value string) error - Dump(path string) (string, error) - Inject(path string, value string) error - List(path string) ([]string, error) - Rm(path string) error - Exists(path string) (bool, error) -} - -type Dbd struct { - conn *dbus.Conn -} - -func NewClient() (Client, error) { - conn, err := dbus.SystemBus() - - if err != nil { - return nil, err - } - return &Dbd{ - conn: conn, - }, nil -} - -// -// -// -// -func (c *Dbd) Read(path string) (string, error) { - obj := c.conn.Object("com.citrix.xenclient.db", "/") - - var s string - err := obj.Call("com.citrix.xenclient.db.read", 0, path).Store(&s) - - return s, err -} - -// -// -// -// -func (c *Dbd) ReadBinary(path string) ([]byte, error) { - obj := c.conn.Object("com.citrix.xenclient.db", "/") - - var b []byte - err := obj.Call("com.citrix.xenclient.db.read_binary", 0, path).Store(&b) - - return b, err -} - -// -// -// -// -func (c *Dbd) Write(path string, value string) error { - obj := c.conn.Object("com.citrix.xenclient.db", "/") - - call := obj.Call("com.citrix.xenclient.db.write", 0, path, value) - - return call.Err -} - -// -// -// -// -func (c *Dbd) Dump(path string) (string, error) { - obj := c.conn.Object("com.citrix.xenclient.db", "/") - - var s string - err := obj.Call("com.citrix.xenclient.db.dump", 0, path).Store(&s) - - return s, err -} - -// -// -// -// -func (c *Dbd) Inject(path string, value string) error { - obj := c.conn.Object("com.citrix.xenclient.db", "/") - - call := obj.Call("com.citrix.xenclient.db.inject", 0, path, value) - - return call.Err -} - -// -// -// -// -func (c *Dbd) List(path string) ([]string, error) { - obj := c.conn.Object("com.citrix.xenclient.db", "/") - - var s []string - err := obj.Call("com.citrix.xenclient.db.list", 0, path).Store(&s) - - return s, err -} - -// -// -// -func (c *Dbd) Rm(path string) error { - obj := c.conn.Object("com.citrix.xenclient.db", "/") - - call := obj.Call("com.citrix.xenclient.db.rm", 0, path) - - return call.Err -} - -// -// -// -// -func (c *Dbd) Exists(path string) (bool, error) { - obj := c.conn.Object("com.citrix.xenclient.db", "/") - - var b bool - err := obj.Call("com.citrix.xenclient.db.read", 0, path).Store(&b) - - return b, err -} From e8550a2fac47e76bcd68dbff0e2360a997e834a3 Mon Sep 17 00:00:00 2001 From: "Daniel P. Smith" Date: Sun, 8 Mar 2026 17:06:34 -0400 Subject: [PATCH 3/3] db-cmd: renaming dbdcmd to db-cmd This aligns the the existing Ocaml db-cmd. While renaming, expand the command to be subcommand compatible with Ocaml db-cmd. Signed-off-by: Daniel P. Smith --- Makefile | 2 +- cmd/db-cmd/main.go | 199 +++++++++++++++++++++++++++++++++++++++++++++ cmd/dbdcmd/main.go | 96 ---------------------- 3 files changed, 200 insertions(+), 97 deletions(-) create mode 100644 cmd/db-cmd/main.go delete mode 100644 cmd/dbdcmd/main.go diff --git a/Makefile b/Makefile index 9eda553..e8c547a 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ bindir = $(exec_prefix)/bin PKGBASE := github.com/openxt/openxt-go PKGS := argo db ioctl -CMDS := argo-nc dbdcmd dbus-send +CMDS := argo-nc db-cmd dbus-send VERSION := 0.1.0 # FIPS is not available until Go 1.24 diff --git a/cmd/db-cmd/main.go b/cmd/db-cmd/main.go new file mode 100644 index 0000000..7f238f4 --- /dev/null +++ b/cmd/db-cmd/main.go @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright 2026 Apertus Soutions, LLC +// + +package main + +import ( + "encoding/binary" + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/godbus/dbus/v5" + argoDbus "github.com/openxt/openxt-go/argo/dbus" + "github.com/openxt/openxt-go/db" + flag "github.com/spf13/pflag" +) + +func die(format string, a ...interface{}) { + fmt.Fprintf(os.Stderr, format, a...) + fmt.Fprintln(os.Stderr) + os.Exit(1) +} + +func usage() { + fmt.Fprintf(os.Stderr, "Usage of %s []:\n", os.Args[0]) + flag.PrintDefaults() + die(` +Available commands are: + cat Dump raw value for + exists Check if exist + ls List tree start at + nodes List immediate childtren of + read Retrieve string value for + rm Delete + write Store for `) +} + +func list(c *db.DbClient, fullPath bool, indent int, path string) (string, error) { + path = strings.TrimRight(path, db.PathDelimiter) + result, err := c.List(path) + if err != nil { + return "", err + } + + var key string + if fullPath { + key = path + } else { + key = strings.Repeat(" ", indent) + if path != "" { + key += filepath.Base(path) + } + } + + if len(result) == 0 { + value, err := c.Read(path) + if err != nil { + return "", fmt.Errorf("failed reading %s: %v\n", path, err) + } + return fmt.Sprintf("%s = \"%s\"", key, value), nil + } + + out := key + " =" + for _, elem := range result { + r, err := list(c, fullPath, indent+1, path+"/"+elem) + if err != nil { + return "", err + } + + out += "\n" + r + } + + return out, nil +} + +func main() { + var conn *dbus.Conn + + helpFlag := flag.BoolP("help", "h", false, "Print help") + fullPathFlag := flag.BoolP("full", "f", false, "Full path") + platBusFlag := flag.BoolP("platform", "p", false, "Connect to the platform bus") + flag.CommandLine.MarkHidden("full") + flag.Parse() + + if *helpFlag { + usage() + } + + if *platBusFlag { + var err error + conn, err = argoDbus.ConnectPlatformBus() + if err != nil { + die("Error connecting to platform bus: %v\n", err) + } + } else { + var err error + conn, err = dbus.SystemBus() + if err != nil { + die("Error connecting to system bus: %v\n", err) + } + } + defer conn.Close() + + args := flag.Args() + if len(args) < 1 { + usage() + } + + client := db.NewDbClient(conn, db.DbServiceName, "/") + + operation := args[0] + + args = args[1:] + arglen := len(args) + + switch operation { + case "cat": + if arglen != 1 { + fmt.Fprintf(os.Stderr, + "Error: incorrect number of arguments.\n") + usage() + } + result, err := client.ReadBinary(args[1]) + if err != nil { + die("DB read binary error: %v", err) + } + binary.Write(os.Stdout, binary.LittleEndian, result) + + case "exists": + if arglen != 1 { + fmt.Fprintf(os.Stderr, + "Error: incorrect number of arguments.\n") + usage() + } + result, err := client.Exists(os.Args[0]) + if err != nil { + die("DB exists error: %v", err) + } + fmt.Printf("%t", result) + case "ls": + path := "/" + if len(args) != 0 { + path = args[0] + } + result, err := list(client, *fullPathFlag, 0, path) + if err != nil { + die("DB list error: %v", err) + } + fmt.Printf("%s\n", result) + + case "nodes": + if arglen != 1 { + fmt.Fprintf(os.Stderr, + "Error: incorrect number of arguments.\n") + usage() + } + result, err := client.List(args[0]) + if err != nil { + die("DB read error: %v", err) + } + fmt.Printf("%s\n", strings.Join(result, " ")) + case "read": + if arglen != 1 { + fmt.Fprintf(os.Stderr, + "Error: incorrect number of arguments.\n") + usage() + } + result, err := client.Read(args[0]) + if err != nil { + die("DB read error: %v", err) + } + fmt.Printf("%s\n", result) + case "rm": + if arglen != 1 { + fmt.Fprintf(os.Stderr, + "Error: incorrect number of arguments.\n") + usage() + } + err := client.Rm(args[0]) + if err != nil { + die("DB rm error: %v", err) + } + case "write": + if arglen != 2 { + fmt.Fprintf(os.Stderr, + "Error: incorrect number of arguments.\n") + usage() + } + err := client.Write(args[0], args[1]) + if err != nil { + die("DB write error: %v", err) + } + default: + usage() + } +} diff --git a/cmd/dbdcmd/main.go b/cmd/dbdcmd/main.go deleted file mode 100644 index dda4b28..0000000 --- a/cmd/dbdcmd/main.go +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// -// Copyright 2026 Apertus Soutions, LLC -// - -package main - -import ( - "fmt" - "os" - - "github.com/godbus/dbus/v5" - "github.com/openxt/openxt-go/db" -) - -func die(format string, a ...interface{}) { - fmt.Fprintf(os.Stderr, format, a...) - fmt.Fprintln(os.Stderr) - os.Exit(1) -} - -func usage() { - die( - `Usage: dbcmd [] - -Available commands are: - read Retrieve from db - write Store for in the db - rm Delete from db - exists Check if exist in the db - help Print this help`) -} - -func main() { - arglen := len(os.Args) - if arglen < 2 { - usage() - } - - conn, err := dbus.SystemBus() - if err != nil { - die("Error connecting to system bus: %v\n", err) - } - defer conn.Close() - - db := db.NewDbClient(conn, db.DbServiceName, "/") - - operation := os.Args[1] - - switch operation { - case "read": - if arglen != 3 { - fmt.Fprintf(os.Stderr, - "Error: incorrect number of arguments.\n") - usage() - } - result, err := db.Read(os.Args[2]) - if err != nil { - die("DB read error: %v", err) - } - fmt.Println(os.Stdout, "%s", result) - case "write": - if arglen != 4 { - fmt.Fprintf(os.Stderr, - "Error: incorrect number of arguments.\n") - usage() - } - err := db.Write(os.Args[2], os.Args[3]) - if err != nil { - die("DB write error: %v", err) - } - case "rm": - if arglen != 3 { - fmt.Fprintf(os.Stderr, - "Error: incorrect number of arguments.\n") - usage() - } - err := db.Rm(os.Args[2]) - if err != nil { - die("DB rm error: %v", err) - } - case "exists": - if arglen != 3 { - fmt.Fprintf(os.Stderr, - "Error: incorrect number of arguments.\n") - usage() - } - result, err := db.Exists(os.Args[2]) - if err != nil { - die("DB exists error: %v", err) - } - fmt.Println(os.Stdout, "%t", result) - default: - usage() - } -}