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

	CFURLRef url = NULL;

	UniChar szPath[MAX_PATH];
	if (S_OK == SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, (LPWSTR) szPath)) {
		CFStringRef directoryPath = CFStringCreateWithCharacters(alloc, szPath, strlen_UniChar(szPath));
		if (directoryPath) {
			CFStringRef completePath = CFStringCreateWithFormat(alloc, NULL, CFSTR("%@\\Apple\\"), directoryPath);
			if (completePath) {
				url = CFURLCreateWithFileSystemPath(alloc, completePath, kCFURLWindowsPathStyle, true);
				CFRelease(completePath);
			}
			CFRelease(directoryPath);
		}
	}

	// 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 _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
}
예제 #3
0
// Try to remove the dynamic MIME file used for dynamic content-type generation.
// You cannot rely on registry being sane at this point, as we can't guarantee
// the order destructors are called, so please don't access it here.
void __destructor fini_remove_dynamic_plist(void)
{
    CFURLRef    home_directory = NULL;
    CFURLRef    pref_directory = NULL;
    CFURLRef    mime_file      = NULL;
    CFURLRef    mime_file_lock = NULL;
    SInt32      error_code     = -1;

    // Resolve the home directory.
    home_directory = CFCopyHomeDirectoryURLForUser(NULL);

    if (home_directory == NULL) {
        goto finished;
    }

    // Resolve Preferences directory (this is how CoreFoundation does it), I
    // don't want to have to rely on this, but they don't make it easy.
    pref_directory = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorDefault,
                                                                 CFSTR("Library/Preferences/"),
                                                                 kCFURLPOSIXPathStyle,
                                                                 true,
                                                                 home_directory);

    if (pref_directory == NULL) {
        goto finished;
    }

    // Append the name of my cache file.
    mime_file  = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorDefault,
                                                             CFSTR("com.google.netscapesecurity.plist"),
                                                             kCFURLPOSIXPathStyle,
                                                             false,
                                                             pref_directory);
    mime_file_lock = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorDefault,
                                                                 CFSTR("com.google.netscapesecurity.plist.lockfile"),
                                                                 kCFURLPOSIXPathStyle,
                                                                 false,
                                                                 pref_directory);

    if (!mime_file || !mime_file_lock) {
        goto finished;
    }

    // Delete the file, and possibly stale lockfile, I don't care if it fails.
    CFURLDestroyResource(mime_file, &error_code);
    CFURLDestroyResource(mime_file_lock, &error_code);

finished:
    CFRelease(home_directory);
    CFRelease(pref_directory);
    CFRelease(mime_file);
    CFRelease(mime_file_lock);

    return;
}
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 ||  DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
    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 || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
        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;
}
예제 #5
0
CFURLRef makeCFURL(CFStringRef s, bool isDirectory, CFURLRef base)
{
	if (base)
		return CFURLCreateWithFileSystemPathRelativeToBase(NULL, s, kCFURLPOSIXPathStyle, isDirectory, base);
	else
		return CFURLCreateWithFileSystemPath(NULL, s, kCFURLPOSIXPathStyle, isDirectory);
}
// 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();
}
예제 #7
0
void ACSharedArtImageSourceWriteResourceToPathAtIndex(ACSharedArtImageSourceRef isrc, CFStringRef path, CFIndex index)
{
	CFURLRef baseURLRef = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,path,kCFURLPOSIXPathStyle,true);
	CFStringRef extension = __ACSharedArtImageSourceGetExtensionForWritingAtIndex(isrc, index);
	CFURLRef urlRef = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorDefault,extension,kCFURLPOSIXPathStyle,false,baseURLRef);
	ACSharedArtImageType type = ACSharedArtImageSourceGetType(isrc);

	if (type == kSharedArtImageTypePDF && index == 0)
	{
		/* Just write the pure data */
		CFDataRef dataRef = ACSharedArtImageSourceCreateDataAtIndex(isrc, index);
		ACWriteDataToURL(dataRef, urlRef);
		CFRelease(dataRef);
	}
	else
	{
		CGImageRef imgRef = ACSharedArtImageSourceCreateImageAtIndex(isrc,index);
		ACWriteImageToURLWithType(imgRef, urlRef, kUTTypePNG);
		CGImageRelease(imgRef);
	}
	
	CFRelease(urlRef);
	CFRelease(extension);
	CFRelease(baseURLRef);
}
예제 #8
0
// Utility routine to get a bundle from the system folder by file name....typically used to find OpenGL to get extension functions.
int load_bundle_by_filename (const char * in_filename, CFBundleRef * io_bundle_ref)
{
    OSStatus		err = noErr;
	FSRef			framework_fs;
    CFURLRef		framework_url = NULL;
	CFURLRef		bundle_url = NULL;
	CFStringRef		bundle_name = NULL;
	CFBundleRef		bundle_ref = NULL;
	
	bundle_name = CFStringCreateWithCString(kCFAllocatorDefault, in_filename, kCFStringEncodingUTF8);
    if (bundle_name == NULL) {
		err = paramErr;
    	goto bail; }
	
	err = FSFindFolder(kSystemDomain, kFrameworksFolderType, false, &framework_fs);
    if (noErr != err) {
		err = dirNFErr;
    	goto bail; }
	
    // create URL to folder
    framework_url = CFURLCreateFromFSRef (kCFAllocatorDefault, &framework_fs);
	if(framework_url == NULL) {
		err = ioErr;
		goto bail; }
	
	bundle_url = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorDefault, bundle_name, kCFURLPOSIXPathStyle, false, framework_url);
	if(bundle_url == NULL) {
		err = fnfErr;
		goto bail; }
	
    bundle_ref = CFBundleCreate (kCFAllocatorDefault, bundle_url);
	if(bundle_ref == NULL) {
		err = permErr;
		goto bail; }
	
    if (!CFBundleLoadExecutable (bundle_ref)) {
        err = bdNamErr;
		goto bail;
    }
	
	if (io_bundle_ref) { *io_bundle_ref = bundle_ref; bundle_ref = NULL; }
