From 9bd46467f5bd8f9cc9bd97758d130430e086e073 Mon Sep 17 00:00:00 2001 From: Manuel Coenen Date: Mon, 9 Dec 2019 12:51:56 +0100 Subject: [PATCH] Rework into arbitrary command exectutor --- README.md | 18 ++++++++---- cmd/eom/execonmcode.go | 35 +++++++++++++++++++++++ executor.go | 65 ++++++++++++++++++++++++++++++++++++++++++ go.mod | 2 +- shutdownsbc.go | 52 --------------------------------- shutdownsbc.service | 2 +- 6 files changed, 115 insertions(+), 59 deletions(-) create mode 100644 cmd/eom/execonmcode.go create mode 100644 executor.go delete mode 100644 shutdownsbc.go diff --git a/README.md b/README.md index 62c9af9..9123ef0 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,17 @@ +# Description +This is a small extension to [DuetSoftwareFramework](https://github.com/christhamm/DuetSoftwareFramework) +to execute arbitrary system commands when a user-defined `M-Code` is encountered. + +An example usage would be to execute system shutdown on the SBC when a e.g. `M7722` is run. + # Usage ``` -$ ./shutdownsbc --help -Usage of ./shutdownsbc: - -shutdownMCode int - Code that will initiate shutdown of the SBC (default 7722) +$ ./execonmcode --help +Usage of ./execonmcode: + -command string + Command to execute + -mCode int + Code that will initiate execution of the command (default 7722) -socketPath string - Path to socket (default "/var/run/duet.sock") + Path to socket (default "/var/run/duet.sock") ``` diff --git a/cmd/eom/execonmcode.go b/cmd/eom/execonmcode.go new file mode 100644 index 0000000..5ff276e --- /dev/null +++ b/cmd/eom/execonmcode.go @@ -0,0 +1,35 @@ +package main + +import ( + "flag" + "log" + + "github.com/wilriker/execonmcode" + "github.com/wilriker/goduetapiclient/connection" +) + +type settings struct { + socketPath string + mCode int64 + command string +} + +func main() { + s := settings{} + + flag.StringVar(&s.socketPath, "socketPath", connection.DefaultSocketPath, "Path to socket") + flag.Int64Var(&s.mCode, "mCode", 7722, "Code that will initiate execution of the command") + flag.StringVar(&s.command, "command", "", "Command to execute") + flag.Parse() + + if s.mCode < 0 { + log.Fatal("--mCode must be >= 0") + } + + if s.command == "" { + log.Fatal("--command must not be empty") + } + + e := execonmcode.NewExecutor(s.socketPath, s.command, s.mCode) + e.Run() +} diff --git a/executor.go b/executor.go new file mode 100644 index 0000000..4c9a081 --- /dev/null +++ b/executor.go @@ -0,0 +1,65 @@ +package execonmcode + +import ( + "log" + "os/exec" + "strings" + + "github.com/wilriker/goduetapiclient/connection" + "github.com/wilriker/goduetapiclient/connection/initmessages" + "github.com/wilriker/goduetapiclient/types" +) + +type Executor struct { + socketPath string + mCode int64 + command string + args []string +} + +func NewExecutor(socketPath, command string, mCode int64) *Executor { + s := strings.Split(command, " ") + a := []string{} + if len(s) > 1 { + a = s[1:] + } + c := s[0] + return &Executor{ + socketPath: socketPath, + command: c, + args: a, + mCode: mCode, + } +} + +func (e *Executor) Run() { + + ic := connection.InterceptConnection{} + err := ic.Connect(initmessages.InterceptionModePre, e.socketPath) + if err != nil { + log.Fatal(err) + } + defer ic.Close() + + for { + c, err := ic.ReceiveCode() + if err != nil { + log.Println("Error:", err) + continue + } + if c.Type == types.MCode && c.MajorNumber != nil && *c.MajorNumber == e.mCode { + cmd := exec.Command(e.command, e.args...) + err := cmd.Run() + if err != nil { + err = ic.ResolveCode(types.Error, err.Error()) + } else { + err = ic.ResolveCode(types.Success, "") + } + if err != nil { + log.Println("Error:", err) + } + } else { + ic.IgnoreCode() + } + } +} diff --git a/go.mod b/go.mod index 2a6923f..75360ed 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/wilriker/dsfext-shutdownsbc +module github.com/wilriker/execonmcode go 1.13 diff --git a/shutdownsbc.go b/shutdownsbc.go deleted file mode 100644 index 26dc571..0000000 --- a/shutdownsbc.go +++ /dev/null @@ -1,52 +0,0 @@ -package main - -import ( - "flag" - "log" - "os/exec" - - "github.com/wilriker/goduetapiclient/connection" - "github.com/wilriker/goduetapiclient/connection/initmessages" - "github.com/wilriker/goduetapiclient/types" -) - -type settings struct { - SocketPath string - ShutdownMCode int64 -} - -func main() { - s := settings{} - - flag.StringVar(&s.SocketPath, "socketPath", connection.DefaultSocketPath, "Path to socket") - flag.Int64Var(&s.ShutdownMCode, "shutdownMCode", 7722, "Code that will initiate shutdown of the SBC") - flag.Parse() - - ic := connection.InterceptConnection{} - err := ic.Connect(initmessages.InterceptionModePre, s.SocketPath) - if err != nil { - panic(err) - } - defer ic.Close() - - for { - c, err := ic.ReceiveCode() - if err != nil { - log.Println("Error:", err) - continue - } - if c.Type == types.MCode && c.MajorNumber != nil && *c.MajorNumber == s.ShutdownMCode { - err = ic.ResolveCode(types.Success, "") - if err != nil { - log.Println("Error:", err) - } - cmd := exec.Command("poweroff") - err := cmd.Run() - if err != nil { - log.Fatal(err) - } - } else { - ic.IgnoreCode() - } - } -} diff --git a/shutdownsbc.service b/shutdownsbc.service index 24b6cdb..4ed02ad 100644 --- a/shutdownsbc.service +++ b/shutdownsbc.service @@ -4,7 +4,7 @@ After=duetcontrolserver.service Requires=duetcontrolserver.service [Service] -ExecStart=/usr/local/bin/shutdownsbc +ExecStart=/usr/local/bin/execonmcode --command "poweroff" Restart=always RestartSec=10