TweetFollow Us on Twitter

CopyFile XCMD
Volume Number:5
Issue Number:10
Column Tag:HyperChat™

Related Info: File Manager

XCMD Corner: CopyFile

By Donald Koscheka, Arthur Young & Co., MacTutor Contributing Editor

Note: Source code files accompanying article are located on MacTech CD-ROM or source code disks.

CopyFile XCMD

From time to time I monitor the developer forums on AppleLink and MacNet to see what the rest of the Macintosh development community is up to. Recently, Richard Greenawalt of Foremost Computer Systems issued a request for some help. It seems he needed a routine that copies Macintosh files, data fork, resource fork and finder information.

Not one to miss an opportunity to write an interesting XCMD, I 'linked Rick back and told him that I would be happy to write the routine for him.

The moral of the story is: ask and you might receive. If you need some help with an XCMD or if this column just doesn’t do it for you, let me know; I will be more than happy to help you out. Although I am up on AppleLink, I prefer to use MacNet (KOSCHEKA). If you don’t have access to a modem, write me care of MacTutor.

Copying a Macintosh file is not difficult as long as you keep in mind that Mac files are really two files in one. Each file on the Macintosh has a split personality - the data fork and the resource fork. Although the two forks act as one entity, the file manager treats them as separate files.

CopyFile is a handy little XCMD that lets you copy files from Hypercard. Actually the routine is written to work from any programming milieu which is why I’ve split it into two listings. The first consists of the Hypercard interface. Note that you need to pass both the file name and the working directory id. The second listing contains the actual code, void of any references to Hypercard. This approach lets me build libraries of usable routines that I can use with or without Hypercard, and I intend to use it for all future listings.

The CopyFile function expects to see the name of the input file, the name of the output file and the working directory id’s of both. This gives you some flexibility in naming the copy as well as deciding what folder to put it in. For example, you can concatenate the name of the input file to “copy of “ so that the duplicated file is called “copy of file”. Put this concept in a loop and you get the finder like capability of creating files and naming them “copy of ... “ , “copy of copy of ...” and so on. I chose not to implement this approach because I think the user should have the opportunity to specify the name of the copied file.

Although there are several ways to go about copying a file, I chose a path that goes something like this: First, get the collective size of the data and resource fork along with the finder information about the input file. Using this information, attempt to create a file that is as large as the input file (ie as large as the data and resource fork combined). If the space can be allocated, then copy each fork in turn. If not, delete the newly created file and quit.

Space for each fork is allocated before we do the copy so that we can determine a priori whether the file will fit. To be safe, we reposition the file mark at the beginning of the file before we start copying. If, for any reason, the file copy fails, delete what remains of the file and return the error message to the caller.

The real work is done by the function, CopyFork. This routine will attempt to read the entire fork into a single buffer. Failing that, it divides the size in half until enough memory can be allocated to read some of the fork. Note that copyfork attempts to allocate a buffer large enough to read the entire fork into memory. If that much memory is not available, it keeps dividing the original size by two until a large enough buffer can be allocated.

That’s file copying in a nutshell. It’s not particularly difficult once you realize that you’re really copying two files - the data fork and the resource fork. I’ve tried it with files up to 4 megabytes in size and it works fine.

/**********************************/
/* File: FileCopy.c*/
/* param0 = file reference num*/
/* ( file is open) IN:    */
/* params[0]= name of input */
/* params[1]= wdid of input */
/* params[2]   = name of output  */
/* params[3]   = wdid of output  */
/**********************************/
#include<MacTypes.h>
#include<OSUtil.h>
#include<MemoryMgr.h>
#include<FileMgr.h>
#include<ResourceMgr.h>
#include<pascal.h>
#include<string.h>
#include  “HyperXCMD.h”
#include“HyperUtils.h”

pascal void main( paramPtr )
 XCmdBlockPtr  paramPtr;
/*****************************
*params[0]= name of input 
*params[1]= wdid of input 
*params[2]  = name of output
*params[3]  = wdid of output
*****************************/
{ OSErr err;
 short  inWD;
 short  outWD;
 long   temp;
 Str31  errCode;
 char   inFile[256];
 char   outFile[256];
 paramPtr->returnValue = 0L;
 /*** (1) Get input parameters     ***/
 HLock( paramPtr->params[0] );
 ZeroToPas( paramPtr, *(paramPtr->params[0]), &inFile );
 HUnlock( paramPtr->params[0] );
 inWD = (short)paramtoNum( paramPtr, 1 );
 HLock( paramPtr->params[2] );
 ZeroToPas( paramPtr, *(paramPtr->params[2]), &outFile );
 HUnlock( paramPtr->params[2] );
 outWD = (short)paramtoNum( paramPtr, 3 );
 temp = (long)CopyFile( inFile, inWD, outFile, outWD );
 /*** Flush the output volume ***/
 err = FlushVol( 0L, 0 );
 NumToStr( paramPtr, temp, &errCode );
 paramPtr->returnValue = PasToZero( paramPtr, &errCode );
}