bail:
		if(bundle_ref)		CFRelease(bundle_ref);
	if(bundle_name)		CFRelease(bundle_name);
	if(bundle_url)		CFRelease(bundle_url);
	if(framework_url)	CFRelease(framework_url);
	
    return err;
}
static CFURLRef _preferencesDirectoryForUserHostSafetyLevel(CFStringRef userName, CFStringRef hostName, unsigned long safeLevel) {
    CFAllocatorRef alloc = __CFPreferencesAllocator();
#if TARGET_OS_WIN32

	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 location = NULL;
    
    CFKnownLocationUser user;
    
    if (userName == kCFPreferencesAnyUser) {
        user = _kCFKnownLocationUserAny;
    } else if (userName == kCFPreferencesCurrentUser) {
        user = _kCFKnownLocationUserCurrent;
    } else {
        user = _kCFKnownLocationUserByName;
    }
    
    CFURLRef base = _CFKnownLocationCreatePreferencesURLForUser(user, userName);
    
    if (hostName == kCFPreferencesCurrentHost) {
        location = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, CFSTR("ByHost"), kCFURLPOSIXPathStyle, true, base);
    } else {
        assert(hostName == kCFPreferencesAnyHost);
        location = CFRetain(base);
    }
    
    CFRelease(base);
    return location;
