/* Implements a simple AppleSingle decoder/encoder, as described in RFC1740 */
/* http://andrew2.andrew.cmu.edu/rfc/rfc1740.html */
#ifdef __MACH__
#include <Carbon/Carbon.h>
#include "apsingle.h"
#include "cvs_hqx.h"
/* stdc */
#include <stdio.h>
#include <string.h>
#define YR_2000_SECONDS 3029572800L
#define CVS_CHANGES
/* struct definitions from RFC1740 */
#if TARGET_API_MAC_CARBON
#pragma options align=mac68k
#elif PRAGMA_ALIGN_SUPPORTED
#pragma options align=mac68k
#endif
typedef struct ASHeader /* header portion of AppleSingle */
{
/* AppleSingle = 0x00051600; AppleDouble = 0x00051607 */
UInt32 magicNum; /* internal file type tag */
UInt32 versionNum; /* format version: 2 = 0x00020000 */
UInt8 filler[16]; /* filler, currently all bits 0 */
UInt16 numEntries; /* number of entries which follow */
} ASHeader ; /* ASHeader */
typedef struct ASEntry /* one AppleSingle entry descriptor */
{
UInt32 entryID; /* entry type: see list, 0 invalid */
UInt32 entryOffset; /* offset, in octets, from beginning */
/* of file to this entry's data */
UInt32 entryLength; /* length of data in octets */
} ASEntry; /* ASEntry */
typedef struct ASFinderInfo
{
FInfo ioFlFndrInfo; /* PBGetFileInfo() or PBGetCatInfo() */
FXInfo ioFlXFndrInfo; /* PBGetCatInfo() (HFS only) */
} ASFinderInfo; /* ASFinderInfo */
typedef struct ASMacInfo /* entry ID 10, Macintosh file information */
{
UInt8 filler[3]; /* filler, currently all bits 0 */
UInt8 ioFlAttrib; /* PBGetFileInfo() or PBGetCatInfo() */
} ASMacInfo;
typedef struct ASFileDates /* entry ID 8, file dates info */
{
SInt32 create; /* file creation date/time */
SInt32 modify; /* last modification date/time */
SInt32 backup; /* last backup date/time */
SInt32 access; /* last access date/time */
} ASFileDates; /* ASFileDates */
#if TARGET_API_MAC_CARBON
#pragma options align=reset
#elif PRAGMA_ALIGN_SUPPORTED
#pragma options align=reset
#endif
/* Prototypes */
OSErr decodeFileDates( ASEntry inEntry, FILE * inFile, const FSRef * ioSpec );
OSErr decodeRealName( ASEntry inEntry, FILE * inFile, const FSRef * ioSpec );
OSErr encodeRealName(FILE * outfp, const FSRef * inSpec );
OSErr encodeComment(FILE * outfp, Str255 comment );
OSErr encodeFileDates(FILE * outfp, const FSCatalogInfo * info);
OSErr encodeFinderInfo( FILE * outfp, const FSCatalogInfo * cinfo);
OSErr encodeMacInfo( FILE * outfp, const FSCatalogInfo * cinfo);
OSErr macFileToFileStream( FILE * outfp, SInt16 refNum, UInt32 bytesExpected);
OSErr encodeDataFork( FILE * outfp, const FSRef * inFile, UInt32 bytesExpected);
OSErr encodeResourceFork( FILE * outfp, const FSRef * inFile, UInt32 bytesExpected);
/* asEntryToMacFile
* Blasts the bytes specified in the entry to already opened Mac file
*/
static OSErr
asEntryToMacFile( ASEntry inEntry, FILE * inFile, SInt16 inRefNum)
{
#define BUFFER_SIZE 8192
char buffer[BUFFER_SIZE];
size_t totalRead = 0, bytesRead;
ByteCount bytesToWrite;
OSErr err;
if ( fseek( inFile, inEntry.entryOffset, SEEK_SET) != 0 )
return -1 ;
while ( totalRead < inEntry.entryLength )
{
// Should we yield in here?
bytesRead = fread( buffer, 1, BUFFER_SIZE, inFile );
if ( bytesRead <= 0 )
return ioErr;
bytesToWrite = totalRead + bytesRead > inEntry.entryLength ?
inEntry.entryLength - totalRead :
bytesRead;
totalRead += bytesRead;
err = FSWriteFork(inRefNum, fsAtMark, 0, bytesToWrite, buffer, &bytesToWrite);
if (err != noErr)
return err;
}
return 0;
}
static OSErr
decodeDataFork( ASEntry inEntry, FILE * inFile, const FSRef * ioSpec )
{
SInt16 refNum;
OSErr err;
HFSUniStr255 forkName;
/* Setup the files */
err = FSGetDataForkName(&forkName);
if (err != noErr)
return err;
err = FSCreateFork(ioSpec, forkName.length, forkName.unicode);
if ( err != noErr )
return err;
err = FSOpenFork(ioSpec, forkName.length, forkName.unicode, fsWrPerm,
&refNum);
if ( err == noErr )
err = asEntryToMacFile( inEntry, inFile, refNum );
FSCloseFork( refNum );
return err;
}
static OSErr
decodeResourceFork( ASEntry inEntry, FILE * inFile, const FSRef * ioSpec )
{
SInt16 refNum;
OSErr err;
HFSUniStr255 forkName;
err = FSGetResourceForkName(&forkName);
if (err != noErr)
return err;
err = FSCreateFork(ioSpec, forkName.length, forkName.unicode);
if ( err != noErr )
return err;
err = FSOpenFork(ioSpec, forkName.length, forkName.unicode, fsWrPerm,
&refNum);
if ( err == noErr )
err = asEntryToMacFile( inEntry, inFile, refNum );
FSCloseFork( refNum );
return err;
}
static OSErr
decodeComment( ASEntry inEntry, FILE * inFile, const FSRef * ioSpec )
{
Str255 newComment;
if ( inEntry.entryLength > 32 ) /* Max file name length for the Mac */
return -1;
if ( fseek( inFile, inEntry.entryOffset, SEEK_SET) != 0 )
return -1 ;
if ( fread( &newComment[1], 1, inEntry.entryLength, inFile ) != inEntry.entryLength )
return -1;
newComment[0] = inEntry.entryLength;
#if 0 // TODO
return FSpDTSetComment(ioSpec, newComment);
#else
return noErr;
#endif
}
static OSErr
decodeFinderInfo( ASEntry inEntry, FILE * inFile, const FSRef * ioSpec )
{
ASFinderInfo info;
OSErr err;
FSCatalogInfo catalogInfo;
if (inEntry.entryLength != sizeof( ASFinderInfo ))
return -1;
if ( fseek( inFile, inEntry.entryOffset, SEEK_SET) != 0 )
return -1 ;
if ( fread( &info, 1, sizeof(info), inFile) != inEntry.entryLength )
return -1;
memcpy(&catalogInfo.finderInfo, &info.ioFlFndrInfo, sizeof(info.ioFlFndrInfo));
memcpy(&catalogInfo.extFinderInfo, &info.ioFlXFndrInfo, sizeof(info.ioFlXFndrInfo));
err = FSSetCatalogInfo(ioSpec,
kFSCatInfoFinderInfo |
kFSCatInfoFinderXInfo, &catalogInfo);
if ( err != noErr )
return -1;
return err;
}
#if 0 // TODO
static OSErr
decodeMacInfo( ASEntry inEntry, FILE * inFile, const FSRef * ioSpec )
{
ASMacInfo info;
OSErr err;
Str31 name;
CInfoPBRec pb;
if (inEntry.entryLength != sizeof( ASMacInfo ))
return -1;
if ( fseek( inFile, inEntry.entryOffset, SEEK_SET) != 0 )
return -1 ;
if ( fread( &info, 1, sizeof(info), inFile) != inEntry.entryLength )
return -1;
memcpy(name, ioSpec->name, ioSpec->name[0] + 1);
pb.hFileInfo.ioNamePtr = name;
pb.hFileInfo.ioVRefNum = ioSpec->vRefNum;
pb.hFileInfo.ioDirID = ioSpec->parID;
pb.hFileInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */
err = PBGetCatInfoSync(&pb);
if ( err != noErr )
return -1;
pb.hFileInfo.ioNamePtr = name;
pb.hFileInfo.ioVRefNum = ioSpec->vRefNum;
pb.hFileInfo.ioDirID = ioSpec->parID;
pb.hFileInfo.ioFlAttrib = info.ioFlAttrib;
err = PBSetCatInfoSync(&pb);
return err;
}
#endif
#if 0 // TODO
OSErr
decodeFileDates( ASEntry inEntry, FILE * inFile, const FSRef * ioSpec )
{
ASFileDates dates;
OSErr err;
FSCatalogInfo catalogInfo;
if ( inEntry.entryLength != sizeof(dates) ) /* Max file name length for the Mac */
return -1;
if ( fseek( inFile, inEntry.entryOffset, SEEK_SET) != 0 )
return -1 ;
if ( fread( &dates, 1, inEntry.entryLength, inFile ) != inEntry.entryLength )
return -1;
catalogInfo.createDate = dates.create + YR_2000_SECONDS;
catalogInfo.contentModDate = dates.modify + YR_2000_SECONDS;
catalogInfo.backupDate = dates.backup + YR_2000_SECONDS;
err = FSSetCatalogInfo(ioSpec,
kFSCatInfoCreateDate |
kFSCatInfoContentMod |
kFSCatInfoBackupDate, &catalogInfo);
return err;
}
#endif
#if 0
OSErr
decodeRealName( ASEntry inEntry, FILE * inFile, const FSRef * ioSpec )
{
Str255 newName;
OSErr err;
if ( inEntry.entryLength > 32 ) /* Max file name length for the Mac */
return -1;
if ( fseek( inFile, inEntry.entryOffset, SEEK_SET) != 0 )
return -1 ;
if ( fread( &newName[1], 1, inEntry.entryLength, inFile ) != inEntry.entryLength )
return -1;
newName[0] = inEntry.entryLength;
err = FSpRename(ioSpec, newName);
if (err == noErr)
memcpy( ioSpec->name, newName, 32 );
return err;
}
#endif
static OSErr
processASEntry( ASEntry inEntry, FILE * inFile, const FSRef * ioSpec )
{
switch (inEntry.entryID)
{
case AS_DATA:
return decodeDataFork( inEntry, inFile, ioSpec );
break;
case AS_RESOURCE:
return decodeResourceFork( inEntry, inFile, ioSpec );
break;
case AS_REALNAME:
// return decodeRealName( inEntry, inFile, ioSpec );
break;
case AS_COMMENT:
return decodeComment( inEntry, inFile, ioSpec );
break;
case AS_ICONBW:
// return decodeIconBW( inEntry, inFile, ioSpec );
break;
case AS_ICONCOLOR:
// return decodeIconColor( inEntry, inFile, ioSpec );
break;
case AS_FILEDATES:
// return decodeFileDates( inEntry, inFile, ioSpec );
break;
case AS_FINDERINFO:
return decodeFinderInfo( inEntry, inFile, ioSpec );
break;
case AS_MACINFO:
#if 0 // TODO
return decodeMacInfo( inEntry, inFile, ioSpec );
#endif
break;
case AS_PRODOSINFO:
case AS_MSDOSINFO:
case AS_AFPNAME:
case AS_AFPINFO:
case AS_AFPDIRID:
default:
return 0;
}
return 0;
}
/* Decodes
* Arguments:
* inFile - name of the AppleSingle file
* outSpec - destination. If destination is renamed (as part of decoding of realName)
* the outSpec is modified to represent the new name
*/
OSErr
decodeAppleSingle(const char * inFile, const char * outFile, long wantedEntries)
{
FILE * in;
size_t bytesRead;
ASHeader header;
OSErr err;
int i;
FSRef outSpec, parentSpec;
char path[1024];
UniChar ustr[256];
SInt32 uniLen = sizeof(ustr) / sizeof(UniChar);
in = fopen( inFile, "rb");
if ( in == NULL )
return fnfErr;
/* Read in the header */
{
bytesRead = fread(&header, 1, sizeof(ASHeader), in );
if ( bytesRead != sizeof(ASHeader))
goto fail;
if ( header.magicNum != AS_MAGIC_NUM )
goto fail;
if ( header.versionNum != 0x00020000 )
goto fail;
if ( header.numEntries == 0 ) /* nothing in this file ? */
goto fail;
}
/* Create the output file */
getcwd(path, sizeof(path));
err = PathToFSRef(path, &parentSpec);
if(err != noErr)
goto fail;
strcat(path, "/");
strcat(path, outFile);
err = PathToFSRef(path, &outSpec);
if (err != noErr && err != fnfErr) goto fail;
if(err == noErr)
{
err = FSDeleteObject(&outSpec); /* Preventive delete, not sure if we need it */
if(err != noErr)
goto fail;
}
/* Setup the files */
err = StrToUnicode(outFile, ustr, &uniLen, 0L);
if (err != noErr) goto fail;
err = FSCreateFileUnicode(&parentSpec, uniLen, ustr, kFSCatInfoNone,
0L, &outSpec, 0L);
if (err != noErr) goto fail;
/* Loop through the entries, processing each */
/* Set the time/date stamps last, because otherwise they'll be destroyed
when we write */
{
Boolean hasDateEntry = false;
ASEntry dateEntry;
for ( i=0; i < header.numEntries; i++ )
{
ASEntry entry;
size_t offset = sizeof( ASHeader ) + sizeof( ASEntry ) * i;
if ( fseek( in, offset, SEEK_SET ) != 0 )
goto fail;
if ( fread( &entry, 1, sizeof( entry ), in ) != sizeof( entry ))
goto fail;
if ( wantedEntries & ( ((UInt32)1) << (entry.entryID - 1 )))
switch (entry.entryID)
{
case AS_DATA:
err = decodeDataFork( entry, in, &outSpec );
break;
case AS_RESOURCE:
err = decodeResourceFork( entry, in, &outSpec );
break;
case AS_REALNAME:
//err = decodeRealName( entry, in, &outSpec );
break;
case AS_COMMENT:
err = decodeComment( entry, in, &outSpec );
break;
case AS_FILEDATES:
/* Save it for postprocessing */
hasDateEntry = true;
dateEntry = entry;
break;
case AS_FINDERINFO:
err = decodeFinderInfo( entry, in, &outSpec );
break;
case AS_MACINFO:
#if 0 // TODO
err = decodeMacInfo( entry, in, &outSpec );
#endif
break;
case AS_ICONBW:
case AS_ICONCOLOR:
fprintf(stderr, "Can't decode AS_ICONBW...");
break;
case AS_PRODOSINFO:
case AS_MSDOSINFO:
case AS_AFPNAME:
case AS_AFPINFO:
case AS_AFPDIRID:
default:
break;
}
if ( err != 0)
break;
}
if ( hasDateEntry )
err = processASEntry( dateEntry, in, &outSpec );
}
fclose(in);
in = NULL;
if ( err == noErr )
return err;
// else fall through failure
fail:
if (in)
fclose(in);
FSDeleteObject(&outSpec); /* Preventive delete, not sure if we need it */
fprintf(stderr, "AppleSingle decoding has failed: %s\n", inFile);
return ioErr;
}
OSErr
encodeRealName(FILE * outfp, const FSRef * inSpec )
{
FSCatalogInfo catalogInfo;
OSErr err;
FSSpec inFSSpec;
err = FSGetCatalogInfo(inSpec, kFSCatInfoNone, &catalogInfo, 0L, &inFSSpec, 0L);
if(err != noErr)
return err;
if ( fwrite( &(inFSSpec.name[1]), 1, inFSSpec.name[0], outfp) < 0 )
return ioErr;
return noErr;
}
OSErr
encodeComment(FILE * outfp, Str255 comment )
{
if ( fwrite( &(comment[1]), 1, comment[0], outfp) < 0 )
return ioErr;
return noErr;
}
#if 0
OSErr
encodeFileDates(FILE * outfp, const FSCatalogInfo * info)
{
ASFileDates dates;
dates.create = info->createDate - YR_2000_SECONDS;
dates.modify = info->contentModDate - YR_2000_SECONDS;
dates.backup = info->backupDate - YR_2000_SECONDS;
dates.access = 0; /* Unknown on the mac */
if ( fwrite( &dates, 1, sizeof(dates), outfp) < 0 )
return ioErr;
return noErr;
}
#endif
OSErr
encodeFinderInfo( FILE * outfp, const FSCatalogInfo * cinfo)
{
ASFinderInfo info;
memcpy(&info.ioFlFndrInfo, &cinfo->finderInfo, sizeof(info.ioFlFndrInfo));
memcpy(&info.ioFlXFndrInfo, &cinfo->extFinderInfo, sizeof(info.ioFlXFndrInfo));
if ( fwrite( &info, 1, sizeof(info), outfp) < 0 )
return ioErr;
return noErr;
}
#if 0 // TODO
OSErr
encodeMacInfo( FILE * outfp, const FSCatalogInfo * cinfo )
{
ASMacInfo info;
memset( &info, 0, sizeof(info));
info.ioFlAttrib = pb->hFileInfo.ioFlAttrib;
if ( fwrite( &info, 1, sizeof(info), outfp) < 0 )
return ioErr;
return noErr;
}
#endif
OSErr
macFileToFileStream( FILE * outfp, SInt16 refNum, UInt32 bytesExpected)
{
#define BUFFER_SIZE 8192
char buffer[BUFFER_SIZE];
UInt32 totalRead = 0;
ByteCount currentRead;
OSErr err;
while ( totalRead < bytesExpected )
{
currentRead = BUFFER_SIZE;
err = FSReadFork( refNum, fsAtMark, 0, currentRead, buffer, ¤tRead);
totalRead += currentRead;
if ( err != noErr && ( totalRead < bytesExpected))
return err;
if ( fwrite( buffer, 1, currentRead, outfp) < 0)
return -1;
}
return noErr;
}
OSErr
encodeDataFork( FILE * outfp, const FSRef * inFile, UInt32 bytesExpected)
{
short refNum;
OSErr err;
HFSUniStr255 forkName;
err = FSGetDataForkName(&forkName);
if (err != noErr)
return err;
err = FSOpenFork(inFile, forkName.length, forkName.unicode, fsRdPerm,
&refNum);
if (err != noErr )
return err;
err = macFileToFileStream( outfp, refNum, bytesExpected );
FSCloseFork( refNum );
return err;
}
OSErr
encodeResourceFork( FILE * outfp, const FSRef * inFile, UInt32 bytesExpected)
{
short refNum;
OSErr err;
HFSUniStr255 forkName;
err = FSGetResourceForkName(&forkName);
if (err != noErr)
return err;
err = FSOpenFork(inFile, forkName.length, forkName.unicode, fsRdPerm,
&refNum);
if (err != noErr )
return err;
err = macFileToFileStream( outfp, refNum, bytesExpected );
FSCloseFork( refNum );
return err;
}
/* Encodes the file as applesingle
*
* These are the possible parts that can be encoded as AppleSingle:
Data Fork 1 Data fork
Resource Fork 2 Resource fork
Real Name 3 File's name as created on home file system
Comment 4 Standard Macintosh comment
File Dates Info 8 File creation date, modification date,
and so on
Finder Info 9 Standard Macintosh Finder information
Macintosh File Info 10 Macintosh file information, attributes and so on
* This routine will encode all parts that are relevant (ex no data fork encoding if data fork length is 0
*/
OSErr
encodeAppleSingle(const char * inFile, const char * outFile, long wantedEntries)
{
OSErr err;
Boolean needDataFork, needResourceFork, needRealName, needComment, needFileDates, needFinderInfo, needMacInfo;
ASHeader header;
ASEntry entry;
UInt16 numEntries;
FILE * outfp;
Str255 comment;
size_t availableOffset;
char path[1024];
FSRef inspec;
FSSpec inFSSpec;
FSCatalogInfo catalogInfo;
needDataFork = needResourceFork = needRealName = needComment
= needFileDates = needFinderInfo = needMacInfo = false;
/* Figure out which parts of will we need to encode */
getcwd(path, sizeof(path));
strcat(path, "/");
strcat(path, inFile);
err = PathToFSRef(path, &inspec);
if(err != noErr)
goto fail;
err = FSGetCatalogInfo(&inspec,
kFSCatInfoFinderInfo |
kFSCatInfoFinderXInfo |
kFSCatInfoCreateDate |
kFSCatInfoContentMod |
kFSCatInfoBackupDate |
kFSCatInfoDataSizes |
kFSCatInfoRsrcSizes, &catalogInfo, 0L, &inFSSpec, 0L);
if(err != noErr)
goto fail;
#if 0 // TODO
if ( FSpDTGetComment(&inFSSpec,comment) != noErr)
#endif
comment[0] = 0;
needDataFork = (catalogInfo.dataLogicalSize > 0)
&& ( AS_DATA_BIT & wantedEntries) ; /* Data fork? */
needResourceFork = (catalogInfo.rsrcLogicalSize > 0)
&& ( AS_RESOURCE_BIT & wantedEntries ); /* Resource fork? */
needComment = comment[0] != 0
&& ( AS_COMMENT_BIT & wantedEntries );
needFinderInfo = ( AS_FINDERINFO_BIT & wantedEntries) != 0;
needRealName = (AS_REALNAME_BIT & wantedEntries) != 0;
#if 0 // TODO
needMacInfo = ( AS_MACINFO_BIT & wantedEntries) != 0;
needFileDates = ( AS_FILEDATES_BIT & wantedEntries) != 0;
#endif
#ifdef CVS_CHANGES
needRealName = false;
needFileDates = false;
#endif
/* The header */
memset(&header, 0, sizeof(ASHeader)); /* for the filler bits */
header.magicNum = AS_MAGIC_NUM;
header.versionNum = 0x00020000;
numEntries = 0;
if ( needDataFork ) numEntries++;
if ( needResourceFork ) numEntries++;
if ( needRealName ) numEntries++;
if ( needComment ) numEntries++;
if ( needFileDates ) numEntries++;
if ( needFinderInfo ) numEntries++;
if ( needMacInfo ) numEntries++;
header.numEntries = numEntries;
outfp = fopen(outFile, "wb");
if ( outfp == NULL)
goto fail;
/* write header */
if ( fwrite( &header, 1, sizeof(ASHeader), outfp) < 0 )
goto fail;
/* write out the entry headers */
availableOffset = sizeof(ASHeader) + numEntries * sizeof(ASEntry);
if ( needRealName )
{
entry.entryID = AS_REALNAME;
entry.entryOffset = availableOffset;
entry.entryLength = inFSSpec.name[0];
if ( fwrite( &entry, 1, sizeof(ASEntry), outfp) < 0 )
goto fail;
availableOffset += entry.entryLength;
}
if ( needComment )
{
entry.entryID = AS_COMMENT;
entry.entryOffset = availableOffset;
entry.entryLength = comment[0];
if ( fwrite( &entry, 1, sizeof(ASEntry), outfp) < 0 )
goto fail;
availableOffset += entry.entryLength;
}
if ( needFileDates )
{
entry.entryID = AS_FILEDATES;
entry.entryOffset = availableOffset;
entry.entryLength = sizeof (ASFileDates );
if ( fwrite( &entry, 1, sizeof(ASEntry), outfp) < 0 )
goto fail;
availableOffset += entry.entryLength;
}
if ( needFinderInfo )
{
entry.entryID = AS_FINDERINFO;
entry.entryOffset = availableOffset;
entry.entryLength = sizeof (ASFinderInfo );
if ( fwrite( &entry, 1, sizeof(ASEntry), outfp) < 0 )
goto fail;
availableOffset += entry.entryLength;
}
if ( needMacInfo )
{
entry.entryID = AS_MACINFO;
entry.entryOffset = availableOffset;
entry.entryLength = sizeof (ASMacInfo );
if ( fwrite( &entry, 1, sizeof(ASEntry), outfp) < 0 )
goto fail;
availableOffset += entry.entryLength;
}
if ( needDataFork )
{
entry.entryID = AS_DATA;
entry.entryOffset = availableOffset;
entry.entryLength = catalogInfo.dataLogicalSize;
if ( fwrite( &entry, 1, sizeof(ASEntry), outfp) < 0 )
goto fail;
availableOffset += entry.entryLength;
}
if ( needResourceFork )
{
entry.entryID = AS_RESOURCE;
entry.entryOffset = availableOffset;
entry.entryLength = catalogInfo.rsrcLogicalSize;
if ( fwrite( &entry, 1, sizeof(ASEntry), outfp) < 0 )
goto fail;
availableOffset += entry.entryLength;
}
/* write out the entry data */
if ( needRealName )
if ( encodeRealName(outfp, &inspec) != noErr )
goto fail;
if ( needComment )
if ( encodeComment(outfp, comment) != noErr )
goto fail;
#if 0 // TODO
if ( needFileDates )
if ( encodeFileDates(outfp, &catalogInfo) != noErr )
goto fail;
#endif
if ( needFinderInfo )
if ( encodeFinderInfo(outfp, &catalogInfo) != noErr )
goto fail;
#if 0 // TODO
if ( needMacInfo )
if ( encodeMacInfo( outfp, &cbrec ) != noErr )
goto fail;
#endif
if ( needDataFork )
if ( encodeDataFork( outfp, &inspec, catalogInfo.dataLogicalSize) != noErr )
goto fail;
if ( needResourceFork )
if ( encodeResourceFork( outfp, &inspec, catalogInfo.rsrcLogicalSize) != noErr )
goto fail;
fclose(outfp);
outfp = NULL;
/* All done! */
return noErr;
fail:
if ( outfp )
fclose(outfp);
remove( outFile);
if (err == noErr)
err = ioErr;
fprintf(stderr, "Unexpected AppleSingle encoding error %s\n", outFile );
return err;
}
#endif /* __MACH__ */
syntax highlighted by Code2HTML, v. 0.9.1