Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Enumerations | Functions
macDirectoryCopy.c File Reference
#include <Types.h>
#include <Errors.h>
#include <Memory.h>
#include <Files.h>
#include <Script.h>
#include "MoreFiles.h"
#include "MoreFilesExtras.h"
#include "MoreDesktopMgr.h"
#include "FileCopy.h"
#include "MacDirectoryCopy.h"
#include <string.h>

Go to the source code of this file.

Classes

struct  EnumerateGlobals
struct  PreflightGlobals

Defines

#define __COMPILINGMOREFILES
#define CallCopyErrProc(userRoutine, error, failedOperation, srcVRefNum, srcDirID, srcName, dstVRefNum, dstDirID, dstName)   (*(userRoutine))((error), (failedOperation), (srcVRefNum), (srcDirID), (srcName), (dstVRefNum), (dstDirID), (dstName))
#define CallCopyFilterProc(userRoutine, cpbPtr)   (*(userRoutine))((cpbPtr))

Typedefs

typedef pascal Boolean(* CopyFilterProcPtr )(const CInfoPBRec *const cpbPtr)
typedef struct EnumerateGlobals
typedef EnumerateGlobalsEnumerateGlobalsPtr
typedef struct PreflightGlobals
typedef PreflightGlobalsPreflightGlobalsPtr

Enumerations

enum  {
  getNextItemOp = 1, copyDirCommentOp = 2, copyDirAccessPrivsOp = 3, copyDirFMAttributesOp = 4,
  dirCreateOp = 5, fileCopyOp = 6
}
enum  { dirCopyBigCopyBuffSize = 0x00004000, dirCopyMinCopyBuffSize = 0x00000200 }

Functions

static void GetLevelSize (long currentDirID, PreflightGlobals *theGlobals)
static OSErr PreflightDirectoryCopySpace (short srcVRefNum, long srcDirID, short dstVRefNum, CopyFilterProcPtr copyFilterProc, Boolean *spaceOK)
static void CopyLevel (long sourceDirID, long dstDirID, EnumerateGlobals *theGlobals)
pascal OSErr FilteredDirectoryCopy (short srcVRefNum, long srcDirID, ConstStr255Param srcName, short dstVRefNum, long dstDirID, ConstStr255Param dstName, void *copyBufferPtr, long copyBufferSize, Boolean preflight, CopyErrProcPtr copyErrHandler, CopyFilterProcPtr copyFilterProc, ConstStr255Param newName)
pascal OSErr MacFSpDirectoryCopyRename (const FSSpec *srcSpec, const FSSpec *dstSpec, ConstStr255Param newName, void *copyBufferPtr, long copyBufferSize, Boolean preflight, CopyErrProcPtr copyErrHandler)

Class Documentation

struct EnumerateGlobals

Definition at line 101 of file macDirectoryCopy.c.

Class Members
Boolean bailout
long bufferSize
Ptr copyBuffer
CopyFilterProcPtr copyFilterProc
short destinationVRefNum
OSErr error
CopyErrProcPtr errorHandler
Str63 itemName
CInfoPBRec myCPB
struct PreflightGlobals

Definition at line 128 of file macDirectoryCopy.c.

Class Members
unsigned long allocBlksNeeded
CopyFilterProcPtr copyFilterProc
unsigned long dstBlksPerAllocBlk
Str63 itemName
CInfoPBRec myCPB
OSErr result
unsigned long tempBlocks

Define Documentation

Definition at line 30 of file macDirectoryCopy.c.

#define CallCopyErrProc (   userRoutine,
  error,
  failedOperation,
  srcVRefNum,
  srcDirID,
  srcName,
  dstVRefNum,
  dstDirID,
  dstName 
)    (*(userRoutine))((error), (failedOperation), (srcVRefNum), (srcDirID), (srcName), (dstVRefNum), (dstDirID), (dstName))

Definition at line 56 of file macDirectoryCopy.c.

#define CallCopyFilterProc (   userRoutine,
  cpbPtr 
)    (*(userRoutine))((cpbPtr))

Definition at line 75 of file macDirectoryCopy.c.


Typedef Documentation

typedef pascal Boolean(* CopyFilterProcPtr)(const CInfoPBRec *const cpbPtr)

Definition at line 61 of file macDirectoryCopy.c.

typedef struct EnumerateGlobals

Definition at line 117 of file macDirectoryCopy.c.