#endif
}
예제 #10
0
//
// Turn a C(++) string into a CFURLRef indicating a file: path
//
CFURLRef makeCFURL(const char *s, bool isDirectory, CFURLRef base)
{
    CFStringRef ss = CFStringCreateWithCStringNoCopy(NULL, s, kCFStringEncodingUTF8, kCFAllocatorNull);
    CFURLRef returnValue = NULL;

	if (base)
    {
		returnValue = CFURLCreateWithFileSystemPathRelativeToBase(NULL,
			ss, kCFURLPOSIXPathStyle, isDirectory, base);
    }
	else
    {
		returnValue = CFURLCreateWithFileSystemPath(NULL,
			ss, kCFURLPOSIXPathStyle, isDirectory);
    }
    
    CFRelease(ss);
    return returnValue;
}
예제 #11
0
/* Lately, dirSpec appears to be (rightfully) unused. */
__private_extern__ CFMutableArrayRef _CFContentsOfDirectory(CFAllocatorRef alloc, char *dirPath, void *dirSpec, CFURLRef dirURL, CFStringRef matchingAbstractType) {
    CFMutableArrayRef files = NULL;
    Boolean releaseBase = false;
    CFIndex pathLength = dirPath ? strlen(dirPath) : 0;
    // MF:!!! Need to use four-letter type codes where appropriate.
    CFStringRef extension = (matchingAbstractType ? _CFCopyExtensionForAbstractType(matchingAbstractType) : NULL);
    CFIndex targetExtLen = (extension ? CFStringGetLength(extension) : 0);

#if DEPLOYMENT_TARGET_WINDOWS
    // This is a replacement for 'dirent' below, and also uses wchar_t to support unicode paths
    wchar_t extBuff[CFMaxPathSize];
    int extBuffInteriorDotCount = 0; //people insist on using extensions like ".trace.plist", so we need to know how many dots back to look :(
    
    if (targetExtLen > 0) {
        CFIndex usedBytes = 0;
        CFStringGetBytes(extension, CFRangeMake(0, targetExtLen), kCFStringEncodingUTF16, 0, false, (uint8_t *)extBuff, CFMaxPathLength, &usedBytes);
        targetExtLen = usedBytes / sizeof(wchar_t);
        extBuff[targetExtLen] = '\0';
        wchar_t *extBuffStr = (wchar_t *)extBuff;
        if (extBuffStr[0] == '.')
            extBuffStr++; //skip the first dot, it's legitimate to have ".plist" for example
        
        wchar_t *extBuffDotPtr = extBuffStr;
        while ((extBuffDotPtr = wcschr(extBuffStr, '.'))) { //find the next . in the extension...
            extBuffInteriorDotCount++;
            extBuffStr = extBuffDotPtr + 1;
        }
    }
    
    wchar_t pathBuf[CFMaxPathSize];
    
    if (!dirPath) {
        if (!_CFURLGetWideFileSystemRepresentation(dirURL, true, pathBuf, CFMaxPathLength)) {
            if (extension) CFRelease(extension);
            return NULL;
        }
        
        pathLength = wcslen(pathBuf);

    } else {
        // Convert dirPath to a wide representation and put it into our pathBuf
        // Get the real length of the string in UTF16 characters
        CFStringRef dirPathStr = CFStringCreateWithCString(kCFAllocatorSystemDefault, dirPath, kCFStringEncodingUTF8);
        CFIndex strLen = CFStringGetLength(dirPathStr);
        
        // Copy the string into the buffer and terminate
        CFStringGetCharacters(dirPathStr, CFRangeMake(0, strLen), (UniChar *)pathBuf);
        pathBuf[strLen] = 0;
        
        CFRelease(dirPathStr);
    }
    
    WIN32_FIND_DATAW  file;
    HANDLE handle;
    
    if (pathLength + 2 >= CFMaxPathLength) {
        if (extension) {
            CFRelease(extension);
        }
        return NULL;
    }

    pathBuf[pathLength] = '\\';
    pathBuf[pathLength + 1] = '*';
    pathBuf[pathLength + 2] = '\0';
    handle = FindFirstFileW(pathBuf, (LPWIN32_FIND_DATAW)&file);
    if (INVALID_HANDLE_VALUE == handle) {
        pathBuf[pathLength] = '\0';
        if (extension) {
            CFRelease(extension);
        }
        return NULL;
    }

    files = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks);

    do {
        CFURLRef fileURL;
        CFIndex namelen = wcslen(file.cFileName);
        if (file.cFileName[0] == '.' && (namelen == 1 || (namelen == 2  && file.cFileName[1] == '.'))) {
            continue;
        }

        if (targetExtLen > namelen) continue;    // if the extension is the same length or longer than the name, it can't possibly match.

        if (targetExtLen > 0) {
	    if (file.cFileName[namelen - 1] == '.') continue; //filename ends with a dot, no extension
	    
	    wchar_t *fileExt = NULL;
            
            if (extBuffInteriorDotCount == 0) {
                fileExt = wcsrchr(file.cFileName, '.');
            } else { //find the Nth occurrence of . from the end of the string, to handle ".foo.bar"
                wchar_t *save = file.cFileName;
                while ((save = wcschr(save, '.')) && !fileExt) {
                    wchar_t *temp = save;
                    int moreDots = 0;
                    while ((temp = wcschr(temp, '.'))) {
                        if (++moreDots == extBuffInteriorDotCount) break;
                    }
                    if (moreDots == extBuffInteriorDotCount) {
                        fileExt = save;
                    }
                }
            }
	    
	    if (!fileExt) continue; //no extension
	    
	    if (((const wchar_t *)extBuff)[0] != '.')
		fileExt++; //omit the dot if the target file extension omits the dot
	    
	    CFIndex fileExtLen = wcslen(fileExt);
	    
	    //if the extensions are different lengths, they can't possibly match
	    if (fileExtLen != targetExtLen) continue;
	    
            // Check to see if it matches the extension we're looking for.
            if (_wcsicmp(fileExt, (const wchar_t *)extBuff) != 0) {
                continue;
            }
        }
	if (dirURL == NULL) {
	    CFStringRef dirURLStr = CFStringCreateWithBytes(alloc, (const uint8_t *)pathBuf, pathLength * sizeof(wchar_t), kCFStringEncodingUTF16, NO);
	    dirURL = CFURLCreateWithFileSystemPath(alloc, dirURLStr, kCFURLWindowsPathStyle, true);
	    CFRelease(dirURLStr);
            releaseBase = true;
        }
        // MF:!!! What about the trailing slash?
        CFStringRef fileURLStr = CFStringCreateWithBytes(alloc, (const uint8_t *)file.cFileName, namelen * sizeof(wchar_t), kCFStringEncodingUTF16, NO);
        fileURL = CFURLCreateWithFileSystemPathRelativeToBase(alloc, fileURLStr, kCFURLWindowsPathStyle, (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? true : false, dirURL);
        CFArrayAppendValue(files, fileURL);
        CFRelease(fileURL);
        CFRelease(fileURLStr);
    } while (FindNextFileW(handle, &file));
    FindClose(handle);
    pathBuf[pathLength] = '\0';

#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
    uint8_t extBuff[CFMaxPathSize];
    int extBuffInteriorDotCount = 0; //people insist on using extensions like ".trace.plist", so we need to know how many dots back to look :(
    
    if (targetExtLen > 0) {
        CFStringGetBytes(extension, CFRangeMake(0, targetExtLen), CFStringFileSystemEncoding(), 0, false, extBuff, CFMaxPathLength, &targetExtLen);
        extBuff[targetExtLen] = '\0';
        char *extBuffStr = (char *)extBuff;
        if (extBuffStr[0] == '.')
            extBuffStr++; //skip the first dot, it's legitimate to have ".plist" for example
        
        char *extBuffDotPtr = extBuffStr;
        while ((extBuffDotPtr = strchr(extBuffStr, '.'))) { //find the next . in the extension...
            extBuffInteriorDotCount++;
            extBuffStr = extBuffDotPtr + 1;
        }
    }
    
    uint8_t pathBuf[CFMaxPathSize];
    
    if (!dirPath) {
        if (!CFURLGetFileSystemRepresentation(dirURL, true, pathBuf, CFMaxPathLength)) {
            if (extension) CFRelease(extension);
            return NULL;
        } else {
            dirPath = (char *)pathBuf;
            pathLength = strlen(dirPath);
        }
    }
    
    struct dirent buffer;
    struct dirent *dp;
    int err;
   
    int no_hang_fd = __CFProphylacticAutofsAccess ? open("/dev/autofs_nowait", 0) : -1;
 
    DIR *dirp = opendir(dirPath);
    if (!dirp) {
        if (extension) {
            CFRelease(extension);
        }
	if (-1 != no_hang_fd) close(no_hang_fd);
        return NULL;
        // raiseErrno("opendir", path);
    }
    files = CFArrayCreateMutable(alloc, 0, & kCFTypeArrayCallBacks);

    while((0 == readdir_r(dirp, &buffer, &dp)) && dp) {
        CFURLRef fileURL;
	unsigned namelen = strlen(dp->d_name);

        // skip . & ..; they cause descenders to go berserk
	if (dp->d_name[0] == '.' && (namelen == 1 || (namelen == 2 && dp->d_name[1] == '.'))) {
            continue;
        }
        
        if (targetExtLen > namelen) continue;    // if the extension is the same length or longer than the name, it can't possibly match.
                
        if (targetExtLen > 0) {
	    if (dp->d_name[namelen - 1] == '.') continue; //filename ends with a dot, no extension
	      
            char *fileExt = NULL;
            if (extBuffInteriorDotCount == 0) {
                fileExt = strrchr(dp->d_name, '.'); 
            } else { //find the Nth occurrence of . from the end of the string, to handle ".foo.bar"
                char *save = dp->d_name;
                while ((save = strchr(save, '.')) && !fileExt) {
                    char *temp = save;
                    int moreDots = 0;
                    while ((temp = strchr(temp, '.'))) {
                        if (++moreDots == extBuffInteriorDotCount) break;
                    }
                    if (moreDots == extBuffInteriorDotCount) {
                        fileExt = save;
                    }
                }
            }
	    
	    if (!fileExt) continue; //no extension
	    
	    if (((char *)extBuff)[0] != '.')
		fileExt++; //omit the dot if the target extension omits the dot; safe, because we checked to make sure it isn't the last character just before
	    
	    size_t fileExtLen = strlen(fileExt);
	    
	    //if the extensions are different lengths, they can't possibly match
	    if (fileExtLen != targetExtLen) continue;
	    
	    // Check to see if it matches the extension we're looking for.
            if (strncmp(fileExt, (char *)extBuff, fileExtLen) != 0) {
                continue;
            }
        }
        if (dirURL == NULL) {
            dirURL = CFURLCreateFromFileSystemRepresentation(alloc, (uint8_t *)dirPath, pathLength, true);
            releaseBase = true;
        }
        if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN || dp->d_type == DT_LNK || dp->d_type == DT_WHT) {
            Boolean isDir = (dp->d_type == DT_DIR);
            if (!isDir) {
                // Ugh; must stat.
                char subdirPath[CFMaxPathLength];
                struct statinfo statBuf;
                strlcpy(subdirPath, dirPath, sizeof(subdirPath));
                strlcat(subdirPath, "/", sizeof(subdirPath));
                strlcat(subdirPath, dp->d_name, sizeof(subdirPath));
                if (stat(subdirPath, &statBuf) == 0) {
                    isDir = ((statBuf.st_mode & S_IFMT) == S_IFDIR);
                }
            }
#if DEPLOYMENT_TARGET_LINUX
            fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(alloc, (uint8_t *)dp->d_name, namelen, isDir, dirURL);
#else
            fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(alloc, (uint8_t *)dp->d_name, dp->d_namlen, isDir, dirURL);
#endif
        } else {
#if DEPLOYMENT_TARGET_LINUX
            fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase (alloc, (uint8_t *)dp->d_name, namelen, false, dirURL);
#else
            fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase (alloc, (uint8_t *)dp->d_name, dp->d_namlen, false, dirURL);
#endif
        }
        CFArrayAppendValue(files, fileURL);
        CFRelease(fileURL);
    }
    err = closedir(dirp);
    if (-1 != no_hang_fd) close(no_hang_fd);
    if (err != 0) {
        CFRelease(files);
        if (releaseBase) {
            CFRelease(dirURL);
        }
        if (extension) {
            CFRelease(extension);
        }
        return NULL;
    }
    
