From f03a0755afbb76eab807c118a7f878f87fb13d53 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Fri, 2 Aug 2019 14:53:43 -0600 Subject: [PATCH] list Windows user services --- manager/install.go | 14 +++++ manager/install_windows.go | 110 +++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) diff --git a/manager/install.go b/manager/install.go index e2ad6b2..9970680 100644 --- a/manager/install.go +++ b/manager/install.go @@ -51,6 +51,10 @@ func Stop(conf *service.Service) error { return stop(conf) } +func List(conf *service.Service) ([]string, []string, []error) { + return list(conf) +} + // IsPrivileged returns true if we suspect that the current user (or process) will be able // to write to system folders, bind to privileged ports, and otherwise // successfully run a system service. @@ -67,6 +71,16 @@ func WhereIs(exe string) (string, error) { return filepath.Abs(filepath.ToSlash(exepath)) } +type ManageError struct { + Name string + Hint string + Parent error +} + +func (e *ManageError) Error() string { + return e.Name + ": " + e.Hint + ": " + e.Parent.Error() +} + type ErrDaemonize struct { DaemonArgs []string error string diff --git a/manager/install_windows.go b/manager/install_windows.go index 8e7b1af..7ebfac3 100644 --- a/manager/install_windows.go +++ b/manager/install_windows.go @@ -130,6 +130,38 @@ func stop(conf *service.Service) error { return runner.Stop(conf) } +func list(c *service.Service) ([]string, []string, []error) { + var errs []error + + regs, err := listRegistry(c) + if nil != err { + errs = append(errs, err) + } + + cfgs, errors := listConfigs(c) + if 0 != len(errors) { + errs = append(errs, errors...) + } + + managed := []string{} + for i := range cfgs { + managed = append(managed, cfgs[i].Name) + } + + others := []string{} + for i := range regs { + reg := regs[i] + for j := range cfgs { + cfg := cfgs[j] + if reg != cfg.Title { + others = append(others, reg) + } + } + } + + return managed, others, errs +} + func getRunnerArgs(c *service.Service) []string { self := os.Args[0] debug := "" @@ -154,6 +186,84 @@ func getRunnerArgs(c *service.Service) []string { } } +type winConf struct { + Filename string `json:"-"` + Name string `json:"name"` + Title string `json:"title"` +} + +func listConfigs(c *service.Service) ([]winConf, []error) { + var errs []error + + smdir := `\opt\serviceman` + if !c.System { + smdir = filepath.Join(c.Home, ".local", smdir) + } + confpath := filepath.Join(smdir, `etc`) + + infos, err := ioutil.ReadDir(confpath) + if nil != err { + if os.IsNotExist(err) { + return nil, nil + } + errs = append(errs, &ManageError{ + Name: confpath, + Hint: "Read directory", + Parent: err, + }) + return nil, errs + } + + // TODO report active status + srvs := []winConf{} + for i := range infos { + filename := strings.ToLower(infos[i].Name()) + if len(filename) <= srvLen || !strings.HasSuffix(srvExt, filename) { + continue + } + + name := filename[:len(filename)-srvLen] + b, err := ioutil.ReadFile(filepath.Join(confpath, filename)) + if nil != err { + errs = append(errs, &ManageError{ + Name: name, + Hint: "Read file", + Parent: err, + }) + continue + } + cfg := &winConf{Filename: filename} + err = json.Unmarshal(b, cfg) + if nil != err { + errs = append(errs, &ManageError{ + Name: name, + Hint: "Parse JSON", + Parent: err, + }) + continue + } + + srvs = append(srvs) + } + + return srvs, nil +} + +func listRegistry(c *service.Service) ([]string, error) { + autorunKey := `SOFTWARE\Microsoft\Windows\CurrentVersion\Run` + k, _, err := registry.CreateKey( + registry.CURRENT_USER, + autorunKey, + registry.QUERY_VALUE, + ) + if err != nil { + log.Fatal(err) + } + defer k.Close() + + return k.ReadValueNames(-1) +} + // copies self to install path and returns config path func installServiceman(c *service.Service) ([]string, error) { // TODO check version and upgrade or dismiss