LISTING 1: CopyFile XCMD.


OSErr CopyFork( inref, outref, siz )
 short  inref;   short  outref;  longsiz;
/*****************************
* Given that the caller has opened
* a fork and passed you the names of 
* the input, copy the number of bytes
* from the input fork to the output 
* fork.
* The input mark should be set to 
* start of fork.
* We use a “semi-smart” algorithm
* to do the copy.  If the entire
* fork can be copied, we try doing 
* that, otherwise, we keep dividing
* the size by two until we get enough
* room to read some data in.
******************************/
{
 OSErr  rd_err   = noErr;
 OSErr  wrt_err  = noErr;
 long   rd_len;  /*** actual bytes read ***/
 Ptr    inbuf;
 /*** make sure that the size is even ***/
 if( siz % 2 )
 ++siz;
 if( siz > 0 ){
 do{
 inbuf = NewPtr( siz );
 if( !inbuf )
 siz = ( siz >> 1 );
 }while( !inbuf );
 /*** inbuf is the buffer that we  ***/
 /*** read the data into. If not   ***/
 /*** allocated, don’t attempt to do ***/
 /*** the read   ***/
 if( inbuf ){
 do{
 rd_len = siz;
 rd_err = FSRead( inref, &rd_len, inbuf );
 wrt_err= FSWrite( outref, &rd_len, inbuf );
 }while( !rd_err && !wrt_err );
 
 DisposPtr( inbuf );
 }
 }
 return( wrt_err );
}

OSErr CopyFile( inFile, inWD, outFile, outWD )
 char   *inFile;
 short  inWD; char *outFile;
 short  outWD;
/*****************************
* (1) Determine the size of the input 
* file. 
* (2) Attempt to allocate that 
* much space for the output file.
* (3) If allocation successful,
* create the output file.
* (4) Once the file is created,
* copy the data fork, the resource
* fork and the finder information
* from the input file.
* The file will be called “copy of...”
* Each time we create the file, first
* see if that name exists, if so, keep
* sticking “copy of” onto the name.
******************************/
{
 OSErr  err;
 OSErr  err2;
 short  inref;
 short  outref;
 long   data_eof = 0L;
 long   rsrc_eof = 0L;
 FInfo  fndrinfo;
 /*** (2) Determine how big the input file is ***/
 if( (err = FSOpen( inFile, inWD, &inref )) == noErr){
 err = GetEOF( inref, &data_eof );
 err = FSClose( inref );
 } 
 if( (err = OpenRF( inFile, inWD, &inref )) == noErr ){
 err = GetEOF( inref, &rsrc_eof );
 err = FSClose( inref );  
 }
 /*** (2) Create  output file and allocate space***/
 if( ( err = GetFInfo( inFile, inWD, &fndrinfo ) ) != noErr )
 return( err );
 if( ( err = Create( outFile, inWD, fndrinfo.fdCreator, fndrinfo.fdType 
)) != noErr )
 return( err );
 /*** (3) Try to allocate enough space for both***/
 /*** forks. Note that if we get enough space. ***/
 if( (err = FSOpen( outFile, outWD, &outref )) != noErr)
 return( err );
 if( (err = SetEOF( outref, data_eof  )) != noErr ){
 err2 = FSClose( outref );
 err2 = FSDelete( outFile, outWD );
 return( err );
 }
 err2   = FSClose( outref );
 err  = OpenRF( outFile, outWD, &outref );
 if( (err = SetEOF( outref, rsrc_eof  )) != noErr ){
 err2 = FSClose( outref );
 err2 = FSDelete( outFile, outWD );
 return( err );
 }
 err2 = FSClose( outref );
 /*** (4) Copy the Data fork***/
 err  = FSOpen( inFile, inWD, &inref );
 if( !err ){
 err2   = SetFPos( inref, fsFromStart, 0L );
 err    = CopyFork( inref, outref, data_eof );
 err2   = FSClose( inref );
 err2   = FSClose( outref );
 }
 if( err ){
 err2 = FSDelete( outFile, outWD );
 return( err );
 }
 /*** (5) Now copy the resource fork ***/
 err  = OpenRF( inFile, inWD, &inref );
 if( !err ){
 err2   = SetFPos( inref, fsFromStart, 0L );
 err  = OpenRF( outFile, outWD, &outref );
 err    = CopyFork( inref, outref, rsrc_eof );
 err2   = FSClose( inref );
 err2   = FSClose( outref );
 }
 if( err ){
 err2 = FSDelete( outFile, outWD );
 return( err );
 }
 return( noErr );
}

