Fix Mac OS X behavior

Some fixes to the Mac OS X build:

- Replace the Carbon calls that were used to set the creator
and file type with xattr calls.  The Carbon stuff still worked
but caused deprecation warnings.  Stop linking against Carbon.

- Correct the way resource forks are accessed (from "/rsrc" to
"/..namedfork/rsrc").  The native resource fork support is
incomplete and doesn't work quite right, so it's now disabled.
(Which means the corrections to the file name don't actually do
anything, but you can at least play with it.)

- Correct the file/aux type conversion, which appeared to do
useful things but actually didn't in some circumstances (e.g. when
adding files, the code for acquiring the file types needs to be in
NuLib2, not NufxLib).

- Set creator and file type to 'pdos' values when extracting from
a Binary ][ archive.

Also, drop some old purify/quantify stuff.
This commit is contained in:
Andy McFadden 2015-01-03 15:15:05 -08:00
parent 1286c3518e
commit 132a8338b9
14 changed files with 345 additions and 244 deletions

View File

@ -19,7 +19,7 @@
#include "NufxLibPriv.h"
#ifdef MAC_LIKE
# include <Carbon/Carbon.h>
# include <sys/xattr.h>
#endif
/*
@ -214,12 +214,10 @@ typedef struct NuFileInfo {
Boolean isRegularFile; /* is this a regular file? */
Boolean isDirectory; /* is this a directory? */
Boolean isForked; /* does file have a non-empty resource fork? */
uint32_t dataEof;
uint32_t rsrcEof;
uint32_t fileType;
uint32_t auxType;
NuDateTime modWhen;
mode_t unixMode; /* UNIX-style permissions */
} NuFileInfo;
@ -258,6 +256,98 @@ static Boolean Nu_IsForkedFile(NuArchive* pArchive, const NuRecord* pRecord)
}
#if defined(MAC_LIKE)
# if defined(HAS_RESOURCE_FORKS)
/*
* String to append to the filename to access the resource fork.
*
* This appears to be the correct way to access the resource fork, since
* at least OS X 10.1. Up until 10.7 ("Lion", July 2011), you could also
* access the fork with "/rsrc".
*/
static const char kMacRsrcPath[] = "/..namedfork/rsrc";
/*
* Generates the resource fork pathname from the file path.
*
* The caller must free the string returned.
*/
static UNICHAR* GetResourcePath(const UNICHAR* pathnameUNI)
{
Assert(pathnameUNI != NULL);
// sizeof(kMacRsrcPath) includes the string and the terminating null byte
const size_t bufLen =
strlen(pathnameUNI) * sizeof(UNICHAR) + sizeof(kMacRsrcPath);
char* buf;
buf = (char*) malloc(bufLen);
snprintf(buf, bufLen, "%s%s", pathnameUNI, kMacRsrcPath);
return buf;
}
# endif /*HAS_RESOURCE_FORKS*/
/*
* Due to historical reasons, the XATTR_FINDERINFO_NAME (defined to be
* ``com.apple.FinderInfo'') extended attribute must be 32 bytes; see the
* ATTR_CMN_FNDRINFO section in getattrlist(2).
*
* The FinderInfo block is the concatenation of a FileInfo structure
* and an ExtendedFileInfo (or ExtendedFolderInfo) structure -- see
* ATTR_CMN_FNDRINFO in getattrlist(2).
*
* All we're really interested in is the file type and creator code,
* which are stored big-endian in the first 8 bytes.
*/
static const int kFinderInfoSize = 32;
/*
* Set the file type and creator type.
*/
static NuError Nu_SetFinderInfo(NuArchive* pArchive, const NuRecord* pRecord,
const UNICHAR* pathnameUNI)
{
uint8_t fiBuf[kFinderInfoSize];
size_t actual = getxattr(pathnameUNI, XATTR_FINDERINFO_NAME,
fiBuf, sizeof(fiBuf), 0, 0);
if (actual == (size_t) -1 && errno == ENOATTR) {
// doesn't yet have Finder info
memset(fiBuf, 0, sizeof(fiBuf));
} else if (actual != kFinderInfoSize) {
Nu_ReportError(NU_BLOB, errno,
"Finder info on '%s' returned %d", pathnameUNI, (int) actual);
return kNuErrFile;
}
/* build type and creator from 8-bit type and 16-bit aux type */
uint32_t fileType, creator;
fileType = ('p' << 24) | ((pRecord->recFileType & 0xff) << 16) |
(pRecord->recExtraType & 0xffff);
creator = 'pdos';
fiBuf[0] = fileType >> 24;
fiBuf[1] = fileType >> 16;
fiBuf[2] = fileType >> 8;
fiBuf[3] = fileType;
fiBuf[4] = creator >> 24;
fiBuf[5] = creator >> 16;
fiBuf[6] = creator >> 8;
fiBuf[7] = creator;
if (setxattr(pathnameUNI, XATTR_FINDERINFO_NAME, fiBuf, sizeof(fiBuf),
0, 0) != 0)
{
Nu_ReportError(NU_BLOB, errno,
"Unable to set Finder info on '%s'", pathnameUNI);
return kNuErrFile;
}
return kNuErrNone;
}
#endif /*MAC_LIKE*/
/*
* Get the file info into a NuFileInfo struct. Fields which are
* inappropriate for the current system are set to default values.
@ -295,99 +385,28 @@ static NuError Nu_GetFileInfo(NuArchive* pArchive, const UNICHAR* pathnameUNI,
/* BUG: should check for 32-bit overflow from 64-bit off_t */
pFileInfo->dataEof = sbuf.st_size;
pFileInfo->rsrcEof = 0;
pFileInfo->fileType = kDefaultFileType;
pFileInfo->auxType = kDefaultAuxType;
# if defined(MAC_LIKE)
pFileInfo->isForked = false;
# if defined(MAC_LIKE) && defined(HAS_RESOURCE_FORKS)
if (!pFileInfo->isDirectory) {
char path[4096]; // TODO: use dynamic alloc or snprintf
/*
* Check for the presence of a resource fork. You can check
* these from a terminal with "ls -l@" -- look for the
* "com.apple.ResourceFork" attribute.
*
* We can either use getxattr() and check for the presence of
* the attribute, or get the file length with stat(). I
* don't know if xattr has always worked with resource forks,
* so we'll stick with stat for now.
*/
UNICHAR* rsrcPath = GetResourcePath(pathnameUNI);
struct stat res_sbuf;
OSErr result;
OSType fileType, creator;
FSCatalogInfo catalogInfo;
FSRef ref;
uint32_t proType, proAux;
strcpy(path, pathnameUNI);
strcat(path, "/rsrc");
cc = stat(path, &res_sbuf);
if (cc) {
if (!errno) {
pFileInfo->rsrcEof = res_sbuf.st_size;
}
}
result = FSPathMakeRef(pathnameUNI, &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;
}
if (stat(rsrcPath, &res_sbuf) == 0) {
pFileInfo->isForked = (res_sbuf.st_size != 0);
}
free(rsrcPath);
}
# endif
Nu_GMTSecondsToDateTime(&sbuf.st_mtime, &pFileInfo->modWhen);
@ -423,47 +442,14 @@ static NuError Nu_FileForkExists(NuArchive* pArchive,
Assert(pExists != NULL);
Assert(pFileInfo != NULL);
#if defined(MAC_LIKE)
/*
* 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->lastFileCreatedUNI == NULL);
err = Nu_GetFileInfo(pArchive, pathnameUNI, 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]; // TODO - dynamic alloc or snprintf
strncpy(path, pathnameUNI, 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)
#if defined(UNIX_LIKE) || defined(WINDOWS_LIKE)
# if !defined(MAC_LIKE)
/*
* On Unix and Windows we ignore "isForkedFile" and "checkRsrcFork".
* The file must not exist at all.
*/
Assert(pArchive->lastFileCreatedUNI == NULL);
# endif
*pExists = true;
err = Nu_GetFileInfo(pArchive, pathnameUNI, pFileInfo);
@ -472,6 +458,16 @@ static NuError Nu_FileForkExists(NuArchive* pArchive,
*pExists = false;
}
# if defined(MAC_LIKE)
/*
* On Mac OS X, we'll use the resource fork, but we may not want to
* overwrite existing data.
*/
if (*pExists && checkRsrcFork) {
*pExists = pFileInfo->isForked;
}
# endif
#elif defined(__ORCAC__)
/*
* If the file doesn't exist, great. If it does, and "lastFileCreated"
@ -617,14 +613,14 @@ bail:
*
* Generally this just involves ensuring that the file is writable. If
* this is a convenient place to truncate it, we should do that too.
*
* 20150103: we don't seem to be doing the truncation here, so prepRsrc
* is unused.
*/
static NuError Nu_PrepareForWriting(NuArchive* pArchive,
const UNICHAR* pathnameUNI, Boolean prepRsrc, NuFileInfo* pFileInfo)
{
NuError err = kNuErrNone;
#if defined(MAC_LIKE)
char path[4096]; // TODO: use dynamic alloc or snprintf
#endif
Assert(pArchive != NULL);
Assert(pathnameUNI != NULL);
@ -638,13 +634,6 @@ static NuError Nu_PrepareForWriting(NuArchive* pArchive,
return kNuErrNotRegularFile;
#if defined(UNIX_LIKE) || defined(WINDOWS_LIKE)
# if defined(MAC_LIKE)
if (prepRsrc) {
strcpy(path, pathnameUNI);
strcat(path, "/rsrc");
pathnameUNI = path;
}
# endif
if (!(pFileInfo->unixMode & S_IWUSR)) {
/* make it writable by owner, plus whatever it was before */
if (chmod(pathnameUNI, S_IWUSR | pFileInfo->unixMode) < 0) {
@ -770,8 +759,9 @@ static NuError Nu_CreatePathIFN(NuArchive* pArchive, const UNICHAR* pathnameUNI,
Assert(fssep != '\0');
pathStart = pathnameUNI;
#if !defined(MAC_LIKE) /* On the Mac, if it's a full path, treat it like one */
// 20150103: not sure what use case this is for
if (pathnameUNI[0] == fssep)
pathStart++;
#endif
@ -820,17 +810,17 @@ bail:
static NuError Nu_OpenFileForWrite(NuArchive* pArchive,
const UNICHAR* pathnameUNI, Boolean openRsrc, FILE** pFp)
{
#if defined(MAC_LIKE)
// TODO: fix this -- use dynamic alloc or snprintf
char path[4096];
#if defined(MAC_LIKE) && defined(HAS_RESOURCE_FORKS)
if (openRsrc) {
strcpy(path, pathnameUNI);
strcat(path, "/rsrc");
pathnameUNI = path;
UNICHAR* rsrcPath = GetResourcePath(pathnameUNI);
*pFp = fopen(rsrcPath, kNuFileOpenWriteTrunc);
free(rsrcPath);
} else {
*pFp = fopen(pathnameUNI, kNuFileOpenWriteTrunc);
}
#endif
#else
*pFp = fopen(pathnameUNI, kNuFileOpenWriteTrunc);
#endif
if (*pFp == NULL)
return errno ? errno : -1;
return kNuErrNone;
@ -1110,33 +1100,10 @@ NuError Nu_CloseOutputFile(NuArchive* pArchive, const NuRecord* pRecord,
err = Nu_SetFileAccess(pArchive, pRecord, pathnameUNI);
BailError(err);
#ifdef MAC_LIKE
OSErr result;
OSType fileType;
FSCatalogInfo catalogInfo;
FSRef ref;
result = FSPathMakeRef(pathnameUNI, &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);
#if defined(MAC_LIKE)
/* could also do this earlier and pass the fd for fsetxattr */
err = Nu_SetFinderInfo(pArchive, pRecord, pathnameUNI);
BailError(err);
#endif
bail:
@ -1180,12 +1147,11 @@ NuError Nu_OpenInputFile(NuArchive* pArchive, const UNICHAR* pathnameUNI,
Assert(pathnameUNI != NULL);
Assert(pFp != NULL);
#if defined(MAC_LIKE)
char path[4096]; // TODO - dynamic alloc or snprintf
#if defined(MAC_LIKE) && defined(HAS_RESOURCE_FORKS)
UNICHAR* rsrcPath = NULL;
if (openRsrc) {
strcpy(path, pathnameUNI);
strcat(path, "/rsrc");
pathnameUNI = path;
rsrcPath = GetResourcePath(pathnameUNI);
pathnameUNI = rsrcPath;
}
#endif
@ -1253,6 +1219,9 @@ bail:
pathnameUNI, openRsrc ? " (rsrc fork)" : "");
}
}
#if defined(MAC_LIKE) && defined(HAS_RESOURCE_FORKS)
free(rsrcPath);
#endif
return err;
}

View File

@ -119,14 +119,10 @@
# endif
#endif
/* resource forks on UFS filesystem under Mac OS X are a kluge */
/*#ifdef MAC*/
/*# define HAS_RESOURCE_FORKS*/
/*#endif*/
#if defined(__ORCAC__) || defined(MAC_LIKE)
# define HAS_RESOURCE_FORKS
#endif
/* not currently using filesystem resource forks */
//#if defined(__ORCAC__) || defined(MAC_LIKE)
//# define HAS_RESOURCE_FORKS
//#endif
/* __FUNCTION__ was missing from BeOS __MWERKS__, and might be gcc-only */
#ifdef __GNUC__

5
nufxlib/configure vendored
View File

@ -3970,11 +3970,6 @@ elif test "$host_os" = "beos"; then
SHARE_FLAGS='-nostartfiles -Xlinker -soname="$@"'
fi
if test "$host_vendor" = "apple" -a ${host_os:0:6} = "darwin"; then
echo "checking for Mac OS X... yes, adding -framework Carbon"
LIBS="$LIBS -framework Carbon"
fi

View File

@ -90,12 +90,6 @@ elif test "$host_os" = "beos"; then
SHARE_FLAGS='-nostartfiles -Xlinker -soname="$@"'
fi
dnl Mac OS X (powerpc-apple-darwin6.6) needs an extra flag.
if test "$host_vendor" = "apple" -a ${host_os:0:6} = "darwin"; then
echo "checking for Mac OS X... yes, adding -framework Carbon"
LIBS="$LIBS -framework Carbon"
fi
AC_SUBST(BUILD_FLAGS)
AC_SUBST(SHARE_FLAGS)

View File

@ -35,28 +35,28 @@ all: $(PRODUCTS)
@true
exerciser: Exerciser.o $(LIB_PRODUCT)
$(PURIFY) $(QUANTIFY) $(CC) -o $@ Exerciser.o $(NUFXLIB) @LIBS@
$(CC) -o $@ Exerciser.o $(NUFXLIB) @LIBS@
imgconv: ImgConv.o $(LIB_PRODUCT)
$(PURIFY) $(QUANTIFY) $(CC) -o $@ ImgConv.o $(NUFXLIB) @LIBS@
$(CC) -o $@ ImgConv.o $(NUFXLIB) @LIBS@
launder: Launder.o $(LIB_PRODUCT)
$(PURIFY) $(QUANTIFY) $(CC) -o $@ Launder.o $(NUFXLIB) @LIBS@
$(CC) -o $@ Launder.o $(NUFXLIB) @LIBS@
test-basic: TestBasic.o $(LIB_PRODUCT)
$(PURIFY) $(QUANTIFY) $(CC) -o $@ TestBasic.o $(NUFXLIB) @LIBS@
$(CC) -o $@ TestBasic.o $(NUFXLIB) @LIBS@
test-extract: TestExtract.o $(LIB_PRODUCT)
$(PURIFY) $(QUANTIFY) $(CC) -o $@ TestExtract.o $(NUFXLIB) @LIBS@
$(CC) -o $@ TestExtract.o $(NUFXLIB) @LIBS@
test-names: TestNames.o $(LIB_PRODUCT)
$(PURIFY) $(QUANTIFY) $(CC) -o $@ TestNames.o $(NUFXLIB) @LIBS@
$(CC) -o $@ TestNames.o $(NUFXLIB) @LIBS@
test-simple: TestSimple.o $(LIB_PRODUCT)
$(PURIFY) $(QUANTIFY) $(CC) -o $@ TestSimple.o $(NUFXLIB) @LIBS@
$(CC) -o $@ TestSimple.o $(NUFXLIB) @LIBS@
test-twirl: TestTwirl.o $(LIB_PRODUCT)
$(PURIFY) $(QUANTIFY) $(CC) -o $@ TestTwirl.o $(NUFXLIB) @LIBS@
$(CC) -o $@ TestTwirl.o $(NUFXLIB) @LIBS@
tags::
ctags --totals -R ../*

View File

@ -1342,8 +1342,16 @@ static NuError BNYExtract(BNYArchive* pBny, BNYEntry* pEntry,
*pConsumedFlag = true;
bail:
if (outfp != NULL && outfp != stdout)
if (outfp != NULL && outfp != stdout) {
#if defined(MAC_LIKE)
if (SetFinderInfo(fileno(outfp), pEntry->fileType,
pEntry->auxType) != kNuErrNone)
{
fprintf(stderr, "WARNING: unable to set finder info\n");
}
#endif
fclose(outfp);
}
return err;
}

View File

@ -309,8 +309,10 @@ const char* NormalizePath(NulibState* pState, NuPathnameProposal* pPathProposal)
AddPreservationString(pState, pPathProposal, pathBuf);
} else if (NuGetThreadID(pPathProposal->pThread) == kNuThreadIDRsrcFork)
{
#ifndef HAS_RESOURCE_FORKS
/* add this in lieu of the preservation extension */
strcat(pathBuf, kResourceStr);
#endif
}
startp = NULL; /* we're done */

View File

@ -44,15 +44,6 @@ OPT = @CFLAGS@
GCC_FLAGS = -Wall -Wwrite-strings -Wstrict-prototypes -Wpointer-arith -Wshadow
CFLAGS = @BUILD_FLAGS@ -I. -I$(NUFXSRCDIR) -I$(includedir) @DEFS@
#ifdef PURIFY_BUILD
# PURIFY = purify
# CFLAGS += -DPURIFY
#endif
#ifdef QUANTIFY_BUILD
# QUANTIFY = quantify
# CFLAGS += -DQUANTIFY
#endif
SRCS = Add.c ArcUtils.c Binary2.c Delete.c Extract.c Filename.c \
List.c Main.c MiscStuff.c MiscUtils.c State.c SysUtils.c
OBJS = Add.o ArcUtils.o Binary2.o Delete.o Extract.o Filename.o \
@ -87,16 +78,8 @@ install-shared:
shared::
LIB_PRODUCT="libnufx.so" $(MAKE) -e
quantify:
-rm -f $(PRODUCT)
@$(MAKE) QUANTIFY_BUILD=1
purify:
-rm -f $(PRODUCT)
@$(MAKE) PURIFY_BUILD=1
$(PRODUCT): $(OBJS) $(NUFXLIB)
$(PURIFY) $(QUANTIFY) $(CC) -o $@ $(OBJS) -L$(NUFXSRCDIR) -L$(libdir) -lnufx @LIBS@
$(CC) -o $@ $(OBJS) -L$(NUFXSRCDIR) -L$(libdir) -lnufx @LIBS@
clean:
-rm -f *.o core

View File

@ -106,6 +106,7 @@ NuError NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
NuError NormalizeDirectoryName(NulibState* pState, const char* srcp,
long srcLen, char fssep, char** pDstp, long dstLen);
char* MakeTempArchiveName(NulibState* pState);
NuError SetFinderInfo(int fd, uint8_t proType, uint16_t proAux);
NuError AddFile(NulibState* pState, NuArchive* pArchive,
const char* pathname);
NuError Mkdir(const char* dir);

View File

@ -1,9 +1,9 @@
NuLib2 README, updated 2014/12/23
NuLib2 README, updated 2015/01/03
http://www.nulib.com/
To build NuLib2, you will also need a copy of NufxLib. This should have come
in the same .tar.gz file. Build the NufxLib library first.
in the same distribution file. Build the NufxLib library first.
UNIX

View File

@ -174,6 +174,16 @@
# define SYSTEM_DEFAULT_EOL "\r"
#endif
#if defined(__APPLE__) && defined(__MACH__) /* OS X */
# define MAC_LIKE
# define UNIX_LIKE
#endif
/* not currently using filesystem resource forks */
//#if defined(__ORCAC__) || defined(MAC_LIKE)
//# define HAS_RESOURCE_FORKS
//#endif
#if defined(APW) || defined(__ORCAC__)
# define __appleiigs__
# pragma lint -1

View File

@ -11,6 +11,9 @@
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#ifdef MAC_LIKE
# include <sys/xattr.h>
#endif
/* get a grip on this opendir/readdir stuff */
#if defined(UNIX_LIKE)
@ -60,6 +63,7 @@
* ===========================================================================
*/
// 20150103: this makes me nervous
#define kTempFileNameLen 20
@ -411,6 +415,149 @@ static void UNIXTimeToDateTime(const time_t* pWhen, NuDateTime *pDateTime)
}
#endif
#if defined(MAC_LIKE)
/*
* Due to historical reasons, the XATTR_FINDERINFO_NAME (defined to be
* ``com.apple.FinderInfo'') extended attribute must be 32 bytes; see the
* ATTR_CMN_FNDRINFO section in getattrlist(2).
*
* The FinderInfo block is the concatenation of a FileInfo structure
* and an ExtendedFileInfo (or ExtendedFolderInfo) structure -- see
* ATTR_CMN_FNDRINFO in getattrlist(2).
*
* All we're really interested in is the file type and creator code,
* which are stored big-endian in the first 8 bytes.
*/
static const int kFinderInfoSize = 32;
/*
* Obtains the creator and file type from the Finder info block, if any,
* and converts the types to ProDOS equivalents.
*
* If the attribute doesn't exist, this returns an error without modifying
* the output args.
*/
static NuError GetTypesFromFinder(const char* pathnameUNI, uint32_t* pFileType,
uint32_t* pAuxType)
{
uint8_t fiBuf[kFinderInfoSize];
size_t actual = getxattr(pathnameUNI, XATTR_FINDERINFO_NAME,
fiBuf, sizeof(fiBuf), 0, 0);
if (actual != kFinderInfoSize) {
return kNuErrNotFound;
}
uint32_t fileType, creator;
fileType = (fiBuf[0] << 24) | (fiBuf[1] << 16) | (fiBuf[2] << 8) |
fiBuf[3];
creator = (fiBuf[4] << 24) | (fiBuf[5] << 16) | (fiBuf[6] << 8) |
fiBuf[7];
uint8_t proType;
uint16_t proAux;
/*
* Convert to ProDOS file/aux type.
*/
if (creator == 'pdos') {
if (fileType == 'PSYS') {
proType = 0xFF; // SYS
proAux = 0x0000;
} else if (fileType == 'PS16') {
proType = 0xB3; // S16
proAux = 0x0000;
} else {
if (((fileType >> 24) & 0xFF) == 'p') {
proType = (fileType >> 16) & 0xFF;
proAux = (uint16_t) fileType;
} else {
proType = 0x00; // NON
proAux = 0x0000;
}
}
} else if (creator == 'dCpy') {
if (fileType == 'dImg') {
proType = 0xE0; // LBR
proAux = 0x0005;
} else {
proType = 0x00; // NON
proAux = 0x0000;
}
} else {
switch(fileType) {
case 'BINA':
proType = 0x06; // BIN
proAux = 0x0000;
break;
case 'TEXT':
proType = 0x04; // TXT
proAux = 0x0000;
break;
case 'MIDI':
proType = 0xD7; // MDI
proAux = 0x0000;
break;
case 'AIFF':
proType = 0xD8; // SND
proAux = 0x0000;
break;
case 'AIFC':
proType = 0xD8; // SND
proAux = 0x0001;
break;
default:
proType = 0x00; // NON
proAux = 0x0000;
break;
}
}
*pFileType = proType;
*pAuxType = proAux;
return kNuErrNone;
}
/*
* Set the file type and creator type.
*/
NuError SetFinderInfo(int fd, uint8_t proType, uint16_t proAux)
{
uint8_t fiBuf[kFinderInfoSize];
size_t actual = fgetxattr(fd, XATTR_FINDERINFO_NAME,
fiBuf, sizeof(fiBuf), 0, 0);
if (actual == (size_t) -1 && errno == ENOATTR) {
// doesn't yet have Finder info
memset(fiBuf, 0, sizeof(fiBuf));
} else if (actual != kFinderInfoSize) {
return kNuErrFile;
}
/* build type and creator from 8-bit type and 16-bit aux type */
uint32_t fileType, creator;
fileType = ('p' << 24) | (proType << 16) | proAux;
creator = 'pdos';
fiBuf[0] = fileType >> 24;
fiBuf[1] = fileType >> 16;
fiBuf[2] = fileType >> 8;
fiBuf[3] = fileType;
fiBuf[4] = creator >> 24;
fiBuf[5] = creator >> 16;
fiBuf[6] = creator >> 8;
fiBuf[7] = creator;
if (fsetxattr(fd, XATTR_FINDERINFO_NAME, fiBuf, sizeof(fiBuf),
0, 0) != 0)
{
return kNuErrFile;
}
return kNuErrNone;
}
#endif /*MAC_LIKE*/
#if defined(UNIX_LIKE) || defined(WINDOWS_LIKE)
/*
* Replace "oldc" with "newc". If we find an instance of "newc" already
@ -493,6 +640,15 @@ static NuError GetFileDetails(NulibState* pState, const char* pathnameMOR,
UNIXTimeToDateTime(&psb->st_mtime, &pDetails->modWhen);
UNIXTimeToDateTime(&psb->st_mtime, &pDetails->createWhen);
#ifdef MAC_LIKE
/*
* Retrieve the file/aux type from the Finder info. We want the
* type-preservation string to take priority, so get this first.
*/
(void) GetTypesFromFinder(livePathStr,
&pDetails->fileType, &pDetails->extraType);
#endif
/*
* Check for file type preservation info in the filename. If present,
* set the file type values and truncate the filename.
@ -612,8 +768,8 @@ static NuError GetFileDetails(NulibState* pState, const char* pathnameMOR,
* Do the system-independent part of the file add, including things like
* adding comments.
*/
NuError DoAddFile(NulibState* pState, NuArchive* pArchive, const char* pathname,
const NuFileDetails* pDetails)
static NuError DoAddFile(NulibState* pState, NuArchive* pArchive,
const char* pathname, const NuFileDetails* pDetails)
{
NuError err;
NuRecordIdx recordIdx = 0;

6
nulib2/configure vendored
View File

@ -4112,12 +4112,6 @@ if test "$host_os" = "beos"; then
fi
fi
if test "$host_vendor" = "apple" -a ${host_os:0:6} = "darwin"; then
echo "checking for Mac OS X... yes, adding -framework Carbon"
LIBS="$LIBS -framework Carbon"
fi
if test "$host_cpu" = "powerpc" -a "$host_os" = "beos"; then
CC=cc
GCC=

View File

@ -125,13 +125,6 @@ if test "$host_os" = "beos"; then
fi
fi
dnl Mac OS X (powerpc-apple-darwin6.6) needs an extra flag.
if test "$host_vendor" = "apple" -a ${host_os:0:6} = "darwin"; then
echo "checking for Mac OS X... yes, adding -framework Carbon"
LIBS="$LIBS -framework Carbon"
fi
dnl Figure out what the build and link flags should be
if test "$host_cpu" = "powerpc" -a "$host_os" = "beos"; then
dnl BeOS/PPC with Metrowerks compiler