Re: NSFileManager and aliases
Re: NSFileManager and aliases
- Subject: Re: NSFileManager and aliases
- From: Charles Srstka <email@hidden>
- Date: Tue, 16 Apr 2002 23:26:27 -0500
On Tuesday, April 16, 2002, at 06:51 PM, Charles Srstka wrote:
>
Well, I've written up a quick and dirty category to make it easy to
>
resolve paths with aliases and symlinks in the middle of them. This
>
ought to work even if you have chains of an alias pointing to a symlink
>
which points to an alias, etc...
>
>
This could probably be more elegant, and is also too long - it needs to
>
be broken up into smaller methods. Still, for the time being, it seems
>
to work...
>
>
<actually, it didn't always>
Well, I found some pretty stupid bugs in that code. Here's a new
version, and this time, it should actually work. It's still too long,
though (it's even longer now that I added stuff in there to resolve '.'
and '..').
@implementation NSString(CSAliasFollowingMethods)
- (NSString *)stringByResolvingAliasesAndSymlinksInPath {
FSRef fileRef;
BOOL targetIsFolder;
NSEnumerator *pathEnum = [[[self stringByExpandingTildeInPath]
pathComponents] objectEnumerator];
NSString *component;
NSString *newPath = nil;
NSFileManager *fm = [NSFileManager defaultManager];
OSErr err;
// check each component of the path to see if it is an alias or
symlink
while(component = [pathEnum nextObject]) {
BOOL isAlias, isSymlink, isDir;
NSDictionary *attrs;
// ignore '.' and double slashes
if([component isEqualToString:@"."] || [component
isEqualToString:@""])
component = [pathEnum nextObject];
// and resolve '..'
if([component isEqualToString:@".."]) {
// can't resolve if relative path; fail
if(!newPath)
return self;
else {
newPath = [newPath stringByDeletingLastPathComponent];
component = [pathEnum nextObject];
}
}
if(newPath)
newPath = [newPath stringByAppendingPathComponent:component];
else if([component isEqualToString:@"/"])
newPath = component;
else
return self; // can't resolve a relative path
attrs = [fm fileAttributesAtPath:newPath traverseLink:NO];
if(!attrs) // file doesn't exist
return self;
isSymlink = [[attrs objectForKey:@"NSFileType"]
isEqualToString:@"NSFileTypeSymbolicLink"];
err = FSPathMakeRef([newPath
fileSystemRepresentation],&fileRef,NULL);
if(err != noErr)
return self;
err = FSIsAliasFile(&fileRef,&isAlias,&isDir);
if(err != noErr)
return self;
// this is so we resolve chains of aliases and symlinks, or
combinations thereof
while(isAlias || isSymlink) {
if(isAlias) {
char path[1024];
BOOL wasAliased;
err =
FSResolveAliasFile(&fileRef,YES,&targetIsFolder,&wasAliased);
if(err != noErr)
return self;
err = FSRefMakePath(&fileRef,path,sizeof(path));
if(err != noErr)
return self;
newPath = [fm stringWithFileSystemRepresentation:path
length:strlen(path)];
} else if(isSymlink) {
NSString *linkedPath = [fm
pathContentOfSymbolicLinkAtPath:newPath];
if(!linkedPath)
return self;
newPath = linkedPath;
}
// update the file's info in case the path changed
attrs = [fm fileAttributesAtPath:newPath traverseLink:NO];
if(!attrs) // file doesn't exist
return self;
isSymlink = [[attrs objectForKey:@"NSFileType"]
isEqualToString:@"NSFileTypeSymbolicLink"];
err = FSPathMakeRef([newPath
fileSystemRepresentation],&fileRef,NULL);
if(err != noErr)
return self;
err = FSIsAliasFile(&fileRef,&isAlias,&isDir);
if(err != noErr)
return self;
}
}
// make sure something didn't go wrong, and the path is still valid
if(![fm fileExistsAtPath:newPath])
return self;
// we should now have the nice cleaned up path.
return newPath;
}
@end
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.