// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//


/*	CFPreferences.c
	Copyright (c) 1998 - 2015 Apple Inc. and the Swift project authors
	Responsibility: David Smith
*/

#include <CoreFoundation/CFPreferences.h>
#include <CoreFoundation/CFURLAccess.h>
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
#include <CoreFoundation/CFUserNotification.h>
#endif
#include <CoreFoundation/CFPropertyList.h>
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
#include <CoreFoundation/CFBundle.h>
#endif
#include <CoreFoundation/CFNumber.h>
#include <CoreFoundation/CFPriv.h>
#include "CFInternal.h"
#include <sys/stat.h>
#if DEPLOYMENT_TARGET_MACOSX
#include <unistd.h>
#include <CoreFoundation/CFUUID.h>
#endif

#if DEBUG_PREFERENCES_MEMORY
#include "../Tests/CFCountingAllocator.c"
#endif

static CFURLRef _CFPreferencesURLForStandardDomainWithSafetyLevel(CFStringRef domainName, CFStringRef userName, CFStringRef hostName, unsigned long safeLevel);

struct __CFPreferencesDomain {
    CFRuntimeBase _base;
    /* WARNING - not copying the callbacks; we know they are always static structs */
    const _CFPreferencesDomainCallBacks *_callBacks;
    CFTypeRef _context;
    void *_domain;
};

CONST_STRING_DECL(kCFPreferencesAnyApplication, "kCFPreferencesAnyApplication")
CONST_STRING_DECL(kCFPreferencesAnyHost, "kCFPreferencesAnyHost")
CONST_STRING_DECL(kCFPreferencesAnyUser, "kCFPreferencesAnyUser")
CONST_STRING_DECL(kCFPreferencesCurrentApplication, "kCFPreferencesCurrentApplication")
CONST_STRING_DECL(kCFPreferencesCurrentHost, "kCFPreferencesCurrentHost")
CONST_STRING_DECL(kCFPreferencesCurrentUser, "kCFPreferencesCurrentUser")


static CFAllocatorRef _preferencesAllocator = NULL;
CF_PRIVATE CFAllocatorRef __CFPreferencesAllocator(void) {
    if (!_preferencesAllocator) {
#if DEBUG_PREFERENCES_MEMORY
        _preferencesAllocator = CFCountingAllocatorCreate(NULL);
#else
        _preferencesAllocator = __CFGetDefaultAllocator();
        CFRetain(_preferencesAllocator);
#endif
    }
    return _preferencesAllocator;
}

// declaration for telling the 
void _CFApplicationPreferencesDomainHasChanged(CFPreferencesDomainRef);

#if DEBUG_PREFERENCES_MEMORY
#warning Preferences debugging on
CF_EXPORT void CFPreferencesDumpMem(void) {
    if (_preferencesAllocator) {
//        CFCountingAllocatorPrintSummary(_preferencesAllocator);
        CFCountingAllocatorPrintPointers(_preferencesAllocator);
    }
//    CFCountingAllocatorReset(_preferencesAllocator);
}
#endif

#if DEPLOYMENT_TARGET_MACOSX
#pragma mark -
#pragma mark Determining host UUID
#endif

#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
// The entry point is in libSystem.B.dylib, but not actually declared
// If this becomes available in a header (<rdar://problem/4943036>), I need to pull this out
int gethostuuid(unsigned char *uuid_buf, const struct timespec *timeoutp);

CF_PRIVATE CFStringRef _CFGetHostUUIDString(void) {
    static CFStringRef __hostUUIDString = NULL;
    
    if (!__hostUUIDString) {
        CFUUIDBytes uuidBytes;
        int getuuidErr = 0;
        struct timespec timeout = {0, 0};   // Infinite timeout for gethostuuid()
        
        getuuidErr = gethostuuid((unsigned char *)&uuidBytes, &timeout);
        if (getuuidErr == -1) {
            // An error has occurred trying to get the host UUID string. There's nothing we can do here, so we should just return NULL.
            CFLog(kCFLogLevelWarning, CFSTR("_CFGetHostUUIDString: unable to determine UUID for host. Error: %d"), errno);
            return NULL;
        }
        
        CFUUIDRef uuidRef = CFUUIDCreateFromUUIDBytes(kCFAllocatorSystemDefault, uuidBytes);
        CFStringRef uuidAsString = CFUUIDCreateString(kCFAllocatorSystemDefault, uuidRef);
        
        if (!OSAtomicCompareAndSwapPtrBarrier(NULL, (void *)uuidAsString, (void *)&__hostUUIDString)) {
            CFRelease(uuidAsString);    // someone else made the assignment, so just release the extra string.
        }
        
        CFRelease(uuidRef);
    }
    
    return __hostUUIDString;
}

