cocoamacosafp

Determine AFP share from a file URL


I writing an application to copy some files to a certain location. It allows the user to choose the destination, which is always on an AFP share. This is done with a NSOpenPanel. The URL that gets returned is: file://localhost/Volumes/Oliver%20Legg's%20Backup/.

What I want to accomplish is when the application is started, if the AFP share isn't mounted I want it to automatically mount it. What is the best way to do this?

The Get Info command lists the server as: afp://Power Mac G5._afpovertcp.local/Oliver%20Legg's%20Backup. How can I programatically get this URL from a file URL? I think if I could get that URL I could mount it using FSMountServerVolumeAsync. Is that the best (easiest, most abstracted) API to use?


Solution

  • You need to use some lower-level File Manager routines to get this information, there's no way to do it with regular Cocoa calls. The URL is obtained using FSCopyURLForVolume() but you need to get a volume reference number for the mounted volume in order to use it:

    #import <CoreServices/CoreServices.h>
    
    //this is the path to the mounted network volume
    NSString* pathToVolume = @"/Volumes/MountedNetworkVolume/";
    
    //get the volume reference number
    FSRef pathRef;
    FSPathMakeRef((UInt8*)[pathToVolume fileSystemRepresentation],&pathRef,NULL);
    FSCatalogInfo catalogInfo;
    OSErr osErr = FSGetCatalogInfo(
                                   &pathRef,
                                   kFSCatInfoVolume,
                                   &catalogInfo,
                                   NULL,
                                   NULL,
                                   NULL
                                   ) ;
    FSVolumeRefNum volumeRefNum = 0;
    if(osErr == noErr) 
        volumeRefNum = catalogInfo.volume;
    
    //get the server URL for the volume
    CFURLRef serverLocation;
    OSStatus result = FSCopyURLForVolume (volumeRefNum,&serverLocation);
    if(result == noErr)
        NSLog(@"The server location is: %@",serverLocation);
    else
        NSLog(@"An error occurred: %i",result);
    CFRelease(serverLocation);
    

    FSMountServerVolumeAsync is definitely the correct way to mount a remote volume.