Beispiel #1
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;
}
Beispiel #2
0
/*
 * Like rename() but will try to copy the file if the rename fails.
 * This is because under OS's with multiple physical volumes if the
 * source and destination are on different volumes the rename will fail
 */
int rename2(char *srcFile, char *destFile)
{
    FILE *f, *g;
#ifdef MACTC5
	int copy=-1;
#endif
    int status = 0;
    long fileLength;

#ifdef MACTC5
	copy=MoveRename(srcFile,destFile);
if (copy)
#else
#if defined(VMS) || defined(C370)
    if (rename(srcFile, destFile) != 0)
#else
    if (rename(srcFile, destFile) == -1)
#endif
#endif
    {
	/* Rename failed, try a copy */
	if (((f = fopen(srcFile, FOPRBIN)) == NULL) ||
	    ((g = fopen(destFile, FOPWBIN)) == NULL))
	    /* Can't open files */
	    return -1;

#ifdef MACTC5
		{
		FInfo finderInfo;
		c2pstr(srcFile);
		c2pstr(destFile);
		if(GetFInfo((uchar *)srcFile,0,&finderInfo)==0)
			SetFInfo((uchar *)destFile,0,&finderInfo);
		p2cstr((uchar *)srcFile);
		p2cstr((uchar *)destFile);
		}
#endif

	/* Get file length and copy it */
	fseek(f, 0L, SEEK_END);
	fileLength = ftell(f);
	rewind(f);
	status = copyfile(f, g, fileLength);
	if (write_error(g))
	    status = -1;

	/* Zap source file if the copy went OK, otherwise zap the (possibly
	   incomplete) destination file */
	if (status >= 0) {
	    wipeout(f);		/* Zap source file */
	    fclose(f);
	    remove(srcFile);
	    fclose(g);
	} else {
	    if (is_regular_file(destFile)) {
		wipeout(g);	/* Zap destination file */
		fclose(g);
		remove(destFile);
	    } else {
		fclose(g);
	    }
	    fclose(f);
	}
    }
    return status;
}