예제 #1
0
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;
}		 
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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 );
}
예제 #6
0
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;
}     
예제 #7
0
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;
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #10
0
/*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;
}
예제 #11
0
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 );
}
예제 #12
0
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;
}
예제 #13
0
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;
}