home *** CD-ROM | disk | FTP | other *** search
- /*
- Copy -- copies one file to another
-
- Instructions for XCMDs are in <XCMD.HowToUse>
- */
-
- #include <HyperXCmd.h>
- #include <SetUpA4.h>
-
- /* Constants */
- #define NULL 0L
- #define FALSE 0
- #define TRUE 1
- #define BLOCK_SIZE 512
-
- /* Macros */
- #define strlen(s) StringLength(paramPtr, (StringPtr) (s))
- #define pasToZero(s) PasToZero(paramPtr, (StringPtr) (s))
- #define zeroToPas(s1,s2) ZeroToPas(paramPtr, (char *) (s1), \
- (StringPtr) (s2))
- #define numToStr(l,s) NumToStr(paramPtr, (long) (l), s)
-
- /* Static variables */
- static char sWrongArgs[] = "\pWrong number of arguments";
-
- /* Prototypes */
- pascal void main(XCmdBlockPtr);
- int CopyFile(char *, char *);
- int CopyBytes(IOParam *io1, IOParam *io2, long bytes);
-
-
- pascal void main(paramPtr)
- XCmdBlockPtr paramPtr;
- {
- int err;
- Str31 str;
- Str255 source, dest;
-
- RememberA0();
- SetUpA4();
- if (paramPtr->paramCount != 2)
- paramPtr->returnValue = pasToZero(sWrongArgs);
- else {
- zeroToPas(*paramPtr->params[0], source);
- zeroToPas(*paramPtr->params[1], dest);
- err = CopyFile((char *) source, (char *) dest);
- if (err) {
- numToStr(err, &str);
- paramPtr->returnValue = pasToZero(str.guts);
- }
- }
- RestoreA4();
- }
-
- int CopyFile(source, dest)
- char *source, *dest;
- {
- /* <FileMgr.h>*/
- FileParam fp1, fp2;
- int err;
- IOParam io1, io2;
-
- /* Start by getting info about the source file */
- fp1.ioCompletion = NULL;
- fp1.ioNamePtr = (StringPtr) source;
- fp1.ioVRefNum = 0;
- fp1.ioFVersNum = 0;
- fp1.ioFDirIndex = 0;
- err = PBGetFInfo(&fp1, FALSE);
- if (err != noErr) {SysBeep(3);
- return (err);}
-
- /* Next create the dest file */
- fp2.ioCompletion = NULL;
- fp2.ioNamePtr = (StringPtr) dest;
- fp2.ioVRefNum = 0;
- fp2.ioFVersNum = 0;
- err = PBCreate(&fp2, FALSE);
- if (err == dupFNErr) {
- /* File already existed -- wipe it out */
- err = PBDelete(&fp2, FALSE);
- if (err != noErr)
- return (err);
- err = PBCreate(&fp2, FALSE);
- if (err != noErr)
- return (err);
- }
- else if (err != noErr)
- return (err);
-
- /* Set the file info on the new file */
- fp2.ioFlFndrInfo = fp1.ioFlFndrInfo;
- fp2.ioFlFndrInfo.fdFlags = 0;
- fp2.ioFlCrDat = fp1.ioFlCrDat;
- fp2.ioFlMdDat = fp1.ioFlMdDat;
- err = PBSetFInfo(&fp2, FALSE);
-
- /* Fill in the I/O params */
- io1.ioCompletion = NULL;
- io1.ioNamePtr = (StringPtr) source;
- io1.ioVRefNum = 0;
- io1.ioVersNum = 0;
- io1.ioPermssn = fsRdPerm;
- io1.ioMisc = NULL;
-
- io2.ioCompletion = NULL;
- io2.ioNamePtr = (StringPtr) dest;
- io2.ioVRefNum = 0;
- io2.ioVersNum = 0;
- io2.ioPermssn = fsWrPerm;
- io2.ioMisc = NULL;
-
- /* Now, copy the files' data forks (if they exist) */
- if (fp1.ioFlLgLen > 0L) {
- /* Start with the destination */
- err = PBOpen(&io2, FALSE);
- if (err != noErr)
- return (err);
- /* Allocate space to copy to */
- io2.ioReqCount = fp1.ioFlLgLen;
- err = PBAllocate(&io2, FALSE);
- if (err != noErr) {
- PBClose(&io2, FALSE);
- return (err);
- }
-
- err = PBOpen(&io1, FALSE);
- if (err != noErr) {
- PBClose(&io2, FALSE);
- return (err);
- }
- err = CopyBytes(&io1, &io2, fp1.ioFlLgLen);
- PBClose(&io1, FALSE);
- PBClose(&io2, FALSE);
- if (err != noErr)
- return (err);
- }
-
- /* Copy the files' resource forks (if they exist) */
- if (fp1.ioFlRLgLen > 0L) {
- /* Start with the destination */
- err = PBOpenRF(&io2, FALSE);
- if (err != noErr)
- return (err);
- /* Allocate space to copy to */
- io2.ioReqCount = fp1.ioFlRLgLen;
- err = PBAllocate(&io2, FALSE);
- if (err != noErr) {
- PBClose(&io2, FALSE);
- return (err);
- }
- err = PBOpenRF(&io1, FALSE);
- if (err != noErr) {
- PBClose(&io2, FALSE);
- return (err);
- }
-
- err = CopyBytes(&io1, &io2, fp1.ioFlRLgLen);
- PBClose(&io1, FALSE);
- PBClose(&io2, FALSE);
- if (err != noErr)
- return (err);
- }
-
- return (err);
- }
-
- int CopyBytes(io1, io2, bytes)
- IOParam *io1, *io2;
- long bytes;
- {
- char buffer[BLOCK_SIZE];
- long numFullBlocks, i;
- int err;
-
- numFullBlocks = bytes / BLOCK_SIZE;
-
- /* Fill in the missing parts of the I/O params */
- io1->ioBuffer = buffer;
- io1->ioReqCount = BLOCK_SIZE;
- io1->ioPosMode = fsFromStart;
- io1->ioPosOffset = 0L;
- io2->ioBuffer = buffer;
- io2->ioReqCount = BLOCK_SIZE;
- io2->ioPosMode = fsFromStart;
- io2->ioPosOffset = 0L;
-
- /* Note: the following loop copies the number of full blocks.
- There may be a partial last block. */
- for (i = 0; i < numFullBlocks; i++) {
- err = PBRead(io1, FALSE);
- if (err != noErr)
- return (err);
- err = PBWrite(io2, FALSE);
- if (err != noErr)
- return (err);
- }
-
- /* Copy the last amount */
- io1->ioReqCount = io2->ioReqCount = bytes % BLOCK_SIZE;
- if (io1->ioReqCount != 0L) {
- err = PBRead(io1, FALSE);
- if (err != noErr)
- return (err);
- err = PBWrite(io2, FALSE);
- if (err != noErr)
- return (err);
- }
-
- return (noErr);
- }
-
- /* C routines for HyperCard callbacks */
- #include <XCmdGlue.inc.c>
-
-
-