home *** CD-ROM | disk | FTP | other *** search
- /*
- fiddling with the standard file package and the high level file
- routines.
-
- This is a Generic file copy program.
-
- New File Feb 17 1987
- Feb 20...Fixed bug which would not allow copy if
- target directory had file with same name
- as target file.
- Feb 20...Added Alert error messages.
-
- Author: Jerry LeVan
- 325 Boone Trail
- Richmond Ky 40475
-
- Environment: MPW v1.01/MPW C v1.0
- MacPlus - Finder v5.3/System v3.2
-
- Build Instructions: c gencopy.c
- rez types.r gencopy.r -o gencopy
- link gencopy.c.o ∂
- "{clibraries}"cruntime.o ∂
- "{clibraries}"cinterface.o ∂
- -o gencopy
- Exercise for the reader:
- a) Use Alerts to give the user better feedback (done!)
- b) Make sure there is room on the target volume prior to copy
- c) Force the file system to use larger buffers to speed the copy
- d) Make sure I have covered all the error conditions
-
- Warning: This program will delete a file if it has the same name
- as the target prior to the start of the copy and the file
- is in the same directory. The program will not allow
- a file to be copied over itself.
-
- */
-
-
- #define BUFSIZ 8192
-
- #define MSG_ID 128
-
- /**********************************************************************/
-
- void InitProgram()
- {
- /* Standard Initialization Sequence */
-
- /*UnloadSeg(_DataInit);*/ /* unload the runtime initializer code */
-
- InitGraf(&qd.thePort); /* set up quickdraw */
- InitFonts(); /* Set up fonts */
- /* FlushEvents(everyEvent,0); empty the event queue */
- InitWindows(); /* Set up window manager */
- InitMenus(); /* Set up menus */
- TEInit(); /* Needed for Dialogs */
- InitDialogs(nil); /* No restart proc */
- InitCursor();
- }
- /********************************************************************/
-
- Boolean GetSourceFile
- (SFReply *reply,OSType *creator,OSType *theType,short *flags)
- {
- Point loc;
- SFTypeList typeList;
- short ntypes;
- FInfo info;
-
-
- loc.v = 80;
- loc.h = 100;
-
- ntypes = -1; /* all files */
- SFGetFile(loc, 0, 0, ntypes, typeList, 0, reply);
-
- if(reply->good)
- {
- /* we need to get the info for the selected file */
-
- if(GetFInfo(reply->fName,reply->vRefNum,&info))
- return false;
-
- *creator = info.fdCreator;
- *theType = info.fdType; /* actually in the reply record */
- *flags = info.fdFlags;
-
- return true;
- }
-
- return false;
- }
-
- /********************************************************************/
-
- Boolean GetDestFile
- (SFReply *infile,SFReply *reply)
- {
- Point loc;
-
-
- loc.v = 80;
- loc.h = 100;
-
-
- SFPutFile(loc,(unsigned char *)"\pSelect Target Name",infile->fName, nil, reply);
-
- if(reply->good)
- {
- /* we can't allow the source and destination to be the same file */
-
- if(EqualString(infile->fName,reply->fName,false,false)&&(infile->vRefNum == reply->vRefNum))
- {
- ParamText((unsigned char*)"Sorry, Source and Destination Can't Be Identical",nil,nil,nil);
- StopAlert(MSG_ID,nil);
- return false;
- }
-
- return true;
- }
- return false;
- }
-
- /********************************************************************/
-
- Boolean CreateTheFile
- (SFReply *infile,SFReply *outfile,OSType creator,OSType theType,OSErr *reason)
- {
- FInfo info;
-
-
- *reason = Create(outfile->fName,outfile->vRefNum,creator,theType);
- if(*reason)
- {
- /* we had an error during the create */
-
- if(*reason == /*dupFNErr*/-48)
- {
- /* try to delete the file */
-
- FSDelete(outfile->fName,outfile->vRefNum);
- *reason=Create(outfile->fName,outfile->vRefNum,creator,theType);
- if(*reason)
- return false; /* some other error */
- else
- return true; /* sucessful open */
- }
- else
- return false; /* some other error */
- }
-
- return true;
- }
-
- /********************************************************************/
-
- void CopyAFork
- (short inref,short outref,OSErr *err)
- {
- char buff[BUFSIZ]; /* one cluster buffer */
- long count; /* count actually transfered */
- OSErr ReadErr,WriteErr; /* error flags */
-
-
- do
- {
- count = BUFSIZ; /* blocksize */
-
- ReadErr=FSRead(inref,&count,buff);
- if(ReadErr)
- {
- if(ReadErr!=eofErr)
- {
- *err = ReadErr;
- return;
- }
- }
-
- WriteErr = FSWrite(outref,&count,buff);
- if(WriteErr)
- {
- *err = WriteErr;
- return;
- }
- }
- while(ReadErr != eofErr);
-
- *err = noErr;
- }
-
- /********************************************************************/
-
- Boolean CopyDataFork
- (SFReply *infile,SFReply *outfile,OSType creator,OSErr *err)
- {
- short inref,outref;
-
-
- /* open the input data fork */
-
- *err = FSOpen(infile->fName,infile->vRefNum,&inref);
- if(*err)
- return false;
-
- /* open the output data fork */
-
- *err = FSOpen(outfile->fName,outfile->vRefNum,&outref);
- if(*err)
- {
- FSClose(inref);
- inref = 0;
- return false;
- }
-
- CopyAFork(inref,outref,err);
-
- FSClose(inref);
- inref = 0;
- FSClose(outref);
- outref = 0;
-
- if(*err)
- {
- FSDelete(outfile->fName,outfile->vRefNum);
- return false;
- }
- else
- {
- return true;
- }
- }
- /********************************************************************/
-
- Boolean CopyResourceFork(SFReply *infile,SFReply *outfile,OSErr *err)
- {
- short inref,outref,theErr;
-
-
- /* open the input resource fork */
-
- *err = OpenRF(infile->fName,infile->vRefNum,&inref);
- if(*err)
- return false;
-
- /* open the output resource fork */
- *err=OpenRF(outfile->fName,outfile->vRefNum,&outref);
- if(*err)
- {
- FSClose(inref);
- inref = 0;
- return false;
- }
-
- /* copy a fork */
-
- CopyAFork(inref,outref,err);
-
- /* clean up */
-
- FSClose(inref);
- inref = 0;
- FSClose(outref);
- outref = 0;
-
- FlushVol(nil,outfile->vRefNum);
-
- if(*err)
- {
- FSDelete(outfile->fName,outfile->vRefNum);
- return false;
- }
- else
- {
- return true;
- }
- }
-
- /********************************************************************/
-
- Boolean SetFileAttributes
- (SFReply *outfile,short flags,OSErr *reason)
- {
- FInfo info;
-
-
- *reason = GetFInfo(outfile->fName,outfile->vRefNum,&info);
- if(*reason)
- return false;
-
- info.fdFlags = flags; /* protected bundle etc */
-
- *reason = SetFInfo(outfile->fName,outfile->vRefNum,&info);
- if(*reason)
- return false;
-
- return true;
- }
-
- /********************************************************************/
- void main()
- {
- SFReply infilespec,outfilespec;
- OSType creator,theType;
- short flags; /* finder flags */
- OSErr reason; /* system error code on bad return */
- unsigned char temp[20]; /* storage for numeric conversion */
-
-
- InitProgram();
-
-
- /* get source file spec, quit if user bails out */
-
- if(!GetSourceFile(&infilespec,&creator,&theType,&flags))
- return;
-
-
- /* get destination file spec, quit if user bails out */
-
- if(!GetDestFile(&infilespec,&outfilespec))
- return;
-
-
- /* create the output file (exit on error) */
-
- if(!CreateTheFile(&infilespec,&outfilespec,creator,theType,&reason))
- {
- NumToString(reason,temp);
- ParamText((unsigned char*)"\pCan't Create Output File",(unsigned char*)"\pReason:",temp,nil);
- StopAlert(MSG_ID,nil);
- return;
- }
-
-
- /* copy the data fork exit on error */
-
- if(!CopyDataFork(&infilespec,&outfilespec,creator,&reason))
- {
- NumToString(reason,temp);
- ParamText((unsigned char*)"\pError Copying Data Fork",(unsigned char*)"\pReason:",temp,nil);
- StopAlert(MSG_ID,nil);
- return;
- }
-
-
- /* copy the resource fork, exit on error */
-
- if(!CopyResourceFork(&infilespec,&outfilespec,&reason))
- {
- NumToString(reason,temp);
- ParamText((unsigned char*)"\pError Copying Resource Fork",(unsigned char*)"\pReason:",temp,nil);
- StopAlert(MSG_ID,nil);
- return;
- }
-
-
-
- /* set the destination file attributes */
-
- if(!SetFileAttributes(&outfilespec,flags,&reason))
- {
- NumToString(reason,temp);
- ParamText((unsigned char*)"\pError Setting File Attributes",(unsigned char*)"\pReason:",temp,nil);
- StopAlert(MSG_ID,nil);
- return;
- }
-
-
- /* advise user of sucessful completion */
-
- ParamText((unsigned char*)"\pNo Errors Detected...Copy Complete",nil,nil,nil);
- NoteAlert(MSG_ID,nil);
- }
-