mirror of
https://github.com/fadden/nulib2.git
synced 2024-10-31 11:08:35 +00:00
From Eric Shepherd: changes to support resource forks and file/creator types
under Mac OS X.
This commit is contained in:
parent
1d38e11b9d
commit
056e4facca
@ -18,6 +18,10 @@
|
||||
*/
|
||||
#include "NufxLibPriv.h"
|
||||
|
||||
#ifdef MAC_LIKE
|
||||
# include <Carbon/Carbon.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For systems (e.g. Visual C++ 6.0) that don't have these standard values.
|
||||
*/
|
||||
@ -40,7 +44,6 @@
|
||||
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* ===========================================================================
|
||||
* DateTime conversions
|
||||
@ -301,6 +304,98 @@ Nu_GetFileInfo(NuArchive* pArchive, const char* pathname,
|
||||
pFileInfo->rsrcEof = 0;
|
||||
pFileInfo->fileType = kDefaultFileType;
|
||||
pFileInfo->auxType = kDefaultAuxType;
|
||||
# if defined(MAC_LIKE)
|
||||
if (!pFileInfo->isDirectory) {
|
||||
char path[4096];
|
||||
struct stat res_sbuf;
|
||||
OSErr result;
|
||||
OSType fileType, creator;
|
||||
FSCatalogInfo catalogInfo;
|
||||
FSRef ref;
|
||||
unsigned long proType, proAux;
|
||||
|
||||
strcpy(path, pathname);
|
||||
strcat(path, "/rsrc");
|
||||
cc = stat(path, &res_sbuf);
|
||||
if (cc) {
|
||||
if (!errno) {
|
||||
pFileInfo->rsrcEof = res_sbuf.st_size;
|
||||
}
|
||||
}
|
||||
|
||||
result = FSPathMakeRef(pathname, &ref, NULL);
|
||||
if (!result) {
|
||||
result = FSGetCatalogInfo(&ref, kFSCatInfoFinderInfo, &catalogInfo,
|
||||
NULL, NULL, NULL);
|
||||
if (!result) {
|
||||
fileType = ((FileInfo *) &catalogInfo.finderInfo)->fileType;
|
||||
creator = ((FileInfo *) &catalogInfo.finderInfo)->fileCreator;
|
||||
|
||||
/* This actually is probably more efficient than a weird table, for
|
||||
so few values */
|
||||
|
||||
switch(creator) {
|
||||
case 'pdos':
|
||||
if (fileType == 'PSYS') {
|
||||
proType = 0xFF;
|
||||
proAux = 0x0000;
|
||||
} else if (fileType == 'PS16') {
|
||||
proType = 0xB3;
|
||||
proAux = 0x0000;
|
||||
} else {
|
||||
if ((fileType >> 24) & 0xFF == 'p') {
|
||||
proType = (fileType >> 16) & 0xFF;
|
||||
proAux = fileType & 0xFFFF;
|
||||
} else {
|
||||
proType = 0x00;
|
||||
proAux = 0x0000;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'dCpy':
|
||||
if (fileType == 'dImg') {
|
||||
proType = 0xE0;
|
||||
proAux = 0x0005;
|
||||
} else {
|
||||
proType = 0x00;
|
||||
proAux = 0x0000;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
switch(fileType) {
|
||||
case 'BINA':
|
||||
proType = 0x06;
|
||||
proAux = 0x0000;
|
||||
break;
|
||||
case 'TEXT':
|
||||
proType = 0x04;
|
||||
proAux = 0x0000;
|
||||
break;
|
||||
case 'MIDI':
|
||||
proType = 0xD7;
|
||||
proAux = 0x0000;
|
||||
break;
|
||||
case 'AIFF':
|
||||
proType = 0xD8;
|
||||
proAux = 0x0000;
|
||||
break;
|
||||
case 'AIFC':
|
||||
proType = 0xD8;
|
||||
proAux = 0x0001;
|
||||
break;
|
||||
default:
|
||||
proType = 0x00;
|
||||
proAux = 0x0000;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
pFileInfo->fileType = proType;
|
||||
pFileInfo->auxType = proAux;
|
||||
}
|
||||
}
|
||||
}
|
||||
# endif
|
||||
Nu_GMTSecondsToDateTime(&sbuf.st_mtime, &pFileInfo->modWhen);
|
||||
pFileInfo->unixMode = sbuf.st_mode;
|
||||
pFileInfo->isValid = true;
|
||||
@ -335,10 +430,45 @@ Nu_FileForkExists(NuArchive* pArchive, const char* pathname,
|
||||
Assert(pExists != nil);
|
||||
Assert(pFileInfo != nil);
|
||||
|
||||
#if defined(UNIX_LIKE) || defined(WINDOWS_LIKE)
|
||||
#if defined(MAC_LIKE)
|
||||
/*
|
||||
* We ignore "isForkedFile" and "checkRsrcFork". The file must not
|
||||
* exist at all.
|
||||
* On Mac OS X, we do much like on Unix, but we do need to look for
|
||||
* a resource fork.
|
||||
*/
|
||||
*pExists = true;
|
||||
if (!checkRsrcFork) {
|
||||
/*
|
||||
* Check the data fork.
|
||||
*/
|
||||
Assert(pArchive->lastFileCreated == nil);
|
||||
err = Nu_GetFileInfo(pArchive, pathname, pFileInfo);
|
||||
if (err == kNuErrFileNotFound) {
|
||||
err = kNuErrNone;
|
||||
*pExists = false;
|
||||
}
|
||||
/* DBUG(("Data fork %s: %d (err %d)\n", pathname, *pExists, err));*/
|
||||
} else {
|
||||
/*
|
||||
* Check the resource fork.
|
||||
*/
|
||||
char path[4096];
|
||||
strncpy(path, pathname, 4089);
|
||||
strcat(path, "/rsrc");
|
||||
err = Nu_GetFileInfo(pArchive, path, pFileInfo);
|
||||
if (err == kNuErrFileNotFound) {
|
||||
err = kNuErrNone;
|
||||
*pExists = false;
|
||||
} else if (!err && !pFileInfo->rsrcEof) {
|
||||
err = kNuErrNone;
|
||||
*pExists = false;
|
||||
}
|
||||
/* DBUG(("Rsrc fork %s: %d (err %d)\n", path, *pExists, err));*/
|
||||
}
|
||||
|
||||
#elif defined(UNIX_LIKE) || defined(WINDOWS_LIKE)
|
||||
/*
|
||||
* On Unix and Windows we ignore "isForkedFile" and "checkRsrcFork".
|
||||
* The file must not exist at all.
|
||||
*/
|
||||
Assert(pArchive->lastFileCreated == nil);
|
||||
|
||||
@ -496,6 +626,9 @@ Nu_PrepareForWriting(NuArchive* pArchive, const char* pathname,
|
||||
Boolean prepRsrc, NuFileInfo* pFileInfo)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
#if defined(MAC_LIKE)
|
||||
char path[4096];
|
||||
#endif
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pathname != nil);
|
||||
@ -509,6 +642,13 @@ Nu_PrepareForWriting(NuArchive* pArchive, const char* pathname,
|
||||
return kNuErrNotRegularFile;
|
||||
|
||||
#if defined(UNIX_LIKE) || defined(WINDOWS_LIKE)
|
||||
# if defined(MAC_LIKE)
|
||||
if (prepRsrc) {
|
||||
strcpy(path, pathname);
|
||||
strcat(path, "/rsrc");
|
||||
pathname = path;
|
||||
}
|
||||
# endif
|
||||
if (!(pFileInfo->unixMode & S_IWUSR)) {
|
||||
/* make it writable by owner, plus whatever it was before */
|
||||
if (chmod(pathname, S_IWUSR | pFileInfo->unixMode) < 0) {
|
||||
@ -636,8 +776,11 @@ Nu_CreatePathIFN(NuArchive* pArchive, const char* pathname, char fssep)
|
||||
Assert(fssep != '\0');
|
||||
|
||||
pathStart = pathname;
|
||||
|
||||
#if !defined(MAC_LIKE) /* On the Mac, if it's a full path, treat it like one */
|
||||
if (pathname[0] == fssep)
|
||||
pathStart++;
|
||||
#endif
|
||||
|
||||
/* NOTE: not expecting names like "foo/bar/ack/", with terminating fssep */
|
||||
pathEnd = strrchr(pathStart, fssep);
|
||||
@ -683,6 +826,14 @@ static NuError
|
||||
Nu_OpenFileForWrite(NuArchive* pArchive, const char* pathname,
|
||||
Boolean openRsrc, FILE** pFp)
|
||||
{
|
||||
#if defined(MAC_LIKE)
|
||||
char path[4096];
|
||||
if (openRsrc) {
|
||||
strcpy(path, pathname);
|
||||
strcat(path, "/rsrc");
|
||||
pathname = path;
|
||||
}
|
||||
#endif
|
||||
*pFp = fopen(pathname, kNuFileOpenWriteTrunc);
|
||||
if (*pFp == nil)
|
||||
return errno ? errno : -1;
|
||||
@ -965,6 +1116,35 @@ Nu_CloseOutputFile(NuArchive* pArchive, const NuRecord* pRecord, FILE* fp,
|
||||
err = Nu_SetFileAccess(pArchive, pRecord, pathname);
|
||||
BailError(err);
|
||||
|
||||
#ifdef MAC_LIKE
|
||||
OSErr result;
|
||||
OSType fileType;
|
||||
FSCatalogInfo catalogInfo;
|
||||
FSRef ref;
|
||||
|
||||
result = FSPathMakeRef(pathname, &ref, NULL);
|
||||
BailError(result);
|
||||
|
||||
result = FSGetCatalogInfo(&ref, kFSCatInfoNodeFlags|kFSCatInfoFinderInfo, &catalogInfo,
|
||||
NULL, NULL, NULL);
|
||||
if (result) {
|
||||
BailError(kNuErrFileStat);
|
||||
}
|
||||
|
||||
/* Build the type and creator */
|
||||
|
||||
fileType = 0x70000000;
|
||||
fileType |= (pRecord->recFileType & 0xFF) << 16;
|
||||
fileType |= (pRecord->recExtraType & 0xFFFF);
|
||||
|
||||
/* Set the type and creator */
|
||||
|
||||
((FileInfo *) &catalogInfo.finderInfo)->fileType = fileType;
|
||||
((FileInfo *) &catalogInfo.finderInfo)->fileCreator = 'pdos';
|
||||
result = FSSetCatalogInfo(&ref, kFSCatInfoFinderInfo, &catalogInfo);
|
||||
BailError(result);
|
||||
#endif
|
||||
|
||||
bail:
|
||||
return kNuErrNone;
|
||||
}
|
||||
@ -1008,6 +1188,15 @@ Nu_OpenInputFile(NuArchive* pArchive, const char* pathname,
|
||||
Assert(pathname != nil);
|
||||
Assert(pFp != nil);
|
||||
|
||||
#if defined(MAC_LIKE)
|
||||
char path[4096];
|
||||
if (openRsrc) {
|
||||
strcpy(path, pathname);
|
||||
strcat(path, "/rsrc");
|
||||
pathname = path;
|
||||
}
|
||||
#endif
|
||||
|
||||
retry:
|
||||
/*
|
||||
* Open sesame.
|
||||
|
@ -107,9 +107,13 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__) /* OS X */
|
||||
# define MAC_LIKE
|
||||
# define UNIX_LIKE
|
||||
#endif
|
||||
|
||||
#if defined(__unix__) || defined(__unix) || defined(__BEOS__) || \
|
||||
defined(__hpux) || defined(_AIX) || defined(__APPLE__)
|
||||
defined(__hpux) || defined(_AIX)
|
||||
# define UNIX_LIKE /* standardize */
|
||||
#endif
|
||||
|
||||
@ -124,7 +128,7 @@
|
||||
/*# define HAS_RESOURCE_FORKS*/
|
||||
/*#endif*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
#if defined(__ORCAC__) || defined(MAC_LIKE)
|
||||
# define HAS_RESOURCE_FORKS
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user