diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 86546cf..5eaadea 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -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. diff --git a/CWProjects.sit b/CWProjects.sit deleted file mode 100755 index 73897e2..0000000 Binary files a/CWProjects.sit and /dev/null differ diff --git a/INSTALL.txt b/INSTALL.txt index 22bfee7..1c0ca42 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -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. diff --git a/physfsMPW.make b/physfsMPW.make deleted file mode 100644 index bc0ae36..0000000 --- a/physfsMPW.make +++ /dev/null @@ -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} - - diff --git a/physfs_platforms.h b/physfs_platforms.h index 75d2f0a..467a96c 100644 --- a/physfs_platforms.h +++ b/physfs_platforms.h @@ -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 diff --git a/platform/macclassic.c b/platform/macclassic.c deleted file mode 100644 index 983f750..0000000 --- a/platform/macclassic.c +++ /dev/null @@ -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 -#include -#include -#include - -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#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 ... */ -