Definition at line 118 of file macDirectoryCopy.c.

typedef struct PreflightGlobals

Definition at line 145 of file macDirectoryCopy.c.

Definition at line 146 of file macDirectoryCopy.c.


Enumeration Type Documentation

anonymous enum
Enumerator:
getNextItemOp 
copyDirCommentOp 
copyDirAccessPrivsOp 
copyDirFMAttributesOp 
dirCreateOp 
fileCopyOp 

Definition at line 42 of file macDirectoryCopy.c.

{
       getNextItemOp               = 1,   /* couldn't access items in this directory - no access privileges */
       copyDirCommentOp            = 2,   /* couldn't copy directory's Finder comment */
       copyDirAccessPrivsOp = 3,   /* couldn't copy directory's AFP access privileges */
       copyDirFMAttributesOp       = 4,   /* couldn't copy directory's File Manager attributes */
       dirCreateOp                        = 5,   /* couldn't create destination directory */
       fileCopyOp                         = 6           /* couldn't copy file */
};
anonymous enum
Enumerator:
dirCopyBigCopyBuffSize 
dirCopyMinCopyBuffSize 

Definition at line 83 of file macDirectoryCopy.c.

{
       dirCopyBigCopyBuffSize  = 0x00004000,
       dirCopyMinCopyBuffSize  = 0x00000200
};

Function Documentation

static void CopyLevel ( long  sourceDirID,
long  dstDirID,
EnumerateGlobals theGlobals 
) [static]

Definition at line 286 of file macDirectoryCopy.c.

