/*	CFXMLPreferencesDomain.c
	Copyright (c) 1998-2017, Apple Inc. and the Swift project authors
 
	Portions Copyright (c) 2014-2017, 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
	Responsibility: David Smith
*/


#include <CoreFoundation/CFPreferences.h>
#include <CoreFoundation/CFURLAccess.h>
#include <CoreFoundation/CFPropertyList.h>
#include <CoreFoundation/CFNumber.h>
#include <CoreFoundation/CFDate.h>
#include "CFInternal.h"
#include <time.h>
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#endif
#if DEPLOYMENT_TARGET_MACOSX
#include <mach/mach.h>
#include <mach/mach_syscalls.h>
#endif

Boolean __CFPreferencesShouldWriteXML(void);

typedef struct {
    CFMutableDictionaryRef _domainDict; // Current value of the domain dictionary
    CFMutableArrayRef _dirtyKeys; // The array of keys which must be synchronized
    CFAbsoluteTime _lastReadTime; // The last time we synchronized with the disk
    CFLock_t _lock; // Lock for accessing fields in the domain
    Boolean _isWorldReadable; // HACK - this is because we have no good way to propogate the kCFPreferencesAnyUser information from the upper level CFPreferences routines  REW, 1/13/00
    char _padding[3];
} _CFXMLPreferencesDomain;

static void *createXMLDomain(CFAllocatorRef allocator, CFTypeRef context);
static void freeXMLDomain(CFAllocatorRef allocator, CFTypeRef context, void *tDomain);
static CFTypeRef fetchXMLValue(CFTypeRef context, void *xmlDomain, CFStringRef key);
static void writeXMLValue(CFTypeRef context, void *xmlDomain, CFStringRef key, CFTypeRef value);
static Boolean synchronizeXMLDomain(CFTypeRef context, void *xmlDomain);
static void getXMLKeysAndValues(CFAllocatorRef alloc, CFTypeRef context, void *xmlDomain, void **buf[], CFIndex *numKeyValuePairs);
static CFDictionaryRef copyXMLDomainDictionary(CFTypeRef context, void *domain);
static void setXMLDomainIsWorldReadable(CFTypeRef context, void *domain, Boolean isWorldReadable);

CF_PRIVATE const _CFPreferencesDomainCallBacks __kCFXMLPropertyListDomainCallBacks = {createXMLDomain, freeXMLDomain, fetchXMLValue, writeXMLValue, synchronizeXMLDomain, getXMLKeysAndValues, copyXMLDomainDictionary, setXMLDomainIsWorldReadable};

// Directly ripped from Foundation....
static void __CFMilliSleep(uint32_t msecs) {
#if DEPLOYMENT_TARGET_WINDOWS
    SleepEx(msecs, false);
#elif defined(__svr4__) || defined(__hpux__)
    sleep((msecs + 900) / 1000);
#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX
    struct timespec input;
    input.tv_sec = msecs / 1000;
    input.tv_nsec = (msecs - input.tv_sec * 1000) * 1000000;
    nanosleep(&input, NULL);
#else
#error Dont know how to define sleep for this platform
#endif
}

static CFLock_t _propDictLock = CFLockInit; // Annoying that we need this, but otherwise we have a multithreading risk