CF_PRIVATE CFStringRef _CFPreferencesGetByHostIdentifierString(void) {
    static CFStringRef __byHostIdentifierString = NULL;

    if (!__byHostIdentifierString) {
        CFStringRef hostID = _CFGetHostUUIDString();
        if (hostID) {
            if (CFStringHasPrefix(hostID, CFSTR("00000000-0000-1000-8000-"))) {
                // If the host UUID is prefixed by "00000000-0000-1000-8000-" then the UUID returned is the "compatible" type. The last field of the string will be the MAC address of the primary ethernet interface of the computer. We use this for compatibility with existing by-host preferences.
                CFStringRef lastField = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, hostID, CFRangeMake(24, 12));
                CFMutableStringRef tmpstr = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, lastField);
                CFStringLowercase(tmpstr, NULL);
                CFStringRef downcasedField = CFStringCreateCopy(kCFAllocatorSystemDefault, tmpstr);
                
                if (!OSAtomicCompareAndSwapPtrBarrier(NULL, (void *)downcasedField, (void *)&__byHostIdentifierString)) {
                    CFRelease(downcasedField);
                }
                
                CFRelease(tmpstr);
                CFRelease(lastField);
            } else {
                // The host UUID is a full UUID, and we should just use that. This doesn't involve any additional string creation, so we should just be able to do the assignment.
                __byHostIdentifierString = hostID;
            }
        } else {
            __byHostIdentifierString = CFSTR("UnknownHostID");
        }
    }
    
    return __byHostIdentifierString;
}

#else

CF_PRIVATE CFStringRef _CFPreferencesGetByHostIdentifierString(void) {
    return CFSTR("");
}

#endif


static unsigned long __CFSafeLaunchLevel = 0;

#if DEPLOYMENT_TARGET_WINDOWS
#include <shfolder.h>

#endif

static CFURLRef _preferencesDirectoryForUserHostSafetyLevel(CFStringRef userName, CFStringRef hostName, unsigned long safeLevel) {
    CFAllocatorRef alloc = __CFPreferencesAllocator();
#if DEPLOYMENT_TARGET_WINDOWS

	CFURLRef url = NULL;

	CFMutableStringRef completePath = _CFCreateApplicationRepositoryPath(alloc, CSIDL_APPDATA);
 	if (completePath) {
	    // append "Preferences\" and make the CFURL
	    CFStringAppend(completePath, CFSTR("Preferences\\"));
		url = CFURLCreateWithFileSystemPath(alloc, completePath, kCFURLWindowsPathStyle, true);
		CFRelease(completePath);
	}


	// Can't find a better place?  Home directory then?
	if (url == NULL)
		url = CFCopyHomeDirectoryURLForUser((userName == kCFPreferencesCurrentUser) ? NULL : userName);

	return url;
 
#else
    CFURLRef  home = NULL;
    CFURLRef  url;
    int levels = 0;
    //    if (hostName != kCFPreferencesCurrentHost && hostName != kCFPreferencesAnyHost) return NULL; // Arbitrary host access not permitted
    if (userName == kCFPreferencesAnyUser) {
        if (!home) home = CFURLCreateWithFileSystemPath(alloc, CFSTR("/Library/Preferences/"), kCFURLPOSIXPathStyle, true);
        levels = 1;
        if (hostName == kCFPreferencesCurrentHost) url = home;
        else {
            url = CFURLCreateWithFileSystemPathRelativeToBase(alloc, CFSTR("Network/"), kCFURLPOSIXPathStyle, true, home);
            levels ++;
            CFRelease(home);
        }
    } else {
        home = CFCopyHomeDirectoryURLForUser((userName == kCFPreferencesCurrentUser) ? NULL : userName);
        if (home) {
            url = (safeLevel > 0) ? CFURLCreateWithFileSystemPathRelativeToBase(alloc, CFSTR("Library/Safe Preferences/"), kCFURLPOSIXPathStyle, true, home) :
            CFURLCreateWithFileSystemPathRelativeToBase(alloc, CFSTR("Library/Preferences/"), kCFURLPOSIXPathStyle, true, home);
            levels = 2;
            CFRelease(home);
            if (hostName != kCFPreferencesAnyHost) {
                home = url;
                url = CFURLCreateWithFileSystemPathRelativeToBase(alloc, CFSTR("ByHost/"), kCFURLPOSIXPathStyle, true, home);
                levels ++;
                CFRelease(home);
            }
        } else {
            url = NULL;
        }
    }
    return url;
#endif
}

static CFURLRef  _preferencesDirectoryForUserHost(CFStringRef  userName, CFStringRef  hostName) {
    return _preferencesDirectoryForUserHostSafetyLevel(userName, hostName, __CFSafeLaunchLevel);
}

static Boolean __CFPreferencesWritesXML = true;