#else
    
#error _CFContentsOfDirectory() unknown architecture, not implemented
    
#endif

    if (extension) {
        CFRelease(extension);
    }
    if (releaseBase) {
        CFRelease(dirURL);
    }
    return files;
}
// 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 TARGET_OS_OSX || TARGET_OS_LINUX
            mode = isWorldReadable ? S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH : S_IRUSR|S_IWUSR;
#else
	    mode = 0666;
#endif
#if TARGET_OS_OSX
            {	// 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;
}
예제 #13
0
파일: FSFormatName.c 프로젝트: aosm/libfs
CFStringRef FSCopyFormatNameForFSType(CFStringRef fsType, int16_t fsSubtype, bool localized, bool encrypted) 
{
    CFTypeRef formatName;
    CFStringRef formatNameTableKey;
    CFIndex indx;

    if (NULL == fsType) return NULL;

    // Create a key for cache localized name table (i.e. "0hfs0")
    formatNameTableKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d%@%d"), (localized ? 1 : 0), fsType, fsSubtype);

    // Use OSSpinLock to protect the table accessed from multiple threads
    OSSpinLockLock(&__FSLocalizedNameTableLock);
    formatName = (void*)((NULL == __FSLocalizedNameTable) ? NULL : CFDictionaryGetValue(__FSLocalizedNameTable, (const void *)formatNameTableKey));
    OSSpinLockUnlock(&__FSLocalizedNameTableLock);

    if (NULL == formatName) { // not in the cache
        CFBundleRef bundle = NULL;
        CFURLRef bundleURL;
        CFStringRef fsTypeName;
	static CFArrayRef searchPaths = NULL;

        /* Construct a bundle path URL from the fsType argument and create a CFBundle.  We search (using CFCopySearchPathForDirectoriesInDomains) /Network/Library/Filesystems, /Library/Filesystems, and /System/Library/Filesystems. */

        // Create CFURL for /System/Library/Filesystems and cache it
	if (NULL == searchPaths) {
		CFArrayRef tmpPaths = CFCopySearchPathForDirectoriesInDomains(kCFLibraryDirectory, kCFSystemDomainMask | kCFNetworkDomainMask | kCFLocalDomainMask, true);
		CFMutableArrayRef tmpStrings;
		CFIndex i;

		if (NULL == tmpPaths)
			return NULL;	// No directories to search?!?!

		tmpStrings = CFArrayCreateMutable(NULL, CFArrayGetCount(tmpPaths), NULL);
		if (tmpStrings == NULL)
			goto done;
		for (i = 0; i < CFArrayGetCount(tmpPaths); i++) {
			CFStringRef tStr;
			CFURLRef tURL;
			char path[PATH_MAX + 1];
			CFTypeRef tobject = CFArrayGetValueAtIndex(tmpPaths, i);

			if (CFGetTypeID(tobject) == CFURLGetTypeID()) {
				if (false ==
					CFURLGetFileSystemRepresentation(
						tobject,
						false,
						(UInt8*)path,
						sizeof(path))) {
					goto done;
				}
			} else if (CFGetTypeID(tobject) == CFStringGetTypeID()) {
				CFStringGetCString(tobject, path, sizeof(path), kCFStringEncodingUTF8);
			} else {
				goto done;
			}
			strlcat(path, "/Filesystems", sizeof(path));
			tStr = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8);
			if (tStr == NULL)
				goto done;
			tURL = CFURLCreateWithFileSystemPath(NULL, tStr, kCFURLPOSIXPathStyle, true);
			if (tURL) {
				CFArrayAppendValue(tmpStrings, tURL);
			}
			CFRelease(tStr);
		}
		searchPaths = CFArrayCreateCopy(NULL, tmpStrings);
done:
		CFRelease(tmpStrings);
		CFRelease(tmpPaths);
		if (searchPaths == NULL)
			return NULL;
	}

	for (indx = 0; indx < CFArrayGetCount(searchPaths); indx++) {
		CFURLRef libRef = CFArrayGetValueAtIndex(searchPaths, indx);

		fsTypeName = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@.fs"), fsType);
		bundleURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL, fsTypeName, kCFURLPOSIXPathStyle, true, libRef);
		bundle = CFBundleCreate(NULL, bundleURL);

		CFRelease(fsTypeName);
		CFRelease(bundleURL);
		if (NULL != bundle) {
			break;
		}
	}

        if (NULL != bundle) { // the bundle exists at path	
			CFDictionaryRef localPersonalities = NULL;

			// Access the Info dictionary in the bundle 
			CFDictionaryRef bundleDict = CFBundleGetInfoDictionary(bundle);

			// Get localized FSPersonalities only if we want localized name
			if (localized == true) {
				localPersonalities = CFBundleGetValueForInfoDictionaryKey(bundle, KEY_FS_PERSONALITIES);
//NSLog(CFSTR("localPersonalities = %@\n"), localPersonalities);
			}

			/* Get global FSPersonalities.  We need to access this since FSSubType exists only
			 * in global FSPersonalities 
			 */
            CFDictionaryRef globalPersonalities = CFDictionaryGetValue(bundleDict, (const void *) KEY_FS_PERSONALITIES);
//NSLog(CFSTR("globalPersonalities = %@\n"), globalPersonalities);
			CFIndex numPersonalities;
            if (((NULL != localPersonalities) || (localized == false)) &&	// localPersonalities or we don't want localizations 
			    (NULL != globalPersonalities) && 
				((numPersonalities = CFDictionaryGetCount(globalPersonalities)) > 0)) {

				// read all FSPersonalities keys and values 
                CFDictionaryRef valuesBuffer[MAX_FS_SUBTYPES];
				CFStringRef keysBuffer[MAX_FS_SUBTYPES];
				CFDictionaryRef *values = ((numPersonalities > MAX_FS_SUBTYPES) ? (CFDictionaryRef *)malloc(sizeof(CFDictionaryRef) * numPersonalities) : valuesBuffer);
				CFStringRef *keys = ((numPersonalities > MAX_FS_SUBTYPES) ? (CFStringRef *)malloc(sizeof(CFStringRef) * numPersonalities) : keysBuffer);
                CFDictionaryGetKeysAndValues(globalPersonalities, (const void **)keys, (const void **)values);

				// create CFNumberRef for the FSSubType 
		        CFNumberRef subTypeID = CFNumberCreate(NULL, kCFNumberSInt16Type, (const void *)&fsSubtype);
				CFStringRef FSNameKey = NULL;
				
				// search for valid FSSubType - we will use its key from global FSPersonalties to 
				// access FSName from localized FSPersonalities
				CFIndex index;
				CFNumberRef readSubTypeID;
				for (index = 0; index < numPersonalities; index++) {
					if ((true == CFDictionaryGetValueIfPresent(values[index], (const void *)KEY_FS_SUBTYPE, (const void **)&readSubTypeID)) &&
						(CFNumberCompare(subTypeID, readSubTypeID, NULL) == 0)) {
						FSNameKey = keys[index];
						break;
					}
				}

                CFRelease(subTypeID);
				
                /* If a personality hasn't been found, use the last value in the dictionary (note the content of CFDictionary is unordered so choosing the last doesn't produce consistent result) */
                if (NULL == FSNameKey) {
                    FSNameKey = keys[numPersonalities - 1]; // is selecting the last entry right ?
                }

				// Get FSName from the FSPersonalities entry
				CFDictionaryRef FSNameDict;
				if (localized == true) { 
					FSNameDict = CFDictionaryGetValue(localPersonalities, FSNameKey);
				} else {
					FSNameDict = CFDictionaryGetValue(globalPersonalities, FSNameKey);
				}
				if (NULL != FSNameDict) {
					CFStringRef tempName = CFDictionaryGetValue(FSNameDict, (const void *)KEY_FS_NAME);
					CFStringRef encrName = CFDictionaryGetValue(FSNameDict, CFSTR(kFSCoreStorageEncryptNameKey));
					if (tempName) {
						if (encrName) {
							formatName = (void*)CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
							if (formatName != NULL) {
								(void)CFDictionarySetValue((void*)formatName, tempName, encrName);
							}
						} else {
							formatName = tempName;
						}
					}
				}

				if (values != valuesBuffer) free(values);
				if (keys != keysBuffer) free(keys);
            }
        }

        // If all failed, return "Unknown format (f_fstypename)" as the last resort
        if (NULL == formatName) {
            static CFStringRef unknownTypeString = NULL;
			CFStringRef unknownFSNameString = NULL;

            // This should use the framework bundle this code resides. CarbonCore ??? */
            if (NULL == unknownTypeString) unknownTypeString = CFCopyLocalizedString(UNKNOWN_FS_NAME, "This string is displayed when localized file system name cannot be determined.");
			
			unknownFSNameString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%@)"), unknownTypeString, fsType);
			formatName = (void*)unknownFSNameString;
        }
        
        // Cache the result
        OSSpinLockLock(&__FSLocalizedNameTableLock);
        if (NULL == __FSLocalizedNameTable) __FSLocalizedNameTable = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
