···11+package main
22+33+import (
44+ "fmt"
55+ "os"
66+ "path"
77+ "slices"
88+ "syscall"
99+)
1010+1111+func getServiceDirs() (serviceDirs []string) {
1212+ if os.Getuid() == 0 {
1313+ serviceDirs = []string{"/etc/dinit.d", "/run/dinit.d", "/usr/local/lib/dinit.d", "/lib/dinit.d"}
1414+ } else {
1515+ if xdg_home, ok := os.LookupEnv("XDG_CONFIG_HOME"); ok {
1616+ serviceDirs = append(serviceDirs, path.Join(xdg_home, "dinit.d"))
1717+ }
1818+ if home, ok := os.LookupEnv("HOME"); ok {
1919+ serviceDirs = append(serviceDirs, path.Join(home, ".config/dinit.d"))
2020+ }
2121+ serviceDirs = slices.Concat(serviceDirs, []string{"/etc/dinit.d/user", "/usr/lib/dinit.d/user", "/usr/local/lib/dinit.d/user"})
2222+ }
2323+ return
2424+}
2525+2626+type Service struct {
2727+ Name string
2828+ Path string
2929+}
3030+3131+func main() {
3232+ dirs := getServiceDirs()
3333+ services := []Service{}
3434+ for _, dir := range dirs {
3535+ entries, err := os.ReadDir(dir)
3636+ if err != nil {
3737+ // missing dir is ok
3838+ if !os.IsNotExist(err) {
3939+ fmt.Println(err)
4040+ }
4141+ } else {
4242+ for _, entry := range entries {
4343+ if entry.Type().IsRegular() {
4444+ name := entry.Name()
4545+ path := path.Join(dir, name)
4646+ services = append(services, Service{
4747+ Name: name,
4848+ Path: path,
4949+ })
5050+ }
5151+ }
5252+ }
5353+ }
5454+5555+ if len(os.Args) < 2 {
5656+ listAll(services)
5757+ } else {
5858+ edit(services, os.Args[1])
5959+ }
6060+}
6161+6262+func listAll(services []Service) {
6363+ longest := 0
6464+ for _, srv := range services {
6565+ longest = max(longest, len(srv.Name))
6666+ }
6767+ for _, srv := range services {
6868+ fmt.Fprintf(os.Stdout, "%-*s%s\n", longest+4, srv.Name, srv.Path)
6969+ }
7070+}
7171+7272+func edit(services []Service, name string) {
7373+ i := slices.IndexFunc(services, func(srv Service) bool { return srv.Name == name })
7474+ if i < 0 {
7575+ fmt.Println("service not found:", name)
7676+ os.Exit(1)
7777+ } else {
7878+ if editor_sh, ok := os.LookupEnv("EDITOR"); ok {
7979+ err := syscall.Exec("/bin/sh", []string{"sh", "-c", editor_sh + " " + services[i].Path}, os.Environ())
8080+ if err != nil {
8181+ fmt.Println(err)
8282+ os.Exit(1)
8383+ }
8484+ }
8585+ }
8686+}
+16-7
readme.md
···2233Please don't have space or other weird characters inside the service file path, since it's passed to `sh -c '$EDITOR $service_file_path'`.
4455-## Building
55+## Usage
66+77+```
88+# list all
99+dinit-edit
1010+# edit one
1111+dinit-edit <service>
1212+```
1313+1414+## Buliding Go implementation
1515+1616+```
1717+go build dinit-edit.go
1818+```
1919+2020+## Building Zig implementatino
621722Use Zig 0.14.1
823···1126install ./main <somewhere>
1227```
13281414-```
1515-# list all
1616-dinit-edit
1717-# edit one
1818-dinit-edit <service>
1919-```