{
       long currentSrcDirID;
       long newDirID;
       short index = 1;
       
       do
       {      
              /* Get next source item at the current directory level */
              
              theGlobals->myCPB.dirInfo.ioFDirIndex = index;
              theGlobals->myCPB.dirInfo.ioDrDirID = sourceDirID;
              theGlobals->error = PBGetCatInfoSync(&theGlobals->myCPB);             

              if ( theGlobals->error == noErr )
              {
                     if ( (theGlobals->copyFilterProc == NULL) ||
                             CallCopyFilterProc(theGlobals->copyFilterProc, &theGlobals->myCPB) ) /* filter if filter proc was supplied */
                     {
                            /* Either there's no filter proc OR the filter proc says to use this item */

                            /* We have an item.  Is it a file or directory? */
                            if ( (theGlobals->myCPB.hFileInfo.ioFlAttrib & ioDirMask) != 0 )
                            {
                                   /* We have a directory */
                                   
                                   /* Create a new directory at the destination. No errors allowed! */
                                   theGlobals->error = DirCreate(theGlobals->destinationVRefNum, dstDirID, theGlobals->itemName, &newDirID);
                                   if ( theGlobals->error == noErr )
                                   {
                                          /* Save the current source directory ID where we can get it when we come back
                                          ** from recursion land. */
                                          currentSrcDirID = theGlobals->myCPB.dirInfo.ioDrDirID;
                                          
                                          /* Dive again (copy the directory level we just found below this one) */
                                          CopyLevel(theGlobals->myCPB.dirInfo.ioDrDirID, newDirID, theGlobals);
                                          
                                          if ( !theGlobals->bailout )
                                          {
                                                 /* Copy comment from old to new directory. */
                                                 /* Ignore the result because we really don't care if it worked or not. */
                                                 (void) DTCopyComment(theGlobals->myCPB.dirInfo.ioVRefNum, currentSrcDirID, NULL, theGlobals->destinationVRefNum, newDirID, NULL);
                                                 
                                                 /* Copy directory attributes (dates, etc.) to newDirID. */
                                                 /* No errors allowed */
                                                 theGlobals->error = CopyFileMgrAttributes(theGlobals->myCPB.dirInfo.ioVRefNum, currentSrcDirID, NULL, theGlobals->destinationVRefNum, newDirID, NULL, true);
                                                 
                                                 /* handle any errors from CopyFileMgrAttributes */
                                                 if ( theGlobals->error != noErr )
                                                 {
                                                        if ( theGlobals->errorHandler != NULL )
                                                        {
                                                               theGlobals->bailout =  CallCopyErrProc(theGlobals->errorHandler, theGlobals->error, copyDirFMAttributesOp,
                                                                                                         theGlobals->myCPB.dirInfo.ioVRefNum, currentSrcDirID, NULL,
                                                                                                         theGlobals->destinationVRefNum, newDirID, NULL);
                                                        }
                                                        else
                                                        {
                                                               /* If you don't handle the errors with an error handler, */
                                                               /* then the copy stops here. */
                                                               theGlobals->bailout = true;
                                                        }
                                                 }
                                          }
                                   }
                                   else   /* error handling for DirCreate */
                                   {
                                          if ( theGlobals->errorHandler != NULL )
                                          {
                                                 theGlobals->bailout = CallCopyErrProc(theGlobals->errorHandler, theGlobals->error, dirCreateOp,
                                                                                                  theGlobals->myCPB.dirInfo.ioVRefNum, currentSrcDirID, NULL,
                                                                                                  theGlobals->destinationVRefNum, dstDirID, theGlobals->itemName);
                                          }
                                          else
                                          {
                                                 /* If you don't handle the errors with an error handler, */
                                                 /* then the copy stops here. */
                                                 theGlobals->bailout = true;
                                          }
                                   }
                                   
                                   if ( !theGlobals->bailout )
                                   {
                                          /* clear error return on way back if we aren't bailing out */
                                          theGlobals->error = noErr;
                                   }
                            }
                            else
                            {
                                   /* We have a file, so copy it */
                                   
                                   theGlobals->error = FileCopy(theGlobals->myCPB.hFileInfo.ioVRefNum,
                                                                                     theGlobals->myCPB.hFileInfo.ioFlParID,
                                                                                     theGlobals->itemName,
                                                                                     theGlobals->destinationVRefNum,
                                                                                     dstDirID,
                                                                                     NULL,
                                                                                     NULL,
                                                                                     theGlobals->copyBuffer,
                                                                                     theGlobals->bufferSize,
                                                                                     false);
                                                 
                                   /* handle any errors from FileCopy */
                                   if ( theGlobals->error != noErr )
                                   {
                                          if ( theGlobals->errorHandler != NULL )
                                          {
                                                 theGlobals->bailout = CallCopyErrProc(theGlobals->errorHandler, theGlobals->error, fileCopyOp,
                                                                                           theGlobals->myCPB.hFileInfo.ioVRefNum, theGlobals->myCPB.hFileInfo.ioFlParID, theGlobals->itemName,
                                                                                           theGlobals->destinationVRefNum, dstDirID, NULL);
                                                 if ( !theGlobals->bailout )
                                                 {
                                                        /* If the CopyErrProc handled the problem, clear the error here */
                                                        theGlobals->error = noErr;
                                                 }
                                          }
                                          else
                                          {
                                                 /* If you don't handle the errors with an error handler, */
                                                 /* then the copy stops here. */
                                                 theGlobals->bailout = true;
                                          }
                                   }
                            }
                     }
              }
              else
              {      /* error handling for PBGetCatInfo */
                     /* it's normal to get a fnfErr when indexing; that only means you've hit the end of the directory */
                     if ( theGlobals->error != fnfErr )
                     {
                            if ( theGlobals->errorHandler != NULL )
                            { 
                                   theGlobals->bailout = CallCopyErrProc(theGlobals->errorHandler, theGlobals->error, getNextItemOp,
                                                                             theGlobals->myCPB.dirInfo.ioVRefNum, sourceDirID, NULL, 0, 0, NULL);
                                   if ( !theGlobals->bailout )
                                   {
                                          /* If the CopyErrProc handled the problem, clear the error here */
                                          theGlobals->error = noErr;
                                   }
                            }
                            else
                            {
                                   /* If you don't handle the errors with an error handler, */
                                   /* then the copy stops here. */
                                   theGlobals->bailout = true;
                            }
                     }
              }
              ++index; /* prepare to get next item */
       } while ( (theGlobals->error == noErr) && (!theGlobals->bailout) ); /* time to fall back a level? */
}

Here is the call graph for this function:

Here is the caller graph for this function:

pascal OSErr FilteredDirectoryCopy ( short  srcVRefNum,
long  srcDirID,
ConstStr255Param  srcName,
short  dstVRefNum,
long  dstDirID,
ConstStr255Param  dstName,
void copyBufferPtr,
long  copyBufferSize,
Boolean  preflight,
CopyErrProcPtr  copyErrHandler,
CopyFilterProcPtr  copyFilterProc,
ConstStr255Param  newName 
)

Definition at line 553 of file macDirectoryCopy.c.

