From d6f09d7c84a97452463d9e9455afa815a8e02af8 Mon Sep 17 00:00:00 2001 From: kalipso Date: Sat, 28 Oct 2023 11:40:17 +0200 Subject: [PATCH] [triggers/usb] add UsbDisconnect Trigger --- triggers/triggers.go | 1 + triggers/usb.go | 96 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 triggers/usb.go diff --git a/triggers/triggers.go b/triggers/triggers.go index d9794df..be9e56f 100644 --- a/triggers/triggers.go +++ b/triggers/triggers.go @@ -30,6 +30,7 @@ func GetAllTriggers() []DocumentedTrigger { return []DocumentedTrigger{ TimeOut{}, EthernetDisconnect{}, + UsbDisconnect{}, } } diff --git a/triggers/usb.go b/triggers/usb.go new file mode 100644 index 0000000..cb829ce --- /dev/null +++ b/triggers/usb.go @@ -0,0 +1,96 @@ +package triggers + +import ( + "encoding/json" + "errors" + "fmt" + "os" + "time" + + "unknown.com/gokill/actions" + "unknown.com/gokill/internal" +) + +type UsbDisconnect struct { + WaitTillConnected bool `json:"waitTillConnected"` + DeviceName string `json:"deviceName"` + action actions.Action +} + +func isUsbConnected(deviceName string) bool { + devicePath := "/dev/disk/by-id/" + deviceName + + _, err := os.Open(devicePath) + + if errors.Is(err, os.ErrNotExist) { + return false + } + + return true +} + +func (t UsbDisconnect) Listen() { + if t.WaitTillConnected { + for !isUsbConnected(t.DeviceName) { + time.Sleep(1 * time.Second) + } + + fmt.Sprintln("Device %s detected.", t.DeviceName) + fmt.Println("UsbDisconnect Trigger is Armed") + } + + for { + if !isUsbConnected(t.DeviceName) { + break + } + + time.Sleep(1 * time.Second) + } + + actions.Fire(t.action) +} + +func CreateUsbDisconnect(config internal.KillSwitchConfig) (UsbDisconnect, error) { + result := UsbDisconnect{ + WaitTillConnected: true, + } + + err := json.Unmarshal(config.Options, &result) + + if err != nil { + return UsbDisconnect{}, err + } + + if result.DeviceName == "" { + return UsbDisconnect{}, internal.OptionMissingError{"deviceName"} + } + + action, err := actions.NewAction(config.Actions) + + if err != nil { + return UsbDisconnect{}, err + } + + result.action = action + + return result, nil +} + +func (e UsbDisconnect) Create(config internal.KillSwitchConfig) (Trigger, error) { + return CreateUsbDisconnect(config) +} + +func (p UsbDisconnect) GetName() string { + return "UsbDisconnect" +} + +func (p UsbDisconnect) GetDescription() string { + return "Triggers when given usb drive is disconnected" +} + +func (p UsbDisconnect) GetOptions() []internal.ConfigOption { + return []internal.ConfigOption{ + {"waitTillConnected", "bool", "Only trigger when device was connected before", "true"}, + {"deviceId", "string", "Name of device under /dev/disk/by-id/", "\"\""}, + } +}