diff --git a/cmd/ctrld/cli.go b/cmd/ctrld/cli.go index daf672c..a0304da 100644 --- a/cmd/ctrld/cli.go +++ b/cmd/ctrld/cli.go @@ -137,6 +137,7 @@ func initCLI() { if err != nil { mainLog.Fatal().Err(err).Msg("failed create new service") } + s = newService(s) serviceLogger, err := s.Logger(nil) if err != nil { mainLog.Error().Err(err).Msg("failed to get service logger") @@ -310,6 +311,7 @@ func initCLI() { mainLog.Error().Msg(err.Error()) return } + s = newService(s) tasks := []task{ {s.Stop, false}, {s.Uninstall, false}, @@ -371,6 +373,7 @@ func initCLI() { mainLog.Error().Msg(err.Error()) return } + s = newService(s) initLogging() if doTasks([]task{{s.Stop, true}}) { prog.resetDNS() @@ -394,6 +397,7 @@ func initCLI() { mainLog.Error().Msg(err.Error()) return } + s = newService(s) initLogging() if doTasks([]task{{s.Restart, true}}) { mainLog.Notice().Msg("Service restarted") @@ -414,6 +418,7 @@ func initCLI() { mainLog.Error().Msg(err.Error()) return } + s = newService(s) status, err := serviceStatus(s) if err != nil { mainLog.Error().Msg(err.Error()) diff --git a/cmd/ctrld/service.go b/cmd/ctrld/service.go index 43d3261..cc42f8b 100644 --- a/cmd/ctrld/service.go +++ b/cmd/ctrld/service.go @@ -7,8 +7,40 @@ import ( "os/exec" "github.com/kardianos/service" + + "github.com/Control-D-Inc/ctrld/internal/router" ) +func newService(s service.Service) service.Service { + // TODO: unify for other SysV system. + if router.IsGLiNet() { + return &sysV{s} + } + return s +} + +// sysV wraps a service.Service, and provide start/stop/status command +// base on "/etc/init.d/". +// +// Use this on system wherer "service" command is not available, like GL.iNET router. +type sysV struct { + service.Service +} + +func (s *sysV) Start() error { + _, err := exec.Command("/etc/init.d/ctrld", "start").CombinedOutput() + return err +} + +func (s *sysV) Stop() error { + _, err := exec.Command("/etc/init.d/ctrld", "stop").CombinedOutput() + return err +} + +func (s *sysV) Status() (service.Status, error) { + return unixSystemVServiceStatus() +} + type task struct { f func() error abortOnError bool diff --git a/internal/router/openwrt.go b/internal/router/openwrt.go index 97f4628..6e5881d 100644 --- a/internal/router/openwrt.go +++ b/internal/router/openwrt.go @@ -13,6 +13,16 @@ var errUCIEntryNotFound = errors.New("uci: Entry not found") const openwrtDNSMasqConfigPath = "/tmp/dnsmasq.d/ctrld.conf" +// IsGLiNet reports whether the router is an GL.iNet router. +func IsGLiNet() bool { + if Name() != OpenWrt { + return false + } + buf, _ := os.ReadFile("/proc/version") + // The output of /proc/version contains "(glinet@glinet)". + return bytes.Contains(buf, []byte(" (glinet")) +} + func setupOpenWrt() error { // Delete dnsmasq port if set. if _, err := uci("delete", "dhcp.@dnsmasq[0].port"); err != nil && !errors.Is(err, errUCIEntryNotFound) {