CF_INLINE CFDictionaryRef URLPropertyDictForPOSIXMode(SInt32 mode) {
    static CFMutableDictionaryRef _propertyDict = NULL;
    CFNumberRef num = CFNumberCreate(__CFPreferencesAllocator(), kCFNumberSInt32Type, &mode);
    __CFLock(&_propDictLock);
    if (!_propertyDict) {
        _propertyDict = CFDictionaryCreateMutable(__CFPreferencesAllocator(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    }
    CFDictionarySetValue(_propertyDict, kCFURLFilePOSIXMode, num);
    CFRelease(num);
    return _propertyDict;
}

CF_INLINE void URLPropertyDictRelease(void) {
    __CFUnlock(&_propDictLock);
}

// Asssumes caller already knows the directory doesn't exist.
static Boolean _createDirectory(CFURLRef dirURL, Boolean worldReadable) {
    CFAllocatorRef alloc = __CFPreferencesAllocator();
    CFURLRef parentURL = CFURLCreateCopyDeletingLastPathComponent(alloc, dirURL);
    CFBooleanRef val = (CFBooleanRef) CFURLCreatePropertyFromResource(alloc, parentURL, kCFURLFileExists, NULL);
    Boolean parentExists = (val && CFBooleanGetValue(val));
    SInt32 mode;
    Boolean result;
    if (val) CFRelease(val);
    if (!parentExists) {
        CFStringRef path = CFURLCopyPath(parentURL);
        if (!CFEqual(path, CFSTR("/"))) {
            _createDirectory(parentURL, worldReadable);
            val = (CFBooleanRef) CFURLCreatePropertyFromResource(alloc, parentURL, kCFURLFileExists, NULL);
            parentExists = (val && CFBooleanGetValue(val));
            if (val) CFRelease(val);
        }
        CFRelease(path);
    }
    if (parentURL) CFRelease(parentURL);
    if (!parentExists) return false;

#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX
    mode = worldReadable ? S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH : S_IRWXU;
#else
    mode = 0666;
#endif

    result = CFURLWriteDataAndPropertiesToResource(dirURL, (CFDataRef)dirURL, URLPropertyDictForPOSIXMode(mode), NULL);
    URLPropertyDictRelease();
    return result;
}


/* XML - context is the CFURL where the property list is stored on disk; domain is an _CFXMLPreferencesDomain */
static void *createXMLDomain(CFAllocatorRef allocator, CFTypeRef context) {
    _CFXMLPreferencesDomain *domain = (_CFXMLPreferencesDomain*) CFAllocatorAllocate(allocator, sizeof(_CFXMLPreferencesDomain), 0);
    domain->_lastReadTime = 0.0;
    domain->_domainDict = NULL;
    domain->_dirtyKeys = CFArrayCreateMutable(allocator, 0, & kCFTypeArrayCallBacks);
	const CFLock_t lock = CFLockInit;
    domain->_lock = lock;
    domain->_isWorldReadable = false;
    return domain;
}

static void freeXMLDomain(CFAllocatorRef allocator, CFTypeRef context, void *tDomain) {
    _CFXMLPreferencesDomain *domain = (_CFXMLPreferencesDomain *)tDomain;
    if (domain->_domainDict) CFRelease(domain->_domainDict);
    if (domain->_dirtyKeys) CFRelease(domain->_dirtyKeys);
    CFAllocatorDeallocate(allocator, domain);
}

// Assumes the domain has already been locked
static void _loadXMLDomainIfStale(CFURLRef url, _CFXMLPreferencesDomain *domain) {
    CFAllocatorRef alloc = __CFPreferencesAllocator();
    int idx;
    if (domain->_domainDict) {
        CFDateRef modDate;
        CFAbsoluteTime modTime;
    	CFURLRef testURL = url;

        if (CFDictionaryGetCount(domain->_domainDict) == 0) {
            // domain never existed; check the parent directory, not the child
            testURL = CFURLCreateWithFileSystemPathRelativeToBase(alloc, CFSTR(".."), kCFURLPOSIXPathStyle, true, url);
        }

        modDate = (CFDateRef )CFURLCreatePropertyFromResource(alloc, testURL, kCFURLFileLastModificationTime, NULL);
        modTime = modDate ? CFDateGetAbsoluteTime(modDate) : 0.0;

        // free before possible return. we can test non-NULL of modDate but don't depend on contents after this.
        if (testURL != url) CFRelease(testURL);
        if (modDate) CFRelease(modDate);
        
        if (modDate != NULL && modTime < domain->_lastReadTime) {            // We're up-to-date
            return;
        }
    }

	
    // We're out-of-date; destroy domainDict and reload
    if (domain->_domainDict) {
        CFRelease(domain->_domainDict);
        domain->_domainDict = NULL;
    }

    // We no longer lock on read; instead, we assume parse failures are because someone else is writing the file, and just try to parse again.  If we fail 3 times in a row, we assume the file is corrupted.  REW, 7/13/99

    for (idx = 0; idx < 3; idx ++) {
        CFDataRef data;
        if (!CFURLCreateDataAndPropertiesFromResource(alloc, url, &data, NULL, NULL, NULL) || !data) {
            // Either a file system error (so we can't read the file), or an empty (or perhaps non-existant) file
            domain->_domainDict = CFDictionaryCreateMutable(alloc, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
            break;
        } else {
            CFTypeRef pList = CFPropertyListCreateFromXMLData(alloc, data, kCFPropertyListImmutable, NULL);
            CFRelease(data);
            if (pList && CFGetTypeID(pList) == CFDictionaryGetTypeID()) {
                domain->_domainDict = CFDictionaryCreateMutableCopy(alloc, 0, (CFDictionaryRef)pList);
                CFRelease(pList);
                break;
            } else if (pList) {
                CFRelease(pList);
            }
            // Assume the file is being written; sleep for a short time (to allow the write to complete) then re-read
            __CFMilliSleep(150);
        }
    }
    if (!domain->_domainDict) {
        // Failed to ever load
        domain->_domainDict = CFDictionaryCreateMutable(alloc, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    }
    domain->_lastReadTime = CFAbsoluteTimeGetCurrent();
}

static CFTypeRef fetchXMLValue(CFTypeRef context, void *xmlDomain, CFStringRef key) {
    _CFXMLPreferencesDomain *domain = (_CFXMLPreferencesDomain *)xmlDomain;
    CFTypeRef result;
 
    // Never reload if we've looked at the file system within the last 5 seconds.
    __CFLock(&domain->_lock);
    if (domain->_domainDict == NULL) _loadXMLDomainIfStale((CFURLRef )context, domain);
    result = CFDictionaryGetValue(domain->_domainDict, key);
    if (result) CFRetain(result); 
    __CFUnlock(&domain->_lock);

    return result;
}


#if DEPLOYMENT_TARGET_MACOSX
#include <sys/fcntl.h>

/* __CFWriteBytesToFileWithAtomicity is a "safe save" facility. Write the bytes using the specified mode on the file to the provided URL. If the atomic flag is true, try to do it in a fashion that will enable a safe save.
 */
static Boolean __CFWriteBytesToFileWithAtomicity(CFURLRef url, const void *bytes, int length, SInt32 mode, Boolean atomic) {
    int fd = -1;
    char auxPath[CFMaxPathSize + 16];
    char cpath[CFMaxPathSize];
    uid_t owner = getuid();
    gid_t group = getgid();
    Boolean writingFileAsRoot = ((getuid() != geteuid()) && (geteuid() == 0));
    
    if (!CFURLGetFileSystemRepresentation(url, true, (uint8_t *)cpath, CFMaxPathSize)) {
        return false;
    }
    
    if (-1 == mode || writingFileAsRoot) {
        struct stat statBuf;
        if (0 == stat(cpath, &statBuf)) {
            mode = statBuf.st_mode;
            owner = statBuf.st_uid;
            group = statBuf.st_gid;
        } else {
            mode = 0664;
            if (writingFileAsRoot && (0 == strncmp(cpath, "/Library/Preferences", 20))) {
                owner = geteuid();
                group = 80;
            }
        }
    }
    
    if (atomic) {
        CFURLRef dir = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorSystemDefault, url);
        CFURLRef tempFile = CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault, dir, CFSTR("cf#XXXXX"), false);
        CFRelease(dir);
        if (!CFURLGetFileSystemRepresentation(tempFile, true, (uint8_t *)auxPath, CFMaxPathSize)) {
            CFRelease(tempFile);
            return false;
        }
        CFRelease(tempFile);
        fd = mkstemp(auxPath);
    } else {
        fd = open(cpath, O_WRONLY|O_CREAT|O_TRUNC, mode);
    }
    
    if (fd < 0) return false;
    
    if (length && (write(fd, bytes, length) != length || fsync(fd) < 0)) {
        int saveerr = thread_errno();
        close(fd);
        if (atomic)
            unlink(auxPath);
        thread_set_errno(saveerr);
        return false;
    }
    
    close(fd);
    
    if (atomic) {
        // preserve the mode as passed in originally
        chmod(auxPath, mode);
                
        if (0 != rename(auxPath, cpath)) {
            unlink(auxPath);
            return false;
        }
        
        // If the file was renamed successfully and we wrote it as root we need to reset the owner & group as they were.
        if (writingFileAsRoot) {
            chown(cpath, owner, group);
        }
    }
    return true;
}
#endif

// domain should already be locked.
static Boolean _writeXMLFile(CFURLRef url, CFMutableDictionaryRef dict, Boolean isWorldReadable, Boolean *tryAgain) {
    Boolean success = false;
    CFAllocatorRef alloc = __CFPreferencesAllocator();
    *tryAgain = false;
    if (CFDictionaryGetCount(dict) == 0) {
        // Destroy the file
        CFBooleanRef val = (CFBooleanRef) CFURLCreatePropertyFromResource(alloc, url, kCFURLFileExists, NULL);
        if (val && CFBooleanGetValue(val)) {
            success = CFURLDestroyResource(url, NULL);
        } else {
            success = true;
        }
        if (val) CFRelease(val);
    } else {
        CFPropertyListFormat desiredFormat = __CFPreferencesShouldWriteXML() ? kCFPropertyListXMLFormat_v1_0 : kCFPropertyListBinaryFormat_v1_0;
        CFDataRef data = CFPropertyListCreateData(alloc, dict, desiredFormat, 0, NULL);
        if (data) {
            SInt32 mode;
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX
            mode = isWorldReadable ? S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH : S_IRUSR|S_IWUSR;
#else
	    mode = 0666;
#endif
#if DEPLOYMENT_TARGET_MACOSX
            {	// Try quick atomic way first, then fallback to slower ways and error cases
                CFStringRef scheme = CFURLCopyScheme(url);
                if (!scheme) {
                    *tryAgain = false;
                    CFRelease(data);
                    return false;
                } else if (CFStringCompare(scheme, CFSTR("file"), 0) == kCFCompareEqualTo) {
                    SInt32 length = CFDataGetLength(data);
                    const void *bytes = (0 == length) ? (const void *)"" : CFDataGetBytePtr(data);
                    Boolean atomicWriteSuccess = __CFWriteBytesToFileWithAtomicity(url, bytes, length, mode, true);
                    if (atomicWriteSuccess) {
                        CFRelease(scheme);
                        *tryAgain = false;
                        CFRelease(data);
                        return true;
                    }
                    if (!atomicWriteSuccess && thread_errno() == ENOSPC) {
                        CFRelease(scheme);
                        *tryAgain = false;
                        CFRelease(data);
                        return false;
                    }
                }
                CFRelease(scheme);
            }
#endif
            success = CFURLWriteDataAndPropertiesToResource(url, data, URLPropertyDictForPOSIXMode(mode), NULL);
            URLPropertyDictRelease();
            if (success) {
                CFDataRef readData;
                if (!CFURLCreateDataAndPropertiesFromResource(alloc, url, &readData, NULL, NULL, NULL) || !CFEqual(readData, data)) {
                    success = false;
                    *tryAgain = true;
                }
                if (readData) CFRelease(readData);
            } else {
                CFBooleanRef val = (CFBooleanRef) CFURLCreatePropertyFromResource(alloc, url, kCFURLFileExists, NULL);
                if (!val || !CFBooleanGetValue(val)) {
                    CFURLRef tmpURL = CFURLCreateWithFileSystemPathRelativeToBase(alloc, CFSTR("."), kCFURLPOSIXPathStyle, true, url); // Just "." because url is not a directory URL
                    CFURLRef parentURL = tmpURL ? CFURLCopyAbsoluteURL(tmpURL) : NULL;
                    if (tmpURL) CFRelease(tmpURL);
                    if (val) CFRelease(val);
                    val = (CFBooleanRef) CFURLCreatePropertyFromResource(alloc, parentURL, kCFURLFileExists, NULL);
                    if ((!val || !CFBooleanGetValue(val)) && _createDirectory(parentURL, isWorldReadable)) {
                        // parent directory didn't exist; now it does; try again to write
                        success = CFURLWriteDataAndPropertiesToResource(url, data, URLPropertyDictForPOSIXMode(mode), NULL);
                        URLPropertyDictRelease();
                        if (success) {
                            CFDataRef rdData;
                            if (!CFURLCreateDataAndPropertiesFromResource(alloc, url, &rdData, NULL, NULL, NULL) || !CFEqual(rdData, data)) {
                                success = false;
                                *tryAgain = true;
                            }
                            if (rdData) CFRelease(rdData);
                        }
                        
                    }
                    if (parentURL) CFRelease(parentURL);
                }
                if (val) CFRelease(val);
            }
            CFRelease(data);
        } else {
            // ???  This should never happen
            CFLog(__kCFLogAssertion, CFSTR("Could not generate XML data for property list"));
            success = false;
        }
    }
    return success;
}

static void writeXMLValue(CFTypeRef context, void *xmlDomain, CFStringRef key, CFTypeRef value) {
    _CFXMLPreferencesDomain *domain = (_CFXMLPreferencesDomain *)xmlDomain;
    const void *existing = NULL;

    __CFLock(&domain->_lock);
    if (domain->_domainDict == NULL) {
        _loadXMLDomainIfStale((CFURLRef )context, domain);
    }

	// check to see if the value is the same
	// if (1) the key is present AND value is !NULL and equal to existing, do nothing, or
	// if (2) the key is not present AND value is NULL, do nothing
	// these things are no-ops, and should not dirty the domain
    if (CFDictionaryGetValueIfPresent(domain->_domainDict, key, &existing)) {
	if (NULL != value && (existing == value || CFEqual(existing, value))) {
	    __CFUnlock(&domain->_lock);
	    return;
	}
    } else {
	if (NULL == value) {
	    __CFUnlock(&domain->_lock);
	    return;
	}
    }

	// We must append first so key gets another retain (in case we're
	// about to remove it from the dictionary, and that's the sole reference)
    // This should be a set not an array.
    if (!CFArrayContainsValue(domain->_dirtyKeys, CFRangeMake(0, CFArrayGetCount(domain->_dirtyKeys)), key)) {
	CFArrayAppendValue(domain->_dirtyKeys, key);
    }
    if (value) {
        // Must copy for two reasons - we don't want mutable objects in the cache, and we don't want objects allocated from a different allocator in the cache.
        CFTypeRef newValue = CFPropertyListCreateDeepCopy(__CFPreferencesAllocator(), value, kCFPropertyListImmutable);
        CFDictionarySetValue(domain->_domainDict, key, newValue);
        CFRelease(newValue);
    } else {
        CFDictionaryRemoveValue(domain->_domainDict, key);
    }
    __CFUnlock(&domain->_lock);
}

static void getXMLKeysAndValues(CFAllocatorRef alloc, CFTypeRef context, void *xmlDomain, void **buf[], CFIndex *numKeyValuePairs) {
    _CFXMLPreferencesDomain *domain = (_CFXMLPreferencesDomain *)xmlDomain;
    CFIndex count;
    __CFLock(&domain->_lock);
    if (!domain->_domainDict) {
        _loadXMLDomainIfStale((CFURLRef )context, domain);
    }
    count = CFDictionaryGetCount(domain->_domainDict);
    if (buf) {
        void **values;
        if (count <= *numKeyValuePairs) {
            values = *buf + count;
            CFDictionaryGetKeysAndValues(domain->_domainDict, (const void **)*buf, (const void **)values);
        } else if (alloc != kCFAllocatorNull) {
	    *buf = (void**) CFAllocatorReallocate(alloc, (*buf ? *buf : NULL), count * 2 * sizeof(void *), 0);
            if (*buf) {
                values = *buf + count;
                CFDictionaryGetKeysAndValues(domain->_domainDict, (const void **)*buf, (const void **)values);
            }
        }
    }
    *numKeyValuePairs = count;
    __CFUnlock(&domain->_lock);
}

static CFDictionaryRef copyXMLDomainDictionary(CFTypeRef context, void *xmlDomain) {
    _CFXMLPreferencesDomain *domain = (_CFXMLPreferencesDomain *)xmlDomain;
    CFDictionaryRef result;
    
    __CFLock(&domain->_lock);
    if(!domain->_domainDict) {
        _loadXMLDomainIfStale((CFURLRef)context, domain);
    }
    
    result = (CFDictionaryRef)CFPropertyListCreateDeepCopy(__CFPreferencesAllocator(), domain->_domainDict, kCFPropertyListImmutable);
    
    __CFUnlock(&domain->_lock);
    return result;
}


static void setXMLDomainIsWorldReadable(CFTypeRef context, void *domain, Boolean isWorldReadable) {
    ((_CFXMLPreferencesDomain *)domain)->_isWorldReadable = isWorldReadable;
}

static Boolean synchronizeXMLDomain(CFTypeRef context, void *xmlDomain) {
    _CFXMLPreferencesDomain *domain = (_CFXMLPreferencesDomain *)xmlDomain;
    CFMutableDictionaryRef cachedDict;
    CFMutableArrayRef changedKeys;
    SInt32 idx,  count;
    Boolean success, tryAgain;
    
    __CFLock(&domain->_lock);
    cachedDict = domain->_domainDict;
    changedKeys = domain->_dirtyKeys;
    count = CFArrayGetCount(changedKeys);
    
    if (count == 0) {
        // no changes were made to this domain; just remove it from the cache to guarantee it will be taken from disk next access
        if (cachedDict) {
            CFRelease(cachedDict);
            domain->_domainDict = NULL;
        }
        __CFUnlock(&domain->_lock);
        return true;
    }

    domain->_domainDict = NULL; // This forces a reload.  Note that we now have a retain on cachedDict
    do {
        _loadXMLDomainIfStale((CFURLRef )context, domain);
        // now cachedDict holds our changes; domain->_domainDict has the latest version from the disk
        for (idx = 0; idx < count; idx ++) {
            CFStringRef key = (CFStringRef) CFArrayGetValueAtIndex(changedKeys, idx);
            CFTypeRef value = CFDictionaryGetValue(cachedDict, key);
            if (value)
                CFDictionarySetValue(domain->_domainDict, key, value);
            else
                CFDictionaryRemoveValue(domain->_domainDict, key);
        }
        success = _writeXMLFile((CFURLRef )context, domain->_domainDict, domain->_isWorldReadable, &tryAgain);
        if (tryAgain) {
            __CFMilliSleep(50);
        }
    } while (tryAgain);
    CFRelease(cachedDict);
    if (success) {
	CFArrayRemoveAllValues(domain->_dirtyKeys);
    }
    domain->_lastReadTime = CFAbsoluteTimeGetCurrent();
    __CFUnlock(&domain->_lock);
    return success;
}

