diff options
Diffstat (limited to 'internal/state')
| -rw-r--r-- | internal/state/data.go | 51 | ||||
| -rw-r--r-- | internal/state/exit.go | 73 | ||||
| -rw-r--r-- | internal/state/print.go | 61 | ||||
| -rw-r--r-- | internal/state/register.go | 35 | ||||
| -rw-r--r-- | internal/state/track.go | 64 | ||||
| -rw-r--r-- | internal/state/value.go | 21 |
6 files changed, 73 insertions, 232 deletions
diff --git a/internal/state/data.go b/internal/state/data.go new file mode 100644 index 00000000..65b6395e --- /dev/null +++ b/internal/state/data.go @@ -0,0 +1,51 @@ +package state + +import ( + "encoding/gob" + "os" + "path" +) + +// we unfortunately have to assume there are never races between processes +// this and launcher should eventually be replaced by a server process + +type launcherState struct { + PID int + Launcher string + Argv []string + Command []string + Capability Enablements +} + +func ReadLaunchers(runDirPath, uid string) ([]*launcherState, error) { + var f *os.File + var r []*launcherState + launcherPrefix := path.Join(runDirPath, uid) + + if pl, err := os.ReadDir(launcherPrefix); err != nil { + return nil, err + } else { + for _, e := range pl { + if err = func() error { + if f, err = os.Open(path.Join(launcherPrefix, e.Name())); err != nil { + return err + } else { + defer func() { + if f.Close() != nil { + // unreachable + panic("foreign state file closed prematurely") + } + }() + + var s launcherState + r = append(r, &s) + return gob.NewDecoder(f).Decode(&s) + } + }(); err != nil { + return nil, err + } + } + } + + return r, nil +} diff --git a/internal/state/exit.go b/internal/state/exit.go deleted file mode 100644 index 0eb80a83..00000000 --- a/internal/state/exit.go +++ /dev/null @@ -1,73 +0,0 @@ -package state - -import ( - "errors" - "fmt" - "io/fs" - "os" - - "git.ophivana.moe/cat/fortify/internal/acl" - "git.ophivana.moe/cat/fortify/internal/verbose" - "git.ophivana.moe/cat/fortify/internal/xcb" -) - -func Fatal(msg ...any) { - fmt.Println(msg...) - BeforeExit() - os.Exit(1) -} - -func BeforeExit() { - if u == nil { - fmt.Println("warn: beforeExit called before app init") - return - } - - if statePath == "" { - verbose.Println("State path is unset") - } else { - if err := os.Remove(statePath); err != nil && !errors.Is(err, fs.ErrNotExist) { - fmt.Println("Error removing state file:", err) - } - } - - if d, err := readLaunchers(u.Uid); err != nil { - fmt.Println("Error reading active launchers:", err) - os.Exit(1) - } else if len(d) > 0 { - // other launchers are still active - verbose.Printf("Found %d active launchers, exiting without cleaning up\n", len(d)) - return - } - - verbose.Println("No other launchers active, will clean up") - - if xcbActionComplete { - verbose.Printf("X11: Removing XHost entry SI:localuser:%s\n", u.Username) - if err := xcb.ChangeHosts(xcb.HostModeDelete, xcb.FamilyServerInterpreted, "localuser\x00"+u.Username); err != nil { - fmt.Println("Error removing XHost entry:", err) - } - } - - for _, candidate := range cleanupCandidate { - if err := acl.UpdatePerm(candidate, uid); err != nil { - fmt.Printf("Error stripping ACL entry from '%s': %s\n", candidate, err) - } - verbose.Printf("Stripped ACL entry for user '%s' from '%s'\n", u.Username, candidate) - } - - if dbusProxy != nil { - verbose.Println("D-Bus proxy registered, cleaning up") - - if err := dbusProxy.Close(); err != nil { - if errors.Is(err, os.ErrClosed) { - verbose.Println("D-Bus proxy already closed") - } else { - fmt.Println("Error closing D-Bus proxy:", err) - } - } - - // wait for Proxy.Wait to return - <-*dbusDone - } -} diff --git a/internal/state/print.go b/internal/state/print.go index 0881f199..83912d32 100644 --- a/internal/state/print.go +++ b/internal/state/print.go @@ -1,68 +1,37 @@ package state import ( - "flag" "fmt" "os" "strconv" "strings" "text/tabwriter" - "git.ophivana.moe/cat/fortify/internal/system" "git.ophivana.moe/cat/fortify/internal/verbose" ) -var ( - stateActionEarly bool - stateActionEarlyC bool -) - -func init() { - flag.BoolVar(&stateActionEarly, "state", false, "print state information of active launchers") - flag.BoolVar(&stateActionEarlyC, "state-current", false, "print state information of active launchers for the specified user") -} - -func Early() { - var w *tabwriter.Writer - - switch { - case stateActionEarly: - if runDir, err := os.ReadDir(system.V.RunDir); err != nil { - fmt.Println("Error reading runtime directory:", err) - } else { - for _, e := range runDir { - if !e.IsDir() { - verbose.Println("Skipped non-directory entry", e.Name()) - continue - } - - if _, err = strconv.Atoi(e.Name()); err != nil { - verbose.Println("Skipped non-uid entry", e.Name()) - continue - } +func MustPrintLauncherStateGlobal(w **tabwriter.Writer, runDirPath string) { + if dirs, err := os.ReadDir(runDirPath); err != nil { + fmt.Println("Error reading runtime directory:", err) + } else { + for _, e := range dirs { + if !e.IsDir() { + verbose.Println("Skipped non-directory entry", e.Name()) + continue + } - printLauncherState(e.Name(), &w) + if _, err = strconv.Atoi(e.Name()); err != nil { + verbose.Println("Skipped non-uid entry", e.Name()) + continue } - } - case stateActionEarlyC: - printLauncherState(u.Uid, &w) - default: - return - } - if w != nil { - if err := w.Flush(); err != nil { - fmt.Println("warn: error formatting output:", err) + MustPrintLauncherState(w, runDirPath, e.Name()) } - } else { - fmt.Println("No information available.") } - - os.Exit(0) } -func printLauncherState(uid string, w **tabwriter.Writer) { - launchers, err := readLaunchers(uid) +func MustPrintLauncherState(w **tabwriter.Writer, runDirPath, uid string) { + launchers, err := ReadLaunchers(runDirPath, uid) if err != nil { fmt.Println("Error reading launchers:", err) os.Exit(1) diff --git a/internal/state/register.go b/internal/state/register.go deleted file mode 100644 index be9ce540..00000000 --- a/internal/state/register.go +++ /dev/null @@ -1,35 +0,0 @@ -package state - -import "git.ophivana.moe/cat/fortify/dbus" - -var ( - cleanupCandidate []string - enablements *Enablements - xcbActionComplete bool - - dbusProxy *dbus.Proxy - dbusDone *chan struct{} -) - -func RegisterRevertPath(p string) { - cleanupCandidate = append(cleanupCandidate, p) -} - -func RegisterEnablement(e Enablements) { - if enablements != nil { - panic("enablement state set twice") - } - enablements = &e -} - -func XcbActionComplete() { - if xcbActionComplete { - Fatal("xcb inserted twice") - } - xcbActionComplete = true -} - -func RegisterDBus(p *dbus.Proxy, done *chan struct{}) { - dbusProxy = p - dbusDone = done -} diff --git a/internal/state/track.go b/internal/state/track.go index 198abebf..308be28a 100644 --- a/internal/state/track.go +++ b/internal/state/track.go @@ -8,42 +8,25 @@ import ( "os/exec" "path" "strconv" - - "git.ophivana.moe/cat/fortify/internal/system" -) - -// we unfortunately have to assume there are never races between processes -// this and launcher should eventually be replaced by a server process - -var ( - statePath string ) -type launcherState struct { - PID int - Launcher string - Argv []string - Command []string - Capability Enablements -} - // SaveProcess called after process start, before wait -func SaveProcess(uid string, cmd *exec.Cmd) error { - statePath = path.Join(system.V.RunDir, uid, strconv.Itoa(cmd.Process.Pid)) +func SaveProcess(uid string, cmd *exec.Cmd, runDirPath string, command []string, enablements Enablements) (string, error) { + statePath := path.Join(runDirPath, uid, strconv.Itoa(cmd.Process.Pid)) state := launcherState{ PID: cmd.Process.Pid, Launcher: cmd.Path, Argv: cmd.Args, Command: command, - Capability: *enablements, + Capability: enablements, } - if err := os.Mkdir(path.Join(system.V.RunDir, uid), 0700); err != nil && !errors.Is(err, fs.ErrExist) { - return err + if err := os.Mkdir(path.Join(runDirPath, uid), 0700); err != nil && !errors.Is(err, fs.ErrExist) { + return statePath, err } if f, err := os.OpenFile(statePath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600); err != nil { - return err + return statePath, err } else { defer func() { if f.Close() != nil { @@ -51,39 +34,6 @@ func SaveProcess(uid string, cmd *exec.Cmd) error { panic("state file closed prematurely") } }() - return gob.NewEncoder(f).Encode(state) - } -} - -func readLaunchers(uid string) ([]*launcherState, error) { - var f *os.File - var r []*launcherState - launcherPrefix := path.Join(system.V.RunDir, uid) - - if pl, err := os.ReadDir(launcherPrefix); err != nil { - return nil, err - } else { - for _, e := range pl { - if err = func() error { - if f, err = os.Open(path.Join(launcherPrefix, e.Name())); err != nil { - return err - } else { - defer func() { - if f.Close() != nil { - // unreachable - panic("foreign state file closed prematurely") - } - }() - - var s launcherState - r = append(r, &s) - return gob.NewDecoder(f).Decode(&s) - } - }(); err != nil { - return nil, err - } - } + return statePath, gob.NewEncoder(f).Encode(state) } - - return r, nil } diff --git a/internal/state/value.go b/internal/state/value.go deleted file mode 100644 index cb20818c..00000000 --- a/internal/state/value.go +++ /dev/null @@ -1,21 +0,0 @@ -package state - -import ( - "os/user" -) - -var ( - u *user.User - uid int - command []string -) - -func Set(val user.User, c []string, d int) { - if u != nil { - panic("state set twice") - } - - u = &val - command = c - uid = d -} |
