Dropped classic Mac OS support. Mac OS X remains supported, though.

This commit is contained in:
Ryan C. Gordon 2007-03-14 07:20:59 +00:00
parent 31ff24a38f
commit 0ed7bbc3cf
6 changed files with 12 additions and 1127 deletions

View File

@ -2,6 +2,9 @@
* CHANGELOG.
*/
03142007 - Dropped classic Mac OS support. It's just too hard to find a working
Mac OS 9 install and reasonable development tools, so it's not
worth it. If you still target OS 8 or 9, please use PhysicsFS 1.0.
03112007 - Removed zlib_license_change.txt ... it's in Subversion and the 1.0
branch for history's sake. Added shared and static build options
to CMakeLists.txt, and the expected "make install" target.

Binary file not shown.

View File

@ -85,27 +85,14 @@ Code exists for PocketPC support, and there are shipping titles that used
MAC OS 8/9:
Double-click on "CWProjects.sit" in the root of the source tree. This will
unpack into a folder called "Mac Classic Support", which has CodeWarrior 6
project files. Newer CodeWarrior releases should be able to read these project
files, too.
Point CodeWarrior at "physfs.mcp" in that new folder, and build. This will
produce a "PhysicsFS" or "PhysicsFS Debug" shared library, depending on what
configuration you chose to build. After building the lib, you can make sure
it works by building the "test_physfs.mcp" project file, which will create
"test_physfs" or "test_physfs Debug". These binaries are linked against the
DLLs you built previously.
There is also an MPW project file included, if you don't have CodeWarrior. It
is untested.
PhysicsFS builds for classic Mac OS do not require CarbonLib...they use
OS 9 APIs exclusively.
If someone is willing to maintain prebuilt PhysicsFS Shared Libraries for
the Mac, I'd like to hear from you; send an email to icculus@icculus.org.
Classic Mac OS support has been dropped in PhysicsFS 2.0. Apple hasn't updated
pre-OSX versions in almost a decade at this point, none of the hardware
they've shipped will boot it for almost as many years, and finding
developer tools for it is becoming almost impossible. As the switch to Intel
hardware has removed the "Classic" emulation environment, it was time to
remove support from PhysicsFS. That being said, the PhysicsFS 1.0 branch can
still target back to Mac OS 8.5, so you can use that if you need support for
this legacy OS. We still very much support Mac OS X, though: see below.

View File

@ -1,145 +0,0 @@
# File: PhysicsFS.make
# Target: PhysicsFS
# Created: Saturday, November 20, 2004 09:37:58 PM
MAKEFILE = PhysicsFS.make
¥MondoBuild¥ = {MAKEFILE} # Make blank to avoid rebuilds when makefile is modified
ObjDir = :obj:
Includes = -i : ¶
-i ":zlib123:"
Sym-PPC = -sym on
PPCCOptions = {Includes} {Sym-PPC} -prefix ":Mac Classic Support:codewarrior_predefs.h" -enum int -alloca
### Source Files ###
SrcFiles = ¶
:archivers:dir.c ¶
:archivers:grp.c ¶
:archivers:hog.c ¶
:archivers:mvl.c ¶
:archivers:qpak.c ¶
:archivers:wad.c ¶
:archivers:zip.c ¶
physfs.c ¶
physfs_unicode.c ¶
physfs_byteorder.c ¶
:platform:macclassic.c ¶
:zlib123:adler32.c ¶
:zlib123:compress.c ¶
:zlib123:crc32.c ¶
:zlib123:deflate.c ¶
:zlib123:gzio.c ¶
:zlib123:infback.c ¶
:zlib123:inffast.c ¶
:zlib123:inflate.c ¶
:zlib123:inftrees.c ¶
:zlib123:trees.c ¶
:zlib123:uncompr.c ¶
:zlib123:zutil.c
### Object Files ###
ObjFiles-PPC = ¶
"{ObjDir}dir.c.x" ¶
"{ObjDir}grp.c.x" ¶
"{ObjDir}hog.c.x" ¶
"{ObjDir}mvl.c.x" ¶
"{ObjDir}qpak.c.x" ¶
"{ObjDir}wad.c.x" ¶
"{ObjDir}zip.c.x" ¶
"{ObjDir}physfs.c.x" ¶
"{ObjDir}physfs_byteorder.c.x" ¶
"{ObjDir}physfs_unicode.c.x" ¶
"{ObjDir}macclassic.c.x" ¶
"{ObjDir}adler32.c.x" ¶
"{ObjDir}compress.c.x" ¶
"{ObjDir}crc32.c.x" ¶
"{ObjDir}deflate.c.x" ¶
"{ObjDir}gzio.c.x" ¶
"{ObjDir}infback.c.x" ¶
"{ObjDir}inffast.c.x" ¶
"{ObjDir}inflate.c.x" ¶
"{ObjDir}inftrees.c.x" ¶
"{ObjDir}trees.c.x" ¶
"{ObjDir}uncompr.c.x" ¶
"{ObjDir}zutil.c.x"
### Libraries ###
LibFiles-PPC = ¶
"{SharedLibraries}InterfaceLib" ¶
"{SharedLibraries}StdCLib" ¶
"{SharedLibraries}MathLib" ¶
"{PPCLibraries}StdCRuntime.o" ¶
"{PPCLibraries}PPCCRuntime.o" ¶
"{PPCLibraries}PPCToolLibs.o"
### Default Rules ###
.c.x Ä .c {¥MondoBuild¥}
{PPCC} {depDir}{default}.c -o {targDir}{default}.c.x {PPCCOptions}
### Build Rules ###
PhysicsFS ÄÄ {ObjFiles-PPC} {LibFiles-PPC} {¥MondoBuild¥}
PPCLink ¶
-o {Targ} ¶
{ObjFiles-PPC} ¶
{LibFiles-PPC} ¶
{Sym-PPC} ¶
-@export ":Mac Classic Support:physfs.exp" ¶
-t 'shlb' ¶
-c '????' ¶
-xm s
### Required Dependencies ###
"{ObjDir}dir.c.x" Ä :archivers:dir.c
"{ObjDir}grp.c.x" Ä :archivers:grp.c
"{ObjDir}hog.c.x" Ä :archivers:hog.c
"{ObjDir}mvl.c.x" Ä :archivers:mvl.c
"{ObjDir}qpak.c.x" Ä :archivers:qpak.c
"{ObjDir}wad.c.x" Ä :archivers:wad.c
"{ObjDir}zip.c.x" Ä :archivers:zip.c
"{ObjDir}physfs.c.x" Ä physfs.c
"{ObjDir}physfs_byteorder.c.x" Ä physfs_byteorder.c
"{ObjDir}physfs_unicode.c.x" Ä physfs_unicode.c
"{ObjDir}macclassic.c.x" Ä :platform:macclassic.c
"{ObjDir}adler32.c.x" Ä :zlib123:adler32.c
"{ObjDir}compress.c.x" Ä :zlib123:compress.c
"{ObjDir}crc32.c.x" Ä :zlib123:crc32.c
"{ObjDir}deflate.c.x" Ä :zlib123:deflate.c
"{ObjDir}gzio.c.x" Ä :zlib123:gzio.c
"{ObjDir}infback.c.x" Ä :zlib123:infback.c
"{ObjDir}inffast.c.x" Ä :zlib123:inffast.c
"{ObjDir}inflate.c.x" Ä :zlib123:inflate.c
"{ObjDir}inftrees.c.x" Ä :zlib123:inftrees.c
"{ObjDir}trees.c.x" Ä :zlib123:trees.c
"{ObjDir}uncompr.c.x" Ä :zlib123:uncompr.c
"{ObjDir}zutil.c.x" Ä :zlib123:zutil.c
### Optional Dependencies ###
### Build this target to generate "include file" dependencies. ###
Dependencies Ä $OutOfDate
MakeDepend ¶
-append {MAKEFILE} ¶
-ignore "{CIncludes}" ¶
-objdir "{ObjDir}" ¶
-objext .x ¶
{Includes} ¶
{SrcFiles}

