/* We spend a lot of time constructing these prefixes; we should cache. REW, 7/19/99 */ static CFStringRef _CFPreferencesCachePrefixForUserHost(CFStringRef userName, CFStringRef hostName) { if (userName == kCFPreferencesAnyUser && hostName == kCFPreferencesAnyHost) { return (CFStringRef)CFRetain(CFSTR("*/*/")); } CFMutableStringRef result = CFStringCreateMutable(__CFPreferencesAllocator(), 0); if (userName == kCFPreferencesCurrentUser) { userName = CFGetUserName(); CFStringAppend(result, userName); CFStringAppend(result, CFSTR("/")); } else if (userName == kCFPreferencesAnyUser) { CFStringAppend(result, CFSTR("*/")); } if (hostName == kCFPreferencesCurrentHost) { CFStringRef hostID = _CFPreferencesGetByHostIdentifierString(); CFStringAppend(result, hostID); CFStringAppend(result, CFSTR("/")); } else if (hostName == kCFPreferencesAnyHost) { CFStringAppend(result, CFSTR("*/")); } return result; }
CFURLRef _Nullable _CFKnownLocationCreatePreferencesURLForUser(CFKnownLocationUser user, CFStringRef _Nullable username) { CFURLRef location = NULL; #if (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI) /* Building for a Darwin OS. (We use these paths on Swift builds as well, so that we can interoperate a little with Darwin's defaults(1) command and the other system facilities; but you want to use the system version of CF if possible on those platforms, which will talk to cfprefsd(8) and has stronger interprocess consistency guarantees.) User: - Any: /Library/Preferences - Current: $HOME/Library/Preferences */ switch (user) { case _kCFKnownLocationUserAny: location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, CFSTR("/Library/Preferences"), kCFURLPOSIXPathStyle, true); break; case _kCFKnownLocationUserCurrent: username = NULL; // passthrough to: case _kCFKnownLocationUserByName: { CFURLRef home = CFCopyHomeDirectoryURLForUser(username); location = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, CFSTR("/Library/Preferences"), kCFURLPOSIXPathStyle, true, home); CFRelease(home); break; } } #elif !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS && !DEPLOYMENT_TARGET_ANDROID /* Building for an OS that uses the FHS, BSD's hier(7), and/or the XDG specification for paths: User: - Any: /usr/local/etc/ - Current: $XDG_CONFIG_PATH (usually: $HOME/.config/). */ switch (user) { case _kCFKnownLocationUserAny: location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, CFSTR("/usr/local/etc"), kCFURLPOSIXPathStyle, true); break; case _kCFKnownLocationUserByName: assert(username == NULL); // passthrough to: case _kCFKnownLocationUserCurrent: { CFStringRef path = _CFXDGCreateConfigHomePath(); location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, path, kCFURLPOSIXPathStyle, true); CFRelease(path); break; } } #elif DEPLOYMENT_TARGET_WINDOWS switch (user) { case _kCFKnownLocationUserAny: location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, CFSTR("\\Users\\All Users\\AppData\\Local"), kCFURLWindowsPathStyle, true); break; case _kCFKnownLocationUserCurrent: username = CFGetUserName(); // fallthrough case _kCFKnownLocationUserByName: const char *user = CFStringGetCStringPtr(username, kCFStringEncodingUTF8); CFURLRef userdir = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (const unsigned char *)user, strlen(user), true); CFURLRef homedir = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, CFSTR("\\Users"), kCFURLWindowsPathStyle, true, userdir); location = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, CFSTR("\\AppData\\Local"), kCFURLWindowsPathStyle, true, homedir); CFRelease(homedir); CFRelease(userdir); break; } #else #error For this platform, you need to define a preferences path for both 'any user' (i.e. installation-wide preferences) or the current user. #endif return location; }