76 lines
1.8 KiB
Go
76 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
mqtt "github.com/eclipse/paho.mqtt.golang"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"time"
|
|
)
|
|
|
|
type Result struct {
|
|
Command string
|
|
Output string
|
|
Error string
|
|
}
|
|
|
|
func main() {
|
|
|
|
var msgchan = make(chan mqtt.Message, 4)
|
|
|
|
if len(os.Args) < 5 {
|
|
log.Fatalf("Usage: %s <broker> <client_id> <username> <password>", os.Args[0])
|
|
}
|
|
opts := mqtt.NewClientOptions()
|
|
opts.AddBroker(os.Args[1])
|
|
opts.SetClientID(os.Args[2])
|
|
opts.SetUsername(os.Args[3])
|
|
opts.SetPassword(os.Args[4])
|
|
opts.SetDefaultPublishHandler(func(client mqtt.Client, msg mqtt.Message) {
|
|
msgchan <- msg
|
|
})
|
|
opts.OnConnect = connectHandler
|
|
opts.SetKeepAlive(20 * time.Second)
|
|
opts.SetAutoReconnect(true)
|
|
opts.SetWill("mqtt2exec/"+os.Args[2]+"/state", "offline", 1, true)
|
|
client := mqtt.NewClient(opts)
|
|
sleep := 1 * time.Second
|
|
for {
|
|
if token := client.Connect(); token.Wait() && token.Error() != nil {
|
|
log.Printf("Initial connection failed: %s", token.Error())
|
|
sleep *= 2
|
|
time.Sleep(sleep)
|
|
} else {
|
|
log.Printf("Connected to broker: %s", os.Args[1])
|
|
break
|
|
}
|
|
}
|
|
for {
|
|
msg := <-msgchan
|
|
if msg.Topic() == "mqtt2exec/"+os.Args[2]+"/run" {
|
|
cmd := exec.Command("/system/xbin/busybox", "ash", "-c", string(msg.Payload()))
|
|
cmd.Stdin = nil
|
|
out, err := cmd.CombinedOutput()
|
|
result := Result{
|
|
Command: string(msg.Payload()),
|
|
Output: string(out),
|
|
}
|
|
if err != nil {
|
|
result.Error = err.Error()
|
|
}
|
|
resultJSON, _ := json.Marshal(result)
|
|
client.Publish("mqtt2exec/"+os.Args[2]+"/result", 0, false, resultJSON)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func connectHandler(c mqtt.Client) {
|
|
token := c.Subscribe("mqtt2exec/"+os.Args[2]+"/run", 2, nil)
|
|
token.Wait()
|
|
if token.Error() != nil {
|
|
log.Printf("mqtt2exec: Error subscribing to topic: %s", token.Error())
|
|
}
|
|
c.Publish("mqtt2exec/"+os.Args[2]+"/state", 1, true, "online")
|
|
}
|