View File

@ -26,7 +26,7 @@
# define PHYSFS_PLATFORM_UNIX
# define PHYSFS_PLATFORM_POSIX
#elif defined(macintosh)
# define PHYSFS_PLATFORM_MACCLASSIC
# error Classic Mac OS support was dropped from PhysicsFS 2.0. Move to OS X.
#elif defined(unix)
# define PHYSFS_PLATFORM_UNIX
# define PHYSFS_PLATFORM_POSIX

View File

@ -1,960 +0,0 @@
/*
* Mac OS classic support routines for PhysicsFS.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/
#define __PHYSICSFS_INTERNAL__
#include "physfs_platforms.h"
#ifdef PHYSFS_PLATFORM_MACCLASSIC
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/*
* Most of the API calls in here are, according to ADC, available since
* Mac OS 8.1. I don't think I used any Mac OS 9 or CarbonLib-specific
* functions. There might be one or two 8.5 calls, and perhaps when the
* ADC docs say "Available in Mac OS 8.1" they really mean "this works
* with System 6, but we don't want to hear about it at this point."
*
* IsAliasFile() showed up in Mac OS 8.5. You can duplicate this code with
* PBGetCatInfoSync(), which is an older API, if you hope the bits in the
* catalog info never change (which they won't for, say, Mac OS 8.1).
* See Apple Technote FL-30:
* http://developer.apple.com/technotes/fl/fl_30.html
*
* If you want to use weak pointers and Gestalt, and choose the correct
* code to use during __PHYSFS_platformInit(), I'll accept a patch, but
* chances are, it wasn't worth the time it took to write this, let alone
* implement that.
*/
#include <OSUtils.h>
#include <Processes.h>
#include <Files.h>
#include <TextUtils.h>
#include <Resources.h>
#include <MacMemory.h>
#include <Events.h>
#include <DriverGestalt.h>
#include <Aliases.h>
#include "physfs_internal.h"
const char *__PHYSFS_platformDirSeparator = ":";
static const char *get_macos_error_string(OSErr err)
{
if (err == noErr)
return(NULL);
switch (err)
{
case fnfErr: return(ERR_NO_SUCH_FILE);
case notOpenErr: return(ERR_NO_SUCH_VOLUME);
case dirFulErr: return(ERR_DIRECTORY_FULL);
case dskFulErr: return(ERR_DISK_FULL);
case nsvErr: return(ERR_NO_SUCH_VOLUME);
case ioErr: return(ERR_IO_ERROR);
case bdNamErr: return(ERR_BAD_FILENAME);
case fnOpnErr: return(ERR_NOT_A_HANDLE);
case eofErr: return(ERR_PAST_EOF);
case posErr: return(ERR_SEEK_OUT_OF_RANGE);
case tmfoErr: return(ERR_TOO_MANY_HANDLES);
case wPrErr: return(ERR_VOL_LOCKED_HW);
case fLckdErr: return(ERR_FILE_LOCKED);
case vLckdErr: return(ERR_VOL_LOCKED_SW);
case fBsyErr: return(ERR_FILE_OR_DIR_BUSY);
case dupFNErr: return(ERR_FILE_EXISTS);
case opWrErr: return(ERR_FILE_ALREADY_OPEN_W);
case rfNumErr: return(ERR_INVALID_REFNUM);
case gfpErr: return(ERR_GETTING_FILE_POS);
case volOffLinErr: return(ERR_VOLUME_OFFLINE);
case permErr: return(ERR_PERMISSION_DENIED);
case volOnLinErr: return(ERR_VOL_ALREADY_ONLINE);
case nsDrvErr: return(ERR_NO_SUCH_DRIVE);
case noMacDskErr: return(ERR_NOT_MAC_DISK);
case extFSErr: return(ERR_VOL_EXTERNAL_FS);
case fsRnErr: return(ERR_PROBLEM_RENAME);
case badMDBErr: return(ERR_BAD_MASTER_BLOCK);
case wrPermErr: return(ERR_PERMISSION_DENIED);
case memFullErr: return(ERR_OUT_OF_MEMORY);
case dirNFErr: return(ERR_NO_SUCH_PATH);
case tmwdoErr: return(ERR_TOO_MANY_HANDLES);
case badMovErr: return(ERR_CANT_MOVE_FORBIDDEN);
case wrgVolTypErr: return(ERR_WRONG_VOL_TYPE);
case volGoneErr: return(ERR_SERVER_VOL_LOST);
case errFSNameTooLong: return(ERR_BAD_FILENAME);
case errFSNotAFolder: return(ERR_NOT_A_DIR);
/*case errFSNotAFile: return(ERR_NOT_A_FILE);*/
case fidNotFound: return(ERR_FILE_ID_NOT_FOUND);
case fidExists: return(ERR_FILE_ID_EXISTS);
case afpAccessDenied: return(ERR_ACCESS_DENIED);
case afpNoServer: return(ERR_SERVER_NO_RESPOND);
case afpUserNotAuth: return(ERR_USER_AUTH_FAILED);
case afpPwdExpiredErr: return(ERR_PWORD_EXPIRED);
case paramErr:
case errFSBadFSRef:
case errFSBadBuffer:
case errFSMissingName:
case errFSBadPosMode:
case errFSBadAllocFlags:
case errFSBadItemCount:
case errFSBadSearchParams:
case afpDenyConflict:
return(ERR_PHYSFS_BAD_OS_CALL);
default: return(ERR_MACOS_GENERIC);
} /* switch */
return(NULL);
} /* get_macos_error_string */
static OSErr oserr(OSErr retval)
{
char buf[sizeof (ERR_MACOS_GENERIC) + 32];
const char *errstr = get_macos_error_string(retval);
if (errstr != NULL)
{
if (strcmp(errstr, ERR_MACOS_GENERIC) == 0)
{
sprintf(buf, ERR_MACOS_GENERIC, (int) retval);
errstr = buf;
} /* if */
__PHYSFS_setError(errstr);
} /* if */
return(retval);
} /* oserr */
static struct ProcessInfoRec procInfo;
static FSSpec procfsspec;
int __PHYSFS_platformInit(void)
{
OSErr err;
ProcessSerialNumber psn;
BAIL_IF_MACRO(oserr(GetCurrentProcess(&psn)) != noErr, NULL, 0);
memset(&procInfo, '\0', sizeof (ProcessInfoRec));
memset(&procfsspec, '\0', sizeof (FSSpec));
procInfo.processInfoLength = sizeof (ProcessInfoRec);
procInfo.processAppSpec = &procfsspec;
err = GetProcessInformation(&psn, &procInfo);
BAIL_IF_MACRO(oserr(err) != noErr, NULL, 0);
return(1); /* we're golden. */
} /* __PHYSFS_platformInit */
int __PHYSFS_platformDeinit(void)
{
return(1); /* always succeed. */
} /* __PHYSFS_platformDeinit */
/*
* CD detection code is borrowed from Apple Technical Q&A DV18.
* http://developer.apple.com/qa/dv/dv18.html
*/
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
DriverGestaltParam pb;
DrvQEl *dqp;
OSErr status;
pb.csCode = kDriverGestaltCode;
pb.driverGestaltSelector = kdgDeviceType;
dqp = (DrvQEl *) GetDrvQHdr()->qHead;
while (dqp != NULL)
{
pb.ioCRefNum = dqp->dQRefNum;
pb.ioVRefNum = dqp->dQDrive;
status = PBStatusSync((ParmBlkPtr) &pb);
if ((status == noErr) && (pb.driverGestaltResponse == kdgCDType))
{
Str63 volName;
size_t size;
HParamBlockRec hpbr;
memset(&hpbr, '\0', sizeof (HParamBlockRec));
hpbr.volumeParam.ioNamePtr = volName;
hpbr.volumeParam.ioVRefNum = dqp->dQDrive;
hpbr.volumeParam.ioVolIndex = 0;
if (PBHGetVInfoSync(&hpbr) == noErr)
{
size = (size_t) volName[0]; /* convert to ASCIZ string... */
memmove(&volName[0], &volName[1], size);
volName[size] = '\0';
cb(data, (const char *) volName);
} /* if */
} /* if */
dqp = (DrvQEl *) dqp->qLink;
} /* while */
} /* __PHYSFS_platformDetectAvailableCDs */
static char *convFSSpecToPath(FSSpec *spec, int includeFile)
{
char *ptr;
char *retval = NULL;
UInt32 retLength = 0;
CInfoPBRec infoPB;
Str255 str255;
str255[0] = spec->name[0];
memcpy(&str255[1], &spec->name[1], str255[0]);
memset(&infoPB, '\0', sizeof (CInfoPBRec));
infoPB.dirInfo.ioNamePtr = str255; /* put name in here. */
infoPB.dirInfo.ioVRefNum = spec->vRefNum; /* ID of bin's volume. */
infoPB.dirInfo.ioDrParID = spec->parID; /* ID of bin's dir. */
infoPB.dirInfo.ioFDirIndex = (includeFile) ? 0 : -1;
/* walk the tree back to the root dir (volume), building path string... */
do
{
/* check parent dir of what we last looked at... */
infoPB.dirInfo.ioDrDirID = infoPB.dirInfo.ioDrParID;
if (oserr(PBGetCatInfoSync(&infoPB)) != noErr)
{
if (retval != NULL)
allocator.Free(retval);
return(NULL);
} /* if */
infoPB.dirInfo.ioFDirIndex = -1; /* look at parent dir next time. */
/* allocate more space for the retval... */
retLength += str255[0] + 1; /* + 1 for a ':' or null char... */
ptr = (char *) allocator.Malloc(retLength);
if (ptr == NULL)
{
if (retval != NULL)
allocator.Free(retval);
BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
} /* if */
/* prepend new dir to retval and cleanup... */
memcpy(ptr, &str255[1], str255[0]);
ptr[str255[0]] = '\0'; /* null terminate it. */
if (retval != NULL)
{
strcat(ptr, ":");
strcat(ptr, retval);
allocator.Free(retval);
} /* if */
retval = ptr;
} while (infoPB.dirInfo.ioDrDirID != fsRtDirID);
return(retval);
} /* convFSSpecToPath */
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
{
FSSpec spec;
/* Get the name of the binary's parent directory. */
FSMakeFSSpec(procfsspec.vRefNum, procfsspec.parID, procfsspec.name, &spec);
return(convFSSpecToPath(&spec, 0));
} /* __PHYSFS_platformCalcBaseDir */
char *__PHYSFS_platformGetUserName(void)
{
char *retval = NULL;
StringHandle strHandle;
short origResourceFile = CurResFile();
/* use the System resource file. */
UseResFile(0);
/* apparently, -16096 specifies the username. */
strHandle = GetString(-16096);
UseResFile(origResourceFile);
BAIL_IF_MACRO(strHandle == NULL, NULL, NULL);
HLock((Handle) strHandle);
retval = (char *) allocator.Malloc((*strHandle)[0] + 1);
if (retval == NULL)
{
HUnlock((Handle) strHandle);
BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
} /* if */
memcpy(retval, &(*strHandle)[1], (*strHandle)[0]);
retval[(*strHandle)[0]] = '\0'; /* null-terminate it. */
HUnlock((Handle) strHandle);
return(retval);
} /* __PHYSFS_platformGetUserName */
char *__PHYSFS_platformGetUserDir(void)
{
#if 0
return(NULL); /* bah...use default behaviour, I guess. */
#else
/* (Hmm. Default behaviour is broken in the base library. :) ) */
return(__PHYSFS_platformCalcBaseDir(NULL));
#endif
} /* __PHYSFS_platformGetUserDir */
PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
{
return(1); /* single threaded. */
} /* __PHYSFS_platformGetThreadID */
int __PHYSFS_platformStricmp(const char *x, const char *y)
{
int ux, uy;
do
{
ux = toupper((int) *x);
uy = toupper((int) *y);
if (ux != uy)
return((ux > uy) ? 1 : -1);
x++;
y++;
} while ((ux) && (uy));
return(0);
} /* __PHYSFS_platformStricmp */
int __PHYSFS_platformStrnicmp(const char *x, const char *y, PHYSFS_uint32 len)
{
int ux, uy;
if (!len)
return(0);
do
{
ux = toupper((int) *x);
uy = toupper((int) *y);
if (ux != uy)
return((ux > uy) ? 1 : -1);
x++;
y++;
len--;
} while ((ux) && (uy) && (len));
return(0);
} /* __PHYSFS_platformStrnicmp */
static OSErr fnameToFSSpecNoAlias(const char *fname, FSSpec *spec)
{
OSErr err;
Str255 str255;
int needColon = (strchr(fname, ':') == NULL);
int len = strlen(fname) + ((needColon) ? 1 : 0);
if (len > 255)
return(bdNamErr);
/* !!! FIXME: What happens with relative pathnames? */
str255[0] = len;
memcpy(&str255[1], fname, len);
/* probably just a volume name, which seems to need a ':' at the end. */
if (needColon)
str255[len] = ':';
err = oserr(FSMakeFSSpec(0, 0, str255, spec));
return(err);
} /* fnameToFSSpecNoAlias */
static OSErr fnameToFSSpec(const char *fname, FSSpec *spec)
{
Boolean alias = 0;
Boolean folder = 0;
OSErr err = fnameToFSSpecNoAlias(fname, spec);
if (err == dirNFErr) /* might be an alias in the middle of the path. */
{
/*
* Has to be at least two ':' chars, or we wouldn't get a
* dir-not-found condition. (no ':' means it was just a volume,
* just one ':' means we would have gotten a fnfErr, if anything.
*/
char *ptr;
char *start;
char *path = alloca(strlen(fname) + 1);
strcpy(path, fname);
ptr = strchr(path, ':');
BAIL_IF_MACRO(!ptr, ERR_NO_SUCH_FILE, err); /* just in case */
ptr = strchr(ptr + 1, ':');
BAIL_IF_MACRO(!ptr, ERR_NO_SUCH_FILE, err); /* just in case */
*ptr = '\0';
err = fnameToFSSpecNoAlias(path, spec); /* get first dir. */
BAIL_IF_MACRO(oserr(err) != noErr, NULL, err);
start = ptr;
ptr = strchr(start + 1, ':');
/* Now check each element of the path for aliases... */
do
{
CInfoPBRec infoPB;
memset(&infoPB, '\0', sizeof (CInfoPBRec));
infoPB.dirInfo.ioNamePtr = spec->name;
infoPB.dirInfo.ioVRefNum = spec->vRefNum;
infoPB.dirInfo.ioDrDirID = spec->parID;
infoPB.dirInfo.ioFDirIndex = 0;
err = PBGetCatInfoSync(&infoPB);
if (err != noErr) /* not an alias, really just a bogus path. */
return(fnameToFSSpecNoAlias(fname, spec)); /* reset */
if ((infoPB.dirInfo.ioFlAttrib & kioFlAttribDirMask) != 0)
spec->parID = infoPB.dirInfo.ioDrDirID;
if (ptr != NULL) /* terminate string after next element. */
*ptr = '\0';
*start = strlen(start + 1); /* make it a pstring. */
err = FSMakeFSSpec(spec->vRefNum, spec->parID,
(const unsigned char *) start, spec);
if (err != noErr) /* not an alias, really a bogus path. */
return(fnameToFSSpecNoAlias(fname, spec)); /* reset */
err = ResolveAliasFileWithMountFlags(spec, 1, &folder, &alias, 0);
if (err != noErr) /* not an alias, really a bogus path. */
return(fnameToFSSpecNoAlias(fname, spec)); /* reset */
start = ptr; /* move to the next element. */
if (ptr != NULL)
ptr = strchr(start + 1, ':');
} while (start != NULL);
} /* if */
else /* there's something there; make sure final file is not an alias. */
{
BAIL_IF_MACRO(oserr(err) != noErr, NULL, err);
err = ResolveAliasFileWithMountFlags(spec, 1, &folder, &alias, 0);
BAIL_IF_MACRO(oserr(err) != noErr, NULL, err);
} /* else */
return(noErr); /* w00t. */
} /* fnameToFSSpec */
int __PHYSFS_platformExists(const char *fname)
{
FSSpec spec;
return(fnameToFSSpec(fname, &spec) == noErr);
} /* __PHYSFS_platformExists */
int __PHYSFS_platformIsSymLink(const char *fname)
{
OSErr err;
FSSpec spec;
Boolean a = 0;
Boolean f = 0;
CInfoPBRec infoPB;
char *ptr;
char *dir = alloca(strlen(fname) + 1);
BAIL_IF_MACRO(dir == NULL, ERR_OUT_OF_MEMORY, 0);
strcpy(dir, fname);
ptr = strrchr(dir, ':');
if (ptr == NULL) /* just a volume name? Can't be a symlink. */
return(0);
/* resolve aliases up to the actual file... */
*ptr = '\0';
BAIL_IF_MACRO(fnameToFSSpec(dir, &spec) != noErr, NULL, 0);
*ptr = strlen(ptr + 1); /* ptr is now a pascal string. Yikes! */
memset(&infoPB, '\0', sizeof (CInfoPBRec));
infoPB.dirInfo.ioNamePtr = spec.name;
infoPB.dirInfo.ioVRefNum = spec.vRefNum;
infoPB.dirInfo.ioDrDirID = spec.parID;
infoPB.dirInfo.ioFDirIndex = 0;
BAIL_IF_MACRO(oserr(PBGetCatInfoSync(&infoPB)) != noErr, NULL, 0);
err = FSMakeFSSpec(spec.vRefNum, infoPB.dirInfo.ioDrDirID,
(const unsigned char *) ptr, &spec);
BAIL_IF_MACRO(oserr(err) != noErr, NULL, 0);
BAIL_IF_MACRO(oserr(IsAliasFile(&spec, &a, &f)) != noErr, NULL, 0);
return(a);
} /* __PHYSFS_platformIsSymlink */
int __PHYSFS_platformIsDirectory(const char *fname)
{
FSSpec spec;
CInfoPBRec infoPB;
OSErr err;
BAIL_IF_MACRO(fnameToFSSpec(fname, &spec) != noErr, NULL, 0);
memset(&infoPB, '\0', sizeof (CInfoPBRec));
infoPB.dirInfo.ioNamePtr = spec.name; /* put name in here. */
infoPB.dirInfo.ioVRefNum = spec.vRefNum; /* ID of file's volume. */
infoPB.dirInfo.ioDrDirID = spec.parID; /* ID of bin's dir. */
infoPB.dirInfo.ioFDirIndex = 0; /* file (not parent) info. */
err = PBGetCatInfoSync(&infoPB);
BAIL_IF_MACRO(oserr(err) != noErr, NULL, 0);
return((infoPB.dirInfo.ioFlAttrib & kioFlAttribDirMask) != 0);
} /* __PHYSFS_platformIsDirectory */
char *__PHYSFS_platformCvtToDependent(const char *prepend,
const char *dirName,
const char *append)
{
int len = ((prepend) ? strlen(prepend) : 0) +
((append) ? strlen(append) : 0) +
strlen(dirName) + 1;
const char *src;
char *dst;
char *retval = (char *) allocator.Malloc(len);
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
if (prepend != NULL)
{
strcpy(retval, prepend);
dst = retval + strlen(retval);
} /* if */
else
{
*retval = '\0';
dst = retval;
} /* else */
for (src = dirName; *src; src++, dst++)
*dst = ((*src == '/') ? ':' : *src);
*dst = '\0';
return(retval);
} /* __PHYSFS_platformCvtToDependent */
void __PHYSFS_platformTimeslice(void)
{
SystemTask();
} /* __PHYSFS_platformTimeslice */
/* returns int so we can use BAIL*MACRO... */
static int macClassicEnumerateFiles(const char *dirname,
int omitSymLinks,
PHYSFS_EnumFilesCallback callback,
const char *origdir,
void *callbackdata)
{
UInt16 i;
UInt16 max;
FSSpec spec;
CInfoPBRec infoPB;
Str255 str255;
long dirID;
BAIL_IF_MACRO(fnameToFSSpec(dirname, &spec) != noErr, NULL, 0);
/* get the dir ID of what we want to enumerate... */
memset(&infoPB, '\0', sizeof (CInfoPBRec));
infoPB.dirInfo.ioNamePtr = spec.name; /* name of dir to enum. */
infoPB.dirInfo.ioVRefNum = spec.vRefNum; /* ID of file's volume. */
infoPB.dirInfo.ioDrDirID = spec.parID; /* ID of dir. */
infoPB.dirInfo.ioFDirIndex = 0; /* file (not parent) info. */
BAIL_IF_MACRO(oserr(PBGetCatInfoSync(&infoPB)) != noErr, NULL, NULL);
if ((infoPB.dirInfo.ioFlAttrib & kioFlAttribDirMask) == 0)
BAIL_MACRO(ERR_NOT_A_DIR, NULL);
dirID = infoPB.dirInfo.ioDrDirID;
max = infoPB.dirInfo.ioDrNmFls;
for (i = 1; i <= max; i++)
{
size_t size;
FSSpec aliasspec;
Boolean alias = 0;
Boolean folder = 0;
memset(&infoPB, '\0', sizeof (CInfoPBRec));
str255[0] = 0;
infoPB.dirInfo.ioNamePtr = str255; /* store name in here. */
infoPB.dirInfo.ioVRefNum = spec.vRefNum; /* ID of dir's volume. */
infoPB.dirInfo.ioDrDirID = dirID; /* ID of dir. */
infoPB.dirInfo.ioFDirIndex = i; /* next file's info. */
if (PBGetCatInfoSync(&infoPB) != noErr)
continue; /* skip this file. Oh well. */
if (FSMakeFSSpec(spec.vRefNum, dirID, str255, &aliasspec) != noErr)
continue; /* skip it. */
if (IsAliasFile(&aliasspec, &alias, &folder) != noErr)
continue; /* skip it. */
if ((alias) && (omitSymLinks))
continue;
/* still here? Add it to the list. */
size = (size_t) str255[0]; /* (convert to ASCIZ string...) */
memmove(&str255[0], &str255[1], size);
str255[size] = '\0';
callback(callbackdata, origdir, (const char *) str255);
} /* for */
return(1);
} /* macClassicEnumerateFiles */
void __PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks,
PHYSFS_EnumFilesCallback callback,
const char *origdir,
void *callbackdata)
{
macClassicEnumerateFiles(dirname, omitSymLinks, callback,
origdir, callbackdata);
} /* __PHYSFS_platformEnumerateFiles */
char *__PHYSFS_platformCurrentDir(void)
{
/*
* I don't think Mac OS has a concept of "current directory", beyond
* what is grafted on by a given standard C library implementation,
* so just return the base dir.
* We don't use this for anything crucial at the moment anyhow.
*/
return(__PHYSFS_platformCalcBaseDir(NULL));
} /* __PHYSFS_platformCurrentDir */
char *__PHYSFS_platformRealPath(const char *path)
{
/*
* fnameToFSSpec() will resolve any symlinks to get to the real
* file's FSSpec, which, when converted, will contain the real
* direct path to a given file. convFSSpecToPath() mallocs a
* return value buffer.
*/
FSSpec spec;
BAIL_IF_MACRO(fnameToFSSpec(path, &spec) != noErr, NULL, NULL);
return(convFSSpecToPath(&spec, 1));
} /* __PHYSFS_platformRealPath */
int __PHYSFS_platformMkDir(const char *path)
{
SInt32 val = 0;
FSSpec spec;
OSErr err = fnameToFSSpec(path, &spec);
BAIL_IF_MACRO(err == noErr, ERR_FILE_EXISTS, 0);
BAIL_IF_MACRO(err != fnfErr, NULL, 0);
err = DirCreate(spec.vRefNum, spec.parID, spec.name, &val);
BAIL_IF_MACRO(oserr(err) != noErr, NULL, 0);
return(1);
} /* __PHYSFS_platformMkDir */
static SInt16 *macDoOpen(const char *fname, SInt8 perm, int createIfMissing)
{
int created = 0;
SInt16 *retval = NULL;
FSSpec spec;
OSErr err = fnameToFSSpec(fname, &spec);
BAIL_IF_MACRO((err != noErr) && (err != fnfErr), NULL, NULL);
if (err == fnfErr)
{
BAIL_IF_MACRO(!createIfMissing, ERR_NO_SUCH_FILE, NULL);
err = HCreate(spec.vRefNum, spec.parID, spec.name,
procInfo.processSignature, 'BINA');
BAIL_IF_MACRO(oserr(err) != noErr, NULL, NULL);
created = 1;
} /* if */
retval = (SInt16 *) allocator.Malloc(sizeof (SInt16));
if (retval == NULL)
{
if (created)
HDelete(spec.vRefNum, spec.parID, spec.name);
BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
} /* if */
err = HOpenDF(spec.vRefNum, spec.parID, spec.name, perm, retval);
if (oserr(err) != noErr)
{
allocator.Free(retval);
if (created)
HDelete(spec.vRefNum, spec.parID, spec.name);
return(NULL);
} /* if */
return(retval);
} /* macDoOpen */
void *__PHYSFS_platformOpenRead(const char *filename)
{
SInt16 *retval = macDoOpen(filename, fsRdPerm, 0);
if (retval != NULL) /* got a file; seek to start. */
{
if (oserr(SetFPos(*retval, fsFromStart, 0)) != noErr)
{
FSClose(*retval);
return(NULL);
} /* if */
} /* if */
return((void *) retval);
} /* __PHYSFS_platformOpenRead */
void *__PHYSFS_platformOpenWrite(const char *filename)
{
SInt16 *retval = macDoOpen(filename, fsRdWrPerm, 1);
if (retval != NULL) /* got a file; truncate it. */
{
if ((oserr(SetEOF(*retval, 0)) != noErr) ||
(oserr(SetFPos(*retval, fsFromStart, 0)) != noErr))
{
FSClose(*retval);
return(NULL);
} /* if */
} /* if */
return((void *) retval);
} /* __PHYSFS_platformOpenWrite */
void *__PHYSFS_platformOpenAppend(const char *filename)
{
SInt16 *retval = macDoOpen(filename, fsRdWrPerm, 1);
if (retval != NULL) /* got a file; seek to end. */
{
if (oserr(SetFPos(*retval, fsFromLEOF, 0)) != noErr)
{
FSClose(*retval);
return(NULL);
} /* if */
} /* if */
return(retval);
} /* __PHYSFS_platformOpenAppend */
PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
PHYSFS_uint32 size, PHYSFS_uint32 count)
{
SInt16 ref = *((SInt16 *) opaque);
SInt32 br = size*count;
BAIL_IF_MACRO(oserr(FSRead(ref, &br, buffer)) != noErr, NULL, br/size);
BAIL_IF_MACRO(br != size*count, NULL, br/size); /* !!! FIXME: seek back if only read part of an object! */
return(count);
} /* __PHYSFS_platformRead */
PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
PHYSFS_uint32 size, PHYSFS_uint32 count)
{
SInt16 ref = *((SInt16 *) opaque);
SInt32 bw = size*count;
BAIL_IF_MACRO(oserr(FSWrite(ref, &bw, buffer)) != noErr, NULL, bw/size);
BAIL_IF_MACRO(bw != size*count, NULL, bw/size); /* !!! FIXME: seek back if only wrote part of an object! */
return(count);
} /* __PHYSFS_platformWrite */
int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
{
SInt16 ref = *((SInt16 *) opaque);
OSErr err = SetFPos(ref, fsFromStart, (SInt32) pos);
BAIL_IF_MACRO(oserr(err) != noErr, NULL, 0);
return(1);
} /* __PHYSFS_platformSeek */
PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
{
SInt16 ref = *((SInt16 *) opaque);
SInt32 curPos;
BAIL_IF_MACRO(oserr(GetFPos(ref, &curPos)) != noErr, NULL, -1);
return((PHYSFS_sint64) curPos);
} /* __PHYSFS_platformTell */
PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
{
SInt16 ref = *((SInt16 *) opaque);
SInt32 eofPos;
BAIL_IF_MACRO(oserr(GetEOF(ref, &eofPos)) != noErr, NULL, -1);
return((PHYSFS_sint64) eofPos);
} /* __PHYSFS_platformFileLength */
int __PHYSFS_platformEOF(void *opaque)
{
SInt16 ref = *((SInt16 *) opaque);
SInt32 eofPos, curPos;
BAIL_IF_MACRO(oserr(GetEOF(ref, &eofPos)) != noErr, NULL, 1);
BAIL_IF_MACRO(oserr(GetFPos(ref, &curPos)) != noErr, NULL, 1);
return(curPos >= eofPos);
} /* __PHYSFS_platformEOF */
int __PHYSFS_platformFlush(void *opaque)
{
SInt16 ref = *((SInt16 *) opaque);
ParamBlockRec pb;
memset(&pb, '\0', sizeof (ParamBlockRec));
pb.ioParam.ioRefNum = ref;
BAIL_IF_MACRO(oserr(PBFlushFileSync(&pb)) != noErr, NULL, 0);
return(1);
} /* __PHYSFS_platformFlush */
int __PHYSFS_platformClose(void *opaque)
{
SInt16 ref = *((SInt16 *) opaque);
SInt16 vRefNum;
Str63 volName;
int flushVol = 0;
if (GetVRefNum(ref, &vRefNum) == noErr)
{
HParamBlockRec hpbr;
memset(&hpbr, '\0', sizeof (HParamBlockRec));
hpbr.volumeParam.ioNamePtr = volName;
hpbr.volumeParam.ioVRefNum = vRefNum;
hpbr.volumeParam.ioVolIndex = 0;
if (PBHGetVInfoSync(&hpbr) == noErr)
flushVol = 1;
} /* if */
BAIL_IF_MACRO(oserr(FSClose(ref)) != noErr, NULL, 0);
allocator.Free(opaque);
if (flushVol)
FlushVol(volName, vRefNum); /* update catalog info, etc. */
return(1);
} /* __PHYSFS_platformClose */
int __PHYSFS_platformDelete(const char *path)
{
FSSpec spec;
OSErr err;
BAIL_IF_MACRO(fnameToFSSpec(path, &spec) != noErr, NULL, 0);
err = HDelete(spec.vRefNum, spec.parID, spec.name);
BAIL_IF_MACRO(oserr(err) != noErr, NULL, 0);
return(1);
} /* __PHYSFS_platformDelete */
void *__PHYSFS_platformCreateMutex(void)
{
return((void *) 0x0001); /* no mutexes on Mac OS classic. */
} /* __PHYSFS_platformCreateMutex */
void __PHYSFS_platformDestroyMutex(void *mutex)
{
/* no mutexes on Mac OS classic. */
} /* __PHYSFS_platformDestroyMutex */
int __PHYSFS_platformGrabMutex(void *mutex)
{
return(1); /* no mutexes on Mac OS classic. */
} /* __PHYSFS_platformGrabMutex */
void __PHYSFS_platformReleaseMutex(void *mutex)
{
/* no mutexes on Mac OS classic. */
} /* __PHYSFS_platformReleaseMutex */
PHYSFS_sint64 __PHYSFS_platformGetLastModTime(const char *fname)
{
FSSpec spec;
CInfoPBRec infoPB;
UInt32 modDate;
if (fnameToFSSpec(fname, &spec) != noErr)
return(-1); /* fnameToFSSpec() sets physfs error message. */
memset(&infoPB, '\0', sizeof (CInfoPBRec));
infoPB.dirInfo.ioNamePtr = spec.name;
infoPB.dirInfo.ioVRefNum = spec.vRefNum;
infoPB.dirInfo.ioDrDirID = spec.parID;
infoPB.dirInfo.ioFDirIndex = 0;
BAIL_IF_MACRO(oserr(PBGetCatInfoSync(&infoPB)) != noErr, NULL, -1);
modDate = ((infoPB.dirInfo.ioFlAttrib & kioFlAttribDirMask) != 0) ?
infoPB.dirInfo.ioDrMdDat : infoPB.hFileInfo.ioFlMdDat;
/* epoch is different on Mac OS. They use Jan 1, 1904, apparently. */
/* subtract seconds between those epochs, counting leap years. */
modDate -= 2082844800;
return((PHYSFS_sint64) modDate);
} /* __PHYSFS_platformGetLastModTime */
/* !!! FIXME: Don't use C runtime for allocators? */
int __PHYSFS_platformAllocatorInit(void)
{
return(1); /* always succeeds. */
} /* __PHYSFS_platformAllocatorInit */
void __PHYSFS_platformAllocatorDeinit(void)
{
/* no-op */
} /* __PHYSFS_platformAllocatorInit */
void *__PHYSFS_platformAllocatorMalloc(PHYSFS_uint64 s)
{
BAIL_IF_MACRO(__PHYSFS_ui64FitsAddressSpace(s), ERR_OUT_OF_MEMORY, NULL);
#undef malloc
return(malloc((size_t) s));
} /* __PHYSFS_platformMalloc */
void *__PHYSFS_platformAllocatorRealloc(void *ptr, PHYSFS_uint64 s)
{
BAIL_IF_MACRO(__PHYSFS_ui64FitsAddressSpace(s), ERR_OUT_OF_MEMORY, NULL);
#undef realloc
return(realloc(ptr, (size_t) s));
} /* __PHYSFS_platformRealloc */
void __PHYSFS_platformAllocatorFree(void *ptr)
{
#undef free
free(ptr);
} /* __PHYSFS_platformAllocatorFree */
#endif /* PHYSFS_PLATFORM_MACCLASSIC */
/* end of macclassic.c ... */