//	NSLog(CFSTR("Setting value %@ for key %@\n"), formatName, formatNameTableKey);	
        CFDictionarySetValue(__FSLocalizedNameTable, (const void *)formatNameTableKey, (const void *)formatName);
        OSSpinLockUnlock(&__FSLocalizedNameTableLock);
//	NSLog(CFSTR("Localized Name Table = %@\n"), __FSLocalizedNameTable);
        
        if (NULL != bundle) CFRelease(bundle); // it has to be released here since formatName might be owned by the bundle
    }

     CFRelease(formatNameTableKey);

     if (CFGetTypeID(formatName) == CFStringGetTypeID()) {
	     return CFRetain(formatName);
     } else if (CFGetTypeID(formatName) == CFDictionaryGetTypeID()) {
	     // Dictionary with the (possibly localized) name as the key, and the encrypted name as the value
	     // If we want the encrypted name, we return the value, else we return the key
	     size_t numEntries = CFDictionaryGetCount((void*)formatName);
	     void *keyNames[numEntries];
	     void *values[numEntries];
	     CFDictionaryGetKeysAndValues((void*)formatName, (const void**)&keyNames, (const void**)&values);
	     if (encrypted)
		     return CFRetain(values[0]);
	     else
		     return CFRetain(keyNames[0]);
     }
	     
    return CFRetain(formatName);
}
예제 #14
0
int main (int argc, char * const argv[])
{
    int err = EXIT_SUCCESS;
    int ch;

    CFStringRef urlString = NULL;
    Boolean urlStringIsPath = FALSE;
    CFURLPathStyle urlStringPathStyle = kCFURLPOSIXPathStyle;

    CFStringRef baseURLString = NULL;
    Boolean baseURLStringIsPath = FALSE;
    CFURLPathStyle baseURLStringPathStyle = kCFURLPOSIXPathStyle;

    Boolean deletePathExtension = FALSE;
    Boolean appendPathExtension = FALSE;
    CFStringRef pathExtension = NULL;

    Boolean deleteLastPathComponent = FALSE;
    Boolean appendPathComponent = FALSE;
    CFStringRef lastPathComponent = NULL;

    CFURLRef baseURL = NULL;
    CFURLRef testURL = NULL;
    Boolean makeAbsolute = FALSE;
    CFURLRef tempURL = NULL;

    CFIndex bufferLength;
    UInt8 *buffer = NULL;
    CFIndex componentLength;
    Boolean isAbsolute;

    CFStringRef tempStr = NULL;

    /* crack command line args */
    while ( ((ch = getopt(argc, argv, "hPS:ps:b:axX:cC:")) != -1) && (err == EXIT_SUCCESS) )
    {
        switch ( ch )
        {
        case 'P':
            urlStringIsPath = TRUE;
            break;
        case 'S':
            /* get pathStyle for urlString */
            switch ( tolower(optarg[0]) )
            {
            case 'p':
                urlStringPathStyle = kCFURLPOSIXPathStyle;
                break;
            case 'h':
                urlStringPathStyle = kCFURLHFSPathStyle;
                break;
            case 'w':
                urlStringPathStyle = kCFURLWindowsPathStyle;
                break;
            default:
                break;
            }
            break;
        case 'p':
            baseURLStringIsPath = TRUE;
            break;
        case 's':
            /* get pathStyle for baseURLString */
            switch ( tolower(optarg[0]) )
            {
            case 'p':
                baseURLStringPathStyle = kCFURLPOSIXPathStyle;
                break;
            case 'h':
                baseURLStringPathStyle = kCFURLHFSPathStyle;
                break;
            case 'w':
                baseURLStringPathStyle = kCFURLWindowsPathStyle;
                break;
            default:
                break;
            }
            break;
        case 'b':
            CF_RELEASE_CLEAR(baseURLString);
            baseURLString = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)optarg, strlen(optarg), kCFStringEncodingUTF8, FALSE);
            require_action(baseURLString != NULL, CFStringCreateWithBytes_baseURLString, err = EXIT_FAILURE);
            break;
        case 'a':
            makeAbsolute = TRUE;
            break;
        case 'x':
            deletePathExtension = TRUE;
            break;
        case 'X':
            appendPathExtension = TRUE;
            CF_RELEASE_CLEAR(pathExtension);
            pathExtension = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)optarg, strlen(optarg), kCFStringEncodingUTF8, FALSE);
            require_action(pathExtension != NULL, CFStringCreateWithBytes_pathExtension, err = EXIT_FAILURE);
            break;
        case 'c':
            deleteLastPathComponent = TRUE;
            break;
        case 'C':
            appendPathComponent = TRUE;
            CF_RELEASE_CLEAR(lastPathComponent);
            lastPathComponent = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)optarg, strlen(optarg), kCFStringEncodingUTF8, FALSE);
            require_action(lastPathComponent != NULL, CFStringCreateWithBytes_lastPathComponent, err = EXIT_FAILURE);
            break;
        case 'h':
        case '?':
        default:
            err = EXIT_FAILURE;
            break;
        }
    }
    /* was the usage parsed correctly? */
    require_action_quiet(!err, command_err, usage(); err = EXIT_FAILURE);

    /* were any mutually exclusive options used incorrectly? */
    require_action((!deletePathExtension && !appendPathExtension) || (deletePathExtension != appendPathExtension), command_err, usage(); err = EXIT_FAILURE);
    require_action((!deleteLastPathComponent && !appendPathComponent) || (deleteLastPathComponent != appendPathComponent), command_err, usage(); err = EXIT_FAILURE);

    /* there should be one argument left -- the urlString */
    require_action((argc - optind) == 1, command_err, usage(); err = EXIT_FAILURE);
    urlString = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)argv[optind], strlen(argv[optind]), kCFStringEncodingUTF8, FALSE);
    require_action(urlString != NULL, command_err, usage(); err = EXIT_FAILURE);

    if ( baseURLString )
    {
        /* create the url with a baseURL */
        if ( baseURLStringIsPath )
        {
            baseURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, baseURLString, baseURLStringPathStyle, TRUE);
            require_action(baseURL != NULL, command_err, usage(); err = EXIT_FAILURE);
        }
        else
        {
            baseURL = CFURLCreateWithString(kCFAllocatorDefault, baseURLString, NULL);
            require_action(baseURL != NULL, command_err, usage(); err = EXIT_FAILURE);
        }

        if ( urlStringIsPath )
        {
            testURL = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorDefault, urlString, urlStringPathStyle, HasDirectoryPath(urlString, urlStringPathStyle), baseURL);
            require_action(testURL != NULL, command_err, usage(); err = EXIT_FAILURE);
        }
        else
        {
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;
}