LISTING 2: CopyFile and CopyFork Functions.

 
AAPL
$96.88
Apple Inc.
-0.31
MSFT
$44.47
Microsoft Corpora
-0.41
GOOG
$593.30
Google Inc.
-2.68

MacTech Search:
Community Search:

Software Updates via MacUpdate

Audio Hijack Pro 2.11.0 - Record and enh...
Audio Hijack Pro drastically changes the way you use audio on your computer, giving you the freedom to listen to audio when you want and how you want. Record and enhance any audio with Audio Hijack... Read more
Intermission 1.1.1 - Pause and rewind li...
Intermission allows you to pause and rewind live audio from any application on your Mac. Intermission will buffer up to 3 hours of audio, allowing users to skip through any assortment of audio... Read more
Airfoil 4.8.7 - Send audio from any app...
Airfoil allows you to send any audio to AirPort Express units, Apple TVs, and even other Macs and PCs, all in sync! It's your audio - everywhere. With Airfoil you can take audio from any... Read more
Microsoft Remote Desktop 8.0.8 - Connect...
With Microsoft Remote Desktop, you can connect to a remote PC and your work resources from almost anywhere. Experience the power of Windows with RemoteFX in a Remote Desktop client designed to help... Read more
xACT 2.30 - Audio compression toolkit. (...
xACT stands for X Aaudio Compression Toolkit, an application that encodes and decodes FLAC, SHN, Monkey’s Audio, TTA, Wavpack, and Apple Lossless files. It also can encode these formats to MP3, AAC... Read more
Firefox 31.0 - Fast, safe Web browser. (...
Firefox for Mac offers a fast, safe Web browsing experience. Browse quickly, securely, and effortlessly. With its industry-leading features, Firefox is the choice of Web development professionals... Read more
Little Snitch 3.3.3 - Alerts you to outg...
Little Snitch gives you control over your private outgoing data. Track background activityAs soon as your computer connects to the Internet, applications often have permission to send any... Read more
Thunderbird 31.0 - Email client from Moz...
As of July 2012, Thunderbird has transitioned to a new governance model, with new features being developed by the broader free software and open source community, and security fixes and improvements... Read more
Together 3.2 - Store and organize all of...
Together helps you organize your Mac, giving you the ability to store, edit and preview your files in a single clean, uncluttered interface. Smart storage. With simple drag-and-drop functionality,... Read more
Cyberduck 4.5 - FTP and SFTP browser. (F...
Cyberduck is a robust FTP/FTP-TLS/SFTP browser for the Mac whose lack of visual clutter and cleverly intuitive features make it easy to use. Support for external editors and system technologies such... Read more

Latest Forum Discussions

See All

Thomas Was Alone Goes Universal, Slashes...
Thomas Was Alone Goes Universal, Slashes Price to $3.99 Posted by Ellis Spice on July 24th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Book Your Appointment with F.E.A.R. this...
Book Your Appointment with F.E.A.R. | Read more »
It Came From Canada: Epic Skater
For all the hate that it gets for being a pastime for slackers, skateboarding really does require a lot of skill. All those flips and spins take real athleticism, and there’s all the jargon to memorize. Fortunately for us less extreme individuals,... | Read more »
Cultures Review
Cultures Review By Jennifer Allen on July 24th, 2014 Our Rating: :: SLOW-PACED EMPIRE BUILDINGiPad Only App - Designed for the iPad Cute it might seem, but Cultures is a bit too slow paced when it comes to those pesky timers to... | Read more »
More Paintings Have Been Added to Paint...
More Paintings Have Been Added to Paint it Back! Posted by Jessica Fisher on July 24th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
The Order of Souls Review
The Order of Souls Review By Campbell Bird on July 24th, 2014 Our Rating: :: STORY GRINDUniversal App - Designed for iPhone and iPad The Order of Souls is a free-to-play, turn-based RPG with a genre-mixing art style, interesting... | Read more »
Revolution 60 Review
Revolution 60 Review By Jordan Minor on July 24th, 2014 Our Rating: :: LASS EFFECTUniversal App - Designed for iPhone and iPad Revolution 60 is a bold, cinematic action game with ambition to spare.   | Read more »
Matter (Photography)
Matter 1.0.1 Device: iOS Universal Category: Photography Price: $1.99, Version: 1.0.1 (iTunes) Description: Add stunning 3D effects to your photos with real-time shadows and reflections. Export your creations as photos or video loops... | Read more »
Fanatic Earth Review
Fanatic Earth Review By Brittany Vincent on July 24th, 2014 Our Rating: :: BY-THE-NUMBERSUniversal App - Designed for iPhone and iPad Kemco’s stable of mobile RPGs grows, but in Fanatic Earth’s situation it’s a case of quantity... | Read more »
Together for iOS (Productivity)
Together for iOS 1.0 Device: iOS Universal Category: Productivity Price: $9.99, Version: 1.0 (iTunes) Description: Together is an app for keeping things in one place. Notes, documents, images, movies, sounds, web pages and bookmarks... | Read more »

Price Scanner via MacPrices.net

What Should Apple’s Next MacBook Priority Be;...
Stabley Times’ Phil Moore says that after expanding its iMac lineup with a new low end model, Apple’s next Mac hardware decision will be how it wants to approach expanding its MacBook lineup as well... Read more
ArtRage For iPhone Painting App Free During C...
ArtRage for iPhone is currently being offered for free (regularly $1.99) during Comic-Con San Diego #SDCC, July 24-27, in celebration of the upcoming ArtRage 4.5 and other 64-bit versions of the... Read more
With The Apple/IBM Alliance, Is The iPad Now...
Almost since the iPad was rolled out in 2010, and especially after Apple made a 128 GB storage configuration available in 2012, there’s been debate over whether the iPad is a serious tool for... Read more
MacBook Airs on sale starting at $799, free s...
B&H Photo has the new 2014 MacBook Airs on sale for up to $100 off MSRP for a limited time. Shipping is free, and B&H charges NY sales tax only. They also include free copies of Parallels... Read more
Apple 27″ Thunderbolt Display (refurbished) a...
The Apple Store has Apple Certified Refurbished 27″ Thunderbolt Displays available for $799 including free shipping. That’s $200 off the cost of new models. Read more
WaterField Designs Unveils Cycling Ride Pouch...
High end computer case and bag maker WaterField Designs of San Francisco now enters the cycling market with the introduction of the Cycling Ride Pouch – an upscale toolkit with a scratch-free iPhone... Read more
Kingston Digital Ships Large Capacity Near 1T...
Kingston Digital, Inc., the Flash memory affiliate of Kingston Technology Company, Inc.,has announced its latest addition to the SSDNow V300 series, the V310. The Kingston SSDNow V310 solid-state... Read more
Apple’s Fiscal Third Quarter Results; Record...
Apple has announced financial results for its fiscal 2014 third quarter ended June 28, 2014, racking up quarterly revenue of $37.4 billion and quarterly net profit of $7.7 billion, or $1.28 per... Read more
15-inch 2.0GHz MacBook Pro Retina on sale for...
B&H Photo has the 15″ 2.0GHz Retina MacBook Pro on sale for $1829 including free shipping plus NY sales tax only. Their price is $170 off MSRP. B&H will also include free copies of Parallels... Read more
Apple restocks refurbished Mac minis for up t...
The Apple Store has restocked Apple Certified Refurbished Mac minis for up to $150 off the cost of new models. Apple’s one-year warranty is included with each mini, and shipping is free: - 2.5GHz Mac... Read more

Jobs Board

Sr Software Lead Engineer, *Apple* Online S...
Sr Software Lead Engineer, Apple Online Store Publishing Systems Keywords: Company: Apple Job Code: E3PCAK8MgYYkw Location (City or ZIP): Santa Clara Status: Full Read more
Senior Interaction Designer, *Apple* Online...
**Job Summary** Apple is looking for a hands on Senior…will be a key player in designing for the Apple Online Store. The ideal designer will have a Read more
*Apple* Sales Chat Rep - Apple (United State...
…is looking for motivated, outgoing, and tech savvy individuals who want to offer Apple Customers an unparalleled customer experience over chat. At Apple , we believe Read more
Mac Expert - *Apple* Online Store Mexico -...
…MUST be fluent in English and Spanish to be considered for this position At Apple , we believe that hard work, a fun environment, creativity and innovation fuel the Read more
*Apple* Industrial Design CAD Sculptor - App...
**Job Summary** The Apple Industrial Design team is looking for a CAD sculptor/Digital 3D modeler to create high quality CAD models used in the industrial design process Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.