/*
* PDP-8/E Simulator
*
* Copyright © 1994-2015 Bernhard Baehr
*
* NSFileManager+Additions.h - Additional functions for file management
*
* This file is part of PDP-8/E Simulator.
*
* PDP-8/E Simulator is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#import
#import "utilities.h"
#import "NSFileManager+Additions.h"
/* declarations from Mac OS X 10.6 CFURL.h to dynamically load und call new APIs while building
with the Mac OS X 10.4 SDK */
#import
typedef struct __CFError *CFErrorRef;
typedef CFOptionFlags CFURLBookmarkResolutionOptions;
enum {
kCFBookmarkResolutionWithoutUIMask = ( 1UL << 8 ),
// don't perform any UI during bookmark resolution
kCFBookmarkResolutionWithoutMountingMask = ( 1UL << 9 ),
// don't mount a volume during bookmark resolution
};
static CFDataRef (*CFURLCreateBookmarkDataFromFile) (CFAllocatorRef allocator,
CFURLRef fileURL, CFErrorRef *errorRef);
static CFURLRef (*CFURLCreateByResolvingBookmarkData) (CFAllocatorRef allocator,
CFDataRef bookmark, CFURLBookmarkResolutionOptions options, CFURLRef relativeToURL,
CFArrayRef resourcePropertiesToInclude, Boolean* isStale, CFErrorRef* error);
/*
NSFileManager: Resolve an alias
Original Source:
(See copyright notice at )
The old Alias Manager functions are depecated since Mac OS 10.8 and no longer work with OS X 10.10.
The CFURL Bookmark functions are available since Mac OS 10.6. Because we build against the
Mac OS X 10.4 SDK, we call them dynamically. For the new code, see
http://stackoverflow.com/questions/21244781
*/
@implementation NSFileManager (Additions)
- (BOOL) fsRef:(FSRef *)fsRef forPath:(NSString *)path
{
BOOL ok = NO;
CFURLRef url = CFURLCreateWithFileSystemPath(NULL, (CFStringRef) path, kCFURLPOSIXPathStyle, NO);
if (url) {
ok = CFURLGetFSRef(url, fsRef);
CFRelease (url);
}
return ok;
}
- (NSString *) pathResolvedNew:(NSString *)path
// This code runs with Mac OS 10.6 and better; the dlsym() is only required until we build with newer SDKs
{
if (CFURLCreateBookmarkDataFromFile == NULL)
CFURLCreateBookmarkDataFromFile = dlsym(RTLD_NEXT, "CFURLCreateBookmarkDataFromFile");
if (CFURLCreateByResolvingBookmarkData == NULL)
CFURLCreateByResolvingBookmarkData = dlsym(RTLD_NEXT, "CFURLCreateByResolvingBookmarkData");
CFStringRef resolvedPath = nil;
CFURLRef url = CFURLCreateWithFileSystemPath(NULL, (CFStringRef) path, kCFURLPOSIXPathStyle, NO);
if (url != NULL) {
CFErrorRef *err = nil;
CFDataRef bookmark = CFURLCreateBookmarkDataFromFile(NULL, url, err);
if (bookmark != NULL) {
CFURLRef resolvedurl = CFURLCreateByResolvingBookmarkData(NULL, bookmark,
kCFBookmarkResolutionWithoutUIMask, NULL, NULL, NO, err);
if (resolvedurl != NULL) {
resolvedPath = CFURLCopyFileSystemPath(resolvedurl, kCFURLPOSIXPathStyle);
CFRelease (resolvedurl);
}
}
CFRelease (url);
}
return [((NSString *) resolvedPath) autorelease];
}
- (NSString *) pathResolvedOld:(NSString *)path
// This code runs with Mac OS 10.4 to 10.9, it is deprecated since Mac OS 10.8, it doesn't work with Yosemite
{
CFStringRef resolvedPath = nil;
CFURLRef url = CFURLCreateWithFileSystemPath(NULL, (CFStringRef) path, kCFURLPOSIXPathStyle, NO);
if (url != NULL) {
FSRef fsRef;
if (CFURLGetFSRef(url, &fsRef)) {
Boolean targetIsFolder, wasAliased;
if (FSResolveAliasFile(&fsRef, true, &targetIsFolder, &wasAliased) == noErr &&
wasAliased) {
CFURLRef resolvedurl = CFURLCreateFromFSRef(NULL, &fsRef);
if (resolvedurl != NULL) {
resolvedPath = CFURLCopyFileSystemPath(resolvedurl,
kCFURLPOSIXPathStyle);
CFRelease (resolvedurl);
}
}
}
CFRelease (url);
}
return [((NSString *) resolvedPath) autorelease];
}
- (NSString *) pathResolved:(NSString *)path
{
return runningOnSnowLeopardOrNewer() ? [self pathResolvedNew:path] : [self pathResolvedOld:path];
}
- (BOOL) isAliasPath:(NSString *)path
{
return [self pathResolved:path] != nil;
}
- (NSString *) resolveAliasPath:(NSString *)path
{
NSString *resolved = [self pathResolved:path];
return resolved ? resolved : path;
}
@end