int doItTheHardWay(unsigned char *pathString,FSSpec *spec,Boolean noDrillDown) { char *token; Str255 lookup; Boolean firstTime=true; OSErr err; long parentDirectory,tokenLength; token = strtok((char*) pathString,":"); if (token == 0) return -1; while (token) { tokenLength = strlen(token) > 255 ? 255 : strlen(token); if (firstTime) { strncpy((char*) lookup+1,(char*) token,tokenLength); lookup[0] = tokenLength+1; lookup[lookup[0]] = ':'; firstTime = false; } else { if (tokenLength == 255) { /* This is broken */ FSSpec spec2; strncpy((char*) lookup+1,(char*) token,tokenLength); lookup[0] = tokenLength; if ((err = FSMakeFSSpecCompat(spec->vRefNum,spec->parID, lookup, &spec2)) != noErr) return err; } else { strncpy((char*) lookup+2,(char*) token,tokenLength); lookup[0] = tokenLength+1; lookup[1] = ':'; } } if ((err = FSMakeFSSpecCompat(spec->vRefNum,spec->parID, lookup, spec)) != noErr) return err; fetchFileSpec(spec,spec->name,&parentDirectory); token = strtok(nil,":"); } if (noDrillDown) spec->parID = parentDirectory; return noErr; }
int lookupPath(char *pathString, int pathStringLength, FSSpec *spec,Boolean noDrillDown,Boolean tryShortCut) { /* Resolve the given path and return the resulting folder or volume reference number in *refNumPtr. Return error if the path is bad. */ char tempName[1001]; OSErr err; int i; if (pathStringLength < 256 && tryShortCut) { /* First locate by farily normal methods, with perhaps an alias lookup */ tempName[0] = pathStringLength; strncpy((char *)tempName+1,pathString,pathStringLength); err = FSMakeFSSpecCompat(0,0,(unsigned char*) tempName,spec); if (err == noErr) { if (noDrillDown == false) { fetchFileSpec(spec,spec->name,nil); } return noErr; } } /* Than failed, we might have an alias chain, or other issue so first setup for directory or file then do it the hard way */ strncpy((char *)tempName,pathString,pathStringLength); if (noDrillDown) { tempName[pathStringLength] = 0x00; } else { tempName[pathStringLength] = ':'; tempName[pathStringLength+1] = 0x00; } i = 0; while(tempName[i]) { if(tempName[i] == ':') { if(tempName[i+1] == ':') return fnfErr; /* fix for :: doItTheHardWay can't deal with this */ } i++; } err = doItTheHardWay((unsigned char*) tempName,spec,noDrillDown); return err; }
int FSpGetDefaultDir( FSSpecPtr dirSpec) /* On return the default directory. */ { OSErr err; short vRefNum = 0; long int dirID = 0; err = HGetVol(NULL, &vRefNum, &dirID); if (err == noErr) { err = FSMakeFSSpecCompat(vRefNum, dirID, (ConstStr255Param) NULL, dirSpec); } return err; }
static int fetchFileSpec(FSSpec *spec,unsigned char *name,long *parentDirectory) { long aliasGestaltInfo; CInfoPBRec pb; Boolean result,ignore; FSSpec spec2; OSErr err; pb.hFileInfo.ioNamePtr = name; pb.hFileInfo.ioFVersNum = 0; pb.hFileInfo.ioFDirIndex = 0; pb.hFileInfo.ioVRefNum = spec->vRefNum; pb.hFileInfo.ioDirID = spec->parID; if (PBGetCatInfoSync(&pb) == noErr) { if (pb.hFileInfo.ioFlFndrInfo.fdFlags & kIsAlias) { err = FSMakeFSSpecCompat(spec->vRefNum, spec->parID, name,&spec2); #if TARGET_CPU_PPC if ((Gestalt(gestaltAliasMgrAttr, &aliasGestaltInfo) == noErr) && aliasGestaltInfo & (1<<gestaltAliasMgrResolveAliasFileWithMountOptions) && ((Ptr) ResolveAliasFileWithMountFlags != (Ptr)kUnresolvedCFragSymbolAddress)) { err = ResolveAliasFileWithMountFlags(&spec2,false,&ignore,&ignore,kResolveAliasFileNoUI); } else #endif err = ResolveAliasFile(&spec2,false,&ignore,&ignore); if (err == noErr) { fetchFileSpec(&spec2,spec2.name,parentDirectory); *spec = spec2; result = true; goto done; } } spec->parID = pb.hFileInfo.ioDirID; result = true; goto done; } result = false; done: if (parentDirectory != nil) *parentDirectory = pb.dirInfo.ioDrParID; return result; }
pascal OSErr GetFullPath(short vRefNum, long dirID, ConstStr255Param name, short *fullPathLength, Handle *fullPath) { OSErr result; FSSpec spec; *fullPathLength = 0; *fullPath = NULL; result = FSMakeFSSpecCompat(vRefNum, dirID, name, &spec); if ( (result == noErr) || (result == fnfErr) ) { result = FSpGetFullPath(&spec, fullPathLength, fullPath); } return ( result ); }
static OSErr MoveRename( const FSSpec *srcFileSpecPtr, /* Source object. */ const FSSpec *dstDirSpecPtr, /* Destination directory. */ StringPtr copyName) /* New name for object in destination * directory. */ { OSErr err; long srcID, dstID; Boolean srcIsDir, dstIsDir; Str31 tmpName; FSSpec dstFileSpec, srcDirSpec, tmpSrcFileSpec, tmpDstFileSpec; Boolean locked; if (srcFileSpecPtr->parID == 1) { /* * Trying to rename a volume. */ return badMovErr; } if (srcFileSpecPtr->vRefNum != dstDirSpecPtr->vRefNum) { /* * Renaming across volumes. */ return diffVolErr; } err = FSpGetFLockCompat(srcFileSpecPtr, &locked); if (locked) { FSpRstFLockCompat(srcFileSpecPtr); } if (err == noErr) { err = FSpGetDirectoryID(dstDirSpecPtr, &dstID, &dstIsDir); } if (err == noErr) { if (srcFileSpecPtr->parID == dstID) { /* * Renaming object within directory. */ err = FSpRenameCompat(srcFileSpecPtr, copyName); goto done; } if (Pstrequal(srcFileSpecPtr->name, copyName)) { /* * Moving object to another directory (under same name). */ err = FSpCatMoveCompat(srcFileSpecPtr, dstDirSpecPtr); goto done; } err = FSpGetDirectoryID(srcFileSpecPtr, &srcID, &srcIsDir); } if (err == noErr) { /* * Fullblown: rename source object to temp name, move temp to * dest directory, and rename temp to target. */ err = GenerateUniqueName(srcFileSpecPtr->vRefNum, srcFileSpecPtr->parID, dstID, tmpName); FSMakeFSSpecCompat(srcFileSpecPtr->vRefNum, srcFileSpecPtr->parID, tmpName, &tmpSrcFileSpec); FSMakeFSSpecCompat(dstDirSpecPtr->vRefNum, dstID, tmpName, &tmpDstFileSpec); } if (err == noErr) { err = FSpRenameCompat(srcFileSpecPtr, tmpName); } if (err == noErr) { err = FSpCatMoveCompat(&tmpSrcFileSpec, dstDirSpecPtr); if (err == noErr) { err = FSpRenameCompat(&tmpDstFileSpec, copyName); if (err == noErr) { goto done; } FSMakeFSSpecCompat(srcFileSpecPtr->vRefNum, srcFileSpecPtr->parID, NULL, &srcDirSpec); FSpCatMoveCompat(&tmpDstFileSpec, &srcDirSpec); } FSpRenameCompat(&tmpSrcFileSpec, srcFileSpecPtr->name); } done: if (locked != false) { if (err == noErr) { FSMakeFSSpecCompat(dstDirSpecPtr->vRefNum, dstID, copyName, &dstFileSpec); FSpSetFLockCompat(&dstFileSpec); } else { FSpSetFLockCompat(srcFileSpecPtr); } } return err; }
int TclpCopyDirectory( char *src, /* Pathname of directory to be copied. */ char *dst, /* Pathname of target directory. */ Tcl_DString *errorPtr) /* If non-NULL, initialized DString for * error reporting. */ { OSErr err, saveErr; long srcID, tmpDirID; FSSpec srcFileSpec, dstFileSpec, dstDirSpec, tmpDirSpec, tmpFileSpec; Boolean srcIsDirectory, srcLocked; Boolean dstIsDirectory, dstExists; Str31 tmpName; err = FSpLocationFromPath(strlen(src), src, &srcFileSpec); if (err == noErr) { err = FSpGetDirectoryID(&srcFileSpec, &srcID, &srcIsDirectory); } if (err == noErr) { if (srcIsDirectory == false) { err = afpObjectTypeErr; /* ENOTDIR. */ } } if (err == noErr) { err = GetFileSpecs(dst, &dstFileSpec, &dstDirSpec, &dstExists, &dstIsDirectory); } if (dstExists) { if (dstIsDirectory == false) { err = afpObjectTypeErr; /* ENOTDIR. */ } else { err = dupFNErr; /* EEXIST. */ } } if (err != noErr) { goto done; } if ((srcFileSpec.vRefNum == dstFileSpec.vRefNum) && (srcFileSpec.parID == dstFileSpec.parID) && (Pstrequal(srcFileSpec.name, dstFileSpec.name) != 0)) { /* * Copying on top of self. No-op. */ goto done; } /* * This algorthm will work making a copy of the source directory in * the current directory with a new name, in a new directory with the * same name, and in a new directory with a new name: * * 1. Make dstDir/tmpDir. * 2. Copy srcDir/src to dstDir/tmpDir/src * 3. Rename dstDir/tmpDir/src to dstDir/tmpDir/dst (if necessary). * 4. CatMove dstDir/tmpDir/dst to dstDir/dst. * 5. Remove dstDir/tmpDir. */ err = FSpGetFLockCompat(&srcFileSpec, &srcLocked); if (srcLocked) { FSpRstFLockCompat(&srcFileSpec); } if (err == noErr) { err = GenerateUniqueName(dstFileSpec.vRefNum, dstFileSpec.parID, dstFileSpec.parID, tmpName); } if (err == noErr) { FSMakeFSSpecCompat(dstFileSpec.vRefNum, dstFileSpec.parID, tmpName, &tmpDirSpec); err = FSpDirCreateCompat(&tmpDirSpec, smSystemScript, &tmpDirID); } if (err == noErr) { err = FSpDirectoryCopy(&srcFileSpec, &tmpDirSpec, NULL, 0, true, CopyErrHandler); } /* * Even if the Copy failed, Rename/Move whatever did get copied to the * appropriate final destination, if possible. */ saveErr = err; err = noErr; if (Pstrequal(srcFileSpec.name, dstFileSpec.name) == 0) { err = FSMakeFSSpecCompat(tmpDirSpec.vRefNum, tmpDirID, srcFileSpec.name, &tmpFileSpec); if (err == noErr) { err = FSpRenameCompat(&tmpFileSpec, dstFileSpec.name); } } if (err == noErr) { err = FSMakeFSSpecCompat(tmpDirSpec.vRefNum, tmpDirID, dstFileSpec.name, &tmpFileSpec); } if (err == noErr) { err = FSpCatMoveCompat(&tmpFileSpec, &dstDirSpec); } if (err == noErr) { if (srcLocked) { FSpSetFLockCompat(&dstFileSpec); } } FSpDeleteCompat(&tmpDirSpec); if (saveErr != noErr) { err = saveErr; } done: if (err != noErr) { errno = TclMacOSErrorToPosixError(err); if (errorPtr != NULL) { Tcl_DStringAppend(errorPtr, dst, -1); } return TCL_ERROR; } return TCL_OK; }
int TclpCopyFile( char *src, /* Pathname of file to be copied. */ char *dst) /* Pathname of file to copy to. */ { OSErr err, dstErr; Boolean dstExists, dstIsDirectory, dstLocked; FSSpec srcFileSpec, dstFileSpec, dstDirSpec, tmpFileSpec; Str31 tmpName; err = FSpLocationFromPath(strlen(src), src, &srcFileSpec); if (err == noErr) { err = GetFileSpecs(dst, &dstFileSpec, &dstDirSpec, &dstExists, &dstIsDirectory); } if (dstExists) { if (dstIsDirectory) { errno = EISDIR; return TCL_ERROR; } err = FSpGetFLockCompat(&dstFileSpec, &dstLocked); if (dstLocked) { FSpRstFLockCompat(&dstFileSpec); } /* * Backup dest file. */ dstErr = GenerateUniqueName(dstFileSpec.vRefNum, dstFileSpec.parID, dstFileSpec.parID, tmpName); if (dstErr == noErr) { dstErr = FSpRenameCompat(&dstFileSpec, tmpName); } } if (err == noErr) { err = FSpFileCopy(&srcFileSpec, &dstDirSpec, (StringPtr) dstFileSpec.name, NULL, 0, true); } if ((dstExists != false) && (dstErr == noErr)) { FSMakeFSSpecCompat(dstFileSpec.vRefNum, dstFileSpec.parID, tmpName, &tmpFileSpec); if (err == noErr) { /* * Delete backup file. */ FSpDeleteCompat(&tmpFileSpec); } else { /* * Restore backup file. */ FSpDeleteCompat(&dstFileSpec); FSpRenameCompat(&tmpFileSpec, dstFileSpec.name); if (dstLocked) { FSpSetFLockCompat(&dstFileSpec); } } } if (err != noErr) { errno = TclMacOSErrorToPosixError(err); return TCL_ERROR; } return TCL_OK; }
int TclpRenameFile( char *src, /* Pathname of file or dir to be renamed. */ char *dst) /* New pathname for file or directory. */ { FSSpec srcFileSpec, dstFileSpec, dstDirSpec; OSErr err; long srcID, dummy; Boolean srcIsDirectory, dstIsDirectory, dstExists, dstLocked; err = FSpLocationFromPath(strlen(src), src, &srcFileSpec); if (err == noErr) { FSpGetDirectoryID(&srcFileSpec, &srcID, &srcIsDirectory); } if (err == noErr) { err = GetFileSpecs(dst, &dstFileSpec, &dstDirSpec, &dstExists, &dstIsDirectory); } if (err == noErr) { if (dstExists == 0) { err = MoveRename(&srcFileSpec, &dstDirSpec, dstFileSpec.name); goto end; } err = FSpGetFLockCompat(&dstFileSpec, &dstLocked); if (dstLocked) { FSpRstFLockCompat(&dstFileSpec); } } if (err == noErr) { if (srcIsDirectory) { if (dstIsDirectory) { /* * The following call will remove an empty directory. If it * fails, it's because it wasn't empty. */ if (TclpRemoveDirectory(dst, 0, NULL) != TCL_OK) { return TCL_ERROR; } /* * Now that that empty directory is gone, we can try * renaming src. If that fails, we'll put this empty * directory back, for completeness. */ err = MoveRename(&srcFileSpec, &dstDirSpec, dstFileSpec.name); if (err != noErr) { FSpDirCreateCompat(&dstFileSpec, smSystemScript, &dummy); if (dstLocked) { FSpSetFLockCompat(&dstFileSpec); } } } else { errno = ENOTDIR; return TCL_ERROR; } } else { if (dstIsDirectory) { errno = EISDIR; return TCL_ERROR; } else { /* * Overwrite existing file by: * * 1. Rename existing file to temp name. * 2. Rename old file to new name. * 3. If success, delete temp file. If failure, * put temp file back to old name. */ Str31 tmpName; FSSpec tmpFileSpec; err = GenerateUniqueName(dstFileSpec.vRefNum, dstFileSpec.parID, dstFileSpec.parID, tmpName); if (err == noErr) { err = FSpRenameCompat(&dstFileSpec, tmpName); } if (err == noErr) { err = FSMakeFSSpecCompat(dstFileSpec.vRefNum, dstFileSpec.parID, tmpName, &tmpFileSpec); } if (err == noErr) { err = MoveRename(&srcFileSpec, &dstDirSpec, dstFileSpec.name); } if (err == noErr) { FSpDeleteCompat(&tmpFileSpec); } else { FSpDeleteCompat(&dstFileSpec); FSpRenameCompat(&tmpFileSpec, dstFileSpec.name); if (dstLocked) { FSpSetFLockCompat(&dstFileSpec); } } } } } end: if (err != noErr) { errno = TclMacOSErrorToPosixError(err); return TCL_ERROR; } return TCL_OK; }
/*Get the file ID that unique IDs this file or directory, also resolve any alias if required */ int fetchFileInfo(int dirIndex,FSSpec *spec,unsigned char *name,Boolean doAlias,long *parentDirectory, int *isFolder,int *createDateStorage,int *modificationDateStorage,squeakFileOffsetType *sizeOfFile,Str255 *longFileName) { long aliasGestaltInfo; CInfoPBRec pb; Boolean isFolder2; OSErr error,result; *isFolder = false; pb.hFileInfo.ioNamePtr = name; pb.hFileInfo.ioFVersNum = 0; pb.hFileInfo.ioFDirIndex = dirIndex; pb.hFileInfo.ioVRefNum = spec->vRefNum; pb.hFileInfo.ioDirID = spec->parID; if ((error = PBGetCatInfoSync(&pb)) == noErr) { if ((pb.hFileInfo.ioFlFndrInfo.fdFlags & kIsAlias) && doAlias) { FSSpec spec2,spec3; Boolean isAlias; OSErr err; err = FSMakeFSSpecCompat(spec->vRefNum, spec->parID, name,&spec2); spec3 = spec2; #if TARGET_CPU_PPC if ((Gestalt(gestaltAliasMgrAttr, &aliasGestaltInfo) == noErr) && aliasGestaltInfo & (1<<gestaltAliasMgrResolveAliasFileWithMountOptions) && ((Ptr) ResolveAliasFileWithMountFlags != (Ptr)kUnresolvedCFragSymbolAddress)) { err = ResolveAliasFileWithMountFlags(&spec2,false,&isFolder2,&isAlias,kResolveAliasFileNoUI); } else { err = ResolveAliasFile(&spec2,false,&isFolder2,&isAlias); } #else err = ResolveAliasFile(&spec2,false,&isFolder2,&isAlias); #endif *isFolder = isFolder2; if (err == noErr) { resolveLongName(0,0,nil,&spec3,*isFolder,longFileName,sizeOfFile); result = noErr; goto done; } } if ((pb.hFileInfo.ioFlAttrib & kioFlAttribDirMask) != 0) *sizeOfFile = 0; else *sizeOfFile = pb.hFileInfo.ioFlLgLen; resolveLongName(pb.hFileInfo.ioVRefNum,pb.hFileInfo.ioFlParID,name,nil,((pb.hFileInfo.ioFlAttrib & kioFlAttribDirMask) > 0),longFileName,sizeOfFile); spec->parID = pb.hFileInfo.ioDirID; result = noErr; goto done; } result = error; memcpy(longFileName,name,sizeof(StrFileName)); done: *isFolder = ((pb.hFileInfo.ioFlAttrib & kioFlAttribDirMask) > 0) || *isFolder; *createDateStorage = pb.hFileInfo.ioFlCrDat; *modificationDateStorage = pb.hFileInfo.ioFlMdDat; *parentDirectory = pb.dirInfo.ioDrParID; return result; }
static OSErr FSpGetFullPath(const FSSpec *spec, short *fullPathLength, Handle *fullPath) { OSErr result; OSErr realResult; FSSpec tempSpec; CInfoPBRec pb; *fullPathLength = 0; *fullPath = nil; /* Default to noErr */ realResult = result = noErr; result = FSMakeFSSpecCompat(spec->vRefNum, spec->parID, spec->name, &tempSpec); if ( result == noErr ) { if ( tempSpec.parID == fsRtParID ) { /* The object is a volume */ /* Add a colon to make it a full pathname */ ++tempSpec.name[0]; tempSpec.name[tempSpec.name[0]] = ':'; /* We're done */ result = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); *fullPathLength = tempSpec.name[0]; } else { /* The object isn't a volume */ /* Is the object a file or a directory? */ pb.dirInfo.ioNamePtr = tempSpec.name; pb.dirInfo.ioVRefNum = tempSpec.vRefNum; pb.dirInfo.ioDrDirID = tempSpec.parID; pb.dirInfo.ioFDirIndex = 0; result = PBGetCatInfoSync(&pb); // Allow file/directory name at end of path to not exist. realResult = result; if ( (result == noErr) || (result == fnfErr) ) { /* if the object is a directory, append a colon so full pathname ends with colon */ if ( (result == noErr) && (pb.hFileInfo.ioFlAttrib & kioFlAttribDirMask) != 0 ) { ++tempSpec.name[0]; tempSpec.name[tempSpec.name[0]] = ':'; } /* Put the object name in first */ result = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); *fullPathLength = tempSpec.name[0]; if ( result == noErr ) { /* Get the ancestor directory names */ pb.dirInfo.ioNamePtr = tempSpec.name; pb.dirInfo.ioVRefNum = tempSpec.vRefNum; pb.dirInfo.ioDrParID = tempSpec.parID; do /* loop until we have an error or find the root directory */ { pb.dirInfo.ioFDirIndex = -1; pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID; result = PBGetCatInfoSync(&pb); if ( result == noErr ) { /* Append colon to directory name */ ++tempSpec.name[0]; tempSpec.name[tempSpec.name[0]] = ':'; /* Add directory name to beginning of fullPath */ (void) Munger(*fullPath, 0, nil, 0, &tempSpec.name[1], tempSpec.name[0]); *fullPathLength += tempSpec.name[0]; result = MemError(); } } while ( (result == noErr) && (pb.dirInfo.ioDrDirID != fsRtDirID) ); } } } } if ( result == noErr ) { /* Return the length */ /// *fullPathLength = GetHandleSize(*fullPath); result = realResult; // return realResult in case it was fnfErr } else { /* Dispose of the handle and return nil and zero length */ if ( *fullPath != nil ) { DisposeHandle(*fullPath); } *fullPath = nil; *fullPathLength = 0; } return ( result ); }
int doItTheHardWay(unsigned char *pathString,FSSpec *spec,Boolean noDrillDown) { char *token; Str255 lookup; UniChar buffer[1024]; Boolean firstTime=true; OSErr err; long parentDirectory,tokenLength; FSRef parentFSRef,childFSRef; CFStringRef aLevel; FSSpec fix; token = strtok((char*) pathString,":"); if (token == 0) return -1; while (token) { tokenLength = strlen(token); if (firstTime) {// Mmm will crash if volume name is 255 characters, unlikely strncpy((char*) lookup+1,(char*) token,tokenLength); lookup[0] = tokenLength+1; lookup[lookup[0]] = ':'; firstTime = false; err = FSMakeFSSpecCompat(spec->vRefNum,spec->parID, lookup, spec); if (err != noErr) return err; err = FSpMakeFSRef(spec,&parentFSRef); if (err != noErr) return err; } else { fix = *spec; fix.name[0] = 0; err = FSpMakeFSRef(&fix,&parentFSRef); if (err != noErr) return err; aLevel = CFStringCreateWithCString(kCFAllocatorDefault,token,gCurrentVMEncoding); if (aLevel == nil) return -1000; tokenLength = CFStringGetLength(aLevel); CFStringGetCharacters(aLevel,CFRangeMake(0,tokenLength),buffer); err = FSMakeFSRefUnicode(&parentFSRef,tokenLength,buffer,gCurrentVMEncoding,&childFSRef); if (err != noErr) { CFStringGetPascalString(aLevel,spec->name,64,gCurrentVMEncoding); CFRelease(aLevel); token = strtok(nil,":"); if (token == nil) return err; else return -1001; } CFRelease(aLevel); parentFSRef = childFSRef; err = FSGetCatalogInfo (&parentFSRef,kFSCatInfoNone,nil,nil,spec,nil); if (err != noErr) return err; } fetchFileSpec(spec,spec->name,&parentDirectory); token = strtok(nil,":"); } if (noDrillDown) spec->parID = parentDirectory; return noErr; }
static int FSpLocationFromPathAlias( int length, /* Length of path. */ CONST char *path, /* The path to convert. */ FSSpecPtr fileSpecPtr, /* On return the spec for the path. */ Boolean resolveLink) /* Resolve the last path component? */ { Str255 fileName; OSErr err; short vRefNum; long dirID; int pos, cur; Boolean isDirectory; Boolean wasAlias=FALSE; FSSpec lastFileSpec; /* * Check to see if this is a full path. If partial * we assume that path starts with the current working * directory. (Ie. volume & dir = 0) */ vRefNum = 0; dirID = 0; cur = 0; if (length == 0) { return fnfErr; } if (path[cur] == ':') { cur++; if (cur >= length) { /* * If path = ":", just return current directory. */ FSMakeFSSpecCompat(0, 0, NULL, fileSpecPtr); return noErr; } } else { while (path[cur] != ':' && cur < length) { cur++; } if (cur > 255) { return bdNamErr; } if (cur < length) { /* * This is a full path */ cur++; strncpy((char *) fileName + 1, path, cur); fileName[0] = cur; err = FSMakeFSSpecCompat(0, 0, fileName, fileSpecPtr); if (err != noErr) return err; FSpGetDirectoryID(fileSpecPtr, &dirID, &isDirectory); vRefNum = fileSpecPtr->vRefNum; } else { cur = 0; } } isDirectory = 1; while (cur < length) { if (!isDirectory) { return dirNFErr; } pos = cur; while (path[pos] != ':' && pos < length) { pos++; } if (pos == cur) { /* Move up one dir */ /* cur++; */ strcpy((char *) fileName + 1, "::"); fileName[0] = 2; } else if (pos - cur > 255) { return bdNamErr; } else { strncpy((char *) fileName + 1, &path[cur], pos - cur); fileName[0] = pos - cur; } err = FSMakeFSSpecCompat(vRefNum, dirID, fileName, fileSpecPtr); if (err != noErr) return err; lastFileSpec=*fileSpecPtr; err = ResolveAliasFile(fileSpecPtr, true, &isDirectory, &wasAlias); if (err != noErr) { /* ignore alias resolve errors on last path component */ if (pos < length) return err; else *fileSpecPtr=lastFileSpec; } FSpGetDirectoryID(fileSpecPtr, &dirID, &isDirectory); vRefNum = fileSpecPtr->vRefNum; cur = pos; if (path[cur] == ':') { cur++; } } if(!resolveLink && wasAlias) *fileSpecPtr=lastFileSpec; return noErr; }