pascal OSErr FSpCatMoveCompat(const FSSpec *source, const FSSpec *dest) { #if !__MACOSSEVENORLATER if ( !FSHasFSSpecCalls() && !QTHasFSSpecCalls() ) { CMovePBRec pb; /* source and destination volume must be the same */ if ( source->vRefNum != dest->vRefNum ) return ( paramErr ); pb.ioNamePtr = (StringPtr) &(source->name); pb.ioVRefNum = source->vRefNum; pb.ioDirID = source->parID; pb.ioNewDirID = dest->parID; pb.ioNewName = (StringPtr) &(dest->name); return ( PBCatMoveSync(&pb) ); } else #endif /* !__MACOSSEVENORLATER */ { return ( FSpCatMove(source, dest) ); } }
pascal OSErr FSpExchangeFilesCompat(const FSSpec *source, const FSSpec *dest) { #if !__MACOSSEVENFIVEORLATER if ( #if !__MACOSSEVENORLATER !FSHasFSSpecCalls() || #endif /* !__MACOSSEVENORLATER */ !HasFSpExchangeFilesCompatibilityFix() ) { HParamBlockRec pb; CInfoPBRec catInfoSource, catInfoDest; OSErr result, result2; Str31 unique1, unique2; StringPtr unique1Ptr, unique2Ptr, swapola; GetVolParmsInfoBuffer volInfo; long theSeed, temp; /* Make sure the source and destination are on the same volume */ if ( source->vRefNum != dest->vRefNum ) { result = diffVolErr; goto errorExit3; } /* Try PBExchangeFiles first since it preserves the file ID reference */ pb.fidParam.ioNamePtr = (StringPtr) &(source->name); pb.fidParam.ioVRefNum = source->vRefNum; pb.fidParam.ioDestNamePtr = (StringPtr) &(dest->name); pb.fidParam.ioDestDirID = dest->parID; pb.fidParam.ioSrcDirID = source->parID; result = PBExchangeFilesSync(&pb); /* Note: The compatibility case won't work for files with *Btree control blocks. */ /* Right now the only *Btree files are created by the system. */ if ( result != noErr ) { pb.ioParam.ioNamePtr = NULL; pb.ioParam.ioBuffer = (Ptr) &volInfo; pb.ioParam.ioReqCount = sizeof(volInfo); result2 = PBHGetVolParmsSync(&pb); /* continue if volume has no fileID support (or no GetVolParms support) */ if ( (result2 == noErr) && hasFileIDs(volInfo) ) { goto errorExit3; } /* Get the catalog information for each file */ /* and make sure both files are *really* files */ catInfoSource.hFileInfo.ioVRefNum = source->vRefNum; catInfoSource.hFileInfo.ioFDirIndex = 0; catInfoSource.hFileInfo.ioNamePtr = (StringPtr) &(source->name); catInfoSource.hFileInfo.ioDirID = source->parID; catInfoSource.hFileInfo.ioACUser = 0; /* ioACUser used to be filler2 */ result = PBGetCatInfoSync(&catInfoSource); if ( result != noErr ) { goto errorExit3; } if ( (catInfoSource.hFileInfo.ioFlAttrib & kioFlAttribDirMask) != 0 ) { result = notAFileErr; goto errorExit3; } catInfoDest.hFileInfo.ioVRefNum = dest->vRefNum; catInfoDest.hFileInfo.ioFDirIndex = 0; catInfoDest.hFileInfo.ioNamePtr = (StringPtr) &(dest->name); catInfoDest.hFileInfo.ioDirID = dest->parID; catInfoDest.hFileInfo.ioACUser = 0; /* ioACUser used to be filler2 */ result = PBGetCatInfoSync(&catInfoDest); if ( result != noErr ) { goto errorExit3; } if ( (catInfoDest.hFileInfo.ioFlAttrib & kioFlAttribDirMask) != 0 ) { result = notAFileErr; goto errorExit3; } /* generate 2 filenames that are unique in both directories */ theSeed = 0x64666A6C; /* a fine unlikely filename */ unique1Ptr = (StringPtr)&unique1; unique2Ptr = (StringPtr)&unique2; result = GenerateUniqueName(source->vRefNum, &theSeed, source->parID, dest->parID, unique1Ptr); if ( result != noErr ) { goto errorExit3; } GenerateUniqueName(source->vRefNum, &theSeed, source->parID, dest->parID, unique2Ptr); if ( result != noErr ) { goto errorExit3; } /* rename source to unique1 */ pb.fileParam.ioNamePtr = (StringPtr) &(source->name); pb.ioParam.ioMisc = (Ptr) unique1Ptr; pb.ioParam.ioVersNum = 0; result = PBHRenameSync(&pb); if ( result != noErr ) { goto errorExit3; } /* rename dest to unique2 */ pb.ioParam.ioMisc = (Ptr) unique2Ptr; pb.ioParam.ioVersNum = 0; pb.fileParam.ioNamePtr = (StringPtr) &(dest->name); pb.fileParam.ioDirID = dest->parID; result = PBHRenameSync(&pb); if ( result != noErr ) { goto errorExit2; /* back out gracefully by renaming unique1 back to source */ } /* If files are not in same directory, swap their locations */ if ( source->parID != dest->parID ) { /* move source file to dest directory */ pb.copyParam.ioNamePtr = unique1Ptr; pb.copyParam.ioNewName = NULL; pb.copyParam.ioNewDirID = dest->parID; pb.copyParam.ioDirID = source->parID; result = PBCatMoveSync((CMovePBPtr) &pb); if ( result != noErr ) { goto errorExit1; /* back out gracefully by renaming both files to original names */ } /* move dest file to source directory */ pb.copyParam.ioNamePtr = unique2Ptr; pb.copyParam.ioNewDirID = source->parID; pb.copyParam.ioDirID = dest->parID; result = PBCatMoveSync((CMovePBPtr) &pb); if ( result != noErr) { /* life is very bad. We'll at least try to move source back */ pb.copyParam.ioNamePtr = unique1Ptr; pb.copyParam.ioNewName = NULL; pb.copyParam.ioNewDirID = source->parID; pb.copyParam.ioDirID = dest->parID; (void) PBCatMoveSync((CMovePBPtr) &pb); /* ignore errors */ goto errorExit1; /* back out gracefully by renaming both files to original names */ } } /* Make unique1Ptr point to file in source->parID */ /* and unique2Ptr point to file in dest->parID */ /* This lets us fall through to the rename code below */ swapola = unique1Ptr; unique1Ptr = unique2Ptr; unique2Ptr = swapola; /* At this point, the files are in their new locations (if they were moved) */ /* Source is named Unique1 (name pointed to by unique2Ptr) and is in dest->parID */ /* Dest is named Unique2 (name pointed to by unique1Ptr) and is in source->parID */ /* Need to swap attributes except mod date and swap names */ /* swap the catalog info by re-aiming the CInfoPB's */ catInfoSource.hFileInfo.ioNamePtr = unique1Ptr; catInfoDest.hFileInfo.ioNamePtr = unique2Ptr; catInfoSource.hFileInfo.ioDirID = source->parID; catInfoDest.hFileInfo.ioDirID = dest->parID; /* Swap the original mod dates with each file */ temp = catInfoSource.hFileInfo.ioFlMdDat; catInfoSource.hFileInfo.ioFlMdDat = catInfoDest.hFileInfo.ioFlMdDat; catInfoDest.hFileInfo.ioFlMdDat = temp; /* Here's the swap (ignore errors) */ (void) PBSetCatInfoSync(&catInfoSource); (void) PBSetCatInfoSync(&catInfoDest); /* rename unique2 back to dest */ errorExit1: pb.ioParam.ioMisc = (Ptr) &(dest->name); pb.ioParam.ioVersNum = 0; pb.fileParam.ioNamePtr = unique2Ptr; pb.fileParam.ioDirID = dest->parID; (void) PBHRenameSync(&pb); /* ignore errors */ /* rename unique1 back to source */ errorExit2: pb.ioParam.ioMisc = (Ptr) &(source->name); pb.ioParam.ioVersNum = 0; pb.fileParam.ioNamePtr = unique1Ptr; pb.fileParam.ioDirID = source->parID; (void) PBHRenameSync(&pb); /* ignore errors */ } errorExit3: { /* null statement */ } return ( result ); } else #endif /* !__MACOSSEVENFIVEORLATER */ { return ( FSpExchangeFiles(source, dest) ); } }
int __cdecl rename ( const char *oldname, const char *newname ) { /* ask OS to move file */ HParamBlockRec hparamBlock; char szOldName[32]; //old file name char szOldDir[256]; //old dir name char szNewName[32]; //new file name char szNewDir[256]; //new dir name char st[256]; //temp array for p-c string convertion char st2[256]; //temp array for p-c string conversion char szT[9]; //temp file name OSErr osErr; CMovePBRec cmovePB; int fTemp = 0; char *pch; char *pchOld; pchOld = strrchr(oldname, ':'); if ( (pchOld!= NULL) && (*(pchOld+1) == '\0') && (strchr(oldname, ':') == strrchr(oldname, ':')) ) { /* rename a volume*/ pch = strrchr(newname, ':'); if (pch != NULL && *(pch+1) != '\0') { /* not rename to another volume name*/ errno = EINVAL; return -1; } else if (pch != NULL && *(pch+1) == '\0') { osErr = __srename(oldname, newname); if (osErr) { _dosmaperr(osErr); return -1; } return 0; } else if (pch == NULL) { strcpy(szNewName, newname); strcat(szNewName, ":"); osErr = __srename(oldname, szNewName); if (osErr) { _dosmaperr(osErr); return -1; } return 0; } } /*Separate file name and directory*/ __getdirandname(szOldDir, szOldName, oldname); __getdirandname(szNewDir, szNewName, newname); if (strcmp(szNewName, "")==0) { errno = EINVAL; return -1; } /*if same dir*/ if (strcmp(szNewDir, szOldDir)==0 ) { osErr = __srename(oldname, newname); if (osErr) { /* error occured -- map error code and return */ _dosmaperr(osErr); return -1; } return 0; } /*if new directory didn't supplied, getcwd*/ if (!*szNewDir) { _getcwd(szNewDir, 255); } /*if same name*/ if (strcmp(szNewName, szOldName)==0 ) { /*just move*/ strcpy(st, oldname); strcpy(st2, szNewDir); cmovePB.ioNamePtr = _c2pstr(st); cmovePB.ioVRefNum = 0; cmovePB.ioNewName =_c2pstr(st2); cmovePB.ioNewDirID = 0; cmovePB.ioDirID = 0; osErr = PBCatMoveSync(&cmovePB); if (osErr) { /* error occured -- map error code and return */ if (osErr == nsvErr || osErr == bdNamErr) { errno = EXDEV; _macerrno = osErr; } else _dosmaperr(osErr); return -1; } return 0; } osErr = __accesspath(szOldDir, szNewName); if (osErr != fnfErr) { /* rename the file to a temp name */ strcpy(st, szOldDir); strcpy(szT, "fnXXXXXX"); if (_mktemp(szT)!=NULL) { strcat(st, szT); fTemp = 1; } } else { *st='\0'; if (*szOldDir) { strcpy(st, szOldDir); } strcat(st, szNewName); } osErr = __srename(oldname, st); if (osErr) { _dosmaperr(osErr); return -1; } strcpy(st2, szNewDir); /* move renamed file to new dir */ cmovePB.ioNamePtr = _c2pstr(st); cmovePB.ioVRefNum = 0; cmovePB.ioNewName =_c2pstr(st2); cmovePB.ioNewDirID = 0; cmovePB.ioDirID = 0; osErr = PBCatMoveSync(&cmovePB); if (osErr) { /* error occured -- rename oldname back */ strcpy(st2, oldname); hparamBlock.ioParam.ioNamePtr = st; hparamBlock.ioParam.ioVRefNum = 0; hparamBlock.ioParam.ioMisc = _c2pstr(st2); hparamBlock.fileParam.ioDirID = 0; PBHRenameSync(&hparamBlock); if (osErr == nsvErr || osErr == bdNamErr) { errno=EXDEV; _macerrno = osErr; } else _dosmaperr(osErr); return -1; } /* rename it to the new name in new dir*/ if (fTemp) { strcpy(st, szNewDir); strcat(st, szT); osErr = __srename(st, newname); if (osErr) { _dosmaperr(osErr); remove(st); return -1; } } return 0; }