home *** CD-ROM | disk | FTP | other *** search
- /* Files.c */
- /*****************************************************************************/
- /* */
- /* System Dependency Library for Building Portable Software */
- /* Macintosh Version */
- /* Written by Thomas R. Lawrence, 1993 - 1994. */
- /* */
- /* This file is Public Domain; it may be used for any purpose whatsoever */
- /* without restriction. */
- /* */
- /* This package is distributed in the hope that it will be useful, */
- /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */
- /* */
- /* Thomas R. Lawrence can be reached at tomlaw@world.std.com. */
- /* */
- /*****************************************************************************/
-
- #include "MiscInfo.h"
- #include "Debug.h"
- #include "Audit.h"
- #include "Definitions.h"
-
- #ifdef THINK_C
- #pragma options(pack_enums)
- #endif
- #include <Files.h>
- #include <Folders.h>
- #include <Finder.h>
- #include <Script.h>
- #include <Events.h>
- #include <Errors.h>
- #include <StandardFile.h>
- #ifdef THINK_C
- #pragma options(!pack_enums)
- #endif
-
- #include "Files.h"
- #include "Memory.h"
- #include "Array.h"
-
-
- /* open file abstraction. for efficiency, we ought to be having buffers */
- /* and all kinds of stuff in here, but we're too lazy to implement it. */
- struct FileType
- {
- /* refnum for Macintosh file system OS calls */
- short Refnum;
- };
-
-
- /* global variable containing the last I/O error. Haven't decided what */
- /* to use it for yet. */
- static OSErr LastError;
-
- /* things for debugging */
- EXECUTE(static ArrayRec* FileSpecList;)
- EXECUTE(static ArrayRec* FileDescriptorList;)
-
-
- /* initialize the file subsystem. should only be called from Screen */
- MyBoolean Eep_InitializeFiles(void)
- {
- APRINT(("+Eep_InitializeFiles"));
- #if DEBUG
- FileSpecList = NewArray();
- if (FileSpecList == NIL)
- {
- FailurePoint1:
- APRINT(("-Eep_InitializeFiles failed"));
- return False;
- }
- FileDescriptorList = NewArray();
- if (FileDescriptorList == NIL)
- {
- FailurePoint2:
- DisposeArray(FileSpecList);
- goto FailurePoint1;
- }
- #endif
- APRINT(("-Eep_InitializeFiles"));
- return True;
- }
-
-
- /* shutdown the file subsystem. */
- void Eep_ShutdownFiles(void)
- {
- APRINT(("+Eep_ShutdownFiles"));
- #if DEBUG
- ERROR(ArrayGetLength(FileSpecList) != 0,PRERR(AllowResume,
- "Eep_ShutdownFiles: some file specs still exist"));
- ERROR(ArrayGetLength(FileDescriptorList) != 0,PRERR(AllowResume,
- "FileDescriptorList: some files are still open"));
- DisposeArray(FileSpecList);
- DisposeArray(FileDescriptorList);
- #endif
- APRINT(("-Eep_ShutdownFiles"));
- }
-
-
- /* this is an internal routine -- do not use */
- #if DEBUG
- MyBoolean Eep_RegisterFileSpec(FileSpec* Spec)
- {
- CheckPtrExistence(Spec);
- return ArrayAppendElement(FileSpecList,Spec);
- }
- #endif
-
-
- /* this routine validates a file specification to make sure it exists */
- #if DEBUG
- void ValidateFileSpec(FileSpec* Spec)
- {
- CheckPtrExistence(Spec);
- ERROR(-1 == ArrayFindElement(FileSpecList,Spec),PRERR(ForceAbort,
- "ValidateFileSpec: undefined file specification"));
- }
- #endif
-
-
- /* make a copy of a file specification */
- /* this routine does not perform operations on file descriptors. */
- FileSpec* DuplicateFileSpec(FileSpec* Original)
- {
- FileSpec* Copy;
-
- APRINT(("+DuplicateFileSpec %xl",Original));
- ERROR(-1 == ArrayFindElement(FileSpecList,Original),PRERR(ForceAbort,
- "DuplicateFileSpec: undefined file specification"));
- Copy = (FileSpec*)AllocPtrCanFail(sizeof(FSSpec),"FileSpec");
- if (Copy != NIL)
- {
- CopyData((char*)Original,(char*)Copy,sizeof(FSSpec));
- if (!Eep_RegisterFileSpec(Copy))
- {
- ReleasePtr((char*)Copy);
- Copy = NIL;
- }
- }
- APRINT(("-DuplicateFileSpec %xl",Copy));
- return Copy;
- }
-
-
- /* dispose of a file specification thing */
- void DisposeFileSpec(FileSpec* Spec)
- {
- APRINT(("+DisposeFileSpec %xl",Spec));
- ERROR(-1 == ArrayFindElement(FileSpecList,Spec),PRERR(ForceAbort,
- "DisposeFileSpec: undefined file specification"));
- EXECUTE(ArrayDeleteElement(FileSpecList,ArrayFindElement(FileSpecList,Spec)));
- ReleasePtr((char*)Spec);
- APRINT(("-DisposeFileSpec"));
- }
-
-
- /* create a new temporary file with a known unique name, and return a specification */
- /* leading to it. the creator and filetype codes may or may not be used by */
- /* the implementation; the Macintosh does use them. The file is actually created. */
- /* this routine does not perform operations on file descriptors. */
- FileSpec* NewTempFileSpec(unsigned long Creator, unsigned long FileType)
- {
- short vRefNum;
- long DirID;
- FSSpec* Temp;
- unsigned char Name[32] = "\pTempFile........";
- int Scan;
- unsigned long Key;
-
- APRINT(("+NewTempFileSpec"));
- FindFolder(kOnSystemDisk,kTemporaryFolderType,kCreateFolder,&vRefNum,&DirID);
- Temp = (FSSpec*)AllocPtrCanFail(sizeof(FSSpec),"FileSpec");
- if (Temp == NIL)
- {
- APRINT(("-NewTempFileSpec NIL"));
- return NIL;
- }
- Key = TickCount();
- TryPoint:
- for (Scan = 0; Scan < 8; Scan += 1)
- {
- Name[Scan + 9] = ((Key >> (Scan * 4)) & 0x0f) + 'a';
- }
- FSMakeFSSpec(vRefNum,DirID,Name,Temp);
- LastError = FSpCreate(Temp,Creator,FileType,smSystemScript);
- if (LastError == dupFNErr)
- {
- Key += 1;
- goto TryPoint;
- }
- if (LastError != noErr)
- {
- ReleasePtr((char*)Temp);
- Temp = NIL;
- }
- if (Temp != NIL)
- {
- if (!Eep_RegisterFileSpec((FileSpec*)Temp))
- {
- ReleasePtr((char*)Temp);
- Temp = NIL;
- }
- }
- APRINT(("-NewTempFileSpec %r",Temp));
- return (FileSpec*)Temp;
- }
-
-
- /* create a file spec leading to a named preference file. The location of preference */
- /* files are implementation defined: UNIX may put them in the user's home directory */
- /* with a leading period; Macintosh puts them in a "Preferences" folder. The file */
- /* is actually created unless it already exists. PrefsFileName is a null terminated */
- /* string. */
- /* this routine does not perform operations on file descriptors. */
- FileSpec* NewPrefsFileSpec(char* PrefsFileName, unsigned long Creator,
- unsigned long FileType)
- {
- short vRefNum;
- long DirID;
- FSSpec* Temp;
- unsigned char Name[32];
- int Scan;
-
- APRINT(("+NewPrefsFileSpec name = %t",PrefsFileName));
- FindFolder(kOnSystemDisk,kPreferencesFolderType,kCreateFolder,&vRefNum,&DirID);
- Temp = (FSSpec*)AllocPtrCanFail(sizeof(FSSpec),"FileSpec");
- if (Temp == NIL)
- {
- APRINT(("-NewPrefsFileSpec NIL"));
- return NIL;
- }
- Scan = 0;
- while ((Scan < 31) && (PrefsFileName[Scan] != 0))
- {
- Name[Scan + 1] = PrefsFileName[Scan];
- Scan += 1;
- }
- Name[0] = Scan;
- FSMakeFSSpec(vRefNum,DirID,Name,Temp);
- LastError = FSpCreate(Temp,Creator,FileType,smSystemScript);
- if (!Eep_RegisterFileSpec((FileSpec*)Temp))
- {
- ReleasePtr((char*)Temp);
- Temp = NIL;
- }
- APRINT(("-NewPrefsFileSpec %r",Temp));
- return (FileSpec*)Temp;
- }
-
-
- /* present a dialog box allowing the user to select where to create a new file. */
- /* If the file will overwrite an existing file, verify this with the user and then */
- /* delete the existing file before returning. DefaultFileName is a null terminated */
- /* string. */
- /* this routine does not perform operations on file descriptors. */
- FileSpec* PutFile(char* DefaultFileName)
- {
- unsigned char Name[32];
- StandardFileReply MySFR;
- int Scan;
- FSSpec* ReturnValue;
-
- APRINT(("+PutFile name = %t",DefaultFileName));
- LastError = noErr;
- Scan = 0;
- while ((Scan < 31) && (DefaultFileName[Scan] != 0))
- {
- Name[Scan + 1] = DefaultFileName[Scan];
- Scan += 1;
- }
- Name[0] = Scan;
- StandardPutFile(NIL,Name,&MySFR);
- if (MySFR.sfGood)
- {
- if (MySFR.sfReplacing)
- {
- FSpDelete(&MySFR.sfFile);
- }
- ReturnValue = (FSSpec*)AllocPtrCanFail(sizeof(FSSpec),"FileSpec");
- if (ReturnValue == NIL)
- {
- APRINT(("-PutFile NIL"));
- return NIL;
- }
- *ReturnValue = MySFR.sfFile;
- if (MySFR.sfReplacing)
- {
- FSpDelete(&MySFR.sfFile);
- }
- }
- else
- {
- ReturnValue = NIL;
- }
- if (ReturnValue != NIL)
- {
- if (!Eep_RegisterFileSpec((FileSpec*)ReturnValue))
- {
- ReleasePtr((char*)ReturnValue);
- ReturnValue = NIL;
- }
- }
- APRINT(("-PutFile %r",ReturnValue));
- return (FileSpec*)ReturnValue;
- }
-
-
- /* let the user find a file with the specified list of types. Whether the types */
- /* are actually used is implementation defined. The Macintosh uses up to 4 types. */
- /* returns NIL if the operation was cancelled. */
- /* this routine does not perform operations on file descriptors. */
- FileSpec* GetFileStandard(long NumFileTypes, unsigned long* ArrayOfFileTypes)
- {
- StandardFileReply MySFR;
- FSSpec* Where;
-
- APRINT(("+GetFileStandard"));
- ERROR((NumFileTypes != 0) && (ArrayOfFileTypes == NIL),PRERR(ForceAbort,
- "GetFileStandard: file type array is NIL"));
- LastError = noErr;
- StandardGetFile(NIL,NumFileTypes,ArrayOfFileTypes,&MySFR);
- if (MySFR.sfGood)
- {
-
- Where = (FSSpec*)AllocPtrCanFail(sizeof(FSSpec),"FileSpec");
- if (Where != NIL)
- {
- *Where = MySFR.sfFile;
- }
- }
- else
- {
- Where = NIL;
- }
- if (Where != NIL)
- {
- if (!Eep_RegisterFileSpec((FileSpec*)Where))
- {
- ReleasePtr((char*)Where);
- Where = NIL;
- }
- }
- APRINT(("-GetFileStandard %r",Where));
- return (FileSpec*)Where;
- }
-
-
- /* get any file. like GetFileStandard except it shows all possible files */
- /* this routine does not perform operations on file descriptors. */
- FileSpec* GetFileAny(void)
- {
- StandardFileReply MySFR;
- FSSpec* Where;
-
- APRINT(("+GetFileAny"));
- LastError = noErr;
- StandardGetFile(NIL,-1,NIL,&MySFR);
- if (MySFR.sfGood)
- {
- Where = (FSSpec*)AllocPtrCanFail(sizeof(FSSpec),"FileSpec");
- if (Where != NIL)
- {
- *Where = MySFR.sfFile;
- }
- }
- else
- {
- Where = NIL;
- }
- if (Where != NIL)
- {
- if (!Eep_RegisterFileSpec((FileSpec*)Where))
- {
- ReleasePtr((char*)Where);
- Where = NIL;
- }
- }
- APRINT(("-GetFileAny %r",Where));
- return (FileSpec*)Where;
- }
-
-
- /* return a pointer containing a non-null-terminated string which is the filename. */
- /* this routine does not perform operations on file descriptors. */
- char* ExtractFileName(FileSpec* Spec)
- {
- char* Name;
-
- CheckPtrExistence(Spec);
- ERROR(-1 == ArrayFindElement(FileSpecList,Spec),PRERR(ForceAbort,
- "ExtractFileName: undefined file specification"));
- Name = AllocPtrCanFail(((FSSpec*)Spec)->name[0],"ExtractFileName");
- if (Name != NIL)
- {
- CopyData((char*)&(((FSSpec*)Spec)->name[1]),&(Name[0]),((FSSpec*)Spec)->name[0]);
- }
- return Name;
- }
-
-
- /* create a file. Returns True if the creation succeeded. Whether or not */
- /* the Creator and FileType codes are used is implementation defined. The Macintosh */
- /* does use them. */
- /* this routine does not perform operations on file descriptors. */
- MyBoolean CreateFile(FileSpec* FileLocation, unsigned long Creator,
- unsigned long FileType)
- {
- APRINT(("+CreateFile name=%p dir=%l vol=%s",(*(FSSpec*)FileLocation).name,
- (*(FSSpec*)FileLocation).parID,(*(FSSpec*)FileLocation).vRefNum));
- CheckPtrExistence(FileLocation);
- ERROR(-1 == ArrayFindElement(FileSpecList,FileLocation),PRERR(ForceAbort,
- "CreateFile: undefined file specification"));
- LastError = FSpCreate((FSSpec*)FileLocation,Creator,FileType,smSystemScript);
- APRINT(("-CreateFile err=%s",LastError));
- return (LastError == noErr);
- }
-
-
- /* delete a file. The file must not be in use. Returns True if successful */
- /* this routine does not perform operations on file descriptors. */
- MyBoolean DeleteFile(FileSpec* FileLocation)
- {
- APRINT(("+DeleteFile"));
- CheckPtrExistence(FileLocation);
- ERROR(-1 == ArrayFindElement(FileSpecList,FileLocation),PRERR(ForceAbort,
- "DeleteFile: undefined file specification"));
- LastError = FSpDelete((FSSpec*)FileLocation);
- APRINT(("-DeleteFile err=%s",LastError));
- return (LastError == noErr);
- }
-
-
- /* Open a file for the specified access. Returns True if successful. */
- /* this routine DOES perform operations on file descriptors. */
- MyBoolean OpenFile(FileSpec* FileLocation, FileType** FileRefOut,
- FileModesType FileAccessMode)
- {
- FileType* FileRef;
- int Permission;
-
- APRINT(("+OpenFile name=%p dir=%l vol=%s",(*(FSSpec*)FileLocation).name,
- (*(FSSpec*)FileLocation).parID,(*(FSSpec*)FileLocation).vRefNum));
- CheckPtrExistence(FileLocation);
- ERROR(-1 == ArrayFindElement(FileSpecList,FileLocation),PRERR(ForceAbort,
- "OpenFile: undefined file specification"));
- FileRef = (FileType*)AllocPtrCanFail(sizeof(FileType),"FileType");
- if (FileRef == NIL)
- {
- FailurePoint1:
- APRINT(("-OpenFile failed"));
- return False;
- }
- switch (FileAccessMode)
- {
- default:
- EXECUTE(PRERR(ForceAbort,"OpenFile: bad file permission specifier"));
- break;
- case eReadOnly:
- Permission = fsRdPerm;
- break;
- case eReadAndWrite:
- Permission = fsRdWrPerm;
- break;
- }
- LastError = FSpOpenDF((FSSpec*)FileLocation,Permission,&(FileRef->Refnum));
- if (LastError != noErr)
- {
- ReleasePtr((char*)FileRef);
- APRINT((" Error",LastError));
- goto FailurePoint1;
- }
- EXECUTE(if (!ArrayAppendElement(FileDescriptorList,FileRef))
- {FSClose(FileRef->Refnum); ReleasePtr((char*)FileRef); FileRef = NIL;
- goto FailurePoint1;})
- *FileRefOut = FileRef;
- APRINT(("-OpenFile %r %s",FileRef,FileRef->Refnum));
- return True;
- }
-
-
- /* close a file. The file must have been open. Implicitly calls FlushLocalBuffers. */
- /* this routine DOES perform operations on file descriptors. */
- void CloseFile(FileType* FileRef)
- {
- APRINT(("+CloseFile %r %s",FileRef,FileRef->Refnum));
- CheckPtrExistence(FileRef);
- ERROR(-1 == ArrayFindElement(FileDescriptorList,FileRef),PRERR(ForceAbort,
- "CloseFile: undefined file descriptor"));
- FlushLocalBuffers(FileRef);
- LastError = FSClose(FileRef->Refnum);
- EXECUTE(ArrayDeleteElement(FileDescriptorList,
- ArrayFindElement(FileDescriptorList,FileRef)));
- ReleasePtr((char*)FileRef);
- APRINT(("-CloseFile err=%s",LastError));
- }
-
-
- /* make sure all data associated with a file gets written out */
- /* this routine DOES perform operations on file descriptors. */
- void FlushLocalBuffers(FileType* FileRef)
- {
- short vRefNum;
-
- APRINT(("+FlushLocalBuffers %r %s",FileRef,FileRef->Refnum));
- CheckPtrExistence(FileRef);
- ERROR(-1 == ArrayFindElement(FileDescriptorList,FileRef),PRERR(ForceAbort,
- "FlushLocalBuffers: undefined file descriptor"));
- LastError = GetVRefNum(FileRef->Refnum,&vRefNum);
- if (LastError == noErr)
- {
- LastError = FlushVol(NIL,vRefNum);
- }
- APRINT(("-FlushLocalBuffers err=%s",LastError));
- }
-
-
- /* write a block of data to the file. Returns the number of bytes which could */
- /* not be written or 0 if all were written. */
- /* This is the only function that calls "FSWrite" */
- /* this routine DOES perform operations on file descriptors. */
- long WriteToFile(FileType* FileRef, char* Buffer, long NumBytes)
- {
- APRINT(("+WriteToFile %r %s",FileRef,FileRef->Refnum));
- CheckPtrExistence(FileRef);
- ERROR(-1 == ArrayFindElement(FileDescriptorList,FileRef),PRERR(ForceAbort,
- "WriteToFile: undefined file descriptor"));
- do
- {
- long NumBytesDone;
-
- NumBytesDone = NumBytes;
- LastError = FSWrite(FileRef->Refnum,&NumBytesDone,Buffer);
- Buffer += NumBytesDone;
- NumBytes -= NumBytesDone;
- ERROR(NumBytes != 0,PRERR(AllowResume,
- "WriteToFile: couldn't write whole block, trying again"));
- } while ((LastError == noErr) && (NumBytes != 0));
- APRINT(("-WriteToFile err=%s",LastError));
- return NumBytes; /* return number of bytes that couldn't be written */
- }
-
-
- /* read a block of data from the file. Returns the number of bytes which */
- /* could not be read, or 0 if all were read. */
- /* This is the only function that calls "FSRead" */
- /* this routine DOES perform operations on file descriptors. */
- long ReadFromFile(FileType* FileRef, char* Buffer, long NumBytesDesired)
- {
- EXECUTE(long TryCount = 0;)
-
- APRINT(("+ReadFromFile %r %s",FileRef,FileRef->Refnum));
- CheckPtrExistence(FileRef);
- ERROR(-1 == ArrayFindElement(FileDescriptorList,FileRef),PRERR(ForceAbort,
- "ReadFromFile: undefined file descriptor"));
- do
- {
- long NumBytesDone;
-
- NumBytesDone = NumBytesDesired;
- LastError = FSRead(FileRef->Refnum,&NumBytesDone,Buffer);
- Buffer += NumBytesDone;
- NumBytesDesired -= NumBytesDone;
- ERROR((NumBytesDesired != 0) && (TryCount > 0),PRERR(AllowResume,
- "ReadFromFile: couldn't read whole block, trying again"));
- EXECUTE(TryCount += 1;)
- } while ((LastError == noErr) && (NumBytesDesired != 0));
- APRINT(("-ReadFromFile err=%s",LastError));
- return NumBytesDesired; /* return number of bytes that couldn't be read */
- }
-
-
- /* get the current index into the specified file */
- /* this routine DOES perform operations on file descriptors. */
- long GetFilePosition(FileType* FileRef)
- {
- long Where;
-
- APRINT(("+GetFilePosition %r %s",FileRef,FileRef->Refnum));
- CheckPtrExistence(FileRef);
- ERROR(-1 == ArrayFindElement(FileDescriptorList,FileRef),PRERR(ForceAbort,
- "GetFilePosition: undefined file descriptor"));
- LastError = GetFPos(FileRef->Refnum,&Where);
- APRINT(("-GetFilePosition err=%s",LastError));
- return Where;
- }
-
-
- /* move to a new location within the specified file */
- /* if the new location is past the EOF, the EOF will be extended to the new location */
- /* this routine DOES perform operations on file descriptors. */
- MyBoolean SetFilePosition(FileType* FileRef, long NewLocation)
- {
- long EOF;
-
- APRINT(("+SetFilePosition %r %s",FileRef,FileRef->Refnum));
- CheckPtrExistence(FileRef);
- ERROR(-1 == ArrayFindElement(FileDescriptorList,FileRef),PRERR(ForceAbort,
- "SetFilePosition: undefined file descriptor"));
- LastError = GetEOF(FileRef->Refnum,&EOF);
- if (EOF < NewLocation)
- {
- LastError = SetEOF(FileRef->Refnum,NewLocation);
- }
- if (LastError == noErr)
- {
- LastError = SetFPos(FileRef->Refnum,fsFromStart,NewLocation);
- }
- APRINT(("-SetFilePosition err=%s",LastError));
- return (LastError == noErr);
- }
-
-
- /* get the length of the specified file */
- /* this routine DOES perform operations on file descriptors. */
- long GetFileLength(FileType* FileRef)
- {
- long EOFPos;
-
- APRINT(("+GetFileLength %r %s",FileRef,FileRef->Refnum));
- CheckPtrExistence(FileRef);
- ERROR(-1 == ArrayFindElement(FileDescriptorList,FileRef),PRERR(ForceAbort,
- "GetFileLength: undefined file descriptor"));
- LastError = GetEOF(FileRef->Refnum,&EOFPos);
- APRINT(("-GetFileLength err=%s",LastError));
- return EOFPos;
- }
-
-
- /* set the length of the specified file. */
- /* returns True if everything went well or False if there was an error */
- /* If the file could not be extended due to lack of disk space, the EOF */
- /* remains unchanged */
- /* this routine DOES perform operations on file descriptors. */
- MyBoolean SetFileLength(FileType* FileRef, long NewFileLength)
- {
- long OldEOF;
-
- APRINT(("+SetFileLength %r %s",FileRef,FileRef->Refnum));
- CheckPtrExistence(FileRef);
- ERROR(-1 == ArrayFindElement(FileDescriptorList,FileRef),PRERR(ForceAbort,
- "SetFileLength: undefined file descriptor"));
- LastError = GetEOF(FileRef->Refnum,&OldEOF);
- if (LastError == noErr)
- {
- LastError = SetEOF(FileRef->Refnum,NewFileLength);
- if (LastError == dskFulErr)
- {
- SetEOF(FileRef->Refnum,OldEOF);
- }
- }
- APRINT(("-SetFileLength err=%s",LastError));
- return (LastError == noErr);
- }
-
-
- /* copy the entire contents of one file to another. Data overwrites destination */
- /* this routine does not perform operations on file descriptors. */
- #define REALBIGBUFFSIZE (65536)
- #define LITTLEBUFFSIZE (1024)
- MyBoolean CopyFile(FileType* Original, FileType* Destination)
- {
- char* Buffer;
- MyBoolean ReleaseBuffer;
- long ActualBufferSize;
- long ByteCount;
- char EmergencyBuff[LITTLEBUFFSIZE];
-
- CheckPtrExistence(Original);
- CheckPtrExistence(Destination);
- if (!SetFilePosition(Original,0))
- {
- return False;
- }
- if (!SetFilePosition(Destination,0))
- {
- return False;
- }
- if (!SetFileLength(Destination,0))
- {
- return False;
- }
- Buffer = AllocPtrCanFail(REALBIGBUFFSIZE,"CopyFileBuffer");
- if (Buffer != NIL)
- {
- ActualBufferSize = REALBIGBUFFSIZE;
- ReleaseBuffer = True;
- }
- else
- {
- ActualBufferSize = LITTLEBUFFSIZE;
- ReleaseBuffer = False;
- Buffer = EmergencyBuff;
- }
- ByteCount = GetFileLength(Original);
- while (ByteCount != 0)
- {
- long LocalBytes;
-
- if (ByteCount > ActualBufferSize)
- {
- LocalBytes = ActualBufferSize;
- }
- else
- {
- LocalBytes = ByteCount;
- }
- if (ReadFromFile(Original,Buffer,LocalBytes) != 0)
- {
- FailurePoint:
- if (ReleaseBuffer)
- {
- ReleasePtr(Buffer);
- }
- return False;
- }
- if (WriteToFile(Destination,Buffer,LocalBytes) != 0)
- {
- goto FailurePoint;
- }
- ByteCount -= LocalBytes;
- }
- if (ReleaseBuffer)
- {
- ReleasePtr(Buffer);
- }
- return True;
- }
-
-
- /* create a temporary file in the directory. the file is actually created so it */
- /* exists (so nobody can grab it out from under you). */
- /* this routine DOES perform operations on file descriptors. */
- FileSpec* NewTempFileInTheSameDirectory(FileSpec* SameDirectoryAsThis)
- {
- FSSpec* NewOne;
- unsigned char Name[32] = "\pTempFile........";
- int Scan;
- unsigned long Key;
-
- ERROR(-1 == ArrayFindElement(FileSpecList,SameDirectoryAsThis),PRERR(ForceAbort,
- "DisposeFileSpec: undefined file specification"));
- CheckPtrExistence(SameDirectoryAsThis);
- NewOne = (FSSpec*)AllocPtrCanFail(sizeof(FSSpec),"SameDirectoryNewName");
- if (NewOne == NIL)
- {
- return NIL;
- }
- Key = TickCount();
- TryPoint:
- for (Scan = 0; Scan < 8; Scan += 1)
- {
- Name[Scan + 9] = ((Key >> (Scan * 4)) & 0x0f) + 'a';
- }
- FSMakeFSSpec(((FSSpec*)SameDirectoryAsThis)->vRefNum,
- ((FSSpec*)SameDirectoryAsThis)->parID,Name,NewOne);
- LastError = FSpCreate(NewOne,'\?\?\?\?','\?\?\?\?',smSystemScript);
- if (LastError == dupFNErr)
- {
- Key += 1;
- goto TryPoint;
- }
- if (LastError != noErr)
- {
- /* some other error occurred -- may be a disk full error. */
- ReleasePtr((char*)NewOne);
- NewOne = NIL;
- }
- if (NewOne != NIL)
- {
- if (!Eep_RegisterFileSpec((FileSpec*)NewOne))
- {
- ReleasePtr((char*)NewOne);
- NewOne = NIL;
- }
- }
- return (FileSpec*)NewOne;
- }
-
-
- /* this operation swaps the data forks for two files. this is used for safe */
- /* saving (i.e. write data before clobbering so that the old file still exists */
- /* if the write fails). You create a new file and write the data to it. Then you */
- /* pass the location of the new file in NewFile and the location of the old */
- /* file in OldFile. The routine swaps the data in the files and the last modified */
- /* dates. If successful, the NewFile (temporary file) will be deleted and the */
- /* OldFileRef reference will be updated (it will NOT be the same) and the NewFileRef */
- /* will be closed. */
- /* NOTE: the files should be created in the same directory. */
- /* this routine DOES perform operations on file descriptors. */
- MyBoolean SwapFileDataForks(FileSpec* NewAndTempFile, FileSpec* OldFile,
- FileType* NewFileRef, FileType** OldFileRef)
- {
- ERROR(-1 == ArrayFindElement(FileSpecList,NewAndTempFile),PRERR(ForceAbort,
- "SwapFileDataForks: undefined file specification"));
- ERROR(-1 == ArrayFindElement(FileSpecList,OldFile),PRERR(ForceAbort,
- "SwapFileDataForks: undefined file specification"));
- ERROR(-1 == ArrayFindElement(FileDescriptorList,NewFileRef),PRERR(ForceAbort,
- "SwapFileDataForks: undefined file descriptor"));
- ERROR(-1 == ArrayFindElement(FileDescriptorList,*OldFileRef),PRERR(ForceAbort,
- "SwapFileDataForks: undefined file descriptor"));
- CheckPtrExistence(NewAndTempFile);
- CheckPtrExistence(OldFile);
- CheckPtrExistence(NewFileRef);
- ERROR(OldFileRef == NIL,PRERR(ForceAbort,"SwapFileDataForks: OldFileRef is NIL"));
- CheckPtrExistence(*OldFileRef);
- LastError = FSpExchangeFiles((FSSpec*)NewAndTempFile,(FSSpec*)OldFile);
- if (LastError != noErr)
- {
- return False;
- }
- CloseFile(*OldFileRef);
- *OldFileRef = NewFileRef;
- DeleteFile(NewAndTempFile);
- SetTag(NewAndTempFile,"SwapFileDataForks: NewAndTempFile");
- CheckPtrExistence(*OldFileRef);
- return True;
- }
-