{
       EnumerateGlobals theGlobals;
       Boolean       isDirectory;
       OSErr  error;
       Boolean ourCopyBuffer = false;
       Str63  srcDirName, oldDiskName;
       Boolean spaceOK;                   
       
       /* Make sure a copy buffer is allocated. */
       if ( copyBufferPtr == NULL )
       {
              /* The caller didn't supply a copy buffer so grab one from the application heap.
              ** Try to get a big copy buffer, if we can't, try for a 512-byte buffer.
              ** If 512 bytes aren't available, we're in trouble. */
              copyBufferSize = dirCopyBigCopyBuffSize;
              copyBufferPtr = NewPtr(copyBufferSize);
              if ( copyBufferPtr == NULL )
              {
                     copyBufferSize = dirCopyMinCopyBuffSize;
                     copyBufferPtr = NewPtr(copyBufferSize);
                     if ( copyBufferPtr == NULL )
                     {
                            return ( memFullErr );
                     }
              }
              ourCopyBuffer = true;
       }
       
       /* Get the real dirID where we're copying from and make sure it is a directory. */
       error = GetDirectoryID(srcVRefNum, srcDirID, srcName, &srcDirID, &isDirectory);
       if ( error != noErr )
       {
              goto ErrorExit;
       }
       if ( !isDirectory )
       {
              error = dirNFErr;
              goto ErrorExit;
       }
       
       /* Special case destination if it is the root parent directory. */
       /* Since you can't create the root directory, this is needed if */
       /* you want to copy a directory's content to a disk's root directory. */
       if ( (dstDirID == fsRtParID) && (dstName == NULL) )
       {
              dstDirID = fsRtParID;
              isDirectory = true;
              error = noErr;
       }
       else
       {
              /*  Get the real dirID where we're going to put the copy and make sure it is a directory. */
              error = GetDirectoryID(dstVRefNum, dstDirID, dstName, &dstDirID, &isDirectory);
              if ( error != noErr )
              {
                     goto ErrorExit;
              }
              if ( !isDirectory )
              {
                     error =  dirNFErr;
                     goto ErrorExit;
              }
       }
       
       /* Get the real vRefNum of both the source and destination */
       error = DetermineVRefNum(srcName, srcVRefNum, &srcVRefNum);
       if ( error != noErr )
       {
              goto ErrorExit;
       }
       error = DetermineVRefNum(dstName, dstVRefNum, &dstVRefNum);
       if ( error != noErr )
       {
              goto ErrorExit;
       }
       
       if ( preflight )
       {
              error = PreflightDirectoryCopySpace(srcVRefNum, srcDirID, dstVRefNum, copyFilterProc, &spaceOK);
              if ( error != noErr )
              {
                     goto ErrorExit;
              }
              if ( !spaceOK )
              {
                     error = dskFulErr; /* not enough room on destination */
                     goto ErrorExit;
              }
       }

       /* Create the new directory in the destination directory with the */
       /* same name as the source directory. */
       /* 
              if newName is not empty use it rather than the original dir name.
       */
       if ( newName[0] == 0 )
       {
              error = GetDirName(srcVRefNum, srcDirID, srcDirName);
              if ( error != noErr )
              {
                     goto ErrorExit;
              }
       }
       else
       {
              memcpy(srcDirName, newName, 32 );
              
       }      
       /* Again, special case destination if the destination is the */
       /* root parent directory. This time, we'll rename the disk to */
       /* the source directory name. */
       if ( dstDirID == fsRtParID )
       {
              /* Get the current name of the destination disk */
              error = GetDirName(dstVRefNum, fsRtDirID, oldDiskName);
              if ( error == noErr )       
              {
                     /* Shorten the name if it's too long to be the volume name */
                     TruncPString(srcDirName, srcDirName, 27);
                     
                     /* Rename the disk */
                     error = HRename(dstVRefNum, fsRtParID, oldDiskName, srcDirName);
                     /* and copy to the root directory */
                     dstDirID = fsRtDirID;
              }
       }
       else
       {
              error = DirCreate(dstVRefNum, dstDirID, srcDirName, &dstDirID);
       }
       if ( error != noErr )
       {
              /* handle any errors from DirCreate */
              if ( copyErrHandler != NULL )
              {
                     if ( CallCopyErrProc(copyErrHandler, error, dirCreateOp,
                                                                                           srcVRefNum, srcDirID, NULL,
                                                                                           dstVRefNum, dstDirID, srcDirName) )
                     {
                            goto ErrorExit;
                     }
                     else
                     {
                            /* If the CopyErrProc handled the problem, clear the error here */
                            /* and continue */
                            error = noErr;
                     }
              }
              else
              {
                     /* If you don't handle the errors with an error handler, */
                     /* then the copy stops here. */
                     goto ErrorExit;
              }
       }
       
       /* dstDirID is now the newly created directory! */
              
       /* Set up the globals we need to access from the recursive routine. */
       theGlobals.copyBuffer = (Ptr)copyBufferPtr;
       theGlobals.bufferSize = copyBufferSize;
       theGlobals.destinationVRefNum = dstVRefNum; /* so we can get to it always */
       theGlobals.myCPB.hFileInfo.ioNamePtr = (StringPtr)&theGlobals.itemName;
       theGlobals.myCPB.hFileInfo.ioVRefNum = srcVRefNum;
       theGlobals.errorHandler = copyErrHandler;
       theGlobals.bailout = false;
       theGlobals.copyFilterProc =  copyFilterProc;
              
       /* Here we go into recursion land... */
       CopyLevel(srcDirID, dstDirID, &theGlobals);
       error = theGlobals.error;   /* get the result */
       
       if ( !theGlobals.bailout )
       {
              /* Copy comment from source to destination directory. */
              /* Ignore the result because we really don't care if it worked or not. */
              (void) DTCopyComment(srcVRefNum, srcDirID, NULL, dstVRefNum, dstDirID, NULL);
              
              /* Copy the File Manager attributes */
              error = CopyFileMgrAttributes(srcVRefNum, srcDirID, NULL,
                                   dstVRefNum, dstDirID, NULL, true);
              
              /* handle any errors from CopyFileMgrAttributes */
              if ( (error != noErr) && (copyErrHandler != NULL) )
              {
                     theGlobals.bailout = CallCopyErrProc(copyErrHandler, error, copyDirFMAttributesOp,
                                                                                    srcVRefNum, srcDirID, NULL,
                                                                                    dstVRefNum, dstDirID, NULL);
              }
       }

ErrorExit:
       /* Get rid of the copy buffer if we allocated it. */
       if ( ourCopyBuffer )
       {
              DisposePtr((Ptr)copyBufferPtr);
       }

       return ( error );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void GetLevelSize ( long  currentDirID,
PreflightGlobals theGlobals 
) [static]

Definition at line 167 of file macDirectoryCopy.c.

{
       short  index = 1;
       
       do
       {
              theGlobals->myCPB.dirInfo.ioFDirIndex = index;
              theGlobals->myCPB.dirInfo.ioDrDirID = currentDirID;     /* we need to do this every time */
                                                                                                         /* through, since GetCatInfo  */
                                                                                                         /* returns ioFlNum in this field */
              theGlobals->result = PBGetCatInfoSync(&theGlobals->myCPB);
              if ( theGlobals->result == noErr )
              {
                     if ( (theGlobals->copyFilterProc == NULL) ||
                             CallCopyFilterProc(theGlobals->copyFilterProc, &theGlobals->myCPB) ) /* filter if filter proc was supplied */
                     {
                            /* Either there's no filter proc OR the filter proc says to use this item */
                            if ( (theGlobals->myCPB.dirInfo.ioFlAttrib & ioDirMask) != 0 )
                            {
                                   /* we have a directory */
                                   
                                   GetLevelSize(theGlobals->myCPB.dirInfo.ioDrDirID, theGlobals); /* recurse */
                                   theGlobals->result = noErr; /* clear error return on way back */
                            }
                            else
                            {
                                   /* We have a file - add its allocation blocks to allocBlksNeeded. */
                                   /* Since space on Mac OS disks is always allocated in allocation blocks, */
                                   /* this takes into account rounding up to the end of an allocation block. */
                                   
                                   /* get number of 512-byte blocks needed for data fork */
                                   if ( ((unsigned long)theGlobals->myCPB.hFileInfo.ioFlLgLen & 0x000001ff) != 0 )
                                   {
                                          theGlobals->tempBlocks = ((unsigned long)theGlobals->myCPB.hFileInfo.ioFlLgLen >> 9) + 1;
                                   }
                                   else
                                   {
                                          theGlobals->tempBlocks = (unsigned long)theGlobals->myCPB.hFileInfo.ioFlLgLen >> 9;
                                   }
                                   /* now, calculate number of new allocation blocks needed for the data fork and add it to the total */
                                   if ( theGlobals->tempBlocks % theGlobals->dstBlksPerAllocBlk )
                                   {
                                          theGlobals->allocBlksNeeded += (theGlobals->tempBlocks / theGlobals->dstBlksPerAllocBlk) + 1;
                                   }
                                   else
                                   {
                                          theGlobals->allocBlksNeeded += theGlobals->tempBlocks / theGlobals->dstBlksPerAllocBlk;
                                   }
                                   
                                   /* get number of 512-byte blocks needed for resource fork */
                                   if ( ((unsigned long)theGlobals->myCPB.hFileInfo.ioFlRLgLen & 0x000001ff) != 0 )
                                   {
                                          theGlobals->tempBlocks = ((unsigned long)theGlobals->myCPB.hFileInfo.ioFlRLgLen >> 9) + 1;
                                   }
                                   else
                                   {
                                          theGlobals->tempBlocks = (unsigned long)theGlobals->myCPB.hFileInfo.ioFlRLgLen >> 9;
                                   }
                                   /* now, calculate number of new allocation blocks needed for the resource  fork and add it to the total */
                                   if ( theGlobals->tempBlocks % theGlobals->dstBlksPerAllocBlk )
                                   {
                                          theGlobals->allocBlksNeeded += (theGlobals->tempBlocks / theGlobals->dstBlksPerAllocBlk) + 1;
                                   }
                                   else
                                   {
                                          theGlobals->allocBlksNeeded += theGlobals->tempBlocks / theGlobals->dstBlksPerAllocBlk;
                                   }
                            }
                     }
              }
              ++index;
       } while ( theGlobals->result == noErr );
}

Here is the caller graph for this function:

pascal OSErr MacFSpDirectoryCopyRename ( const FSSpec srcSpec,
const FSSpec dstSpec,
ConstStr255Param  newName,
void copyBufferPtr,
long  copyBufferSize,
Boolean  preflight,
CopyErrProcPtr  copyErrHandler 
)

Definition at line 769 of file macDirectoryCopy.c.

{
       return ( FilteredDirectoryCopy(srcSpec->vRefNum, srcSpec->parID, srcSpec->name,
                                                           dstSpec->vRefNum, dstSpec->parID, dstSpec->name,
                                                           copyBufferPtr, copyBufferSize, preflight,
                                                           copyErrHandler, NULL, newName) );
}

Here is the call graph for this function:

static OSErr PreflightDirectoryCopySpace ( short  srcVRefNum,
long  srcDirID,
short  dstVRefNum,
CopyFilterProcPtr  copyFilterProc,
Boolean spaceOK 
) [static]

Definition at line 244 of file macDirectoryCopy.c.

{
       XVolumeParam pb;
       OSErr error;
       unsigned long dstFreeBlocks;
       PreflightGlobals theGlobals;
       
       error = XGetVolumeInfoNoName(NULL, dstVRefNum, &pb);
       if ( error == noErr )
       {
              /* Convert freeBytes to free disk blocks (512-byte blocks) */
              dstFreeBlocks = (pb.ioVFreeBytes >> 9);
       
              /* get allocation block size (always multiple of 512) and divide by 512
                to get number of 512-byte blocks per allocation block */
              theGlobals.dstBlksPerAllocBlk = ((unsigned long)pb.ioVAlBlkSiz >> 9);
              
              theGlobals.allocBlksNeeded = 0;

              theGlobals.myCPB.dirInfo.ioNamePtr = theGlobals.itemName;
              theGlobals.myCPB.dirInfo.ioVRefNum = srcVRefNum;
              
              theGlobals.copyFilterProc = copyFilterProc;
              
              GetLevelSize(srcDirID, &theGlobals);
              
              /* Is there enough room on the destination volume for the source file?                                   */
              /* Note:      This will work because the largest number of disk blocks supported                  */
              /*                   on a 2TB volume is 0xffffffff and (allocBlksNeeded * dstBlksPerAllocBlk)     */
              /*                   will always be less than 0xffffffff.                                                                     */
              *spaceOK = ((theGlobals.allocBlksNeeded * theGlobals.dstBlksPerAllocBlk) <= dstFreeBlocks);
       }

       return ( error );
}

Here is the call graph for this function:

Here is the caller graph for this function: