diff --git a/main.go b/main.go index 52becdb..d24a8dd 100644 --- a/main.go +++ b/main.go @@ -37,6 +37,8 @@ import ( // ErrPgrepNotFound occurs when pgrep program is not found. var ErrPgrepNotFound = errors.New("pgrep not found") +var ErrNotFound = errors.New("process is not on list") +var ErrIsOnList = errors.New("process is already on list") // Configuration holds a list of process names to be tracked and a listen address. type Configuration struct { @@ -60,6 +62,20 @@ func LoadConfiguration(path string) (conf *Configuration, err error) { return conf, nil } +func StoreConfiguration(path string, conf *Configuration) (err error) { + config, err := json.Marshal(*conf) + if err != nil { + return err + } + + err = ioutil.WriteFile(path, config, 0644) + if err != nil { + return err + } + + return nil +} + // ProcessList is a map of processes' statuses. type ProcessList map[string]bool @@ -113,23 +129,83 @@ func AreProcessesUp(processes *[]string) func(http.ResponseWriter, *http.Request } } -func version() { - fmt.Println("httpprocwatchd ver. 1.0") - fmt.Println("Copyright (c) 2021 Alexander \"Arav\" Andreev ") - fmt.Println("This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.") - fmt.Println("This is free software, and you are welcome to redistribute it") - fmt.Println("under certain conditions; type `show c' for details.") +func AddProcessToList(process string, conf *Configuration, configPath string) error { + for _, v := range conf.Processes { + if v == process { + return ErrIsOnList + } + } + + conf.Processes = append(conf.Processes, process) + if err := StoreConfiguration(configPath, conf); err != nil { + return err + } + + return nil } +func RemoveProcessFromList(process string, conf *Configuration, configPath string) error { + for k, v := range conf.Processes { + if v == process { + copy(conf.Processes[:k], conf.Processes[k+1:]) + + if err := StoreConfiguration(configPath, conf); err != nil { + return err + } + + return nil + } + } + + return ErrNotFound +} + +func ListWatchedProcesses(processes *[]string) { + lastidx := len(*processes) - 1 + for k, v := range *processes { + if k == lastidx { + fmt.Printf("%s\n", v) + } else { + fmt.Printf("%s, ", v) + } + } +} + +func version() { + fmt.Println("httpprocwatchd ver. 1.1") + fmt.Println("Copyright (c) 2021 Alexander \"Arav\" Andreev ") + fmt.Println("License GPLv3+: GNU GPL version 3 or later .") + fmt.Println("This is free software, and you are welcome to change and redistribute it.") + fmt.Println("There is NO WARRANTY, to the extent permitted by law.") +} + +var oConfigPath string +var oShowVersion bool +var oListProcesses bool + +var oAddProcess string +var oRemoveProcess string + func main() { log.SetFlags(0) - configPath := flag.String("config", "processes.json", "path to configuration file") - showVersion := flag.Bool("version", false, "show version") + flag.StringVar(&oConfigPath, "config", "processes.json", "path to configuration file") + flag.StringVar(&oConfigPath, "c", "processes.json", "path to configuration file (shorthand)") + flag.BoolVar(&oShowVersion, "version", false, "show version") + flag.BoolVar(&oShowVersion, "v", false, "show version (shorthand)") + + flag.BoolVar(&oListProcesses, "list", false, "list watched processes") + flag.BoolVar(&oListProcesses, "l", false, "list watched processes (shorthand)") + + flag.StringVar(&oAddProcess, "add", "", "add process to list") + flag.StringVar(&oAddProcess, "a", "", "add process to list (shorthand)") + + flag.StringVar(&oRemoveProcess, "remove", "", "remove process from list") + flag.StringVar(&oRemoveProcess, "r", "", "remove process from list (shorthand)") flag.Parse() - if *showVersion { + if oShowVersion { version() return } @@ -138,11 +214,31 @@ func main() { log.Fatalln(ErrPgrepNotFound) } - conf, err := LoadConfiguration(*configPath) + conf, err := LoadConfiguration(oConfigPath) if err != nil { log.Fatalf("Cannot load configuration file: %s\n", err) } + if oListProcesses { + ListWatchedProcesses(&conf.Processes) + return + } + + if oAddProcess != "" { + err := AddProcessToList(oAddProcess, conf, oConfigPath) + if err != nil { + log.Fatalf("Cannot add process: %s\n", err) + } + return + } + + if oRemoveProcess != "" { + err := RemoveProcessFromList(oRemoveProcess, conf, oConfigPath) + if err != nil { + log.Fatalf("Cannot remove process: %s\n", err) + } + return + } router := http.NewServeMux() router.HandleFunc("/processes", AreProcessesUp(&conf.Processes))