Improve Mac OS X file type handling

The previous code only created files with 'pdos'/'pXYZ' attributes,
and didn't correctly recognize specific types like 'pdos'/'TEXT'.
The code should now perform the conversions according to the spec,
though it still doesn't handle the 'pdos'/'XY  ' case.
This commit is contained in:
Andy McFadden 2015-12-26 15:17:37 -08:00
parent f37b387cc6
commit eb40d65f1d
4 changed files with 92 additions and 34 deletions

View File

@ -1,5 +1,6 @@
2015/12/26 fadden 2015/12/26 fadden
- Fix handling of entries with missing threads. - Fix handling of entries with missing threads.
- Improve handling of Mac OS X file type attributes.
2015/01/09 ***** v3.0.0 shipped ***** 2015/01/09 ***** v3.0.0 shipped *****

View File

@ -327,20 +327,44 @@ static NuError Nu_SetFinderInfo(NuArchive* pArchive, const NuRecord* pRecord,
return kNuErrFile; return kNuErrFile;
} }
/* build type and creator from 8-bit type and 16-bit aux type */ uint8_t proType = (uint8_t) pRecord->recFileType;
uint32_t fileType, creator; uint16_t proAux = (uint16_t) pRecord->recExtraType;
fileType = ('p' << 24) | ((pRecord->recFileType & 0xff) << 16) |
(pRecord->recExtraType & 0xffff);
creator = 'pdos';
fiBuf[0] = fileType >> 24; /*
fiBuf[1] = fileType >> 16; * Attempt to use one of the convenience types. If nothing matches,
fiBuf[2] = fileType >> 8; * use the generic pdos/pXYZ approach. Note that PSYS/PS16 will
fiBuf[3] = fileType; * lose the file's aux type.
fiBuf[4] = creator >> 24; *
fiBuf[5] = creator >> 16; * I'm told this is from page 336 of _Programmer's Reference for
fiBuf[6] = creator >> 8; * System 6.0_.
fiBuf[7] = creator; */
uint8_t* fileTypeBuf = fiBuf;
uint8_t* creatorBuf = fiBuf + 4;
memcpy(creatorBuf, "pdos", 4);
if (proType == 0x00 && proAux == 0x0000) {
memcpy(fileTypeBuf, "BINA", 4);
} else if (proType == 0x04 && proAux == 0x0000) {
memcpy(fileTypeBuf, "TEXT", 4);
} else if (proType == 0xff) {
memcpy(fileTypeBuf, "PSYS", 4);
} else if (proType == 0xb3 && (proAux & 0xff00) != 0xdb00) {
memcpy(fileTypeBuf, "PS16", 4);
} else if (proType == 0xd7 && proAux == 0x0000) {
memcpy(fileTypeBuf, "MIDI", 4);
} else if (proType == 0xd8 && proAux == 0x0000) {
memcpy(fileTypeBuf, "AIFF", 4);
} else if (proType == 0xd8 && proAux == 0x0001) {
memcpy(fileTypeBuf, "AIFC", 4);
} else if (proType == 0xe0 && proAux == 0x0005) {
memcpy(creatorBuf, "dCpy", 4);
memcpy(fileTypeBuf, "dImg", 4);
} else {
fileTypeBuf[0] = 'p';
fileTypeBuf[1] = proType;
fileTypeBuf[2] = (uint8_t) (proAux >> 8);
fileTypeBuf[3] = (uint8_t) proAux;
}
if (setxattr(pathnameUNI, XATTR_FINDERINFO_NAME, fiBuf, sizeof(fiBuf), if (setxattr(pathnameUNI, XATTR_FINDERINFO_NAME, fiBuf, sizeof(fiBuf),
0, 0) != 0) 0, 0) != 0)

View File

@ -1,5 +1,6 @@
2015/12/26 fadden 2015/12/26 fadden
- Fix handling of entries with missing threads. - Fix handling of entries with missing threads.
- Improve handling of Mac OS X file type attributes.
2015/01/09 ***** v3.0.0 shipped ***** 2015/01/09 ***** v3.0.0 shipped *****

View File

