diff options
Diffstat (limited to 'internal/final')
| -rw-r--r-- | internal/final/exit.go | 73 | ||||
| -rw-r--r-- | internal/final/prepare.go | 20 | ||||
| -rw-r--r-- | internal/final/register.go | 48 |
3 files changed, 141 insertions, 0 deletions
diff --git a/internal/final/exit.go b/internal/final/exit.go new file mode 100644 index 00000000..86cc2e71 --- /dev/null +++ b/internal/final/exit.go @@ -0,0 +1,73 @@ +package final + +import ( + "errors" + "fmt" + "git.ophivana.moe/cat/fortify/internal/acl" + "git.ophivana.moe/cat/fortify/internal/state" + "git.ophivana.moe/cat/fortify/internal/verbose" + "git.ophivana.moe/cat/fortify/internal/xcb" + "io/fs" + "os" +) + +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 := state.ReadLaunchers(runDirPath, 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/final/prepare.go b/internal/final/prepare.go new file mode 100644 index 00000000..859013cf --- /dev/null +++ b/internal/final/prepare.go @@ -0,0 +1,20 @@ +package final + +import "os/user" + +var ( + u *user.User + uid int + + runDirPath string +) + +func Prepare(val user.User, d int, s string) { + if u != nil { + panic("final prepared twice") + } + + u = &val + uid = d + runDirPath = s +} diff --git a/internal/final/register.go b/internal/final/register.go new file mode 100644 index 00000000..16e8d868 --- /dev/null +++ b/internal/final/register.go @@ -0,0 +1,48 @@ +package final + +import ( + "git.ophivana.moe/cat/fortify/dbus" + "git.ophivana.moe/cat/fortify/internal/state" +) + +var ( + cleanupCandidate []string + enablements *state.Enablements + xcbActionComplete bool + + dbusProxy *dbus.Proxy + dbusDone *chan struct{} + + statePath string +) + +func RegisterRevertPath(p string) { + cleanupCandidate = append(cleanupCandidate, p) +} + +func RegisterEnablement(e state.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 +} + +func RegisterStatePath(v string) { + if statePath != "" { + panic("statePath set twice") + } + + statePath = v +} |
