platform/macclassic.c
changeset 424 a691527e9f6e
parent 393 468f75bf4d7d
child 427 c38ace41039f
equal deleted inserted replaced
423:524e087944b4 424:a691527e9f6e
    58 #include "physfs_internal.h"
    58 #include "physfs_internal.h"
    59 
    59 
    60 
    60 
    61 const char *__PHYSFS_platformDirSeparator = ":";
    61 const char *__PHYSFS_platformDirSeparator = ":";
    62 
    62 
       
    63 
       
    64 static const char *get_os_error_string(OSErr err)
       
    65 {
       
    66     if (err == noErr)
       
    67         return(NULL);
       
    68 
       
    69     switch (err)
       
    70     {
       
    71         case fnfErr: return("File not found");
       
    72         case notOpenErr: return("Volume not found");
       
    73         case dirFulErr: return("Directory full");
       
    74         case dskFulErr: return("Disk full");
       
    75         case nsvErr: return("Volume not found");
       
    76         case ioErr: return(ERR_IO_ERROR);
       
    77         case bdNamErr: return(ERR_BAD_FILENAME);
       
    78         case fnOpnErr: return(ERR_NOT_A_HANDLE);
       
    79         case eofErr: return(ERR_PAST_EOF);
       
    80         case posErr: return(ERR_SEEK_OUT_OF_RANGE);
       
    81         case tmfoErr: return("Too many files open");
       
    82         case wPrErr: return("Volume is locked through hardware");
       
    83         case fLckdErr: return("File is locked");
       
    84         case vLckdErr: return("Volume is locked through software");
       
    85         case fBsyErr: return("File/directory is busy");
       
    86         case dupFNErr: return(FILE_ALREADY_EXISTS);
       
    87         case opWrErr: return("File already open for writing");
       
    88         case rfNumErr: return("Invalid reference number");
       
    89         case gfpErr: return("Error getting file position");
       
    90         case volOffLinErr: return("Volume is offline");
       
    91         case permErr: return("Permission denied");
       
    92         case volOnLinErr: return("Volume already online");
       
    93         case nsDrvErr: return("No such drive");
       
    94         case noMacDskErr: return("Not a Macintosh disk");
       
    95         case extFSErr: return("Volume belongs to an external file system");
       
    96         case fsRnErr: return("Problem during rename");
       
    97         case badMDBErr: return("Bad master directory block");
       
    98         case wrPermErr: return("Write permission denied");
       
    99         case memFullErr: return(ERR_OUT_OF_MEMORY);
       
   100         case dirNFErr: return("Directory not found or incomplete pathname");
       
   101         case tmwdoErr: return("Too many working directories open");
       
   102         case badMovErr: return("Attempt to move forbidden");
       
   103         case wrgVolTypErr: return("Wrong volume type");
       
   104         case volGoneErr: return("Server volume has been disconnected");
       
   105         case errFSNameTooLong: return(ERR_BAD_FILENAME);
       
   106         case errFSNotAFolder: return("Not a folder");
       
   107         case errFSNotAFile: return("Not a file");
       
   108         case fidNotFound: return("File ID not found");
       
   109         case fidExists: return("File ID already exists");
       
   110         case afpAccessDenied: return("Access denied");
       
   111         case afpNoServer: return("Server not responding");
       
   112         case afpUserNotAuth: return("User authentication failed");
       
   113         case afpPwdExpiredErr: return("Password has expired on server");
       
   114 
       
   115         case paramErr:
       
   116         case errFSBadFSRef:
       
   117         case errFSBadBuffer:
       
   118         case errFSMissingName:
       
   119         case errFSBadPosMode:
       
   120         case errFSBadAllocFlags:
       
   121         case errFSBadItemCount
       
   122         case errFSBadSearchParams
       
   123         case afpDenyConflict
       
   124             return("(BUG) PhysicsFS gave wrong params to the OS.");
       
   125 
       
   126         default: return(ERR_OS_ERROR);
       
   127     } /* switch */
       
   128 
       
   129     return(NULL);
       
   130 } /* get_os_error_string */
       
   131 
       
   132 
       
   133 static OSErr oserr(OSErr err)
       
   134 {
       
   135     char buf[128];
       
   136     const char *errstr = get_os_error_string(err);
       
   137     if (err == ERR_OS_ERROR)
       
   138     {
       
   139         snprintf(buf, "MacOS reported error (%d)", (int) err);
       
   140         errstr = buf;
       
   141     } /* if */
       
   142 
       
   143     if (errstr != NULL)
       
   144         __PHYSFS_SetError(errstr);
       
   145 
       
   146     return(err);
       
   147 } /* oserr */
       
   148 
       
   149 
    63 static struct ProcessInfoRec procInfo;
   150 static struct ProcessInfoRec procInfo;
    64 static FSSpec procfsspec;
   151 static FSSpec procfsspec;
    65 
   152 
    66 int __PHYSFS_platformInit(void)
   153 int __PHYSFS_platformInit(void)
    67 {
   154 {
    68     OSErr err;
   155     OSErr err;
    69     ProcessSerialNumber psn;
   156     ProcessSerialNumber psn;
    70     BAIL_IF_MACRO(GetCurrentProcess(&psn) != noErr, ERR_OS_ERROR, 0);
   157     BAIL_IF_MACRO(oserr(GetCurrentProcess(&psn)) != noErr, NULL, 0);
    71     memset(&procInfo, '\0', sizeof (ProcessInfoRec));
   158     memset(&procInfo, '\0', sizeof (ProcessInfoRec));
    72     memset(&procfsspec, '\0', sizeof (FSSpec));
   159     memset(&procfsspec, '\0', sizeof (FSSpec));
    73     procInfo.processInfoLength = sizeof (ProcessInfoRec);
   160     procInfo.processInfoLength = sizeof (ProcessInfoRec);
    74     procInfo.processAppSpec = &procfsspec;
   161     procInfo.processAppSpec = &procfsspec;
    75     err = GetProcessInformation(&psn, &procInfo);
   162     err = GetProcessInformation(&psn, &procInfo);
    76     BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, 0);
   163     BAIL_IF_MACRO(oserr(err) != noErr, NULL, 0);
    77     return(1);  /* we're golden. */
   164     return(1);  /* we're golden. */
    78 } /* __PHYSFS_platformInit */
   165 } /* __PHYSFS_platformInit */
    79 
   166 
    80 
   167 
    81 int __PHYSFS_platformDeinit(void)
   168 int __PHYSFS_platformDeinit(void)
   163     /* walk the tree back to the root dir (volume), building path string... */
   250     /* walk the tree back to the root dir (volume), building path string... */
   164     do
   251     do
   165     {
   252     {
   166         /* check parent dir of what we last looked at... */
   253         /* check parent dir of what we last looked at... */
   167         infoPB.dirInfo.ioDrDirID = infoPB.dirInfo.ioDrParID;
   254         infoPB.dirInfo.ioDrDirID = infoPB.dirInfo.ioDrParID;
   168         if (PBGetCatInfoSync(&infoPB) != noErr)
   255         if (oserr(PBGetCatInfoSync(&infoPB)) != noErr)
   169         {
   256         {
   170             if (retval != NULL)
   257             if (retval != NULL)
   171                 free(retval);
   258                 free(retval);
   172             BAIL_MACRO(ERR_OS_ERROR, NULL);
   259             return(NULL);
   173         } /* if */
   260         } /* if */
   174 
   261 
   175         infoPB.dirInfo.ioFDirIndex = -1;  /* look at parent dir next time. */
   262         infoPB.dirInfo.ioFDirIndex = -1;  /* look at parent dir next time. */
   176 
   263 
   177         /* allocate more space for the retval... */
   264         /* allocate more space for the retval... */
   217     short origResourceFile = CurResFile();
   304     short origResourceFile = CurResFile();
   218 
   305 
   219     /* use the System resource file. */
   306     /* use the System resource file. */
   220     UseResFile(0);
   307     UseResFile(0);
   221     /* apparently, -16096 specifies the username. */
   308     /* apparently, -16096 specifies the username. */
   222     strHandle = GetString(-16096);
   309     strHandle = oserr(GetString(-16096));
   223     UseResFile(origResourceFile);
   310     UseResFile(origResourceFile);
   224     BAIL_IF_MACRO(strHandle == NULL, ERR_OS_ERROR, NULL);
   311     BAIL_IF_MACRO(strHandle == NULL, NULL, NULL);
   225 
   312 
   226     HLock((Handle) strHandle);
   313     HLock((Handle) strHandle);
   227     retval = (char *) malloc((*strHandle)[0] + 1);
   314     retval = (char *) malloc((*strHandle)[0] + 1);
   228     if (retval == NULL)
   315     if (retval == NULL)
   229     {
   316     {
   278 
   365 
   279     /* probably just a volume name, which seems to need a ':' at the end. */
   366     /* probably just a volume name, which seems to need a ':' at the end. */
   280     if (needColon)
   367     if (needColon)
   281         str255[len] = ':';
   368         str255[len] = ':';
   282 
   369 
   283     err = FSMakeFSSpec(0, 0, str255, spec);
   370     err = oserr(FSMakeFSSpec(0, 0, str255, spec));
   284     return(err);
   371     return(err);
   285 } /* fnameToFSSpecNoAlias */
   372 } /* fnameToFSSpecNoAlias */
   286 
   373 
   287 
   374 
   288 static OSErr fnameToFSSpec(const char *fname, FSSpec *spec)
   375 static OSErr fnameToFSSpec(const char *fname, FSSpec *spec)
   306         BAIL_IF_MACRO(!ptr, ERR_NO_SUCH_FILE, err); /* just in case */
   393         BAIL_IF_MACRO(!ptr, ERR_NO_SUCH_FILE, err); /* just in case */
   307         ptr = strchr(ptr + 1, ':');
   394         ptr = strchr(ptr + 1, ':');
   308         BAIL_IF_MACRO(!ptr, ERR_NO_SUCH_FILE, err); /* just in case */
   395         BAIL_IF_MACRO(!ptr, ERR_NO_SUCH_FILE, err); /* just in case */
   309         *ptr = '\0';
   396         *ptr = '\0';
   310         err = fnameToFSSpecNoAlias(path, spec); /* get first dir. */
   397         err = fnameToFSSpecNoAlias(path, spec); /* get first dir. */
   311         BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, err);
   398         BAIL_IF_MACRO(oserr(err) != noErr, NULL, err);
   312         start = ptr;
   399         start = ptr;
   313         ptr = strchr(start + 1, ':');
   400         ptr = strchr(start + 1, ':');
   314 
   401 
   315         /* Now check each element of the path for aliases... */
   402         /* Now check each element of the path for aliases... */
   316         do
   403         do
   347         } while (start != NULL);
   434         } while (start != NULL);
   348     } /* if */
   435     } /* if */
   349 
   436 
   350     else /* there's something there; make sure final file is not an alias. */
   437     else /* there's something there; make sure final file is not an alias. */
   351     {
   438     {
   352         BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, err);
   439         BAIL_IF_MACRO(oserr(err) != noErr, NULL, err);
   353         err = ResolveAliasFileWithMountFlags(spec, 1, &folder, &alias, 0);
   440         err = ResolveAliasFileWithMountFlags(spec, 1, &folder, &alias, 0);
   354         BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, err);
   441         BAIL_IF_MACRO(oserr(err) != noErr, NULL, err);
   355     } /* else */
   442     } /* else */
   356 
   443 
   357     return(noErr);  /* w00t. */
   444     return(noErr);  /* w00t. */
   358 } /* fnameToFSSpec */
   445 } /* fnameToFSSpec */
   359 
   446 
   388     memset(&infoPB, '\0', sizeof (CInfoPBRec));
   475     memset(&infoPB, '\0', sizeof (CInfoPBRec));
   389     infoPB.dirInfo.ioNamePtr = spec.name;
   476     infoPB.dirInfo.ioNamePtr = spec.name;
   390     infoPB.dirInfo.ioVRefNum = spec.vRefNum;
   477     infoPB.dirInfo.ioVRefNum = spec.vRefNum;
   391     infoPB.dirInfo.ioDrDirID = spec.parID;
   478     infoPB.dirInfo.ioDrDirID = spec.parID;
   392     infoPB.dirInfo.ioFDirIndex = 0;
   479     infoPB.dirInfo.ioFDirIndex = 0;
   393     BAIL_IF_MACRO(PBGetCatInfoSync(&infoPB) != noErr, ERR_OS_ERROR, 0);
   480     BAIL_IF_MACRO(oserr(PBGetCatInfoSync(&infoPB)) != noErr, NULL, 0);
   394 
   481 
   395     err = FSMakeFSSpec(spec.vRefNum, infoPB.dirInfo.ioDrDirID,
   482     err = FSMakeFSSpec(spec.vRefNum, infoPB.dirInfo.ioDrDirID,
   396                        (const unsigned char *) ptr, &spec);
   483                        (const unsigned char *) ptr, &spec);
   397     BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, 0);
   484     BAIL_IF_MACRO(oserr(err) != noErr, NULL, 0);
   398     BAIL_IF_MACRO(IsAliasFile(&spec, &a, &f) != noErr, ERR_OS_ERROR, 0);
   485     BAIL_IF_MACRO(oserr(IsAliasFile(&spec, &a, &f)) != noErr, NULL, 0);
   399     return(a);
   486     return(a);
   400 } /* __PHYSFS_platformIsSymlink */
   487 } /* __PHYSFS_platformIsSymlink */
   401 
   488 
   402 
   489 
   403 int __PHYSFS_platformIsDirectory(const char *fname)
   490 int __PHYSFS_platformIsDirectory(const char *fname)
   411     infoPB.dirInfo.ioNamePtr = spec.name;     /* put name in here.       */
   498     infoPB.dirInfo.ioNamePtr = spec.name;     /* put name in here.       */
   412     infoPB.dirInfo.ioVRefNum = spec.vRefNum;  /* ID of file's volume.    */ 
   499     infoPB.dirInfo.ioVRefNum = spec.vRefNum;  /* ID of file's volume.    */ 
   413     infoPB.dirInfo.ioDrDirID = spec.parID;    /* ID of bin's dir.        */
   500     infoPB.dirInfo.ioDrDirID = spec.parID;    /* ID of bin's dir.        */
   414     infoPB.dirInfo.ioFDirIndex = 0;           /* file (not parent) info. */
   501     infoPB.dirInfo.ioFDirIndex = 0;           /* file (not parent) info. */
   415     err = PBGetCatInfoSync(&infoPB);
   502     err = PBGetCatInfoSync(&infoPB);
   416     BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, 0);
   503     BAIL_IF_MACRO(oserr(err) != noErr, NULL, 0);
   417     return((infoPB.dirInfo.ioFlAttrib & kioFlAttribDirMask) != 0);
   504     return((infoPB.dirInfo.ioFlAttrib & kioFlAttribDirMask) != 0);
   418 } /* __PHYSFS_platformIsDirectory */
   505 } /* __PHYSFS_platformIsDirectory */
   419 
   506 
   420 
   507 
   421 char *__PHYSFS_platformCvtToDependent(const char *prepend,
   508 char *__PHYSFS_platformCvtToDependent(const char *prepend,
   472     memset(&infoPB, '\0', sizeof (CInfoPBRec));
   559     memset(&infoPB, '\0', sizeof (CInfoPBRec));
   473     infoPB.dirInfo.ioNamePtr = spec.name;     /* name of dir to enum.    */
   560     infoPB.dirInfo.ioNamePtr = spec.name;     /* name of dir to enum.    */
   474     infoPB.dirInfo.ioVRefNum = spec.vRefNum;  /* ID of file's volume.    */ 
   561     infoPB.dirInfo.ioVRefNum = spec.vRefNum;  /* ID of file's volume.    */ 
   475     infoPB.dirInfo.ioDrDirID = spec.parID;    /* ID of dir.              */
   562     infoPB.dirInfo.ioDrDirID = spec.parID;    /* ID of dir.              */
   476     infoPB.dirInfo.ioFDirIndex = 0;           /* file (not parent) info. */
   563     infoPB.dirInfo.ioFDirIndex = 0;           /* file (not parent) info. */
   477     BAIL_IF_MACRO(PBGetCatInfoSync(&infoPB) != noErr, ERR_OS_ERROR, NULL);
   564     BAIL_IF_MACRO(oserr(PBGetCatInfoSync(&infoPB)) != noErr, NULL, NULL);
   478 
   565 
   479     if ((infoPB.dirInfo.ioFlAttrib & kioFlAttribDirMask) == 0)
   566     if ((infoPB.dirInfo.ioFlAttrib & kioFlAttribDirMask) == 0)
   480         BAIL_MACRO(ERR_NOT_A_DIR, NULL);
   567         BAIL_MACRO(ERR_NOT_A_DIR, NULL);
   481 
   568 
   482     dirID = infoPB.dirInfo.ioDrDirID;
   569     dirID = infoPB.dirInfo.ioDrDirID;
   549 
   636 
   550     BAIL_IF_MACRO(err == noErr, ERR_FILE_EXISTS, 0);
   637     BAIL_IF_MACRO(err == noErr, ERR_FILE_EXISTS, 0);
   551     BAIL_IF_MACRO(err != fnfErr, NULL, 0);
   638     BAIL_IF_MACRO(err != fnfErr, NULL, 0);
   552 
   639 
   553     err = DirCreate(spec.vRefNum, spec.parID, spec.name, &val);
   640     err = DirCreate(spec.vRefNum, spec.parID, spec.name, &val);
   554     BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, 0);
   641     BAIL_IF_MACRO(oserr(err) != noErr, NULL, 0);
   555     return(1);
   642     return(1);
   556 } /* __PHYSFS_platformMkDir */
   643 } /* __PHYSFS_platformMkDir */
   557 
   644 
   558 
   645 
   559 static SInt16 *macDoOpen(const char *fname, SInt8 perm, int createIfMissing)
   646 static SInt16 *macDoOpen(const char *fname, SInt8 perm, int createIfMissing)
   566     if (err == fnfErr)
   653     if (err == fnfErr)
   567     {
   654     {
   568         BAIL_IF_MACRO(!createIfMissing, ERR_NO_SUCH_FILE, NULL);
   655         BAIL_IF_MACRO(!createIfMissing, ERR_NO_SUCH_FILE, NULL);
   569         err = HCreate(spec.vRefNum, spec.parID, spec.name,
   656         err = HCreate(spec.vRefNum, spec.parID, spec.name,
   570                       procInfo.processSignature, 'BINA');
   657                       procInfo.processSignature, 'BINA');
   571         BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, NULL);
   658         BAIL_IF_MACRO(oserr(err) != noErr, NULL, NULL);
   572         created = 1;
   659         created = 1;
   573     } /* if */
   660     } /* if */
   574 
   661 
   575     retval = (SInt16 *) malloc(sizeof (SInt16));
   662     retval = (SInt16 *) malloc(sizeof (SInt16));
   576     if (retval == NULL)
   663     if (retval == NULL)
   578         if (created)
   665         if (created)
   579             HDelete(spec.vRefNum, spec.parID, spec.name);
   666             HDelete(spec.vRefNum, spec.parID, spec.name);
   580         BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
   667         BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
   581     } /* if */
   668     } /* if */
   582 
   669 
   583     if (HOpenDF(spec.vRefNum, spec.parID, spec.name, perm, retval) != noErr)
   670     err = HOpenDF(spec.vRefNum, spec.parID, spec.name, perm, retval)
       
   671     if (oserr(err) != noErr)
   584     {
   672     {
   585         free(retval);
   673         free(retval);
   586         if (created)
   674         if (created)
   587             HDelete(spec.vRefNum, spec.parID, spec.name);
   675             HDelete(spec.vRefNum, spec.parID, spec.name);
   588         BAIL_MACRO(ERR_OS_ERROR, NULL);
   676         return(NULL);
   589     } /* if */
   677     } /* if */
   590 
   678 
   591     return(retval);
   679     return(retval);
   592 } /* macDoOpen */
   680 } /* macDoOpen */
   593 
   681 
   595 void *__PHYSFS_platformOpenRead(const char *filename)
   683 void *__PHYSFS_platformOpenRead(const char *filename)
   596 {
   684 {
   597     SInt16 *retval = macDoOpen(filename, fsRdPerm, 0);
   685     SInt16 *retval = macDoOpen(filename, fsRdPerm, 0);
   598     if (retval != NULL)   /* got a file; seek to start. */
   686     if (retval != NULL)   /* got a file; seek to start. */
   599     {
   687     {
   600         if (SetFPos(*retval, fsFromStart, 0) != noErr)
   688         if (oserr(SetFPos(*retval, fsFromStart, 0)) != noErr)
   601         {
   689         {
   602             FSClose(*retval);
   690             FSClose(*retval);
   603             BAIL_MACRO(ERR_OS_ERROR, NULL);
   691             return(NULL);
   604         } /* if */
   692         } /* if */
   605     } /* if */
   693     } /* if */
   606 
   694 
   607     return((void *) retval);
   695     return((void *) retval);
   608 } /* __PHYSFS_platformOpenRead */
   696 } /* __PHYSFS_platformOpenRead */
   611 void *__PHYSFS_platformOpenWrite(const char *filename)
   699 void *__PHYSFS_platformOpenWrite(const char *filename)
   612 {
   700 {
   613     SInt16 *retval = macDoOpen(filename, fsRdWrPerm, 1);
   701     SInt16 *retval = macDoOpen(filename, fsRdWrPerm, 1);
   614     if (retval != NULL)   /* got a file; truncate it. */
   702     if (retval != NULL)   /* got a file; truncate it. */
   615     {
   703     {
   616         if ((SetEOF(*retval, 0) != noErr) ||
   704         if ((oserr(SetEOF(*retval, 0)) != noErr) ||
   617             (SetFPos(*retval, fsFromStart, 0) != noErr))
   705             (oserr(SetFPos(*retval, fsFromStart, 0)) != noErr))
   618         {
   706         {
   619             FSClose(*retval);
   707             FSClose(*retval);
   620             BAIL_MACRO(ERR_OS_ERROR, NULL);
   708             return(NULL);
   621         } /* if */
   709         } /* if */
   622     } /* if */
   710     } /* if */
   623 
   711 
   624     return((void *) retval);
   712     return((void *) retval);
   625 } /* __PHYSFS_platformOpenWrite */
   713 } /* __PHYSFS_platformOpenWrite */
   628 void *__PHYSFS_platformOpenAppend(const char *filename)
   716 void *__PHYSFS_platformOpenAppend(const char *filename)
   629 {
   717 {
   630     SInt16 *retval = macDoOpen(filename, fsRdWrPerm, 1);
   718     SInt16 *retval = macDoOpen(filename, fsRdWrPerm, 1);
   631     if (retval != NULL)   /* got a file; seek to end. */
   719     if (retval != NULL)   /* got a file; seek to end. */
   632     {
   720     {
   633         if (SetFPos(*retval, fsFromLEOF, 0) != noErr)
   721         if (oserr(SetFPos(*retval, fsFromLEOF, 0)) != noErr)
   634         {
   722         {
   635             FSClose(*retval);
   723             FSClose(*retval);
   636             BAIL_MACRO(ERR_OS_ERROR, NULL);
   724             return(NULL);
   637         } /* if */
   725         } /* if */
   638     } /* if */
   726     } /* if */
   639 
   727 
   640     return(retval);
   728     return(retval);
   641 } /* __PHYSFS_platformOpenAppend */
   729 } /* __PHYSFS_platformOpenAppend */
   649     PHYSFS_uint32 i;
   737     PHYSFS_uint32 i;
   650 
   738 
   651     for (i = 0; i < count; i++)
   739     for (i = 0; i < count; i++)
   652     {
   740     {
   653         br = size;
   741         br = size;
   654         BAIL_IF_MACRO(FSRead(ref, &br, buffer) != noErr, ERR_OS_ERROR, i);
   742         BAIL_IF_MACRO(oserr(FSRead(ref, &br, buffer)) != noErr, NULL, i);
   655         BAIL_IF_MACRO(br != size, ERR_OS_ERROR, i);
   743         BAIL_IF_MACRO(br != size, NULL, i);  /* !!! FIXME: seek back if only read part of an object! */
   656         buffer = ((PHYSFS_uint8 *) buffer) + size;
   744         buffer = ((PHYSFS_uint8 *) buffer) + size;
   657     } /* for */
   745     } /* for */
   658 
   746 
   659     return(count);
   747     return(count);
   660 } /* __PHYSFS_platformRead */
   748 } /* __PHYSFS_platformRead */
   668     PHYSFS_uint32 i;
   756     PHYSFS_uint32 i;
   669 
   757 
   670     for (i = 0; i < count; i++)
   758     for (i = 0; i < count; i++)
   671     {
   759     {
   672         bw = size;
   760         bw = size;
   673         BAIL_IF_MACRO(FSWrite(ref, &bw, buffer) != noErr, ERR_OS_ERROR, i);
   761         BAIL_IF_MACRO(oserr(FSWrite(ref, &bw, buffer)) != noErr, NULL, i);
   674         BAIL_IF_MACRO(bw != size, ERR_OS_ERROR, i);
   762         BAIL_IF_MACRO(bw != size, NULL, i); /* !!! FIXME: seek back if only wrote part of an object! */
   675         buffer = ((PHYSFS_uint8 *) buffer) + size;
   763         buffer = ((PHYSFS_uint8 *) buffer) + size;
   676     } /* for */
   764     } /* for */
   677 
   765 
   678     return(count);
   766     return(count);
   679 } /* __PHYSFS_platformWrite */
   767 } /* __PHYSFS_platformWrite */
   681 
   769 
   682 int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
   770 int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
   683 {
   771 {
   684     SInt16 ref = *((SInt16 *) opaque);
   772     SInt16 ref = *((SInt16 *) opaque);
   685     OSErr err = SetFPos(ref, fsFromStart, (SInt32) pos);
   773     OSErr err = SetFPos(ref, fsFromStart, (SInt32) pos);
   686     BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, 0);
   774     BAIL_IF_MACRO(oserr(err) != noErr, NULL, 0);
   687     return(1);
   775     return(1);
   688 } /* __PHYSFS_platformSeek */
   776 } /* __PHYSFS_platformSeek */
   689 
   777 
   690 
   778 
   691 PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
   779 PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
   692 {
   780 {
   693     SInt16 ref = *((SInt16 *) opaque);
   781     SInt16 ref = *((SInt16 *) opaque);
   694     SInt32 curPos;
   782     SInt32 curPos;
   695     BAIL_IF_MACRO(GetFPos(ref, &curPos) != noErr, ERR_OS_ERROR, -1);
   783     BAIL_IF_MACRO(oserr(GetFPos(ref, &curPos)) != noErr, NULL, -1);
   696     return((PHYSFS_sint64) curPos);
   784     return((PHYSFS_sint64) curPos);
   697 } /* __PHYSFS_platformTell */
   785 } /* __PHYSFS_platformTell */
   698 
   786 
   699 
   787 
   700 PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
   788 PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
   701 {
   789 {
   702     SInt16 ref = *((SInt16 *) opaque);
   790     SInt16 ref = *((SInt16 *) opaque);
   703     SInt32 eofPos;
   791     SInt32 eofPos;
   704     BAIL_IF_MACRO(GetEOF(ref, &eofPos) != noErr, ERR_OS_ERROR, -1);
   792     BAIL_IF_MACRO(oserr(GetEOF(ref, &eofPos)) != noErr, NULL, -1);
   705     return((PHYSFS_sint64) eofPos);
   793     return((PHYSFS_sint64) eofPos);
   706 } /* __PHYSFS_platformFileLength */
   794 } /* __PHYSFS_platformFileLength */
   707 
   795 
   708 
   796 
   709 int __PHYSFS_platformEOF(void *opaque)
   797 int __PHYSFS_platformEOF(void *opaque)
   710 {
   798 {
   711     SInt16 ref = *((SInt16 *) opaque);
   799     SInt16 ref = *((SInt16 *) opaque);
   712     SInt32 eofPos, curPos;
   800     SInt32 eofPos, curPos;
   713     BAIL_IF_MACRO(GetEOF(ref, &eofPos) != noErr, ERR_OS_ERROR, 1);
   801     BAIL_IF_MACRO(oserr(GetEOF(ref, &eofPos)) != noErr, NULL, 1);
   714     BAIL_IF_MACRO(GetFPos(ref, &curPos) != noErr, ERR_OS_ERROR, 1);
   802     BAIL_IF_MACRO(oserr(GetFPos(ref, &curPos)) != noErr, NULL, 1);
   715     return(curPos >= eofPos);
   803     return(curPos >= eofPos);
   716 } /* __PHYSFS_platformEOF */
   804 } /* __PHYSFS_platformEOF */
   717 
   805 
   718 
   806 
   719 int __PHYSFS_platformFlush(void *opaque)
   807 int __PHYSFS_platformFlush(void *opaque)
   720 {
   808 {
   721     SInt16 ref = *((SInt16 *) opaque);
   809     SInt16 ref = *((SInt16 *) opaque);
   722     ParamBlockRec pb;
   810     ParamBlockRec pb;
   723     memset(&pb, '\0', sizeof (ParamBlockRec));
   811     memset(&pb, '\0', sizeof (ParamBlockRec));
   724     pb.ioParam.ioRefNum = ref;
   812     pb.ioParam.ioRefNum = ref;
   725     BAIL_IF_MACRO(PBFlushFileSync(&pb) != noErr, ERR_OS_ERROR, 0);
   813     BAIL_IF_MACRO(oserr(PBFlushFileSync(&pb)) != noErr, NULL, 0);
   726     return(1);
   814     return(1);
   727 } /* __PHYSFS_platformFlush */
   815 } /* __PHYSFS_platformFlush */
   728 
   816 
   729 
   817 
   730 int __PHYSFS_platformClose(void *opaque)
   818 int __PHYSFS_platformClose(void *opaque)
   731 {
   819 {
   732     SInt16 ref = *((SInt16 *) opaque);
   820     SInt16 ref = *((SInt16 *) opaque);
   733     SInt16 vRefNum;
   821     SInt16 vRefNum;
   734     HParamBlockRec hpbr;
       
   735     Str63 volName;
   822     Str63 volName;
   736 
   823     int flushVol = 0;
   737     BAIL_IF_MACRO(GetVRefNum(ref, &vRefNum) != noErr, ERR_OS_ERROR, 0);
   824 
   738 
   825     if (GetVRefNum(ref, &vRefNum) == noErr)
   739     memset(&hpbr, '\0', sizeof (HParamBlockRec));
   826     {
   740     hpbr.volumeParam.ioNamePtr = volName;
   827         HParamBlockRec hpbr;
   741     hpbr.volumeParam.ioVRefNum = vRefNum;
   828         memset(&hpbr, '\0', sizeof (HParamBlockRec));
   742     hpbr.volumeParam.ioVolIndex = 0;
   829         hpbr.volumeParam.ioNamePtr = volName;
   743     BAIL_IF_MACRO(PBHGetVInfoSync(&hpbr) != noErr, ERR_OS_ERROR, 0);
   830         hpbr.volumeParam.ioVRefNum = vRefNum;
   744 
   831         hpbr.volumeParam.ioVolIndex = 0;
   745     BAIL_IF_MACRO(FSClose(ref) != noErr, ERR_OS_ERROR, 0);
   832         if (PBHGetVInfoSync(&hpbr) == noErr)
       
   833             flushVol = 1;
       
   834     } /* if */
       
   835 
       
   836     BAIL_IF_MACRO(oserr(FSClose(ref)) != noErr, NULL, 0);
   746     free(opaque);
   837     free(opaque);
   747 
   838 
   748     FlushVol(volName, vRefNum);
   839     if (flushVol)
       
   840         FlushVol(volName, vRefNum);  /* update catalog info, etc. */
       
   841 
   749     return(1);
   842     return(1);
   750 } /* __PHYSFS_platformClose */
   843 } /* __PHYSFS_platformClose */
   751 
   844 
   752 
   845 
   753 int __PHYSFS_platformDelete(const char *path)
   846 int __PHYSFS_platformDelete(const char *path)
   754 {
   847 {
   755     FSSpec spec;
   848     FSSpec spec;
   756     OSErr err;
   849     OSErr err;
   757     BAIL_IF_MACRO(fnameToFSSpec(path, &spec) != noErr, NULL, 0);
   850     BAIL_IF_MACRO(fnameToFSSpec(path, &spec) != noErr, NULL, 0);
   758     err = HDelete(spec.vRefNum, spec.parID, spec.name);
   851     err = HDelete(spec.vRefNum, spec.parID, spec.name);
   759     BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, 0);
   852     BAIL_IF_MACRO(oserr(err) != noErr, NULL, 0);
   760     return(1);
   853     return(1);
   761 } /* __PHYSFS_platformDelete */
   854 } /* __PHYSFS_platformDelete */
   762 
   855 
   763 
   856 
   764 void *__PHYSFS_platformCreateMutex(void)
   857 void *__PHYSFS_platformCreateMutex(void)
   797     memset(&infoPB, '\0', sizeof (CInfoPBRec));
   890     memset(&infoPB, '\0', sizeof (CInfoPBRec));
   798     infoPB.dirInfo.ioNamePtr = spec.name;
   891     infoPB.dirInfo.ioNamePtr = spec.name;
   799     infoPB.dirInfo.ioVRefNum = spec.vRefNum;
   892     infoPB.dirInfo.ioVRefNum = spec.vRefNum;
   800     infoPB.dirInfo.ioDrDirID = spec.parID;
   893     infoPB.dirInfo.ioDrDirID = spec.parID;
   801     infoPB.dirInfo.ioFDirIndex = 0;
   894     infoPB.dirInfo.ioFDirIndex = 0;
   802     BAIL_IF_MACRO(PBGetCatInfoSync(&infoPB) != noErr, ERR_OS_ERROR, -1);
   895     BAIL_IF_MACRO(oserr(PBGetCatInfoSync(&infoPB)) != noErr, NULL, -1);
   803 
   896 
   804     modDate = ((infoPB.dirInfo.ioFlAttrib & kioFlAttribDirMask) != 0) ?
   897     modDate = ((infoPB.dirInfo.ioFlAttrib & kioFlAttribDirMask) != 0) ?
   805                    infoPB.dirInfo.ioDrMdDat : infoPB.hFileInfo.ioFlMdDat;
   898                    infoPB.dirInfo.ioDrMdDat : infoPB.hFileInfo.ioFlMdDat;
   806 
   899 
   807     /* epoch is different on MacOS. They use Jan 1, 1904, apparently. */
   900     /* epoch is different on MacOS. They use Jan 1, 1904, apparently. */