@ -454,6 +454,7 @@ static NuError GetTypesFromFinder(const char* pathnameUNI, uint32_t* pFileType,
creator = (fiBuf[4] << 24) | (fiBuf[5] << 16) | (fiBuf[6] << 8) | creator = (fiBuf[4] << 24) | (fiBuf[5] << 16) | (fiBuf[6] << 8) |
fiBuf[7]; fiBuf[7];
Boolean found = false;
uint8_t proType; uint8_t proType;
uint16_t proAux; uint16_t proAux;
@ -461,31 +462,36 @@ static NuError GetTypesFromFinder(const char* pathnameUNI, uint32_t* pFileType,
* Convert to ProDOS file/aux type. * Convert to ProDOS file/aux type.
*/ */
if (creator == 'pdos') { if (creator == 'pdos') {
/*
* TODO: handle conversion from 'pdos'/'XY ' to $XY/$0000.
* I think this conversion was deprecated and not widely used;
* the inability to retain the aux type renders it inapplicable
* to many files.
*/
if (fileType == 'PSYS') { if (fileType == 'PSYS') {
proType = 0xFF; // SYS proType = 0xFF; // SYS
proAux = 0x0000; proAux = 0x0000;
found = true;
} else if (fileType == 'PS16') { } else if (fileType == 'PS16') {
proType = 0xB3; // S16 proType = 0xB3; // S16
proAux = 0x0000; proAux = 0x0000;
found = true;
} else { } else {
if (((fileType >> 24) & 0xFF) == 'p') { if (((fileType >> 24) & 0xFF) == 'p') {
proType = (fileType >> 16) & 0xFF; proType = (fileType >> 16) & 0xFF;
proAux = (uint16_t) fileType; proAux = (uint16_t) fileType;
} else { found = true;
proType = 0x00; // NON
proAux = 0x0000;
} }
} }
} else if (creator == 'dCpy') { } else if (creator == 'dCpy') {
if (fileType == 'dImg') { if (fileType == 'dImg') {
proType = 0xE0; // LBR proType = 0xE0; // LBR
proAux = 0x0005; proAux = 0x0005;
} else { found = true;
proType = 0x00; // NON
proAux = 0x0000;
} }
} else { }
switch(fileType) { if (!found) {
switch (fileType) {
case 'BINA': case 'BINA':
proType = 0x06; // BIN proType = 0x06; // BIN
proAux = 0x0000; proAux = 0x0000;
@ -519,7 +525,11 @@ static NuError GetTypesFromFinder(const char* pathnameUNI, uint32_t* pFileType,
} }
/* /*
* Set the file type and creator type. * Set the file type and creator type, based on the ProDOS file type
* and aux type.
*
* This is a clone of the function in NufxLib; it exists for the
* benefit of the Binary ][ code.
*/ */
NuError SetFinderInfo(int fd, uint8_t proType, uint16_t proAux) NuError SetFinderInfo(int fd, uint8_t proType, uint16_t proAux)
{ {
@ -534,19 +544,41 @@ NuError SetFinderInfo(int fd, uint8_t proType, uint16_t proAux)
return kNuErrFile; return kNuErrFile;
} }
/* build type and creator from 8-bit type and 16-bit aux type */ /*
uint32_t fileType, creator; * Attempt to use one of the convenience types. If nothing matches,
fileType = ('p' << 24) | (proType << 16) | proAux; * use the generic pdos/pXYZ approach. Note that PSYS/PS16 will
creator = 'pdos'; * lose the file's aux type.
*
* I'm told this is from page 336 of _Programmer's Reference for
* System 6.0_.
*/
uint8_t* fileTypeBuf = fiBuf;
uint8_t* creatorBuf = fiBuf + 4;
fiBuf[0] = fileType >> 24; memcpy(creatorBuf, "pdos", 4);
fiBuf[1] = fileType >> 16; if (proType == 0x00 && proAux == 0x0000) {
fiBuf[2] = fileType >> 8; memcpy(fileTypeBuf, "BINA", 4);
fiBuf[3] = fileType; } else if (proType == 0x04 && proAux == 0x0000) {
fiBuf[4] = creator >> 24; memcpy(fileTypeBuf, "TEXT", 4);
fiBuf[5] = creator >> 16; } else if (proType == 0xff) {
fiBuf[6] = creator >> 8; memcpy(fileTypeBuf, "PSYS", 4);
fiBuf[7] = creator; } else if (proType == 0xb3 && (proAux & 0xff00) != 0xdb00) {
memcpy(fileTypeBuf, "PS16", 4);
} else if (proType == 0xd7 && proAux == 0x0000) {
memcpy(fileTypeBuf, "MIDI", 4);
} else if (proType == 0xd8 && proAux == 0x0000) {
memcpy(fileTypeBuf, "AIFF", 4);
} else if (proType == 0xd8 && proAux == 0x0001) {
memcpy(fileTypeBuf, "AIFC", 4);
} else if (proType == 0xe0 && proAux == 0x0005) {
memcpy(creatorBuf, "dCpy", 4);
memcpy(fileTypeBuf, "dImg", 4);
} else {
fileTypeBuf[0] = 'p';
fileTypeBuf[1] = proType;
fileTypeBuf[2] = (uint8_t) (proAux >> 8);
fileTypeBuf[3] = (uint8_t) proAux;
}
if (fsetxattr(fd, XATTR_FINDERINFO_NAME, fiBuf, sizeof(fiBuf), if (fsetxattr(fd, XATTR_FINDERINFO_NAME, fiBuf, sizeof(fiBuf),
0, 0) != 0) 0, 0) != 0)