#include <CoreFoundation/CoreFoundation.h>
#include <libgen.h>
#include <limits.h>
#include <Kerberos/KerberosDebug.h>
#include <Kerberos/com_err.h>
#include "FSpUtils.h"
OSStatus FSSpecToPOSIXPath (const FSSpec *inSpec, char *ioPath, unsigned long inPathLength)
{
OSStatus err = noErr;
FSRef ref;
FSSpec spec;
CFStringRef nameString = NULL;
CFStringRef pathString = NULL;
CFURLRef pathURL = NULL;
CFURLRef parentURL = NULL;
int i;
dprintf ("FSSpecToPOSIXPath called on volID %d, parID %d and name '", inSpec->vRefNum, inSpec->parID);
for (i = 0; i < inSpec->name[0]; i++) { dprintf ("%c", inSpec->name[i+1]); }
dprintf ("'\n");
if (err == noErr) {
err = FSpMakeFSRef (inSpec, &ref);
}
if (err == noErr) {
err = FSRefMakePath (&ref, (UInt8 *)ioPath, inPathLength);
} else {
err = noErr;
if (err == noErr) {
Str31 name;
name[0] = 0;
err = FSMakeFSSpec (inSpec->vRefNum, inSpec->parID, name, &spec);
}
if (err == noErr) {
err = FSpMakeFSRef (&spec, &ref);
}
if (err == noErr) {
parentURL = CFURLCreateFromFSRef(CFAllocatorGetDefault (), &ref);
if (parentURL == NULL) { err = memFullErr; }
}
if (err == noErr) {
nameString = CFStringCreateWithPascalString (CFAllocatorGetDefault (), inSpec->name,
kCFStringEncodingMacRoman);
if (nameString == NULL) { err = memFullErr; }
}
if (err == noErr) {
pathURL = CFURLCreateCopyAppendingPathComponent (CFAllocatorGetDefault (),
parentURL, nameString,
false );
if (pathURL == NULL) { err = memFullErr; }
}
if (err == noErr) {
pathString = CFURLCopyFileSystemPath (pathURL, kCFURLPOSIXPathStyle);
if (pathString == NULL) { err = memFullErr; }
}
if (err == noErr) {
Boolean converted = CFStringGetCString (pathString, ioPath, inPathLength, CFStringGetSystemEncoding ());
if (!converted) { err = fnfErr; }
}
}
if (parentURL != NULL) { CFRelease (parentURL); }
if (nameString != NULL) { CFRelease (nameString); }
if (pathURL != NULL) { CFRelease (pathURL); }
if (pathString != NULL) { CFRelease (pathString); }
if (err == noErr) {
dprintf ("FSSpecToPOSIXPath returned path '%s'\n", ioPath);
} else {
dprintf ("FSSpecToPOSIXPath returned error %d (%s)\n", err, error_message (err));
}
return err;
}
OSStatus POSIXPathToFSSpec (const char *inPath, FSSpec *outSpec)
{
OSStatus err = noErr;
FSRef ref;
Boolean isDirectory;
FSCatalogInfo info;
CFStringRef pathString = NULL;
CFURLRef pathURL = NULL;
CFURLRef parentURL = NULL;
CFStringRef nameString = NULL;
dprintf ("FSSpecToPOSIXPath called on '%s'\n", inPath);
if (err == noErr) {
err = FSPathMakeRef ((UInt8 *) inPath, &ref, &isDirectory);
}
if (err == noErr) {
err = FSGetCatalogInfo (&ref, kFSCatInfoNone, NULL, NULL, outSpec, NULL);
} else {
err = noErr;
if (err == noErr) {
pathString = CFStringCreateWithCString (CFAllocatorGetDefault (), inPath, CFStringGetSystemEncoding ());
if (pathString == NULL) { err = memFullErr; }
}
if (err == noErr) {
pathURL = CFURLCreateWithFileSystemPath (CFAllocatorGetDefault (),
pathString, kCFURLPOSIXPathStyle,
false );
if (pathURL == NULL) { err = memFullErr; }
}
if (err == noErr) {
parentURL = CFURLCreateCopyDeletingLastPathComponent (CFAllocatorGetDefault (), pathURL);
if (parentURL == NULL) { err = memFullErr; }
}
if (err == noErr) {
Boolean converted = CFURLGetFSRef (parentURL, &ref);
if (!converted) { err = fnfErr; }
}
if (err == noErr) {
err = FSGetCatalogInfo(&ref, kFSCatInfoNodeFlags|kFSCatInfoNodeID, &info, NULL, outSpec, NULL);
}
if (err == noErr) {
nameString = CFURLCopyLastPathComponent (pathURL);
if (nameString == NULL) { err = memFullErr; }
}
if (err == noErr) {
Boolean converted = CFStringGetPascalString (pathString, outSpec->name, sizeof (outSpec->name),
CFStringGetSystemEncoding ());
if (!converted) { err = fnfErr; }
}
if (err == noErr) {
outSpec->parID = info.nodeID;
}
}
if (err == noErr) {
int i;
dprintf ("POSIXPathToFSSpec returned volID %d, parID %d and name '", outSpec->vRefNum, outSpec->parID);
for (i = 0; i < outSpec->name[0]; i++) { dprintf ("%c", outSpec->name[i+1]); }
dprintf ("'\n");
} else {
dprintf ("POSIXPathToFSSpec returned error %d (%s)\n", err, error_message (err));
}
if (pathURL != NULL) { CFRelease (pathURL); }
if (pathString != NULL) { CFRelease (pathString); }
if (parentURL != NULL) { CFRelease (parentURL); }
if (nameString != NULL) { CFRelease (nameString); }
return err;
}