diff --git a/bpb.json b/bpb.json index b2e4748..a90697c 100644 --- a/bpb.json +++ b/bpb.json @@ -2,14 +2,18 @@ "name": "bndd", "version": "1.0", "description": "The boundaries daemon", - "build": "go build -o package/bndd .", + "build": "go build -o package/bndd . && go build -o package/bnd-send-command ./send-command/main.go", "dependencies": { "build_commands": ["go"] }, "json_file": { "command": { - "run": "./bndd" + "run": "./bndd", + "raw-command": "./bnd-send-command" }, - "bin": "bndd" + "bin": { + "run": "bndd", + "raw-command": "bnd-send-cmd" + } } } diff --git a/send-command/main.go b/send-command/main.go new file mode 100644 index 0000000..90965b9 --- /dev/null +++ b/send-command/main.go @@ -0,0 +1,91 @@ +package main + +import ( + "errors" + "fmt" + "io/fs" + "log" + "net" + "os" + "path/filepath" +) + +func main() { + var cmd string + switch len(os.Args) { + case 2: + cmd = os.Args[1] + case 3: + cmd = os.Args[2] + default: + fmt.Println("send a raw message to bndd.") + fmt.Println("usage: [instance-path] .") + fmt.Println("note: quotes must be escaped.") + fmt.Println("note: this program should not be executed from the shell. Use a CLI wrapper instead.") + os.Exit(1) + } + instance_path, err := get_instance_path() + if err != nil { + log.Fatal(err) + } + ln, err := net.Dial("unix", instance_path+"/boundaries.sock") + if err != nil { + log.Fatal(err) + } + ln.Write([]byte(cmd)) + go func() { + for { + buffer := make([]byte, 1024) + n, err := os.Stdin.Read(buffer) + if err != nil { + log.Fatal(err) + } + ln.Write(buffer[:n]) + } + }() + func() { + for { + buffer := make([]byte, 1024) + n, err := ln.Read(buffer) + if err != nil { + log.Fatal(err) + } + os.Stdout.Write(buffer[:n]) + } + }() +} + +func path_exists(path string) (bool, error) { + _, err := os.Stat(path) + if err == nil { + return true, nil + } + if errors.Is(err, fs.ErrNotExist) { + return false, nil + } + return false, err +} + +func get_instance_path() (string, error) { + if len(os.Args) == 3 { + return filepath.Abs(os.Args[1]) + } + + // When send-command has been started by boundaries, this can be used to get the instance it used + app_dir, has := os.LookupEnv("APP_DIR") + if has { + return filepath.Abs(filepath.Join(app_dir, "..", "..")) + } + + // Fallback to the user-path + home, err := os.UserHomeDir() + if err != nil { + return "", err + } + home_instance_path, err := filepath.Abs(filepath.Join(home, "boundaries")) + if exists, err := path_exists(home_instance_path); exists && err == nil { + return home_instance_path, nil + } + + return "", errors.New("no suitable instance path found") +}