Boolean __CFPreferencesShouldWriteXML(void) {
    return __CFPreferencesWritesXML;
}

static CFLock_t domainCacheLock = CFLockInit;
static CFMutableDictionaryRef  domainCache = NULL; // mutable

// Public API

CFTypeRef  CFPreferencesCopyValue(CFStringRef  key, CFStringRef  appName, CFStringRef  user, CFStringRef  host) {
    CFPreferencesDomainRef domain;
    CFAssert(appName != NULL && user != NULL && host != NULL, __kCFLogAssertion, "%s(): Cannot access preferences for a NULL application name, user, or host", __PRETTY_FUNCTION__);
    CFAssert(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);
    
    domain = _CFPreferencesStandardDomain(appName, user, host);
    if (domain) {
        return _CFPreferencesDomainCreateValueForKey(domain, key);
    } else {
        return NULL;
    }
}

CFDictionaryRef CFPreferencesCopyMultiple(CFArrayRef keysToFetch, CFStringRef appName, CFStringRef user, CFStringRef host) {
    CFPreferencesDomainRef domain;
    CFMutableDictionaryRef result;
    CFIndex idx, count;

    CFAssert(appName != NULL && user != NULL && host != NULL, __kCFLogAssertion, "%s(): Cannot access preferences for a NULL application name, user, or host", __PRETTY_FUNCTION__);
    __CFGenericValidateType(appName, CFStringGetTypeID());
    __CFGenericValidateType(user, CFStringGetTypeID());
    __CFGenericValidateType(host, CFStringGetTypeID());

    domain = _CFPreferencesStandardDomain(appName, user, host);
    if (!domain) return NULL;
    if (!keysToFetch) {
        return _CFPreferencesDomainDeepCopyDictionary(domain);
    } else {
        __CFGenericValidateType(keysToFetch, CFArrayGetTypeID());
        count = CFArrayGetCount(keysToFetch);
        result = CFDictionaryCreateMutable(CFGetAllocator(domain), count, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        if (!result) return NULL;
        for (idx = 0; idx < count; idx ++) {
            CFStringRef key = (CFStringRef)CFArrayGetValueAtIndex(keysToFetch, idx);
            CFPropertyListRef value;
            __CFGenericValidateType(key, CFStringGetTypeID());
            value = _CFPreferencesDomainCreateValueForKey(domain, key);
            if (value) {
                CFDictionarySetValue(result, key, value);
                CFRelease(value);
            }
        }
    }
    return result;
}

void CFPreferencesSetValue(CFStringRef  key, CFTypeRef  value, CFStringRef  appName, CFStringRef  user, CFStringRef  host) {
    CFPreferencesDomainRef domain;
    CFAssert(appName != NULL && user != NULL && host != NULL, __kCFLogAssertion, "%s(): Cannot access preferences for a NULL application name, user, or host", __PRETTY_FUNCTION__);
    CFAssert(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);

    domain = _CFPreferencesStandardDomain(appName, user, host);
    if (domain) {
        _CFPreferencesDomainSet(domain, key, value);
        _CFApplicationPreferencesDomainHasChanged(domain);
    }
}


void CFPreferencesSetMultiple(CFDictionaryRef keysToSet, CFArrayRef keysToRemove, CFStringRef appName, CFStringRef user, CFStringRef host) {
    CFPreferencesDomainRef domain;
    CFIndex idx, count;
    CFAssert(appName != NULL && user != NULL && host != NULL, __kCFLogAssertion, "%s(): Cannot access preferences for a NULL application name, user, or host", __PRETTY_FUNCTION__);
    if (keysToSet) __CFGenericValidateType(keysToSet, CFDictionaryGetTypeID());
    if (keysToRemove) __CFGenericValidateType(keysToRemove, CFArrayGetTypeID());
    __CFGenericValidateType(appName, CFStringGetTypeID());
    __CFGenericValidateType(user, CFStringGetTypeID());
    __CFGenericValidateType(host, CFStringGetTypeID());

    CFTypeRef *keys = NULL;
    CFTypeRef *values;
    CFIndex numOfKeysToSet = 0;
    
    domain = _CFPreferencesStandardDomain(appName, user, host);
    if (!domain) return;

    CFAllocatorRef alloc = CFGetAllocator(domain);
    
    if (keysToSet && (count = CFDictionaryGetCount(keysToSet))) {
        numOfKeysToSet = count;
        keys = (CFTypeRef *)CFAllocatorAllocate(alloc, 2*count*sizeof(CFTypeRef), 0);
        if (keys) {
            values = &(keys[count]);
            CFDictionaryGetKeysAndValues(keysToSet, keys, values);
            for (idx = 0; idx < count; idx ++) {
                _CFPreferencesDomainSet(domain, (CFStringRef)keys[idx], values[idx]);
            }
        }
    }
    if (keysToRemove && (count = CFArrayGetCount(keysToRemove))) {
        for (idx = 0; idx < count; idx ++) {
            CFStringRef removedKey = (CFStringRef)CFArrayGetValueAtIndex(keysToRemove, idx);
            _CFPreferencesDomainSet(domain, removedKey, NULL);
        }
    }


    _CFApplicationPreferencesDomainHasChanged(domain);
    
    if(keys) CFAllocatorDeallocate(alloc, keys);
}

Boolean CFPreferencesSynchronize(CFStringRef  appName, CFStringRef  user, CFStringRef  host) {
    CFPreferencesDomainRef domain;
    CFAssert(appName != NULL && user != NULL && host != NULL, __kCFLogAssertion, "%s(): Cannot access preferences for a NULL application name, user, or host", __PRETTY_FUNCTION__);

    domain = _CFPreferencesStandardDomain(appName, user, host);
    if(domain) _CFApplicationPreferencesDomainHasChanged(domain);
    
    return domain ? _CFPreferencesDomainSynchronize(domain) : false;
}

CFArrayRef  CFPreferencesCopyApplicationList(CFStringRef  user, CFStringRef  host) {
    CFArrayRef  array;
    CFAssert(user != NULL && host != NULL, __kCFLogAssertion, "%s(): Cannot access preferences for a NULL user or host", __PRETTY_FUNCTION__);
    array = _CFPreferencesCreateDomainList(user, host);
    return array;
}

CFArrayRef  CFPreferencesCopyKeyList(CFStringRef  appName, CFStringRef  user, CFStringRef  host) {
    CFPreferencesDomainRef domain;
    CFAssert(appName != NULL && user != NULL && host != NULL, __kCFLogAssertion, "%s(): Cannot access preferences for a NULL application name, user, or host", __PRETTY_FUNCTION__);

    domain = _CFPreferencesStandardDomain(appName, user, host);
    if (!domain) {
        return NULL;
    } else {
        CFArrayRef  result;

	CFAllocatorRef alloc = __CFPreferencesAllocator();
	CFDictionaryRef d = _CFPreferencesDomainDeepCopyDictionary(domain);
	CFIndex count = d ? CFDictionaryGetCount(d) : 0;
	CFTypeRef *keys = (CFTypeRef *)CFAllocatorAllocate(alloc, count * sizeof(CFTypeRef), 0);
	if (d) CFDictionaryGetKeysAndValues(d, keys, NULL);
        if (count == 0) {
            result = NULL;
        } else {
            result = CFArrayCreate(alloc, keys, count, &kCFTypeArrayCallBacks);
        }
	CFAllocatorDeallocate(alloc, keys);
	if (d) CFRelease(d);
        return result;
    }
}


/****************************/
/*  CFPreferencesDomain     */
/****************************/

static CFStringRef __CFPreferencesDomainCopyDescription(CFTypeRef cf) {
    return CFStringCreateWithFormat(__CFPreferencesAllocator(), NULL, CFSTR("<Private CFType %p>\n"), cf);
}

static void __CFPreferencesDomainDeallocate(CFTypeRef cf) {
    const struct __CFPreferencesDomain *domain = (struct __CFPreferencesDomain *)cf;
    CFAllocatorRef alloc = __CFPreferencesAllocator();
    domain->_callBacks->freeDomain(alloc, domain->_context, domain->_domain);
    if (domain->_context) CFRelease(domain->_context);
}

static CFTypeID __kCFPreferencesDomainTypeID = _kCFRuntimeNotATypeID;

static const CFRuntimeClass __CFPreferencesDomainClass = {
    0,
    "CFPreferencesDomain",
    NULL,      // init
    NULL,      // copy
    __CFPreferencesDomainDeallocate,
    NULL,
    NULL,
    NULL,      // 
    __CFPreferencesDomainCopyDescription
};

/* 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 = CFCopyUserName();
        CFStringAppend(result, userName);
        CFRelease(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;
}

// It would be nice if we could remember the key for "well-known" combinations, so we're not constantly allocing more strings....  - REW 2/3/99
static CFStringRef  _CFPreferencesStandardDomainCacheKey(CFStringRef  domainName, CFStringRef  userName, CFStringRef  hostName) {
    CFStringRef  prefix = _CFPreferencesCachePrefixForUserHost(userName, hostName);
    CFStringRef  result = NULL;
    
    if (prefix) {
        result = CFStringCreateWithFormat(__CFPreferencesAllocator(), NULL, CFSTR("%@%@"), prefix, domainName);
        CFRelease(prefix);
    }
    return result;
}

static CFURLRef _CFPreferencesURLForStandardDomainWithSafetyLevel(CFStringRef domainName, CFStringRef userName, CFStringRef hostName, unsigned long safeLevel) {
    CFURLRef theURL = NULL;
    CFAllocatorRef prefAlloc = __CFPreferencesAllocator();
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS
    CFURLRef prefDir = _preferencesDirectoryForUserHostSafetyLevel(userName, hostName, safeLevel);
    CFStringRef  appName;
    CFStringRef  fileName;
    Boolean mustFreeAppName = false;
    
    if (!prefDir) return NULL;
    if (domainName == kCFPreferencesAnyApplication) {
        appName = CFSTR(".GlobalPreferences");
    } else if (domainName == kCFPreferencesCurrentApplication) {
        CFBundleRef mainBundle = CFBundleGetMainBundle();
        appName = mainBundle ? CFBundleGetIdentifier(mainBundle) : NULL;
        if (!appName || CFStringGetLength(appName) == 0) {
            appName = _CFProcessNameString();
        }
    } else {
        appName = domainName;
    }
    if (userName != kCFPreferencesAnyUser) {
        if (hostName == kCFPreferencesAnyHost) {
            fileName = CFStringCreateWithFormat(prefAlloc, NULL, CFSTR("%@.plist"), appName);
        } else if (hostName == kCFPreferencesCurrentHost) {
            CFStringRef hostID = _CFPreferencesGetByHostIdentifierString();
            fileName = CFStringCreateWithFormat(prefAlloc, NULL, CFSTR("%@.%@.plist"), appName, hostID);
        } else {
            fileName = CFStringCreateWithFormat(prefAlloc, NULL, CFSTR("%@.%@.plist"), appName, hostName);      // sketchy - this allows someone to set an arbitrary hostname.
        }
    } else {
        fileName = CFStringCreateWithFormat(prefAlloc, NULL, CFSTR("%@.plist"), appName);
    }
    if (mustFreeAppName) {
	CFRelease(appName);
    }
    if (fileName) {
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
        theURL = CFURLCreateWithFileSystemPathRelativeToBase(prefAlloc, fileName, kCFURLPOSIXPathStyle, false, prefDir);
#elif DEPLOYMENT_TARGET_WINDOWS
		theURL = CFURLCreateWithFileSystemPathRelativeToBase(prefAlloc, fileName, kCFURLWindowsPathStyle, false, prefDir);
#endif
        if (prefDir) CFRelease(prefDir);
        CFRelease(fileName);
    }
#else
//#error Do not know where to store NSUserDefaults on this platform
#endif
    return theURL;
}

static CFURLRef _CFPreferencesURLForStandardDomain(CFStringRef domainName, CFStringRef userName, CFStringRef hostName) {
    return _CFPreferencesURLForStandardDomainWithSafetyLevel(domainName, userName, hostName, __CFSafeLaunchLevel);
}

const _CFPreferencesDomainCallBacks __kCFXMLPropertyListDomainCallBacks = {
    
};

CFPreferencesDomainRef _CFPreferencesStandardDomain(CFStringRef  domainName, CFStringRef  userName, CFStringRef  hostName) {
    CFPreferencesDomainRef domain;
    CFStringRef  domainKey;
    Boolean shouldReleaseDomain = true;
     domainKey = _CFPreferencesStandardDomainCacheKey(domainName, userName, hostName);
    __CFLock(&domainCacheLock);
    if (!domainCache) {
        CFAllocatorRef alloc = __CFPreferencesAllocator();
        domainCache = CFDictionaryCreateMutable(alloc, 0, & kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    }
    domain = (CFPreferencesDomainRef)CFDictionaryGetValue(domainCache, domainKey);
    __CFUnlock(&domainCacheLock);
    if (!domain) {
        // Domain's not in the cache; load from permanent storage
		CFURLRef  theURL = _CFPreferencesURLForStandardDomain(domainName, userName, hostName);
        if (theURL) {
			domain = _CFPreferencesDomainCreate(theURL, &__kCFXMLPropertyListDomainCallBacks);

            if (userName == kCFPreferencesAnyUser) {
                _CFPreferencesDomainSetIsWorldReadable(domain, true);
            }
            CFRelease(theURL);
        }
	__CFLock(&domainCacheLock);
        if (domain && domainCache) {
            // We've just synthesized a domain & we're about to throw it in the domain cache. The problem is that someone else might have gotten in here behind our backs, so we can't just blindly set the domain (3021920). We'll need to check to see if this happened, and compensate.
            CFPreferencesDomainRef checkDomain = (CFPreferencesDomainRef)CFDictionaryGetValue(domainCache, domainKey);
            if(checkDomain) {
                // Someone got in here ahead of us, so we shouldn't smash the domain we're given. checkDomain is the current version, we should use that.
                // checkDomain was retrieved with a Get, so we don't want to over-release.
                shouldReleaseDomain = false;
                CFRelease(domain);	// release the domain we synthesized earlier.
                domain = checkDomain;	// repoint it at the domain picked up out of the cache.
            } else {
                // We must not have found the domain in the cache, so it's ok for us to put this in.
                CFDictionarySetValue(domainCache, domainKey, domain);                
            }
            if(shouldReleaseDomain) CFRelease(domain);
        }
	__CFUnlock(&domainCacheLock);
    }
    CFRelease(domainKey);
    return domain;
}

static void __CFPreferencesPerformSynchronize(const void *key, const void *value, void *context) {
    CFPreferencesDomainRef domain = (CFPreferencesDomainRef)value;
    Boolean *cumulativeResult = (Boolean *)context;
    if (!_CFPreferencesDomainSynchronize(domain)) *cumulativeResult = false;
}

CF_PRIVATE Boolean _CFSynchronizeDomainCache(void) {
    Boolean result = true;
    __CFLock(&domainCacheLock);
    if (domainCache) {
        CFDictionaryApplyFunction(domainCache, __CFPreferencesPerformSynchronize, &result);
    }
    __CFUnlock(&domainCacheLock);
    return result;
}

CF_PRIVATE void _CFPreferencesPurgeDomainCache(void) {
    _CFSynchronizeDomainCache();
    __CFLock(&domainCacheLock);
    if (domainCache) {
        CFRelease(domainCache);
        domainCache = NULL;
    }
    __CFUnlock(&domainCacheLock);
}

CF_PRIVATE CFArrayRef  _CFPreferencesCreateDomainList(CFStringRef  userName, CFStringRef  hostName) {
    CFAllocatorRef prefAlloc = __CFPreferencesAllocator();
    CFArrayRef  domains;
    CFMutableArrayRef  marray;
    CFStringRef  *cachedDomainKeys;
    CFPreferencesDomainRef *cachedDomains;
    SInt32 idx, cnt;
    CFStringRef  suffix;
    UInt32 suffixLen;
    CFURLRef prefDir = _preferencesDirectoryForUserHost(userName, hostName);
    
    if (!prefDir) {
        return NULL;
    }
    if (hostName == kCFPreferencesAnyHost) {
        suffix = CFStringCreateWithCString(prefAlloc, ".plist", kCFStringEncodingASCII);
    } else if (hostName == kCFPreferencesCurrentHost) {
        CFStringRef hostID = _CFPreferencesGetByHostIdentifierString();
        suffix = CFStringCreateWithFormat(prefAlloc, NULL, CFSTR(".%@.plist"), hostID);
    } else {
        suffix = CFStringCreateWithFormat(prefAlloc, NULL, CFSTR(".%@.plist"), hostName);   // sketchy - this allows someone to create a domain list for an arbitrary hostname.
    }
    suffixLen = CFStringGetLength(suffix);
    
    domains = (CFArrayRef)CFURLCreatePropertyFromResource(prefAlloc, prefDir, kCFURLFileDirectoryContents, NULL);
    CFRelease(prefDir);
    if (domains){
        marray = CFArrayCreateMutableCopy(prefAlloc, 0, domains);
        CFRelease(domains);
    } else {
        marray = CFArrayCreateMutable(prefAlloc, 0, & kCFTypeArrayCallBacks);
    }
    for (idx = CFArrayGetCount(marray)-1; idx >= 0; idx --) {
        CFURLRef  url = (CFURLRef)CFArrayGetValueAtIndex(marray, idx);
        CFStringRef string = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
        if (!CFStringHasSuffix(string, suffix)) {
            CFArrayRemoveValueAtIndex(marray, idx);
        } else {
            CFStringRef  dom = CFStringCreateWithSubstring(prefAlloc, string, CFRangeMake(0, CFStringGetLength(string) - suffixLen));
            if (CFEqual(dom, CFSTR(".GlobalPreferences"))) {
                CFArraySetValueAtIndex(marray, idx, kCFPreferencesAnyApplication);
            } else {
                CFArraySetValueAtIndex(marray, idx, dom);
            }
            CFRelease(dom);
        }
        CFRelease(string);
    }
    CFRelease(suffix);
    
    // Now add any domains added in the cache; delete any that have been deleted in the cache
    __CFLock(&domainCacheLock);
    if (!domainCache) {
        __CFUnlock(&domainCacheLock);
        return marray;
    }
    cnt = CFDictionaryGetCount(domainCache);
    cachedDomainKeys = (CFStringRef *)CFAllocatorAllocate(prefAlloc, 2 * cnt * sizeof(CFStringRef), 0);
    cachedDomains = (CFPreferencesDomainRef *)(cachedDomainKeys + cnt);
    CFDictionaryGetKeysAndValues(domainCache, (const void **)cachedDomainKeys, (const void **)cachedDomains);
    __CFUnlock(&domainCacheLock);
    suffix = _CFPreferencesCachePrefixForUserHost(userName, hostName);
    suffixLen = CFStringGetLength(suffix);
    
    for (idx = 0; idx < cnt; idx ++) {
        CFStringRef  domainKey = cachedDomainKeys[idx];
        CFPreferencesDomainRef domain = cachedDomains[idx];
        CFStringRef  domainName;
        CFIndex keyCount = 0;
        
        if (!CFStringHasPrefix(domainKey, suffix)) continue;
        domainName = CFStringCreateWithSubstring(prefAlloc, domainKey, CFRangeMake(suffixLen, CFStringGetLength(domainKey) - suffixLen));
        if (CFEqual(domainName, CFSTR("*"))) {
            CFRelease(domainName);
            domainName = (CFStringRef)CFRetain(kCFPreferencesAnyApplication);
        } else if (CFEqual(domainName, kCFPreferencesCurrentApplication)) {
            CFRelease(domainName);
            domainName = (CFStringRef)CFRetain(_CFProcessNameString());
        }
        CFDictionaryRef d = _CFPreferencesDomainDeepCopyDictionary(domain);
        keyCount = d ? CFDictionaryGetCount(d) : 0;
        if (keyCount) CFRelease(d);
        if (keyCount == 0) {
            // Domain was deleted
            SInt32 firstIndexOfValue = CFArrayGetFirstIndexOfValue(marray, CFRangeMake(0, CFArrayGetCount(marray)), domainName);
            if (0 <= firstIndexOfValue) {
                CFArrayRemoveValueAtIndex(marray, firstIndexOfValue);
            }
        } else if (!CFArrayContainsValue(marray, CFRangeMake(0, CFArrayGetCount(marray)), domainName)) {
            CFArrayAppendValue(marray, domainName);
        }
        CFRelease(domainName);
    }
    CFRelease(suffix);
    CFAllocatorDeallocate(prefAlloc, cachedDomainKeys);
    return marray;
}

//
// CFPreferencesDomain functions
//

CFPreferencesDomainRef _CFPreferencesDomainCreate(CFTypeRef  context, const _CFPreferencesDomainCallBacks *callBacks) {
    static dispatch_once_t initOnce = 0;
    dispatch_once(&initOnce, ^{ __kCFPreferencesDomainTypeID = _CFRuntimeRegisterClass(&__CFPreferencesDomainClass); });
    CFAllocatorRef alloc = __CFPreferencesAllocator();
    CFPreferencesDomainRef newDomain;
    CFAssert(callBacks != NULL && callBacks->createDomain != NULL && callBacks->freeDomain != NULL && callBacks->fetchValue != NULL && callBacks->writeValue != NULL, __kCFLogAssertion, "Cannot create a domain with NULL callbacks");
    newDomain = (CFPreferencesDomainRef)_CFRuntimeCreateInstance(alloc, __kCFPreferencesDomainTypeID, sizeof(struct __CFPreferencesDomain) - sizeof(CFRuntimeBase), NULL);
    if (newDomain) {
        newDomain->_callBacks = callBacks;
        if (context) CFRetain(context);
        newDomain->_context = context;
        newDomain->_domain = callBacks->createDomain(alloc, context);
    }
    return newDomain;
}

CFTypeRef  _CFPreferencesDomainCreateValueForKey(CFPreferencesDomainRef domain, CFStringRef key) {
    return domain->_callBacks->fetchValue(domain->_context, domain->_domain, key);
}

void _CFPreferencesDomainSet(CFPreferencesDomainRef domain, CFStringRef  key, CFTypeRef  value) {
    domain->_callBacks->writeValue(domain->_context, domain->_domain, key, value);
}

CF_PRIVATE Boolean _CFPreferencesDomainSynchronize(CFPreferencesDomainRef domain) {
    return domain->_callBacks->synchronize(domain->_context, domain->_domain);
}

CF_PRIVATE void _CFPreferencesDomainSetIsWorldReadable(CFPreferencesDomainRef domain, Boolean isWorldReadable) {
    if (domain->_callBacks->setIsWorldReadable) {
        domain->_callBacks->setIsWorldReadable(domain->_context, domain->_domain, isWorldReadable);
    }
}

CF_PRIVATE void *_CFPreferencesDomainCopyDictFunc(CFPreferencesDomainRef domain) {
    return domain->_callBacks->copyDomainDictionary;
}

void _CFPreferencesDomainSetDictionary(CFPreferencesDomainRef domain, CFDictionaryRef dict) {
    CFAllocatorRef alloc = __CFPreferencesAllocator();
    CFDictionaryRef d = _CFPreferencesDomainDeepCopyDictionary(domain);
    CFIndex idx, count = d ? CFDictionaryGetCount(d) : 0;

    CFTypeRef *keys = (CFTypeRef *)CFAllocatorAllocate(alloc, count * sizeof(CFTypeRef), 0);
    if (d) CFDictionaryGetKeysAndValues(d, keys, NULL);
    for (idx = 0; idx < count; idx ++) {
        _CFPreferencesDomainSet(domain, (CFStringRef)keys[idx], NULL);
    }
    CFAllocatorDeallocate(alloc, keys);
    if (d) CFRelease(d);

    if (dict && (count = CFDictionaryGetCount(dict)) != 0) {
        CFStringRef *newKeys = (CFStringRef *)CFAllocatorAllocate(alloc, count * sizeof(CFStringRef), 0);
        CFDictionaryGetKeysAndValues(dict, (const void **)newKeys, NULL);
        for (idx = 0; idx < count; idx ++) {
            CFStringRef key = newKeys[idx];
            _CFPreferencesDomainSet(domain, key, (CFTypeRef)CFDictionaryGetValue(dict, key));
        }
            CFAllocatorDeallocate(alloc, newKeys);
    }
}

CFDictionaryRef _CFPreferencesDomainDeepCopyDictionary(CFPreferencesDomainRef domain) {
    CFDictionaryRef result = domain->_callBacks->copyDomainDictionary(domain->_context, domain->_domain);
    if(result && CFDictionaryGetCount(result) == 0) {
        CFRelease(result);
        result = NULL;
    }
    return result;
}

Boolean _CFPreferencesDomainExists(CFStringRef domainName, CFStringRef userName, CFStringRef hostName) {
    CFPreferencesDomainRef domain;
    domain = _CFPreferencesStandardDomain(domainName, userName, hostName);
    if (domain) {
		CFDictionaryRef d = _CFPreferencesDomainDeepCopyDictionary(domain);
		if (d) CFRelease(d);
		return d != NULL;
    } else {
        return false;
    }
}

/* Volatile domains - context is ignored; domain is a CFDictionary (mutable) */
static void *createVolatileDomain(CFAllocatorRef allocator, CFTypeRef  context) {
    return CFDictionaryCreateMutable(allocator, 0, & kCFTypeDictionaryKeyCallBacks, & kCFTypeDictionaryValueCallBacks);
}

static void freeVolatileDomain(CFAllocatorRef allocator, CFTypeRef  context, void *domain) {
    CFRelease((CFTypeRef)domain);
}

static CFTypeRef  fetchVolatileValue(CFTypeRef  context, void *domain, CFStringRef  key) {
    CFTypeRef  result = CFDictionaryGetValue((CFMutableDictionaryRef  )domain, key);
    if (result) CFRetain(result);
    return result;
}

static void writeVolatileValue(CFTypeRef  context, void *domain, CFStringRef  key, CFTypeRef  value) {
    if (value)
        CFDictionarySetValue((CFMutableDictionaryRef  )domain, key, value);
    else
        CFDictionaryRemoveValue((CFMutableDictionaryRef  )domain, key);
}

static Boolean synchronizeVolatileDomain(CFTypeRef  context, void *domain) {
    return true;
}

static void getVolatileKeysAndValues(CFAllocatorRef alloc, CFTypeRef context, void *domain, void **buf[], CFIndex *numKeyValuePairs) {
    CFMutableDictionaryRef dict = (CFMutableDictionaryRef)domain;
    CFIndex count = CFDictionaryGetCount(dict);

    if (buf) {
        void **values;
        if ( count < *numKeyValuePairs ) {
            values = *buf + count;
            CFDictionaryGetKeysAndValues(dict, (const void **)*buf, (const void **)values);
        } else if (alloc != kCFAllocatorNull) {
            if (*buf) {
                *buf = (void **)CFAllocatorReallocate(alloc, *buf, count * 2 * sizeof(void *), 0);
            } else {
                *buf = (void **)CFAllocatorAllocate(alloc, count*2*sizeof(void *), 0);
            }
            if (*buf) {
                values = *buf + count;
                CFDictionaryGetKeysAndValues(dict, (const void **)*buf, (const void **)values);
            }
        }
    }
    *numKeyValuePairs = count;
}

static CFDictionaryRef copyVolatileDomainDictionary(CFTypeRef context, void *volatileDomain) {
    CFMutableDictionaryRef dict = (CFMutableDictionaryRef)volatileDomain;
    
    CFDictionaryRef result = (CFDictionaryRef)CFPropertyListCreateDeepCopy(__CFPreferencesAllocator(), dict, kCFPropertyListImmutable);
    return result;
}

const _CFPreferencesDomainCallBacks __kCFVolatileDomainCallBacks = {createVolatileDomain, freeVolatileDomain, fetchVolatileValue, writeVolatileValue, synchronizeVolatileDomain, getVolatileKeysAndValues, copyVolatileDomainDictionary, NULL};
