diff --git a/custom/command_server.go b/custom/command_server.go index b2d9a8d..de28e87 100644 --- a/custom/command_server.go +++ b/custom/command_server.go @@ -7,7 +7,16 @@ var commandServer *libbox.CommandServer type CommandServerHandler struct{} func (csh *CommandServerHandler) ServiceReload() error { - return nil + propagateStatus(Starting) + if commandServer != nil { + commandServer.SetService(nil) + commandServer = nil + } + if box != nil { + box.Close() + box = nil + } + return startService() } func (csh *CommandServerHandler) GetSystemProxyStatus() *libbox.SystemProxyStatus { diff --git a/custom/constant.go b/custom/constant.go new file mode 100644 index 0000000..a0a65a2 --- /dev/null +++ b/custom/constant.go @@ -0,0 +1,15 @@ +package main + +const ( + Stopped = "Stopped" + Starting = "Starting" + Started = "Started" + Stopping = "Stopping" +) + +const ( + EmptyConfiguration = "EmptyConfiguration" + StartCommandServer = "StartCommandServer" + CreateService = "CreateService" + StartService = "StartService" +) diff --git a/custom/custom.go b/custom/custom.go index e3b86a6..32f12c6 100644 --- a/custom/custom.go +++ b/custom/custom.go @@ -16,6 +16,7 @@ import ( var box *libbox.BoxService var configOptions *shared.ConfigOptions +var activeConfigPath *string //export setupOnce func setupOnce(api unsafe.Pointer) { @@ -23,8 +24,9 @@ func setupOnce(api unsafe.Pointer) { } //export setup -func setup(baseDir *C.char, workingDir *C.char, tempDir *C.char) { +func setup(baseDir *C.char, workingDir *C.char, tempDir *C.char, statusPort C.longlong) { Setup(C.GoString(baseDir), C.GoString(workingDir), C.GoString(tempDir)) + statusPropagationPort = int64(statusPort) } //export parse @@ -46,16 +48,30 @@ func changeConfigOptions(configOptionsJson *C.char) *C.char { return C.CString("") } -//export create -func create(configPath *C.char) *C.char { +//export start +func start(configPath *C.char) *C.char { + if status != Stopped { + return C.CString("") + } + propagateStatus(Starting) + path := C.GoString(configPath) - content, err := os.ReadFile(path) + activeConfigPath = &path + err := startService() if err != nil { return C.CString(err.Error()) } + return C.CString("") +} + +func startService() error { + content, err := os.ReadFile(*activeConfigPath) + if err != nil { + return stopAndAlert(EmptyConfiguration, err) + } options, err := parseConfig(string(content)) if err != nil { - return C.CString(err.Error()) + return stopAndAlert(EmptyConfiguration, err) } options = shared.BuildConfig(*configOptions, options) @@ -63,45 +79,33 @@ func create(configPath *C.char) *C.char { err = startCommandServer() if err != nil { - return C.CString(err.Error()) + return stopAndAlert(StartCommandServer, err) } instance, err := NewService(options) if err != nil { - return C.CString(err.Error()) + return stopAndAlert(CreateService, err) + } + err = instance.Start() + if err != nil { + return stopAndAlert(StartService, err) } box = instance - commandServer.SetService(box) - if err != nil { - instance.Close() - box = nil - return C.CString(err.Error()) - } - - return C.CString("") -} - -//export start -func start() *C.char { - if box == nil { - return C.CString("instance not found") - } - - err := box.Start() - if err != nil { - return C.CString(err.Error()) - } - - return C.CString("") + propagateStatus(Started) + return nil } //export stop func stop() *C.char { + if status != Started { + return C.CString("") + } if box == nil { return C.CString("instance not found") } + propagateStatus(Stopping) commandServer.SetService(nil) err := box.Close() @@ -115,6 +119,28 @@ func stop() *C.char { return C.CString(err.Error()) } commandServer = nil + propagateStatus(Stopped) + + return C.CString("") +} + +//export restart +func restart(configPath *C.char) *C.char { + if status != Started { + return C.CString("") + } + if box == nil { + return C.CString("instance not found") + } + + err := stop() + if C.GoString(err) != "" { + return err + } + err = start(configPath) + if C.GoString(err) != "" { + return err + } return C.CString("") } diff --git a/custom/status.go b/custom/status.go new file mode 100644 index 0000000..08c14bf --- /dev/null +++ b/custom/status.go @@ -0,0 +1,33 @@ +package main + +import "C" +import ( + "encoding/json" + + "github.com/hiddify/libcore/bridge" +) + +var statusPropagationPort int64 +var status = Stopped + +type StatusMessage struct { + Status string `json:"status"` + Alert *string `json:"alert"` + Message *string `json:"message"` +} + +func propagateStatus(newStatus string) { + status = newStatus + + msg, _ := json.Marshal(StatusMessage{Status: status}) + bridge.SendStringToPort(statusPropagationPort, string(msg)) +} + +func stopAndAlert(alert string, err error) error { + status = Stopped + message := err.Error() + + msg, _ := json.Marshal(StatusMessage{Status: status, Alert: &alert, Message: &message}) + bridge.SendStringToPort(statusPropagationPort, string(msg)) + return err +}