Clean up getting runtime dir on darwin

This commit is contained in:
Kovid Goyal 2023-02-23 07:38:58 +05:30
parent 4d8ccd8e94
commit 1df3ef648c
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -135,20 +135,34 @@ func macos_user_cache_dir() string {
// the algorithm at https://github.com/ydkhatri/MacForensics/blob/master/darwin_path_generator.py
// but I cant find a good way to get the generateduid. Requires calling dscl in which case we might as well call getconf
// The data is in /var/db/dslocal/nodes/Default/users/<username>.plist but it needs root
// So instead we use various hacks to get it quickly, falling back to running /usr/bin/getconf
is_ok := func(m string) bool {
s, err := os.Stat(m)
if err != nil {
return false
}
stat, ok := s.Sys().(unix.Stat_t)
return ok && s.IsDir() && int(stat.Uid) == os.Geteuid() && s.Mode().Perm() == 0o700 && unix.Access(m, unix.X_OK|unix.W_OK|unix.R_OK) == nil
}
if tdir := strings.TrimRight(os.Getenv("TMPDIR"), "/"); filepath.Base(tdir) == "T" {
if m := filepath.Join(filepath.Dir(tdir), "C"); is_ok(m) {
return m
}
}
matches, err := filepath.Glob("/private/var/folders/*/*/C")
if err == nil {
for _, m := range matches {
s, err := os.Stat(m)
if err == nil {
if stat, ok := s.Sys().(unix.Stat_t); ok && s.IsDir() && int(stat.Uid) == os.Geteuid() && s.Mode().Perm() == 0o700 && unix.Access(m, unix.X_OK|unix.W_OK|unix.R_OK) == nil {
return m
}
if is_ok(m) {
return m
}
}
}
out, err := exec.Command("/usr/bin/getconf", "DARWIN_USER_CACHE_DIR").Output()
if err == nil {
return strings.TrimSpace(UnsafeBytesToString(out))
return strings.TrimRight(strings.TrimSpace(UnsafeBytesToString(out)), "/")
}
return ""
}