diff --git a/README.md b/README.md index 215abcc..c7a21c1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # hfstools +Tools to initialize and repair HFS and HFS+ filesystems. + diff --git a/diskdev_cmds-332.14.patch b/diskdev_cmds-332.14.patch new file mode 100644 index 0000000..6c6aede --- /dev/null +++ b/diskdev_cmds-332.14.patch @@ -0,0 +1,2596 @@ +diff -Naur diskdev_cmds-332.14.bak/Makefile.lnx diskdev_cmds-332.14/Makefile.lnx +--- diskdev_cmds-332.14.bak/Makefile.lnx 1969-12-31 19:00:00.000000000 -0500 ++++ diskdev_cmds-332.14/Makefile.lnx 2006-03-22 09:10:42.000000000 -0500 +@@ -0,0 +1,8 @@ ++CC := gcc ++CFLAGS := -g3 -Wall -I$(PWD)/include -DDEBUG_BUILD=0 -D_FILE_OFFSET_BITS=64 -D LINUX=1 -D BSD=1 ++SUBDIRS := newfs_hfs.tproj fsck_hfs.tproj ++ ++all clean: ++ for d in $(SUBDIRS); do $(MAKE) -C $$d -f Makefile.lnx $@; done ++ ++export CC CFLAGS +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/Makefile.lnx diskdev_cmds-332.14/fsck_hfs.tproj/Makefile.lnx +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/Makefile.lnx 1969-12-31 19:00:00.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/Makefile.lnx 2006-03-22 09:10:42.000000000 -0500 +@@ -0,0 +1,15 @@ ++CFILES = fsck_hfs.c strings.c utilities.c cache.c ++OFILES = $(CFILES:.c=.o) ++ ++all: fsck_hfs ++ ++fsck_hfs: $(OFILES) dfalib/libdfa.a ++ ++dfalib/libdfa.a: FORCE ++ $(MAKE) -C dfalib -f Makefile.lnx libdfa.a ++ ++clean: ++ $(RM) fsck_hfs $(OFILES) ++ $(MAKE) -C dfalib -f Makefile.lnx clean ++ ++.PHONY : FORCE clean +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/cache.c diskdev_cmds-332.14/fsck_hfs.tproj/cache.c +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/cache.c 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/cache.c 2006-03-22 09:10:42.000000000 -0500 +@@ -26,7 +26,11 @@ + #include + #include + #include ++#if LINUX ++#include "missing.h" ++#else + #include ++#endif /* __LINUX__ */ + #include + #include + #include +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/BTree.c diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/BTree.c +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/BTree.c 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/BTree.c 2006-03-22 09:10:42.000000000 -0500 +@@ -1705,7 +1705,9 @@ + UInt16 version, + BTreeInfoRec *info ) + { ++#if !LINUX + #pragma unused (version) ++#endif + + BTreeControlBlockPtr btreePtr; + +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/BTreeTreeOps.c diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/BTreeTreeOps.c +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/BTreeTreeOps.c 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/BTreeTreeOps.c 2006-03-22 09:10:42.000000000 -0500 +@@ -223,7 +223,7 @@ + // + if (curNodeNum == 0) + { +-// Panic("\pSearchTree: curNodeNum is zero!"); ++ Panic("SearchTree: curNodeNum is zero!"); + err = fsBTInvalidNodeErr; + goto ErrorExit; + } +@@ -433,7 +433,7 @@ + M_ExitOnError (err); + + if ( DEBUG_BUILD && updateParent && newRoot ) +- DebugStr("\p InsertLevel: New root from primary key, update from secondary key..."); ++ DebugStr("InsertLevel: New root from primary key, update from secondary key..."); + } + + //////////////////////// Update Parent(s) /////////////////////////////// +@@ -448,7 +448,7 @@ + + secondaryKey = nil; + +- PanicIf ( (level == btreePtr->treeDepth), "\p InsertLevel: unfinished insert!?"); ++ PanicIf ( (level == btreePtr->treeDepth), "InsertLevel: unfinished insert!?"); + + ++level; + +@@ -456,7 +456,7 @@ + index = treePathTable [level].index; + parentNodeNum = treePathTable [level].node; + +- PanicIf ( parentNodeNum == 0, "\p InsertLevel: parent node is zero!?"); ++ PanicIf ( parentNodeNum == 0, "InsertLevel: parent node is zero!?"); + + err = GetNode (btreePtr, parentNodeNum, &parentNode); // released as target node in next level up + M_ExitOnError (err); +@@ -470,7 +470,7 @@ + { + //„„Źdebug: check if ptr == targetNodeNum + GetRecordByIndex (btreePtr, parentNode.buffer, index, &keyPtr, &recPtr, &recSize); +- PanicIf( (*(UInt32 *) recPtr) != targetNodeNum, "\p InsertLevel: parent ptr doesn't match target node!"); ++ PanicIf( (*(UInt32 *) recPtr) != targetNodeNum, "InsertLevel: parent ptr doesn't match target node!"); + + // need to delete and re-insert this parent key/ptr + // we delete it here and it gets re-inserted in the +@@ -532,7 +532,7 @@ + (void) ReleaseNode (btreePtr, targetNode); + (void) ReleaseNode (btreePtr, &siblingNode); + +- Panic ("\p InsertLevel: an error occured!"); ++ Panic ("InsertLevel: an error occured!"); + + return err; + +@@ -566,7 +566,7 @@ + + *rootSplit = false; + +- PanicIf ( targetNode->buffer == siblingNode->buffer, "\p InsertNode: targetNode == siblingNode, huh?"); ++ PanicIf ( targetNode->buffer == siblingNode->buffer, "InsertNode: targetNode == siblingNode, huh?"); + + leftNodeNum = ((NodeDescPtr) targetNode->buffer)->bLink; + rightNodeNum = ((NodeDescPtr) targetNode->buffer)->fLink; +@@ -606,7 +606,7 @@ + + if ( leftNodeNum > 0 ) + { +- PanicIf ( siblingNode->buffer != nil, "\p InsertNode: siblingNode already aquired!"); ++ PanicIf ( siblingNode->buffer != nil, "InsertNode: siblingNode already aquired!"); + + if ( siblingNode->buffer == nil ) + { +@@ -614,7 +614,7 @@ + M_ExitOnError (err); + } + +- PanicIf ( ((NodeDescPtr) siblingNode->buffer)->fLink != nodeNum, "\p InsertNode, RotateLeft: invalid sibling link!" ); ++ PanicIf ( ((NodeDescPtr) siblingNode->buffer)->fLink != nodeNum, "InsertNode, RotateLeft: invalid sibling link!" ); + + if ( !key->skipRotate ) // are rotates allowed? + { +@@ -703,7 +703,7 @@ + + targetNodeNum = treePathTable[level].node; + targetNodePtr = targetNode->buffer; +- PanicIf (targetNodePtr == nil, "\pDeleteTree: targetNode has nil buffer!"); ++ PanicIf (targetNodePtr == nil, "DeleteTree: targetNode has nil buffer!"); + + DeleteRecord (btreePtr, targetNodePtr, index); + +@@ -797,7 +797,7 @@ + + //„„Źdebug: check if ptr == targetNodeNum + GetRecordByIndex (btreePtr, parentNode.buffer, index, &keyPtr, &recPtr, &recSize); +- PanicIf( (*(UInt32 *) recPtr) != targetNodeNum, "\p DeleteTree: parent ptr doesn't match targetNodeNum!!"); ++ PanicIf( (*(UInt32 *) recPtr) != targetNodeNum, " DeleteTree: parent ptr doesn't match targetNodeNum!!"); + + // need to delete and re-insert this parent key/ptr + DeleteRecord (btreePtr, parentNode.buffer, index); +@@ -1018,7 +1018,7 @@ + keyPtr, keyLength, recPtr, recSize); + if ( !didItFit ) + { +- Panic ("\pRotateLeft: InsertKeyRecord (left) returned false!"); ++ Panic ("RotateLeft: InsertKeyRecord (left) returned false!"); + err = fsBTBadRotateErr; + goto ErrorExit; + } +@@ -1031,7 +1031,7 @@ + didItFit = RotateRecordLeft (btreePtr, leftNode, rightNode); + if ( !didItFit ) + { +- Panic ("\pRotateLeft: RotateRecordLeft returned false!"); ++ Panic ("RotateLeft: RotateRecordLeft returned false!"); + err = fsBTBadRotateErr; + goto ErrorExit; + } +@@ -1048,7 +1048,7 @@ + keyPtr, keyLength, recPtr, recSize); + if ( !didItFit ) + { +- Panic ("\pRotateLeft: InsertKeyRecord (right) returned false!"); ++ Panic ("RotateLeft: InsertKeyRecord (right) returned false!"); + err = fsBTBadRotateErr; + goto ErrorExit; + } +@@ -1117,7 +1117,7 @@ + right = rightNode->buffer; + left = leftNode->buffer; + +- PanicIf ( right->bLink != 0 && left == 0, "\p SplitLeft: left sibling missing!?" ); ++ PanicIf ( right->bLink != 0 && left == 0, " SplitLeft: left sibling missing!?" ); + + //„„ type should be kLeafNode or kIndexNode + +@@ -1240,8 +1240,8 @@ + Boolean didItFit; + UInt16 keyLength; + +- PanicIf (leftNode == nil, "\pAddNewRootNode: leftNode == nil"); +- PanicIf (rightNode == nil, "\pAddNewRootNode: rightNode == nil"); ++ PanicIf (leftNode == nil, "AddNewRootNode: leftNode == nil"); ++ PanicIf (rightNode == nil, "AddNewRootNode: rightNode == nil"); + + + /////////////////////// Initialize New Root Node //////////////////////////// +@@ -1264,7 +1264,7 @@ + didItFit = InsertKeyRecord ( btreePtr, rootNode.buffer, 0, keyPtr, keyLength, + (UInt8 *) &rightNode->bLink, 4 ); + +- PanicIf ( !didItFit, "\pAddNewRootNode:InsertKeyRecord failed for left index record"); ++ PanicIf ( !didItFit, "AddNewRootNode:InsertKeyRecord failed for left index record"); + + + //////////////////// Insert Right Node Index Record ///////////////////////// +@@ -1275,7 +1275,7 @@ + didItFit = InsertKeyRecord ( btreePtr, rootNode.buffer, 1, keyPtr, keyLength, + (UInt8 *) &leftNode->fLink, 4 ); + +- PanicIf ( !didItFit, "\pAddNewRootNode:InsertKeyRecord failed for right index record"); ++ PanicIf ( !didItFit, "AddNewRootNode:InsertKeyRecord failed for right index record"); + + + #if DEBUG_TREEOPS +@@ -1355,7 +1355,7 @@ + } + rightPtr = rightNodePtr->buffer; + +- PanicIf ( leftPtr->fLink != 0 && rightPtr == 0, "\p SplitRight: right sibling missing!?" ); ++ PanicIf ( leftPtr->fLink != 0 && rightPtr == 0, "SplitRight: right sibling missing!?" ); + + //„„ type should be kLeafNode or kIndexNode + +@@ -1557,7 +1557,7 @@ + keyPtr, keyLength, recPtr, recSize); + if ( !didItFit ) + { +- Panic ("\pRotateRight: InsertKeyRecord (left) returned false!"); ++ Panic ("RotateRight: InsertKeyRecord (left) returned false!"); + err = fsBTBadRotateErr; + goto ErrorExit; + } +@@ -1572,7 +1572,7 @@ + didItFit = RotateRecordRight( btreePtr, leftNodePtr, rightNodePtr ); + if ( !didItFit ) + { +- Panic ("\pRotateRight: RotateRecordRight returned false!"); ++ Panic ("RotateRight: RotateRecordRight returned false!"); + err = fsBTBadRotateErr; + goto ErrorExit; + } +@@ -1583,7 +1583,7 @@ + keyPtr, keyLength, recPtr, recSize); + if ( !didItFit ) + { +- Panic ("\pRotateRight: InsertKeyRecord (left) returned false!"); ++ Panic ("RotateRight: InsertKeyRecord (left) returned false!"); + err = fsBTBadRotateErr; + goto ErrorExit; + } +@@ -1607,7 +1607,7 @@ + keyPtr, keyLength, recPtr, recSize); + if ( !didItFit ) + { +- Panic ("\pRotateRight: InsertKeyRecord (right) returned false!"); ++ Panic ("RotateRight: InsertKeyRecord (right) returned false!"); + err = fsBTBadRotateErr; + goto ErrorExit; + } +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/BlockCache.c diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/BlockCache.c +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/BlockCache.c 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/BlockCache.c 2006-03-22 09:10:42.000000000 -0500 +@@ -20,6 +20,9 @@ + * @APPLE_LICENSE_HEADER_END@ + */ + ++#if LINUX ++#include "missing.h" ++#endif + #include "SRuntime.h" + #include "Scavenger.h" + #include "../cache.h" +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/Makefile.lnx diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/Makefile.lnx +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/Makefile.lnx 1969-12-31 19:00:00.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/Makefile.lnx 2006-03-22 09:10:42.000000000 -0500 +@@ -0,0 +1,15 @@ ++CFILES = hfs_endian.c BlockCache.c\ ++ BTree.c BTreeAllocate.c BTreeMiscOps.c \ ++ BTreeNodeOps.c BTreeScanner.c BTreeTreeOps.c\ ++ CatalogCheck.c HardLinkCheck.c\ ++ SBTree.c SControl.c SVerify1.c SVerify2.c\ ++ SRepair.c SRebuildCatalogBTree.c\ ++ SUtils.c SKeyCompare.c SDevice.c SExtents.c SAllocate.c\ ++ SCatalog.c SStubs.c VolumeBitmapCheck.c ++OFILES = $(CFILES:.c=.o) ++ ++libdfa.a: $(OFILES) ++ ar rc $@ $? ++ ++clean: ++ $(RM) $(OFILES) libdfa.a +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/SBTree.c diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/SBTree.c +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/SBTree.c 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/SBTree.c 2006-03-22 09:10:42.000000000 -0500 +@@ -93,7 +93,7 @@ + CopyMemory(&resultIterator->key, foundKey, CalcKeySize(btcb, &resultIterator->key)); //„„ warning, this could overflow user's buffer!!! + + if ( DEBUG_BUILD && !ValidHFSRecord(data, btcb, *dataSize) ) +- DebugStr("\pSearchBTreeRecord: bad record?"); ++ DebugStr("SearchBTreeRecord: bad record?"); + } + + ErrorExit: +@@ -190,7 +190,7 @@ + CopyMemory(&iterator->key, key, CalcKeySize(btcb, &iterator->key)); //„„ warning, this could overflow user's buffer!!! + + if ( DEBUG_BUILD && !ValidHFSRecord(data, btcb, *dataSize) ) +- DebugStr("\pGetBTreeRecord: bad record?"); ++ DebugStr("GetBTreeRecord: bad record?"); + + } + +@@ -222,7 +222,7 @@ + CopyMemory(key, &iterator.key, CalcKeySize(btcb, (BTreeKey *) key)); //„„ should we range check against maxkeylen? + + if ( DEBUG_BUILD && !ValidHFSRecord(data, btcb, dataSize) ) +- DebugStr("\pInsertBTreeRecord: bad record?"); ++ DebugStr("InsertBTreeRecord: bad record?"); + + result = BTInsertRecord( fcb, &iterator, &btRecord, dataSize ); + +@@ -284,7 +284,7 @@ + CopyMemory(key, &iterator.key, CalcKeySize(btcb, (BTreeKey *) key)); //„„ should we range check against maxkeylen? + + if ( DEBUG_BUILD && !ValidHFSRecord(newData, btcb, dataSize) ) +- DebugStr("\pReplaceBTreeRecord: bad record?"); ++ DebugStr("ReplaceBTreeRecord: bad record?"); + + result = BTReplaceRecord( fcb, &iterator, &btRecord, dataSize ); + +@@ -301,7 +301,9 @@ + OSStatus + SetEndOfForkProc ( SFCB *filePtr, FSSize minEOF, FSSize maxEOF ) + { ++#if !LINUX + #pragma unused (maxEOF) ++#endif + + OSStatus result; + UInt32 actualSectorsAdded; +@@ -321,7 +323,7 @@ + else + { + if ( DEBUG_BUILD ) +- DebugStr("\pSetEndOfForkProc: minEOF is smaller than current size!"); ++ DebugStr("SetEndOfForkProc: minEOF is smaller than current size!"); + return -1; + } + +@@ -347,7 +349,7 @@ + // Make sure we got at least as much space as we needed + // + if (filePtr->fcbLogicalSize < minEOF) { +- Panic("\pSetEndOfForkProc: disk too full to extend B-tree file"); ++ Panic("SetEndOfForkProc: disk too full to extend B-tree file"); + return dskFulErr; + } + +@@ -419,7 +421,7 @@ + if ( (keyLen < 6) || (keyLen > btcb->maxKeyLength) ) + { + if ( DEBUG_BUILD ) +- DebugStr("\pCheckBTreeKey: bad key length!"); ++ DebugStr("CheckBTreeKey: bad key length!"); + return fsBTInvalidKeyLengthErr; + } + +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/SControl.c diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/SControl.c +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/SControl.c 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/SControl.c 2006-03-22 09:10:42.000000000 -0500 +@@ -739,7 +739,7 @@ + pointer = (ScavStaticStructures *) AllocateClearMemory( sizeof(ScavStaticStructures) ); + if ( pointer == nil ) { + if ( GPtr->logLevel >= kDebugLog ) { +- printf( "\t error %d - could not allocate %ld bytes of memory \n", ++ printf( "\t error %d - could not allocate %i bytes of memory \n", + R_NoMem, sizeof(ScavStaticStructures) ); + } + return( R_NoMem ); +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/SDevice.c diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/SDevice.c +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/SDevice.c 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/SDevice.c 2006-03-22 09:10:42.000000000 -0500 +@@ -28,24 +28,61 @@ + #include + #include + #include +- ++#if LINUX ++#include ++#include ++#else + #include +- ++#endif /* LINUX */ + #else +- + #include + #include + #include + +-#endif +- ++#endif + + OSErr GetDeviceSize(int driveRefNum, UInt64 *numBlocks, UInt32 *blockSize) + { + #if BSD + UInt64 devBlockCount = 0; + int devBlockSize = 0; ++#if LINUX ++ struct stat stbuf; + ++ devBlockSize = 512; ++ ++#ifndef BLKGETSIZE ++#define BLKGETSIZE _IO(0x12,96) ++#endif ++#ifndef BLKGETSIZE64 ++#define BLKGETSIZE64 _IOR(0x12,114,size_t) ++#endif ++ if (fstat(driveRefNum, &stbuf) < 0){ ++ printf("Error: %s\n", strerror(errno)); ++ return(-1); ++ } ++ ++ if (S_ISREG(stbuf.st_mode)) { ++ devBlockCount = stbuf.st_size / 512; ++ } ++ else if (S_ISBLK(stbuf.st_mode)) { ++ unsigned long size; ++ u_int64_t size64; ++ if (!ioctl(driveRefNum, BLKGETSIZE64, &size64)) ++ devBlockCount = size64 / 512; ++ else if (!ioctl(driveRefNum, BLKGETSIZE, &size)) ++ devBlockCount = size; ++ else{ ++ printf("Error: %s\n", strerror(errno)); ++ return(-1); ++ } ++ ++ } ++ else{ ++ printf("Device is not a block device"); ++ return(-1); ++ } ++#elif BSD + if (ioctl(driveRefNum, DKIOCGETBLOCKCOUNT, &devBlockCount) < 0) { + printf("ioctl(DKIOCGETBLOCKCOUNT) for fd %d: %s\n", driveRefNum, strerror(errno)); + return (-1); +@@ -55,6 +92,7 @@ + printf("ioctl(DKIOCGETBLOCKSIZE) for fd %d: %s\n", driveRefNum, strerror(errno)); + return (-1); + } ++#endif /* BSD */ + + if (devBlockSize != 512) { + *numBlocks = (devBlockCount * (UInt64)devBlockSize) / 512; +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/SKeyCompare.c diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/SKeyCompare.c +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/SKeyCompare.c 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/SKeyCompare.c 2006-03-22 09:10:42.000000000 -0500 +@@ -454,7 +454,9 @@ + * The name portion of the key is compared using a 16-bit binary comparison. + * This is called from the b-tree code. + */ ++#if !LINUX + __private_extern__ ++#endif + SInt32 + CompareAttributeKeys(const AttributeKey *searchKey, const AttributeKey *trialKey) + { +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/SRepair.c diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/SRepair.c +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/SRepair.c 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/SRepair.c 2006-03-22 09:10:42.000000000 -0500 +@@ -1593,7 +1593,9 @@ + + static OSErr FixWrapperExtents( SGlobPtr GPtr, RepairOrderPtr p ) + { ++#if !LINUX + #pragma unused (p) ++#endif + + OSErr err; + HFSMasterDirectoryBlock *mdb; +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/SRuntime.h diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/SRuntime.h +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/SRuntime.h 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/SRuntime.h 2006-03-22 09:10:42.000000000 -0500 +@@ -27,8 +27,11 @@ + #define __SRUNTIME__ + + #if BSD +- ++#if LINUX ++#include "missing.h" ++#else + #include ++#endif + #include + #include + #include +@@ -91,10 +94,12 @@ + + typedef u_int32_t HFSCatalogNodeID; + ++#if !LINUX + enum { + false = 0, + true = 1 + }; ++#endif + + /* OS error codes */ + enum { +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/SUtils.c diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/SUtils.c +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/SUtils.c 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/SUtils.c 2006-03-22 09:10:42.000000000 -0500 +@@ -380,7 +380,8 @@ + // GPtr->realVCB Real in-memory vcb + //------------------------------------------------------------------------------ + +-#if !BSD ++#if BSD ++#if !LINUX + OSErr GetVolumeFeatures( SGlobPtr GPtr ) + { + OSErr err; +@@ -418,7 +419,7 @@ + return( noErr ); + } + #endif +- ++#endif + + + /*------------------------------------------------------------------------------- +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/SVerify2.c diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/SVerify2.c +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/SVerify2.c 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/SVerify2.c 2006-03-22 09:10:42.000000000 -0500 +@@ -32,7 +32,9 @@ + */ + + #include ++#if !LINUX + #include ++#endif + + #include "BTree.h" + #include "BTreePrivate.h" +@@ -1240,8 +1242,13 @@ + * clump size for read-only media is irrelevant we skip the clump size + * check to avoid non useful warnings. + */ ++#if LINUX ++ // FIXME ++ isWriteable = 1; ++#else + isWriteable = 0; + ioctl( GPtr->DrvNum, DKIOCISWRITABLE, &isWriteable ); ++#endif + if ( isWriteable != 0 && + volumeHeader->catalogFile.clumpSize != vcb->vcbCatalogFile->fcbClumpSize ) { + PrintError(GPtr, E_InvalidClumpSize, 0); +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/Scavenger.h diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/Scavenger.h +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/Scavenger.h 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/Scavenger.h 2006-03-22 09:10:42.000000000 -0500 +@@ -35,11 +35,16 @@ + #include "BTreeScanner.h" + #include "hfs_endian.h" + ++#if LINUX ++#define XATTR_MAXNAMELEN 127 ++#include ++#else + #include + #include + #include +-#include + #include ++#endif ++#include + + #ifdef __cplusplus + extern "C" { +@@ -1434,4 +1439,8 @@ + }; + #endif + ++#if LINUX ++#undef XATTR_MAXNAMELEN ++#endif ++ + #endif /* __SCAVENGER__ */ +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/hfs_endian.c diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/hfs_endian.c +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/hfs_endian.c 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/hfs_endian.c 2006-03-22 09:10:42.000000000 -0500 +@@ -31,7 +31,11 @@ + #include + #include + ++#if LINUX ++#include "missing.h" ++#else + #include ++#endif + #include + + #include "Scavenger.h" +@@ -559,7 +563,7 @@ + /* Make sure name length is consistent with key length */ + if (keyLength < sizeof(srcKey->parentID) + sizeof(srcKey->nodeName.length) + + srcKey->nodeName.length*sizeof(srcKey->nodeName.unicode[0])) { +- if (debug) printf("hfs_swap_HFSPlusBTInternalNode: catalog record #%d keyLength=%d expected=%lu\n", ++ if (debug) printf("hfs_swap_HFSPlusBTInternalNode: catalog record #%d keyLength=%d expected=%i\n", + srcDesc->numRecords-i, keyLength, sizeof(srcKey->parentID) + sizeof(srcKey->nodeName.length) + + srcKey->nodeName.length*sizeof(srcKey->nodeName.unicode[0])); + WriteError(fcb->fcbVolume->vcbGPtr, E_KeyLen, fcb->fcbFileID, src->blockNum); +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/hfs_endian.h diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/hfs_endian.h +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/dfalib/hfs_endian.h 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/dfalib/hfs_endian.h 2006-03-22 09:10:42.000000000 -0500 +@@ -27,9 +27,14 @@ + * + * This file prototypes endian swapping routines for the HFS/HFS Plus + * volume format. +- */ ++*/ + #include ++#if LINUX ++#include ++#include ++#else + #include ++#endif + #include "SRuntime.h" + + /*********************/ +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/fsck_hfs.c diskdev_cmds-332.14/fsck_hfs.tproj/fsck_hfs.c +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/fsck_hfs.c 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/fsck_hfs.c 2006-03-22 09:19:09.000000000 -0500 +@@ -24,10 +24,14 @@ + #include + #include + #include ++#if !LINUX + #include ++#endif + #include + #include ++#if !LINUX + #include ++#endif + + #include + +@@ -170,10 +174,12 @@ + + if (guiControl) + debug = 0; /* debugging is for command line only */ +- ++#if LINUX ++// FIXME ++#else + if (signal(SIGINT, SIG_IGN) != SIG_IGN) + (void)signal(SIGINT, catch); +- ++#endif + if (argc < 1) { + (void) fprintf(stderr, "%s: missing special-device\n", progname); + usage(); +@@ -194,7 +200,9 @@ + int chkLev, repLev, logLev; + int blockDevice_fd, canWrite; + char *unraw, *mntonname; ++#if !LINUX + struct statfs *fsinfo; ++#endif + int fs_fd=-1; // fd to the root-dir of the fs we're checking (only w/lfag == 1) + + flags = 0; +@@ -203,7 +211,9 @@ + canWrite = 0; + unraw = NULL; + mntonname = NULL; +- ++#if LINUX ++ // FIXME ++#else + if (lflag) { + result = getmntinfo(&fsinfo, MNT_NOWAIT); + +@@ -233,7 +243,7 @@ + } + } + } +- ++#endif + if (debug && preen) + pwarn("starting\n"); + +@@ -306,6 +316,9 @@ + } + } + } else { ++#if LINUX ++ // FIXME ++#else + struct statfs stfs_buf; + /* + * Check to see if root is mounted read-write. +@@ -315,18 +328,24 @@ + else + flags = 0; + ckfini(flags & MNT_RDONLY); ++#endif + } + + /* XXX free any allocated memory here */ + + if (hotroot && fsmodified) { ++#if !LINUX + struct hfs_mount_args args; ++#endif + /* + * We modified the root. Do a mount update on + * it, unless it is read-write, so we can continue. + */ + if (!preen) + printf("\n***** FILE SYSTEM WAS MODIFIED *****\n"); ++#if LINUX ++ // FIXME ++#else + if (flags & MNT_RDONLY) { + bzero(&args, sizeof(args)); + flags |= MNT_UPDATE | MNT_RELOAD; +@@ -335,6 +354,7 @@ + goto ExitThisRoutine; + } + } ++#endif + if (!preen) + printf("\n***** REBOOT NOW *****\n"); + sync(); +@@ -380,11 +400,13 @@ + printf("Can't stat %s: %s\n", dev, strerror(errno)); + return (0); + } ++#if !LINUX + if ((statb.st_mode & S_IFMT) != S_IFCHR) { + pfatal("%s is not a character device", dev); + if (reply("CONTINUE") == 0) + return (0); + } ++#endif + if ((fsreadfd = open(dev, O_RDONLY)) < 0) { + printf("Can't open %s: %s\n", dev, strerror(errno)); + return (0); +@@ -407,10 +429,14 @@ + printf("\n"); + + /* Get device block size to initialize cache */ ++#if LINUX ++ devBlockSize = 512; ++#else + if (ioctl(fsreadfd, DKIOCGETBLOCKSIZE, &devBlockSize) < 0) { + pfatal ("Can't get device block size\n"); + return (0); + } ++#endif + /* Initialize the cache */ + if (CacheInit (&fscache, fsreadfd, fswritefd, devBlockSize, + CACHE_IOSIZE, CACHE_BLOCKS, CACHE_HASHSIZE) != EOK) { +@@ -431,11 +457,15 @@ + + static void getWriteAccess( char *dev, int *blockDevice_fdPtr, int *canWritePtr ) + { ++#if !LINUX + int i; + int myMountsCount; ++#endif + void * myPtr; + char * myCharPtr; ++#if !LINUX + struct statfs * myBufPtr; ++#endif + void * myNamePtr; + + myPtr = NULL; +@@ -456,18 +486,19 @@ + *canWritePtr = 1; + goto ExitThisRoutine; + } +- + // get count of mounts then get the info for each ++#if LINUX ++ // FIXME ++#else + myMountsCount = getfsstat( NULL, 0, MNT_NOWAIT ); + if ( myMountsCount < 0 ) + goto ExitThisRoutine; +- + myPtr = (void *) malloc( sizeof(struct statfs) * myMountsCount ); + if ( myPtr == NULL ) + goto ExitThisRoutine; + myMountsCount = getfsstat( myPtr, +- (sizeof(struct statfs) * myMountsCount), +- MNT_NOWAIT ); ++ (sizeof(struct statfs) * myMountsCount), ++ MNT_NOWAIT ); + if ( myMountsCount < 0 ) + goto ExitThisRoutine; + +@@ -481,8 +512,8 @@ + } + myBufPtr++; + } ++#endif + *canWritePtr = 1; // single user will get us here, f_mntfromname is not /dev/diskXXXX +- + ExitThisRoutine: + if ( myPtr != NULL ) + free( myPtr ); +diff -Naur diskdev_cmds-332.14.bak/fsck_hfs.tproj/utilities.c diskdev_cmds-332.14/fsck_hfs.tproj/utilities.c +--- diskdev_cmds-332.14.bak/fsck_hfs.tproj/utilities.c 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/utilities.c 2006-03-22 09:10:42.000000000 -0500 +@@ -183,12 +183,14 @@ + printf("Can't stat %s\n", raw); + return (origname); + } ++#if !LINUX + if ((stchar.st_mode & S_IFMT) == S_IFCHR) { + return (raw); + } else { + printf("%s is not a character device\n", raw); + return (origname); + } ++#endif + } else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) { + newname = unrawname(newname); + retried++; +@@ -214,7 +216,11 @@ + *dp = 0; + (void)strcpy(rawbuf, name); + *dp = '/'; +- (void)strcat(rawbuf, "/r"); ++#if LINUX ++ (void)strcat(rawbuf, "/"); ++#else ++ (void)strcat(rawbuf,"/r"); ++#endif + (void)strcat(rawbuf, &dp[1]); + + return (rawbuf); +diff -Naur diskdev_cmds-332.14.bak/include/bitstring.h diskdev_cmds-332.14/include/bitstring.h +--- diskdev_cmds-332.14.bak/include/bitstring.h 1969-12-31 19:00:00.000000000 -0500 ++++ diskdev_cmds-332.14/include/bitstring.h 2006-03-22 09:10:42.000000000 -0500 +@@ -0,0 +1,164 @@ ++/* ++ * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ++ * ++ * @APPLE_LICENSE_HEADER_START@ ++ * ++ * The contents of this file constitute Original Code as defined in and ++ * are subject to the Apple Public Source License Version 1.1 (the ++ * "License"). You may not use this file except in compliance with the ++ * License. Please obtain a copy of the License at ++ * http://www.apple.com/publicsource and read it before using this file. ++ * ++ * This Original Code and all software distributed under the License are ++ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ++ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ++ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ++ * License for the specific language governing rights and limitations ++ * under the License. ++ * ++ * @APPLE_LICENSE_HEADER_END@ ++ */ ++/* ++ * Copyright (c) 1989, 1993 ++ * The Regents of the University of California. All rights reserved. ++ * ++ * This code is derived from software contributed to Berkeley by ++ * Paul Vixie. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * This product includes software developed by the University of ++ * California, Berkeley and its contributors. ++ * 4. Neither the name of the University nor the names of its contributors ++ * may be used to endorse or promote products derived from this software ++ * without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * @(#)bitstring.h 8.1 (Berkeley) 7/19/93 ++ */ ++ ++#ifndef _BITSTRING_H_ ++#define _BITSTRING_H_ ++ ++typedef unsigned char bitstr_t; ++ ++/* internal macros */ ++ /* byte of the bitstring bit is in */ ++#define _bit_byte(bit) \ ++ ((bit) >> 3) ++ ++ /* mask for the bit within its byte */ ++#define _bit_mask(bit) \ ++ (1 << ((bit)&0x7)) ++ ++/* external macros */ ++ /* bytes in a bitstring of nbits bits */ ++#define bitstr_size(nbits) \ ++ ((((nbits) - 1) >> 3) + 1) ++ ++ /* allocate a bitstring */ ++#define bit_alloc(nbits) \ ++ (bitstr_t *)calloc(1, \ ++ (unsigned int)bitstr_size(nbits) * sizeof(bitstr_t)) ++ ++ /* allocate a bitstring on the stack */ ++#define bit_decl(name, nbits) \ ++ (name)[bitstr_size(nbits)] ++ ++ /* is bit N of bitstring name set? */ ++#define bit_test(name, bit) \ ++ ((name)[_bit_byte(bit)] & _bit_mask(bit)) ++ ++ /* set bit N of bitstring name */ ++#define bit_set(name, bit) \ ++ (name)[_bit_byte(bit)] |= _bit_mask(bit) ++ ++ /* clear bit N of bitstring name */ ++#define bit_clear(name, bit) \ ++ (name)[_bit_byte(bit)] &= ~_bit_mask(bit) ++ ++ /* clear bits start ... stop in bitstring */ ++#define bit_nclear(name, start, stop) { \ ++ register bitstr_t *_name = name; \ ++ register int _start = start, _stop = stop; \ ++ register int _startbyte = _bit_byte(_start); \ ++ register int _stopbyte = _bit_byte(_stop); \ ++ if (_startbyte == _stopbyte) { \ ++ _name[_startbyte] &= ((0xff >> (8 - (_start&0x7))) | \ ++ (0xff << ((_stop&0x7) + 1))); \ ++ } else { \ ++ _name[_startbyte] &= 0xff >> (8 - (_start&0x7)); \ ++ while (++_startbyte < _stopbyte) \ ++ _name[_startbyte] = 0; \ ++ _name[_stopbyte] &= 0xff << ((_stop&0x7) + 1); \ ++ } \ ++} ++ ++ /* set bits start ... stop in bitstring */ ++#define bit_nset(name, start, stop) { \ ++ register bitstr_t *_name = name; \ ++ register int _start = start, _stop = stop; \ ++ register int _startbyte = _bit_byte(_start); \ ++ register int _stopbyte = _bit_byte(_stop); \ ++ if (_startbyte == _stopbyte) { \ ++ _name[_startbyte] |= ((0xff << (_start&0x7)) & \ ++ (0xff >> (7 - (_stop&0x7)))); \ ++ } else { \ ++ _name[_startbyte] |= 0xff << ((_start)&0x7); \ ++ while (++_startbyte < _stopbyte) \ ++ _name[_startbyte] = 0xff; \ ++ _name[_stopbyte] |= 0xff >> (7 - (_stop&0x7)); \ ++ } \ ++} ++ ++ /* find first bit clear in name */ ++#define bit_ffc(name, nbits, value) { \ ++ register bitstr_t *_name = name; \ ++ register int _byte, _nbits = nbits; \ ++ register int _stopbyte = _bit_byte(_nbits), _value = -1; \ ++ for (_byte = 0; _byte <= _stopbyte; ++_byte) \ ++ if (_name[_byte] != 0xff) { \ ++ _value = _byte << 3; \ ++ for (_stopbyte = _name[_byte]; (_stopbyte&0x1); \ ++ ++_value, _stopbyte >>= 1); \ ++ break; \ ++ } \ ++ *(value) = _value; \ ++} ++ ++ /* find first bit set in name */ ++#define bit_ffs(name, nbits, value) { \ ++ register bitstr_t *_name = name; \ ++ register int _byte, _nbits = nbits; \ ++ register int _stopbyte = _bit_byte(_nbits), _value = -1; \ ++ for (_byte = 0; _byte <= _stopbyte; ++_byte) \ ++ if (_name[_byte]) { \ ++ _value = _byte << 3; \ ++ for (_stopbyte = _name[_byte]; !(_stopbyte&0x1); \ ++ ++_value, _stopbyte >>= 1); \ ++ break; \ ++ } \ ++ *(value) = _value; \ ++} ++ ++#endif /* !_BITSTRING_H_ */ +diff -Naur diskdev_cmds-332.14.bak/include/hfs/hfs_format.h diskdev_cmds-332.14/include/hfs/hfs_format.h +--- diskdev_cmds-332.14.bak/include/hfs/hfs_format.h 1969-12-31 19:00:00.000000000 -0500 ++++ diskdev_cmds-332.14/include/hfs/hfs_format.h 2006-03-22 09:10:42.000000000 -0500 +@@ -0,0 +1,689 @@ ++/* ++ * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. ++ * ++ * @APPLE_LICENSE_HEADER_START@ ++ * ++ * The contents of this file constitute Original Code as defined in and ++ * are subject to the Apple Public Source License Version 1.1 (the ++ * "License"). You may not use this file except in compliance with the ++ * License. Please obtain a copy of the License at ++ * http://www.apple.com/publicsource and read it before using this file. ++ * ++ * This Original Code and all software distributed under the License are ++ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ++ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ++ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ++ * License for the specific language governing rights and limitations ++ * under the License. ++ * ++ * @APPLE_LICENSE_HEADER_END@ ++ */ ++#ifndef __HFS_FORMAT__ ++#define __HFS_FORMAT__ ++ ++#include "missing.h" ++ ++#include ++ ++/* ++ * hfs_format.c ++ * ++ * This file describes the on-disk format for HFS and HFS Plus volumes. ++ * The HFS Plus volume format is desciibed in detail in Apple Technote 1150. ++ * ++ * http://developer.apple.com/technotes/tn/tn1150.html ++ * ++ */ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/* some on-disk hfs structures have 68K alignment (misaligned) */ ++ ++#define PACKED_S __attribute__((packed)) ++ ++/* Signatures used to differentiate between HFS and HFS Plus volumes */ ++enum { ++ kHFSSigWord = 0x4244, /* 'BD' in ASCII */ ++ kHFSPlusSigWord = 0x482B, /* 'H+' in ASCII */ ++ kHFSXSigWord = 0x4858, /* 'HX' in ASCII */ ++ ++ kHFSPlusVersion = 0x0004, /* 'H+' volumes are version 4 only */ ++ kHFSXVersion = 0x0005, /* 'HX' volumes start with version 5 */ ++ ++ kHFSPlusMountVersion = 0x31302E30, /* '10.0' for Mac OS X */ ++ kHFSJMountVersion = 0x4846534a, /* 'HFSJ' for journaled HFS+ on OS X */ ++ kFSKMountVersion = 0x46534b21 /* 'FSK!' for failed journal replay */ ++}PACKED_S; ++ ++ ++#ifdef __APPLE_API_PRIVATE ++/* ++ * Mac OS X has a special directory for linked and unlinked files (HFS Plus only). ++ * This directory and its contents are never exported from the filesystem under ++ * Mac OS X. ++ * ++ * To make this folder name sort last, it has embedded null prefix. ++ * (0xC0, 0x80 in UTF-8) ++ */ ++#define HFSPLUSMETADATAFOLDER "\xC0\x80\xC0\x80\xC0\x80\xC0\x80HFS+ Private Data" ++ ++/* ++ * Files in the HFS Private Data folder have one of the following prefixes ++ * followed by a decimal number (no leading zeros). For indirect nodes this ++ * number is a 32 bit random number. For unlinked (deleted) files that are ++ * still open, the number is the file ID for that file. ++ * ++ * e.g. iNode7182000 and temp3296 ++ */ ++#define HFS_INODE_PREFIX "iNode" ++#define HFS_DELETE_PREFIX "temp" ++ ++#endif /* __APPLE_API_PRIVATE */ ++ ++/* ++ * Indirect link files (hard links) have the following type/creator. ++ */ ++enum { ++ kHardLinkFileType = 0x686C6E6B, /* 'hlnk' */ ++ kHFSPlusCreator = 0x6866732B /* 'hfs+' */ ++}PACKED_S; ++ ++ ++#ifndef _HFSUNISTR255_DEFINED_ ++#define _HFSUNISTR255_DEFINED_ ++/* Unicode strings are used for HFS Plus file and folder names */ ++struct HFSUniStr255 { ++ u_int16_t length; /* number of unicode characters */ ++ u_int16_t unicode[255]; /* unicode characters */ ++} PACKED_S; ++typedef struct HFSUniStr255 HFSUniStr255; ++typedef const HFSUniStr255 *ConstHFSUniStr255Param; ++#endif /* _HFSUNISTR255_DEFINED_ */ ++ ++enum { ++ kHFSMaxVolumeNameChars = 27, ++ kHFSMaxFileNameChars = 31, ++ kHFSPlusMaxFileNameChars = 255 ++}PACKED_S; ++ ++ ++/* Extent overflow file data structures */ ++ ++/* HFS Extent key */ ++struct HFSExtentKey { ++ u_int8_t keyLength; /* length of key, excluding this field */ ++ u_int8_t forkType; /* 0 = data fork, FF = resource fork */ ++ u_int32_t fileID; /* file ID */ ++ u_int16_t startBlock; /* first file allocation block number in this extent */ ++}PACKED_S; ++typedef struct HFSExtentKey HFSExtentKey; ++ ++/* HFS Plus Extent key */ ++struct HFSPlusExtentKey { ++ u_int16_t keyLength; /* length of key, excluding this field */ ++ u_int8_t forkType; /* 0 = data fork, FF = resource fork */ ++ u_int8_t pad; /* make the other fields align on 32-bit boundary */ ++ u_int32_t fileID; /* file ID */ ++ u_int32_t startBlock; /* first file allocation block number in this extent */ ++}PACKED_S; ++typedef struct HFSPlusExtentKey HFSPlusExtentKey; ++ ++/* Number of extent descriptors per extent record */ ++enum { ++ kHFSExtentDensity = 3, ++ kHFSPlusExtentDensity = 8 ++}PACKED_S; ++ ++/* HFS extent descriptor */ ++struct HFSExtentDescriptor { ++ u_int16_t startBlock; /* first allocation block */ ++ u_int16_t blockCount; /* number of allocation blocks */ ++}PACKED_S; ++typedef struct HFSExtentDescriptor HFSExtentDescriptor; ++ ++/* HFS Plus extent descriptor */ ++struct HFSPlusExtentDescriptor { ++ u_int32_t startBlock; /* first allocation block */ ++ u_int32_t blockCount; /* number of allocation blocks */ ++}PACKED_S; ++typedef struct HFSPlusExtentDescriptor HFSPlusExtentDescriptor; ++ ++/* HFS extent record */ ++typedef HFSExtentDescriptor HFSExtentRecord[3]; ++ ++/* HFS Plus extent record */ ++typedef HFSPlusExtentDescriptor HFSPlusExtentRecord[8]; ++ ++ ++/* Finder information */ ++struct FndrFileInfo { ++ u_int32_t fdType; /* file type */ ++ u_int32_t fdCreator; /* file creator */ ++ u_int16_t fdFlags; /* Finder flags */ ++ struct { ++ int16_t v; /* file's location */ ++ int16_t h; ++ } PACKED_S fdLocation; ++ int16_t opaque; ++}PACKED_S; ++typedef struct FndrFileInfo FndrFileInfo; ++ ++struct FndrDirInfo { ++ struct { /* folder's window rectangle */ ++ int16_t top; ++ int16_t left; ++ int16_t bottom; ++ int16_t right; ++ }PACKED_S frRect; ++ unsigned short frFlags; /* Finder flags */ ++ struct { ++ u_int16_t v; /* folder's location */ ++ u_int16_t h; ++ }PACKED_S frLocation; ++ int16_t opaque; ++}PACKED_S; ++typedef struct FndrDirInfo FndrDirInfo; ++ ++struct FndrOpaqueInfo { ++ int8_t opaque[16]; ++}PACKED_S; ++typedef struct FndrOpaqueInfo FndrOpaqueInfo; ++ ++ ++/* HFS Plus Fork data info - 80 bytes */ ++struct HFSPlusForkData { ++ u_int64_t logicalSize; /* fork's logical size in bytes */ ++ u_int32_t clumpSize; /* fork's clump size in bytes */ ++ u_int32_t totalBlocks; /* total blocks used by this fork */ ++ HFSPlusExtentRecord extents; /* initial set of extents */ ++}PACKED_S; ++typedef struct HFSPlusForkData HFSPlusForkData; ++ ++ ++/* Mac OS X has 16 bytes worth of "BSD" info. ++ * ++ * Note: Mac OS 9 implementations and applications ++ * should preserve, but not change, this information. ++ */ ++struct HFSPlusBSDInfo { ++ u_int32_t ownerID; /* user or group ID of file/folder owner */ ++ u_int32_t groupID; /* additional user of group ID */ ++ u_int8_t adminFlags; /* super-user changeable flags */ ++ u_int8_t ownerFlags; /* owner changeable flags */ ++ u_int16_t fileMode; /* file type and permission bits */ ++ union { ++ u_int32_t iNodeNum; /* indirect node number (hard links only) */ ++ u_int32_t linkCount; /* links that refer to this indirect node */ ++ u_int32_t rawDevice; /* special file device (FBLK and FCHR only) */ ++ }PACKED_S special; ++}PACKED_S; ++typedef struct HFSPlusBSDInfo HFSPlusBSDInfo; ++ ++ ++/* Catalog file data structures */ ++ ++enum { ++ kHFSRootParentID = 1, /* Parent ID of the root folder */ ++ kHFSRootFolderID = 2, /* Folder ID of the root folder */ ++ kHFSExtentsFileID = 3, /* File ID of the extents file */ ++ kHFSCatalogFileID = 4, /* File ID of the catalog file */ ++ kHFSBadBlockFileID = 5, /* File ID of the bad allocation block file */ ++ kHFSAllocationFileID = 6, /* File ID of the allocation file (HFS Plus only) */ ++ kHFSStartupFileID = 7, /* File ID of the startup file (HFS Plus only) */ ++ kHFSAttributesFileID = 8, /* File ID of the attribute file (HFS Plus only) */ ++ kHFSRepairCatalogFileID = 14, /* Used when rebuilding Catalog B-tree */ ++ kHFSBogusExtentFileID = 15, /* Used for exchanging extents in extents file */ ++ kHFSFirstUserCatalogNodeID = 16 ++}PACKED_S; ++ ++/* HFS catalog key */ ++struct HFSCatalogKey { ++ u_int8_t keyLength; /* key length (in bytes) */ ++ u_int8_t reserved; /* reserved (set to zero) */ ++ u_int32_t parentID; /* parent folder ID */ ++ u_int8_t nodeName[kHFSMaxFileNameChars + 1]; /* catalog node name */ ++}PACKED_S; ++typedef struct HFSCatalogKey HFSCatalogKey; ++ ++/* HFS Plus catalog key */ ++struct HFSPlusCatalogKey { ++ u_int16_t keyLength; /* key length (in bytes) */ ++ u_int32_t parentID; /* parent folder ID */ ++ HFSUniStr255 nodeName; /* catalog node name */ ++}PACKED_S; ++typedef struct HFSPlusCatalogKey HFSPlusCatalogKey; ++ ++/* Catalog record types */ ++enum { ++ /* HFS Catalog Records */ ++ kHFSFolderRecord = 0x0100, /* Folder record */ ++ kHFSFileRecord = 0x0200, /* File record */ ++ kHFSFolderThreadRecord = 0x0300, /* Folder thread record */ ++ kHFSFileThreadRecord = 0x0400, /* File thread record */ ++ ++ /* HFS Plus Catalog Records */ ++ kHFSPlusFolderRecord = 1, /* Folder record */ ++ kHFSPlusFileRecord = 2, /* File record */ ++ kHFSPlusFolderThreadRecord = 3, /* Folder thread record */ ++ kHFSPlusFileThreadRecord = 4 /* File thread record */ ++}PACKED_S; ++ ++ ++/* Catalog file record flags */ ++enum { ++ kHFSFileLockedBit = 0x0000, /* file is locked and cannot be written to */ ++ kHFSFileLockedMask = 0x0001, ++ ++ kHFSThreadExistsBit = 0x0001, /* a file thread record exists for this file */ ++ kHFSThreadExistsMask = 0x0002, ++ ++ kHFSHasAttributesBit = 0x0002, /* object has extended attributes */ ++ kHFSHasAttributesMask = 0x0004, ++ ++ kHFSHasSecurityBit = 0x0003, /* object has security data (ACLs) */ ++ kHFSHasSecurityMask = 0x0008 ++}PACKED_S; ++ ++ ++/* HFS catalog folder record - 70 bytes */ ++struct HFSCatalogFolder { ++ int16_t recordType; /* == kHFSFolderRecord */ ++ u_int16_t flags; /* folder flags */ ++ u_int16_t valence; /* folder valence */ ++ u_int32_t folderID; /* folder ID */ ++ u_int32_t createDate; /* date and time of creation */ ++ u_int32_t modifyDate; /* date and time of last modification */ ++ u_int32_t backupDate; /* date and time of last backup */ ++ FndrDirInfo userInfo; /* Finder information */ ++ FndrOpaqueInfo finderInfo; /* additional Finder information */ ++ u_int32_t reserved[4]; /* reserved - initialized as zero */ ++}PACKED_S; ++typedef struct HFSCatalogFolder HFSCatalogFolder; ++ ++/* HFS Plus catalog folder record - 88 bytes */ ++struct HFSPlusCatalogFolder { ++ int16_t recordType; /* == kHFSPlusFolderRecord */ ++ u_int16_t flags; /* file flags */ ++ u_int32_t valence; /* folder's valence (limited to 2^16 in Mac OS) */ ++ u_int32_t folderID; /* folder ID */ ++ u_int32_t createDate; /* date and time of creation */ ++ u_int32_t contentModDate; /* date and time of last content modification */ ++ u_int32_t attributeModDate; /* date and time of last attribute modification */ ++ u_int32_t accessDate; /* date and time of last access (MacOS X only) */ ++ u_int32_t backupDate; /* date and time of last backup */ ++ HFSPlusBSDInfo bsdInfo; /* permissions (for MacOS X) */ ++ FndrDirInfo userInfo; /* Finder information */ ++ FndrOpaqueInfo finderInfo; /* additional Finder information */ ++ u_int32_t textEncoding; /* hint for name conversions */ ++ u_int32_t attrBlocks; /* cached count of attribute data blocks */ ++}PACKED_S; ++typedef struct HFSPlusCatalogFolder HFSPlusCatalogFolder; ++ ++/* HFS catalog file record - 102 bytes */ ++struct HFSCatalogFile { ++ int16_t recordType; /* == kHFSFileRecord */ ++ u_int8_t flags; /* file flags */ ++ int8_t fileType; /* file type (unused ?) */ ++ FndrFileInfo userInfo; /* Finder information */ ++ u_int32_t fileID; /* file ID */ ++ u_int16_t dataStartBlock; /* not used - set to zero */ ++ int32_t dataLogicalSize; /* logical EOF of data fork */ ++ int32_t dataPhysicalSize; /* physical EOF of data fork */ ++ u_int16_t rsrcStartBlock; /* not used - set to zero */ ++ int32_t rsrcLogicalSize; /* logical EOF of resource fork */ ++ int32_t rsrcPhysicalSize; /* physical EOF of resource fork */ ++ u_int32_t createDate; /* date and time of creation */ ++ u_int32_t modifyDate; /* date and time of last modification */ ++ u_int32_t backupDate; /* date and time of last backup */ ++ FndrOpaqueInfo finderInfo; /* additional Finder information */ ++ u_int16_t clumpSize; /* file clump size (not used) */ ++ HFSExtentRecord dataExtents; /* first data fork extent record */ ++ HFSExtentRecord rsrcExtents; /* first resource fork extent record */ ++ u_int32_t reserved; /* reserved - initialized as zero */ ++}PACKED_S; ++typedef struct HFSCatalogFile HFSCatalogFile; ++ ++/* HFS Plus catalog file record - 248 bytes */ ++struct HFSPlusCatalogFile { ++ int16_t recordType; /* == kHFSPlusFileRecord */ ++ u_int16_t flags; /* file flags */ ++ u_int32_t reserved1; /* reserved - initialized as zero */ ++ u_int32_t fileID; /* file ID */ ++ u_int32_t createDate; /* date and time of creation */ ++ u_int32_t contentModDate; /* date and time of last content modification */ ++ u_int32_t attributeModDate; /* date and time of last attribute modification */ ++ u_int32_t accessDate; /* date and time of last access (MacOS X only) */ ++ u_int32_t backupDate; /* date and time of last backup */ ++ HFSPlusBSDInfo bsdInfo; /* permissions (for MacOS X) */ ++ FndrFileInfo userInfo; /* Finder information */ ++ FndrOpaqueInfo finderInfo; /* additional Finder information */ ++ u_int32_t textEncoding; /* hint for name conversions */ ++ u_int32_t attrBlocks; /* cached count of attribute data blocks */ ++ ++ /* Note: these start on double long (64 bit) boundry */ ++ HFSPlusForkData dataFork; /* size and block data for data fork */ ++ HFSPlusForkData resourceFork; /* size and block data for resource fork */ ++}PACKED_S; ++typedef struct HFSPlusCatalogFile HFSPlusCatalogFile; ++ ++/* HFS catalog thread record - 46 bytes */ ++struct HFSCatalogThread { ++ int16_t recordType; /* == kHFSFolderThreadRecord or kHFSFileThreadRecord */ ++ int32_t reserved[2]; /* reserved - initialized as zero */ ++ u_int32_t parentID; /* parent ID for this catalog node */ ++ u_int8_t nodeName[kHFSMaxFileNameChars + 1]; /* name of this catalog node */ ++}PACKED_S; ++typedef struct HFSCatalogThread HFSCatalogThread; ++ ++/* HFS Plus catalog thread record -- 264 bytes */ ++struct HFSPlusCatalogThread { ++ int16_t recordType; /* == kHFSPlusFolderThreadRecord or kHFSPlusFileThreadRecord */ ++ int16_t reserved; /* reserved - initialized as zero */ ++ u_int32_t parentID; /* parent ID for this catalog node */ ++ HFSUniStr255 nodeName; /* name of this catalog node (variable length) */ ++}PACKED_S; ++typedef struct HFSPlusCatalogThread HFSPlusCatalogThread; ++ ++#ifdef __APPLE_API_UNSTABLE ++/* ++ These are the types of records in the attribute B-tree. The values were ++ chosen so that they wouldn't conflict with the catalog record types. ++*/ ++enum { ++ kHFSPlusAttrInlineData = 0x10, /* if size < kAttrOverflowSize */ ++ kHFSPlusAttrForkData = 0x20, /* if size >= kAttrOverflowSize */ ++ kHFSPlusAttrExtents = 0x30 /* overflow extents for large attributes */ ++}PACKED_S; ++ ++ ++/* ++ HFSPlusAttrForkData ++ For larger attributes, whose value is stored in allocation blocks. ++ If the attribute has more than 8 extents, there will be additonal ++ records (of type HFSPlusAttrExtents) for this attribute. ++*/ ++struct HFSPlusAttrForkData { ++ u_int32_t recordType; /* == kHFSPlusAttrForkData*/ ++ u_int32_t reserved; ++ HFSPlusForkData theFork; /* size and first extents of value*/ ++}PACKED_S; ++typedef struct HFSPlusAttrForkData HFSPlusAttrForkData; ++ ++/* ++ HFSPlusAttrExtents ++ This record contains information about overflow extents for large, ++ fragmented attributes. ++*/ ++struct HFSPlusAttrExtents { ++ u_int32_t recordType; /* == kHFSPlusAttrExtents*/ ++ u_int32_t reserved; ++ HFSPlusExtentRecord extents; /* additional extents*/ ++}PACKED_S; ++typedef struct HFSPlusAttrExtents HFSPlusAttrExtents; ++ ++/* ++ * Atrributes B-tree Data Record ++ * ++ * For small attributes, whose entire value is stored ++ * within a single B-tree record. ++ */ ++struct HFSPlusAttrData { ++ u_int32_t recordType; /* == kHFSPlusAttrInlineData */ ++ u_int32_t reserved[2]; ++ u_int32_t attrSize; /* size of attribute data in bytes */ ++ u_int8_t attrData[2]; /* variable length */ ++}PACKED_S; ++typedef struct HFSPlusAttrData HFSPlusAttrData; ++ ++ ++/* HFSPlusAttrInlineData is obsolete use HFSPlusAttrData instead */ ++struct HFSPlusAttrInlineData { ++ u_int32_t recordType; ++ u_int32_t reserved; ++ u_int32_t logicalSize; ++ u_int8_t userData[2]; ++}PACKED_S; ++typedef struct HFSPlusAttrInlineData HFSPlusAttrInlineData; ++ ++ ++/* A generic Attribute Record*/ ++union HFSPlusAttrRecord { ++ u_int32_t recordType; ++ HFSPlusAttrInlineData inlineData; /* NOT USED */ ++ HFSPlusAttrData attrData; ++ HFSPlusAttrForkData forkData; ++ HFSPlusAttrExtents overflowExtents; ++}PACKED_S; ++typedef union HFSPlusAttrRecord HFSPlusAttrRecord; ++ ++/* Attribute key */ ++enum { kHFSMaxAttrNameLen = 127 }; ++struct HFSPlusAttrKey { ++ u_int16_t keyLength; /* key length (in bytes) */ ++ u_int16_t pad; /* set to zero */ ++ u_int32_t fileID; /* file associated with attribute */ ++ u_int32_t startBlock; /* first attribue allocation block number for extents */ ++ u_int16_t attrNameLen; /* number of unicode characters */ ++ u_int16_t attrName[127]; /* attribute name (Unicode) */ ++}PACKED_S; ++typedef struct HFSPlusAttrKey HFSPlusAttrKey; ++ ++#define kHFSPlusAttrKeyMaximumLength (sizeof(HFSPlusAttrKey) - sizeof(u_int16_t)) ++#define kHFSPlusAttrKeyMinimumLength (kHFSPlusAttrKeyMaximumLength - (127 * sizeof(u_int16_t))) ++ ++#endif /* __APPLE_API_UNSTABLE */ ++ ++ ++/* Key and node lengths */ ++enum { ++ kHFSPlusExtentKeyMaximumLength = sizeof(HFSPlusExtentKey) - sizeof(u_int16_t), ++ kHFSExtentKeyMaximumLength = sizeof(HFSExtentKey) - sizeof(u_int8_t), ++ kHFSPlusCatalogKeyMaximumLength = sizeof(HFSPlusCatalogKey) - sizeof(u_int16_t), ++ kHFSPlusCatalogKeyMinimumLength = kHFSPlusCatalogKeyMaximumLength - sizeof(HFSUniStr255) + sizeof(u_int16_t), ++ kHFSCatalogKeyMaximumLength = sizeof(HFSCatalogKey) - sizeof(u_int8_t), ++ kHFSCatalogKeyMinimumLength = kHFSCatalogKeyMaximumLength - (kHFSMaxFileNameChars + 1) + sizeof(u_int8_t), ++ kHFSPlusCatalogMinNodeSize = 4096, ++ kHFSPlusExtentMinNodeSize = 512, ++ kHFSPlusAttrMinNodeSize = 4096 ++}PACKED_S; ++ ++/* HFS and HFS Plus volume attribute bits */ ++enum { ++ /* Bits 0-6 are reserved (always cleared by MountVol call) */ ++ kHFSVolumeHardwareLockBit = 7, /* volume is locked by hardware */ ++ kHFSVolumeUnmountedBit = 8, /* volume was successfully unmounted */ ++ kHFSVolumeSparedBlocksBit = 9, /* volume has bad blocks spared */ ++ kHFSVolumeNoCacheRequiredBit = 10, /* don't cache volume blocks (i.e. RAM or ROM disk) */ ++ kHFSBootVolumeInconsistentBit = 11, /* boot volume is inconsistent (System 7.6 and later) */ ++ kHFSCatalogNodeIDsReusedBit = 12, ++ kHFSVolumeJournaledBit = 13, /* this volume has a journal on it */ ++ kHFSVolumeInconsistentBit = 14, /* serious inconsistencies detected at runtime */ ++ kHFSVolumeSoftwareLockBit = 15, /* volume is locked by software */ ++ ++ kHFSVolumeHardwareLockMask = 1 << kHFSVolumeHardwareLockBit, ++ kHFSVolumeUnmountedMask = 1 << kHFSVolumeUnmountedBit, ++ kHFSVolumeSparedBlocksMask = 1 << kHFSVolumeSparedBlocksBit, ++ kHFSVolumeNoCacheRequiredMask = 1 << kHFSVolumeNoCacheRequiredBit, ++ kHFSBootVolumeInconsistentMask = 1 << kHFSBootVolumeInconsistentBit, ++ kHFSCatalogNodeIDsReusedMask = 1 << kHFSCatalogNodeIDsReusedBit, ++ kHFSVolumeJournaledMask = 1 << kHFSVolumeJournaledBit, ++ kHFSVolumeInconsistentMask = 1 << kHFSVolumeInconsistentBit, ++ kHFSVolumeSoftwareLockMask = 1 << kHFSVolumeSoftwareLockBit, ++ kHFSMDBAttributesMask = 0x8380 ++}PACKED_S; ++ ++ ++/* HFS Master Directory Block - 162 bytes */ ++/* Stored at sector #2 (3rd sector) and second-to-last sector. */ ++struct HFSMasterDirectoryBlock { ++ u_int16_t drSigWord; /* == kHFSSigWord */ ++ u_int32_t drCrDate; /* date and time of volume creation */ ++ u_int32_t drLsMod; /* date and time of last modification */ ++ u_int16_t drAtrb; /* volume attributes */ ++ u_int16_t drNmFls; /* number of files in root folder */ ++ u_int16_t drVBMSt; /* first block of volume bitmap */ ++ u_int16_t drAllocPtr; /* start of next allocation search */ ++ u_int16_t drNmAlBlks; /* number of allocation blocks in volume */ ++ u_int32_t drAlBlkSiz; /* size (in bytes) of allocation blocks */ ++ u_int32_t drClpSiz; /* default clump size */ ++ u_int16_t drAlBlSt; /* first allocation block in volume */ ++ u_int32_t drNxtCNID; /* next unused catalog node ID */ ++ u_int16_t drFreeBks; /* number of unused allocation blocks */ ++ u_int8_t drVN[kHFSMaxVolumeNameChars + 1]; /* volume name */ ++ u_int32_t drVolBkUp; /* date and time of last backup */ ++ u_int16_t drVSeqNum; /* volume backup sequence number */ ++ u_int32_t drWrCnt; /* volume write count */ ++ u_int32_t drXTClpSiz; /* clump size for extents overflow file */ ++ u_int32_t drCTClpSiz; /* clump size for catalog file */ ++ u_int16_t drNmRtDirs; /* number of directories in root folder */ ++ u_int32_t drFilCnt; /* number of files in volume */ ++ u_int32_t drDirCnt; /* number of directories in volume */ ++ u_int32_t drFndrInfo[8]; /* information used by the Finder */ ++ u_int16_t drEmbedSigWord; /* embedded volume signature (formerly drVCSize) */ ++ HFSExtentDescriptor drEmbedExtent; /* embedded volume location and size (formerly drVBMCSize and drCtlCSize) */ ++ u_int32_t drXTFlSize; /* size of extents overflow file */ ++ HFSExtentRecord drXTExtRec; /* extent record for extents overflow file */ ++ u_int32_t drCTFlSize; /* size of catalog file */ ++ HFSExtentRecord drCTExtRec; /* extent record for catalog file */ ++}PACKED_S; ++typedef struct HFSMasterDirectoryBlock HFSMasterDirectoryBlock; ++ ++ ++#ifdef __APPLE_API_UNSTABLE ++#define SET_HFS_TEXT_ENCODING(hint) \ ++ (0x656e6300 | ((hint) & 0xff)) ++#define GET_HFS_TEXT_ENCODING(hint) \ ++ (((hint) & 0xffffff00) == 0x656e6300 ? (hint) & 0x000000ff : 0xffffffffU) ++#endif /* __APPLE_API_UNSTABLE */ ++ ++ ++/* HFS Plus Volume Header - 512 bytes */ ++/* Stored at sector #2 (3rd sector) and second-to-last sector. */ ++struct HFSPlusVolumeHeader { ++ u_int16_t signature; /* == kHFSPlusSigWord */ ++ u_int16_t version; /* == kHFSPlusVersion */ ++ u_int32_t attributes; /* volume attributes */ ++ u_int32_t lastMountedVersion; /* implementation version which last mounted volume */ ++ u_int32_t journalInfoBlock; /* block addr of journal info (if volume is journaled, zero otherwise) */ ++ ++ u_int32_t createDate; /* date and time of volume creation */ ++ u_int32_t modifyDate; /* date and time of last modification */ ++ u_int32_t backupDate; /* date and time of last backup */ ++ u_int32_t checkedDate; /* date and time of last disk check */ ++ ++ u_int32_t fileCount; /* number of files in volume */ ++ u_int32_t folderCount; /* number of directories in volume */ ++ ++ u_int32_t blockSize; /* size (in bytes) of allocation blocks */ ++ u_int32_t totalBlocks; /* number of allocation blocks in volume (includes this header and VBM*/ ++ u_int32_t freeBlocks; /* number of unused allocation blocks */ ++ ++ u_int32_t nextAllocation; /* start of next allocation search */ ++ u_int32_t rsrcClumpSize; /* default resource fork clump size */ ++ u_int32_t dataClumpSize; /* default data fork clump size */ ++ u_int32_t nextCatalogID; /* next unused catalog node ID */ ++ ++ u_int32_t writeCount; /* volume write count */ ++ u_int64_t encodingsBitmap; /* which encodings have been use on this volume */ ++ ++ u_int8_t finderInfo[32]; /* information used by the Finder */ ++ ++ HFSPlusForkData allocationFile; /* allocation bitmap file */ ++ HFSPlusForkData extentsFile; /* extents B-tree file */ ++ HFSPlusForkData catalogFile; /* catalog B-tree file */ ++ HFSPlusForkData attributesFile; /* extended attributes B-tree file */ ++ HFSPlusForkData startupFile; /* boot file (secondary loader) */ ++}PACKED_S; ++typedef struct HFSPlusVolumeHeader HFSPlusVolumeHeader; ++ ++ ++/* B-tree structures */ ++ ++enum BTreeKeyLimits{ ++ kMaxKeyLength = 520 ++}PACKED_S; ++ ++union BTreeKey{ ++ u_int8_t length8; ++ u_int16_t length16; ++ u_int8_t rawData [kMaxKeyLength+2]; ++}PACKED_S; ++typedef union BTreeKey BTreeKey; ++ ++/* BTNodeDescriptor -- Every B-tree node starts with these fields. */ ++struct BTNodeDescriptor { ++ u_int32_t fLink; /* next node at this level*/ ++ u_int32_t bLink; /* previous node at this level*/ ++ int8_t kind; /* kind of node (leaf, index, header, map)*/ ++ u_int8_t height; /* zero for header, map; child is one more than parent*/ ++ u_int16_t numRecords; /* number of records in this node*/ ++ u_int16_t reserved; /* reserved - initialized as zero */ ++}PACKED_S; ++typedef struct BTNodeDescriptor BTNodeDescriptor; ++ ++/* Constants for BTNodeDescriptor kind */ ++enum { ++ kBTLeafNode = -1, ++ kBTIndexNode = 0, ++ kBTHeaderNode = 1, ++ kBTMapNode = 2 ++}PACKED_S; ++ ++/* BTHeaderRec -- The first record of a B-tree header node */ ++struct BTHeaderRec { ++ u_int16_t treeDepth; /* maximum height (usually leaf nodes) */ ++ u_int32_t rootNode; /* node number of root node */ ++ u_int32_t leafRecords; /* number of leaf records in all leaf nodes */ ++ u_int32_t firstLeafNode; /* node number of first leaf node */ ++ u_int32_t lastLeafNode; /* node number of last leaf node */ ++ u_int16_t nodeSize; /* size of a node, in bytes */ ++ u_int16_t maxKeyLength; /* reserved */ ++ u_int32_t totalNodes; /* total number of nodes in tree */ ++ u_int32_t freeNodes; /* number of unused (free) nodes in tree */ ++ u_int16_t reserved1; /* unused */ ++ u_int32_t clumpSize; /* reserved */ ++ u_int8_t btreeType; /* reserved */ ++ u_int8_t keyCompareType; /* Key string Comparison Type */ ++ u_int32_t attributes; /* persistent attributes about the tree */ ++ u_int32_t reserved3[16]; /* reserved */ ++}PACKED_S; ++typedef struct BTHeaderRec BTHeaderRec; ++ ++/* Constants for BTHeaderRec attributes */ ++enum { ++ kBTBadCloseMask = 0x00000001, /* reserved */ ++ kBTBigKeysMask = 0x00000002, /* key length field is 16 bits */ ++ kBTVariableIndexKeysMask = 0x00000004 /* keys in index nodes are variable length */ ++}PACKED_S; ++ ++ ++/* Catalog Key Name Comparison Type */ ++enum { ++ kHFSCaseFolding = 0xCF, /* case folding (case-insensitive) */ ++ kHFSBinaryCompare = 0xBC /* binary compare (case-sensitive) */ ++}PACKED_S; ++ ++/* JournalInfoBlock - Structure that describes where our journal lives */ ++struct JournalInfoBlock { ++ u_int32_t flags; ++ u_int32_t device_signature[8]; // signature used to locate our device. ++ u_int64_t offset; // byte offset to the journal on the device ++ u_int64_t size; // size in bytes of the journal ++ u_int32_t reserved[32]; ++}PACKED_S; ++typedef struct JournalInfoBlock JournalInfoBlock; ++ ++enum { ++ kJIJournalInFSMask = 0x00000001, ++ kJIJournalOnOtherDeviceMask = 0x00000002, ++ kJIJournalNeedInitMask = 0x00000004 ++}PACKED_S; ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* __HFS_FORMAT__ */ +diff -Naur diskdev_cmds-332.14.bak/include/hfs/hfs_mount.h diskdev_cmds-332.14/include/hfs/hfs_mount.h +--- diskdev_cmds-332.14.bak/include/hfs/hfs_mount.h 1969-12-31 19:00:00.000000000 -0500 ++++ diskdev_cmds-332.14/include/hfs/hfs_mount.h 2006-03-22 09:10:42.000000000 -0500 +@@ -0,0 +1,78 @@ ++/* ++ * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. ++ * ++ * @APPLE_LICENSE_HEADER_START@ ++ * ++ * The contents of this file constitute Original Code as defined in and ++ * are subject to the Apple Public Source License Version 1.1 (the ++ * "License"). You may not use this file except in compliance with the ++ * License. Please obtain a copy of the License at ++ * http://www.apple.com/publicsource and read it before using this file. ++ * ++ * This Original Code and all software distributed under the License are ++ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ++ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ++ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ++ * License for the specific language governing rights and limitations ++ * under the License. ++ * ++ * @APPLE_LICENSE_HEADER_END@ ++ */ ++/* ++ * Copyright (c) 1997-2002 Apple Computer, Inc. All Rights Reserved ++ * ++ */ ++ ++#ifndef _HFS_MOUNT_H_ ++#define _HFS_MOUNT_H_ ++ ++#include ++ ++#include ++#include ++ ++/* ++ * Arguments to mount HFS-based filesystems ++ */ ++ ++#define OVERRIDE_UNKNOWN_PERMISSIONS 0 ++ ++#define UNKNOWNUID ((uid_t)99) ++#define UNKNOWNGID ((gid_t)99) ++#define UNKNOWNPERMISSIONS (S_IRWXU | S_IROTH | S_IXOTH) /* 705 */ ++ ++#ifdef __APPLE_API_UNSTABLE ++struct hfs_mount_args { ++#ifndef KERNEL ++ char *fspec; /* block special device to mount */ ++#endif ++ uid_t hfs_uid; /* uid that owns hfs files (standard HFS only) */ ++ gid_t hfs_gid; /* gid that owns hfs files (standard HFS only) */ ++ mode_t hfs_mask; /* mask to be applied for hfs perms (standard HFS only) */ ++ u_int32_t hfs_encoding; /* encoding for this volume (standard HFS only) */ ++ struct timezone hfs_timezone; /* user time zone info (standard HFS only) */ ++ int flags; /* mounting flags, see below */ ++ int journal_tbuffer_size; /* size in bytes of the journal transaction buffer */ ++ int journal_flags; /* flags to pass to journal_open/create */ ++ int journal_disable; /* don't use journaling (potentially dangerous) */ ++}; ++ ++#define HFSFSMNT_NOXONFILES 0x1 /* disable execute permissions for files */ ++#define HFSFSMNT_WRAPPER 0x2 /* mount HFS wrapper (if it exists) */ ++#define HFSFSMNT_EXTENDED_ARGS 0x4 /* indicates new fields after "flags" are valid */ ++ ++/* ++ * Sysctl values for HFS ++ */ ++#define HFS_ENCODINGBIAS 1 /* encoding matching CJK bias */ ++#define HFS_EXTEND_FS 2 ++#define HFS_ENCODINGHINT 3 /* guess encoding for string */ ++#define HFS_ENABLE_JOURNALING 0x082969 ++#define HFS_DISABLE_JOURNALING 0x031272 ++#define HFS_GET_JOURNAL_INFO 0x6a6e6c69 ++#define HFS_SET_PKG_EXTENSIONS 0x121031 ++ ++#endif /* __APPLE_API_UNSTABLE */ ++ ++#endif /* ! _HFS_MOUNT_H_ */ +diff -Naur diskdev_cmds-332.14.bak/include/missing.h diskdev_cmds-332.14/include/missing.h +--- diskdev_cmds-332.14.bak/include/missing.h 1969-12-31 19:00:00.000000000 -0500 ++++ diskdev_cmds-332.14/include/missing.h 2006-03-22 09:10:42.000000000 -0500 +@@ -0,0 +1,113 @@ ++#ifndef _MISSING_H_ ++#define _MISSING_H_ ++ ++#include ++#include ++#include ++#include ++ ++#define MAXBSIZE (256 * 4096) ++ ++#ifndef true ++#define true 1 ++#endif ++#ifndef false ++#define false 0 ++#endif ++ ++/* Mac types */ ++ ++/* 8 Bit */ ++#ifndef UInt8 ++#define UInt8 uint8_t ++#endif ++#ifndef u_int8_t ++#define u_int8_t UInt8 ++#endif ++#ifndef SInt8 ++#define SInt8 int8_t ++#endif ++ ++/* 16 Bit */ ++#ifndef UInt16 ++#define UInt16 uint16_t ++#endif ++#ifndef u_int16_t ++#define u_int16_t UInt16 ++#endif ++#ifndef SInt16 ++#define SInt16 int16_t ++#endif ++ ++/* 32 Bit */ ++#ifndef UInt32 ++#define UInt32 uint32_t ++#endif ++#ifndef u_int32_t ++#define u_int32_t UInt32 ++#endif ++#ifndef SInt32 ++#define SInt32 int32_t ++#endif ++ ++/* 64 Bit */ ++#ifndef UInt64 ++#define UInt64 uint64_t ++#endif ++#ifndef u_int64_t ++#define u_int64_t UInt64 ++#endif ++#ifndef SInt64 ++#define SInt64 int64_t ++#endif ++ ++#define UniChar u_int16_t ++#define Boolean u_int8_t ++ ++#define UF_NODUMP 0x00000001 ++ ++/* syslimits.h */ ++#define NAME_MAX 255 ++ ++/* Byteswap stuff */ ++#define NXSwapHostLongToBig(x) cpu_to_be64(x) ++#define NXSwapBigShortToHost(x) be16_to_cpu(x) ++#define OSSwapBigToHostInt16(x) be16_to_cpu(x) ++#define NXSwapBigLongToHost(x) be32_to_cpu(x) ++#define OSSwapBigToHostInt32(x) be32_to_cpu(x) ++#define NXSwapBigLongLongToHost(x) be64_to_cpu(x) ++#define OSSwapBigToHostInt64(x) be64_to_cpu(x) ++ ++#if __BYTE_ORDER == __LITTLE_ENDIAN ++/* Big Endian Swaps */ ++#ifndef be16_to_cpu ++#define be16_to_cpu(x) bswap_16(x) ++#endif ++#ifndef be32_to_cpu ++#define be32_to_cpu(x) bswap_32(x) ++#endif ++#ifndef be64_to_cpu ++#define be64_to_cpu(x) bswap_64(x) ++#endif ++#ifndef cpu_to_be64 ++#define cpu_to_be64(x) bswap_64(x) ++#endif ++#elif __BYTE_ORDER == __BIG_ENDIAN ++/* Big endian doesn't swap */ ++#ifndef be16_to_cpu ++#define be16_to_cpu(x) (x) ++#endif ++#ifndef be32_to_cpu ++#define be32_to_cpu(x) (x) ++#endif ++#ifndef be64_to_cpu ++#define be64_to_cpu(x) (x) ++#endif ++#ifndef cpu_to_be64 ++#define cpu_to_be64(x) (x) ++#endif ++#endif ++ ++#define KAUTH_FILESEC_XATTR "com.apple.system.Security" ++ ++#endif +diff -Naur diskdev_cmds-332.14.bak/include/sys/appleapiopts.h diskdev_cmds-332.14/include/sys/appleapiopts.h +--- diskdev_cmds-332.14.bak/include/sys/appleapiopts.h 1969-12-31 19:00:00.000000000 -0500 ++++ diskdev_cmds-332.14/include/sys/appleapiopts.h 2006-03-22 09:10:42.000000000 -0500 +@@ -0,0 +1,56 @@ ++/* ++ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. ++ * ++ * @APPLE_LICENSE_HEADER_START@ ++ * ++ * The contents of this file constitute Original Code as defined in and ++ * are subject to the Apple Public Source License Version 1.1 (the ++ * "License"). You may not use this file except in compliance with the ++ * License. Please obtain a copy of the License at ++ * http://www.apple.com/publicsource and read it before using this file. ++ * ++ * This Original Code and all software distributed under the License are ++ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ++ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ++ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ++ * License for the specific language governing rights and limitations ++ * under the License. ++ * ++ * @APPLE_LICENSE_HEADER_END@ ++ */ ++ ++#ifndef __SYS_APPLEAPIOPTS_H__ ++#define __SYS_APPLEAPIOPTS_H__ ++ ++ ++#ifndef __APPLE_API_STANDARD ++#define __APPLE_API_STANDARD ++#endif /* __APPLE_API_STANDARD */ ++ ++#ifndef __APPLE_API_STABLE ++#define __APPLE_API_STABLE ++#endif /* __APPLE_API_STABLE */ ++ ++#ifndef __APPLE_API_STRICT_CONFORMANCE ++ ++#ifndef __APPLE_API_EVOLVING ++#define __APPLE_API_EVOLVING ++#endif /* __APPLE_API_EVOLVING */ ++ ++#ifndef __APPLE_API_UNSTABLE ++#define __APPLE_API_UNSTABLE ++#endif /* __APPLE_API_UNSTABLE */ ++ ++#ifndef __APPLE_API_PRIVATE ++#define __APPLE_API_PRIVATE ++#endif /* __APPLE_API_PRIVATE */ ++ ++#ifndef __APPLE_API_OBSOLETE ++#define __APPLE_API_OBSOLETE ++#endif /* __APPLE_API_OBSOLETE */ ++ ++#endif /* __APPLE_API_STRICT_CONFORMANCE */ ++ ++#endif /* __SYS_APPLEAPIOPTS_H__ */ ++ +diff -Naur diskdev_cmds-332.14.bak/newfs_hfs.tproj/Makefile.lnx diskdev_cmds-332.14/newfs_hfs.tproj/Makefile.lnx +--- diskdev_cmds-332.14.bak/newfs_hfs.tproj/Makefile.lnx 1969-12-31 19:00:00.000000000 -0500 ++++ diskdev_cmds-332.14/newfs_hfs.tproj/Makefile.lnx 2006-03-22 09:10:42.000000000 -0500 +@@ -0,0 +1,12 @@ ++CFILES = hfs_endian.c makehfs.c newfs_hfs.c ++OFILES = $(CFILES:.c=.o) ++ ++all: newfs_hfs ++ ++newfs_hfs: $(OFILES) ++ ${CC} ${CFLAGS} -o newfs_hfs ${OFILES} -lssl ++ ++clean: ++ $(RM) newfs_hfs $(OFILES) ++ ++.PHONY : FORCE clean +diff -Naur diskdev_cmds-332.14.bak/newfs_hfs.tproj/hfs_endian.c diskdev_cmds-332.14/newfs_hfs.tproj/hfs_endian.c +--- diskdev_cmds-332.14.bak/newfs_hfs.tproj/hfs_endian.c 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/newfs_hfs.tproj/hfs_endian.c 2006-03-22 09:10:42.000000000 -0500 +@@ -30,7 +30,12 @@ + #include + #include + ++#if LINUX ++#include "missing.h" ++#else + #include ++#endif ++ + #include + + #include "hfs_endian.h" +diff -Naur diskdev_cmds-332.14.bak/newfs_hfs.tproj/hfs_endian.h diskdev_cmds-332.14/newfs_hfs.tproj/hfs_endian.h +--- diskdev_cmds-332.14.bak/newfs_hfs.tproj/hfs_endian.h 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/newfs_hfs.tproj/hfs_endian.h 2006-03-22 09:10:42.000000000 -0500 +@@ -29,7 +29,12 @@ + * volume format. + */ + #include ++#if LINUX ++#include ++#include ++#else + #include ++#endif + + /*********************/ + /* BIG ENDIAN Macros */ +diff -Naur diskdev_cmds-332.14.bak/newfs_hfs.tproj/makehfs.c diskdev_cmds-332.14/newfs_hfs.tproj/makehfs.c +--- diskdev_cmds-332.14.bak/newfs_hfs.tproj/makehfs.c 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/newfs_hfs.tproj/makehfs.c 2006-03-22 09:10:42.000000000 -0500 +@@ -31,10 +31,16 @@ + #include + #include + #include ++#if LINUX ++#include ++#include "missing.h" ++#endif + #include + #include + #include ++#if !LINUX + #include ++#endif + + #include + #include +@@ -47,13 +53,14 @@ + + #include + ++#if !LINUX + #include + + #include + #include + + extern Boolean _CFStringGetFileSystemRepresentation(CFStringRef string, UInt8 *buffer, CFIndex maxBufLen); +- ++#endif + + #include + #include +@@ -129,7 +136,9 @@ + static void MarkBitInAllocationBuffer __P((HFSPlusVolumeHeader *header, + UInt32 allocationBlock, void* sectorBuffer, UInt32 *sector)); + ++#if !LINUX + static UInt32 GetDefaultEncoding(); ++#endif + + static UInt32 UTCToLocal __P((UInt32 utcTime)); + +@@ -158,11 +167,14 @@ + + #define ROUNDUP(x, u) (((x) % (u) == 0) ? (x) : ((x)/(u) + 1) * (u)) + +-#define ENCODING_TO_BIT(e) \ ++#if LINUX ++#define ENCODING_TO_BIT(e) (e) ++#else ++#define ENCODING_TO_BIT(e) + ((e) < 48 ? (e) : \ + ((e) == kCFStringEncodingMacUkrainian ? 48 : \ + ((e) == kCFStringEncodingMacFarsi ? 49 : 0))) +- ++#endif + /* + * make_hfs + * +@@ -528,6 +540,7 @@ + * Map UTF-8 input into a Mac encoding. + * On conversion errors "untitled" is used as a fallback. + */ ++#if !LINUX + { + UniChar unibuf[kHFSMaxVolumeNameChars]; + CFStringRef cfstr; +@@ -553,7 +566,11 @@ + bcopy(&mdbp->drVN[1], defaults->volumeName, mdbp->drVN[0]); + defaults->volumeName[mdbp->drVN[0]] = '\0'; + } ++#endif + /* Save the encoding hint in the Finder Info (field 4). */ ++ mdbp->drVN[0] = strlen(defaults->volumeName); ++ bcopy(defaults->volumeName,&mdbp->drVN[1],mdbp->drVN[0]); ++ + mdbp->drFndrInfo[4] = SET_HFS_TEXT_ENCODING(defaults->encodingHint); + + mdbp->drWrCnt = kWriteSeqNum; +@@ -1100,9 +1117,11 @@ + UInt16 nodeSize; + SInt16 offset; + UInt32 unicodeBytes; ++#if !LINUX + UInt8 canonicalName[256]; + CFStringRef cfstr; + Boolean cfOK; ++#endif + int index = 0; + + nodeSize = dp->catalogNodeSize; +@@ -1122,7 +1141,9 @@ + * First record is always the root directory... + */ + ckp = (HFSPlusCatalogKey *)((UInt8 *)buffer + offset); +- ++#if LINUX ++ ConvertUTF8toUnicode(dp->volumeName, sizeof(ckp->nodeName.unicode), ckp->nodeName.unicode, &ckp->nodeName.length); ++#else + /* Use CFString functions to get a HFSPlus Canonical name */ + cfstr = CFStringCreateWithCString(kCFAllocatorDefault, (char *)dp->volumeName, kCFStringEncodingUTF8); + cfOK = _CFStringGetFileSystemRepresentation(cfstr, canonicalName, sizeof(canonicalName)); +@@ -1139,6 +1160,7 @@ + dp->volumeName, kDefaultVolumeNameStr); + } + CFRelease(cfstr); ++#endif + ckp->nodeName.length = SWAP_BE16 (ckp->nodeName.length); + + unicodeBytes = sizeof(UniChar) * SWAP_BE16 (ckp->nodeName.length); +@@ -1821,15 +1843,15 @@ + off_t sector; + + if ((byteCount % driveInfo->sectorSize) != 0) +- errx(1, "WriteBuffer: byte count %ld is not sector size multiple", byteCount); ++ errx(1, "WriteBuffer: byte count %i is not sector size multiple", byteCount); + + sector = driveInfo->sectorOffset + startingSector; + + if (lseek(driveInfo->fd, sector * driveInfo->sectorSize, SEEK_SET) < 0) +- err(1, "seek (sector %qd)", sector); ++ err(1, "seek (sector %lld)", sector); + + if (write(driveInfo->fd, buffer, byteCount) != byteCount) +- err(1, "write (sector %qd, %ld bytes)", sector, byteCount); ++ err(1, "write (sector %lld, %i bytes)", sector, byteCount); + } + + +@@ -1913,7 +1935,7 @@ + return quotient; + } + +- ++#if !LINUX + #define __kCFUserEncodingFileName ("/.CFUserTextEncoding") + + static UInt32 +@@ -1939,7 +1961,7 @@ + } + return 0; + } +- ++#endif + + static int + ConvertUTF8toUnicode(const UInt8* source, UInt32 bufsize, UniChar* unibuf, +@@ -2006,6 +2028,9 @@ + static int + getencodinghint(unsigned char *name) + { ++#if LINUX ++ return(0); ++#else + int mib[3]; + size_t buflen = sizeof(int); + struct vfsconf vfc; +@@ -2023,7 +2048,8 @@ + return (hint); + error: + hint = GetDefaultEncoding(); +- return (hint); ++ return (0); ++#endif + } + + +@@ -2034,12 +2060,14 @@ + unsigned char digest[20]; + time_t now; + clock_t uptime; +- int mib[2]; +- int sysdata; +- char sysctlstring[128]; + size_t datalen; + double sysloadavg[3]; ++#if !LINUX ++ int sysdata; ++ int mib[2]; ++ char sysctlstring[128]; + struct vmtotal sysvmtotal; ++#endif + + do { + /* Initialize the SHA-1 context for processing: */ +@@ -2052,52 +2080,58 @@ + SHA1_Update(&context, &uptime, sizeof(uptime)); + + /* The kernel's boot time: */ ++#if !LINUX + mib[0] = CTL_KERN; + mib[1] = KERN_BOOTTIME; + datalen = sizeof(sysdata); + sysctl(mib, 2, &sysdata, &datalen, NULL, 0); + SHA1_Update(&context, &sysdata, datalen); +- ++#endif + /* The system's host id: */ ++#if !LINUX + mib[0] = CTL_KERN; + mib[1] = KERN_HOSTID; + datalen = sizeof(sysdata); + sysctl(mib, 2, &sysdata, &datalen, NULL, 0); + SHA1_Update(&context, &sysdata, datalen); +- ++#endif + /* The system's host name: */ ++#if !LINUX + mib[0] = CTL_KERN; + mib[1] = KERN_HOSTNAME; + datalen = sizeof(sysctlstring); + sysctl(mib, 2, sysctlstring, &datalen, NULL, 0); + SHA1_Update(&context, sysctlstring, datalen); +- ++#endif + /* The running kernel's OS release string: */ ++#if !LINUX + mib[0] = CTL_KERN; + mib[1] = KERN_OSRELEASE; + datalen = sizeof(sysctlstring); + sysctl(mib, 2, sysctlstring, &datalen, NULL, 0); + SHA1_Update(&context, sysctlstring, datalen); +- ++#endif + /* The running kernel's version string: */ ++#if !LINUX + mib[0] = CTL_KERN; + mib[1] = KERN_VERSION; + datalen = sizeof(sysctlstring); + sysctl(mib, 2, sysctlstring, &datalen, NULL, 0); + SHA1_Update(&context, sysctlstring, datalen); +- ++#endif + /* The system's load average: */ + datalen = sizeof(sysloadavg); + getloadavg(sysloadavg, 3); + SHA1_Update(&context, &sysloadavg, datalen); + + /* The system's VM statistics: */ ++#if !LINUX + mib[0] = CTL_VM; + mib[1] = VM_METER; + datalen = sizeof(sysvmtotal); + sysctl(mib, 2, &sysvmtotal, &datalen, NULL, 0); + SHA1_Update(&context, &sysvmtotal, datalen); +- ++#endif + /* The current GMT (26 ASCII characters): */ + time(&now); + strncpy(randomInputBuffer, asctime(gmtime(&now)), 26); /* "Mon Mar 27 13:46:26 2000" */ +diff -Naur diskdev_cmds-332.14.bak/newfs_hfs.tproj/newfs_hfs.c diskdev_cmds-332.14/newfs_hfs.tproj/newfs_hfs.c +--- diskdev_cmds-332.14.bak/newfs_hfs.tproj/newfs_hfs.c 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/newfs_hfs.tproj/newfs_hfs.c 2006-03-22 09:10:42.000000000 -0500 +@@ -38,8 +38,13 @@ + #include + #include + #include ++#if LINUX ++#include ++#endif + ++#if !LINUX + #include ++#endif + + #include + #include "newfs_hfs.h" +@@ -73,7 +78,9 @@ + + char *progname; + char gVolumeName[kHFSPlusMaxFileNameChars + 1] = {kDefaultVolumeNameStr}; +-char rawdevice[MAXPATHLEN]; ++#if !LINUX ++char rawdevice[MAXPATHLEN]; ++#endif + char blkdevice[MAXPATHLEN]; + UInt32 gBlockSize = 0; + UInt32 gNextCNID = kHFSFirstUserCatalogNodeID; +@@ -137,8 +144,10 @@ + extern int optind; + int ch; + int forceHFS; ++#if !LINUX + char *cp, *special; + struct statfs *mp; ++#endif + int n; + + if ((progname = strrchr(*argv, '/'))) +@@ -238,7 +247,9 @@ + + if (argc != 1) + usage(); +- ++#if LINUX ++ (void) sprintf(blkdevice, "%s", argv[0]); ++#else + special = argv[0]; + cp = strrchr(special, '/'); + if (cp != 0) +@@ -247,6 +258,7 @@ + special++; + (void) sprintf(rawdevice, "%sr%s", _PATH_DEV, special); + (void) sprintf(blkdevice, "%s%s", _PATH_DEV, special); ++#endif + + if (forceHFS && gJournaled) { + fprintf(stderr, "-h -J: incompatible options specified\n"); +@@ -268,6 +280,9 @@ + /* + * Check if target device is aready mounted + */ ++#if LINUX ++ // FIXME ++#else + n = getmntinfo(&mp, MNT_NOWAIT); + if (n == 0) + fatal("%s: getmntinfo: %s", blkdevice, strerror(errno)); +@@ -277,14 +292,19 @@ + fatal("%s is mounted on %s", blkdevice, mp->f_mntonname); + ++mp; + } ++#endif + +- if (hfs_newfs(rawdevice, forceHFS, true) < 0) { ++ if (hfs_newfs(blkdevice, forceHFS, true) < 0) { ++#if LINUX ++ err(1, NULL); ++#else + /* On ENXIO error use the block device (to get de-blocking) */ + if (errno == ENXIO) { + if (hfs_newfs(blkdevice, forceHFS, false) < 0) + err(1, NULL); + } else + err(1, NULL); ++#endif + } + + exit(0); +@@ -458,7 +478,7 @@ + fatal("%s: block size is too small for %lld sectors", optarg, gBlockSize, sectorCount); + + if (gBlockSize < HFSOPTIMALBLKSIZE) +- warnx("Warning: %ld is a non-optimal block size (4096 would be a better choice)", gBlockSize); ++ warnx("Warning: %i is a non-optimal block size (4096 would be a better choice)", gBlockSize); + } + } + +@@ -472,7 +492,9 @@ + int fso = 0; + int retval = 0; + hfsparams_t defaults = {0}; ++#if !LINUX + u_int64_t maxSectorsPerIO; ++#endif + + if (gNoCreate) { + fso = open( device, O_RDONLY | O_NDELAY, 0 ); +@@ -485,7 +507,33 @@ + + if (fstat( fso, &stbuf) < 0) + fatal("%s: %s", device, strerror(errno)); ++#if LINUX ++ dip.sectorSize = 512; ++ dip.sectorsPerIO = 256; + ++#ifndef BLKGETSIZE ++#define BLKGETSIZE _IO(0x12,96) ++#endif ++#ifndef BLKGETSIZE64 ++#define BLKGETSIZE64 _IOR(0x12,114,size_t) ++#endif ++ ++ if (S_ISREG(stbuf.st_mode)) { ++ dip.totalSectors = stbuf.st_size / 512; ++ } ++ else if (S_ISBLK(stbuf.st_mode)) { ++ unsigned long size; ++ u_int64_t size64; ++ if (!ioctl(fso, BLKGETSIZE64, &size64)) ++ dip.totalSectors = size64 / 512; ++ else if (!ioctl(fso, BLKGETSIZE, &size)) ++ dip.totalSectors = size; ++ else ++ fatal("%s: %s", device, strerror(errno)); ++ } ++ else ++ fatal("%s: is not a block device", device); ++#else + if (ioctl(fso, DKIOCGETBLOCKCOUNT, &dip.totalSectors) < 0) + fatal("%s: %s", device, strerror(errno)); + +@@ -493,14 +541,17 @@ + fatal("%s: %s", device, strerror(errno)); + + if (ioctl(fso, DKIOCGETMAXBLOCKCOUNTWRITE, &maxSectorsPerIO) < 0) +- dip.sectorsPerIO = (128 * 1024) / dip.sectorSize; /* use 128K as default */ ++ dip.sectorsPerIO = (128 * 1024) / dip.sectorSize; /* use 128K as default */ + else + dip.sectorsPerIO = MIN(maxSectorsPerIO, (1024 * 1024) / dip.sectorSize); ++#endif ++ + /* +- * The make_hfs code currentlydoes 512 byte sized I/O. ++ * The make_hfs code currently does 512 byte sized I/O. + * If the sector size is bigger than 512, start over + * using the block device (to get de-blocking). + */ ++#if !LINUX + if (dip.sectorSize != kBytesPerSector) { + if (isRaw) { + close(fso); +@@ -515,7 +566,8 @@ + dip.sectorSize = kBytesPerSector; + } + } +- ++#endif ++ + dip.fd = fso; + dip.sectorOffset = 0; + time(&createtime); +@@ -693,7 +745,7 @@ + defaults->catalogClumpSize = clumpSize; + defaults->catalogNodeSize = catnodesiz; + if (gBlockSize < 4096 && gBlockSize < catnodesiz) +- warnx("Warning: block size %ld is less than catalog b-tree node size %ld", gBlockSize, catnodesiz); ++ warnx("Warning: block size %i is less than catalog b-tree node size %i", gBlockSize, catnodesiz); + + if (extclumpblks == 0) { + clumpSize = CalcHFSPlusBTreeClumpSize(gBlockSize, extnodesiz, sectorCount, FALSE); +@@ -706,7 +758,7 @@ + defaults->extentsClumpSize = clumpSize; + defaults->extentsNodeSize = extnodesiz; + if (gBlockSize < extnodesiz) +- warnx("Warning: block size %ld is less than extents b-tree node size %ld", gBlockSize, extnodesiz); ++ warnx("Warning: block size %i is less than extents b-tree node size %i", gBlockSize, extnodesiz); + + if (atrclumpblks == 0) { + clumpSize = 0; +@@ -754,22 +806,22 @@ + + if (gNoCreate) { + if (!gWrapper) +- printf("%qd sectors (%lu bytes per sector)\n", sectorCount, sectorSize); ++ printf("%lld sectors (%u bytes per sector)\n", sectorCount, sectorSize); + printf("HFS Plus format parameters:\n"); + printf("\tvolume name: \"%s\"\n", gVolumeName); +- printf("\tblock-size: %lu\n", defaults->blockSize); +- printf("\ttotal blocks: %lu\n", totalBlocks); ++ printf("\tblock-size: %u\n", defaults->blockSize); ++ printf("\ttotal blocks: %u\n", totalBlocks); + if (gJournaled) + printf("\tjournal-size: %dk\n", (int)defaults->journalSize/1024); +- printf("\tfirst free catalog node id: %lu\n", defaults->nextFreeFileID); +- printf("\tcatalog b-tree node size: %lu\n", defaults->catalogNodeSize); +- printf("\tinitial catalog file size: %lu\n", defaults->catalogClumpSize); +- printf("\textents b-tree node size: %lu\n", defaults->extentsNodeSize); +- printf("\tinitial extents file size: %lu\n", defaults->extentsClumpSize); +- printf("\tinitial allocation file size: %lu (%lu blocks)\n", ++ printf("\tfirst free catalog node id: %u\n", defaults->nextFreeFileID); ++ printf("\tcatalog b-tree node size: %u\n", defaults->catalogNodeSize); ++ printf("\tinitial catalog file size: %u\n", defaults->catalogClumpSize); ++ printf("\textents b-tree node size: %u\n", defaults->extentsNodeSize); ++ printf("\tinitial extents file size: %u\n", defaults->extentsClumpSize); ++ printf("\tinitial allocation file size: %u (%u blocks)\n", + defaults->allocationClumpSize, defaults->allocationClumpSize / gBlockSize); +- printf("\tdata fork clump size: %lu\n", defaults->dataClumpSize); +- printf("\tresource fork clump size: %lu\n", defaults->rsrcClumpSize); ++ printf("\tdata fork clump size: %u\n", defaults->dataClumpSize); ++ printf("\tresource fork clump size: %u\n", defaults->rsrcClumpSize); + if (defaults->flags & kUseAccessPerms) { + printf("\tuser ID: %d\n", (int)defaults->owner); + printf("\tgroup ID: %d\n", (int)defaults->group); +@@ -844,17 +896,17 @@ + } + + if (gNoCreate) { +- printf("%ld sectors at %ld bytes per sector\n", sectorCount, sectorSize); ++ printf("%i sectors at %i bytes per sector\n", sectorCount, sectorSize); + printf("%s format parameters:\n", gWrapper ? "HFS Wrapper" : "HFS"); + printf("\tvolume name: \"%s\"\n", gVolumeName); +- printf("\tblock-size: %ld\n", defaults->blockSize); +- printf("\ttotal blocks: %ld\n", sectorCount / (alBlkSize / sectorSize) ); +- printf("\tfirst free catalog node id: %ld\n", defaults->nextFreeFileID); +- printf("\tinitial catalog file size: %ld\n", defaults->catalogClumpSize); +- printf("\tinitial extents file size: %ld\n", defaults->extentsClumpSize); +- printf("\tfile clump size: %ld\n", defaults->dataClumpSize); ++ printf("\tblock-size: %i\n", defaults->blockSize); ++ printf("\ttotal blocks: %i\n", sectorCount / (alBlkSize / sectorSize) ); ++ printf("\tfirst free catalog node id: %i\n", defaults->nextFreeFileID); ++ printf("\tinitial catalog file size: %i\n", defaults->catalogClumpSize); ++ printf("\tinitial extents file size: %i\n", defaults->extentsClumpSize); ++ printf("\tfile clump size: %i\n", defaults->dataClumpSize); + if (hfsgrowblks) +- printf("\twrapper growable from %ld to %ld sectors\n", sectorCount, hfsgrowblks); ++ printf("\twrapper growable from %i to %i sectors\n", sectorCount, hfsgrowblks); + } + } + +diff -Naur diskdev_cmds-332.14.bak/newfs_hfs.tproj/newfs_hfs.h diskdev_cmds-332.14/newfs_hfs.tproj/newfs_hfs.h +--- diskdev_cmds-332.14.bak/newfs_hfs.tproj/newfs_hfs.h 2006-02-20 16:45:15.000000000 -0500 ++++ diskdev_cmds-332.14/newfs_hfs.tproj/newfs_hfs.h 2006-03-22 09:10:42.000000000 -0500 +@@ -19,8 +19,12 @@ + * + * @APPLE_LICENSE_HEADER_END@ + */ +- +-#include ++ ++#if LINUX ++#include "missing.h" ++#else ++#include */ ++#endif + + /* + * Mac OS Finder flags +@@ -122,33 +126,33 @@ + #define kDTDF_FileID 16 + #define kDTDF_Name "Desktop DF" + #define kDTDF_Chars 10 +-#define kDTDF_Type 'DTFL' +-#define kDTDF_Creator 'DMGR' ++#define kDTDF_Type 0x4454464C /* 'DTFL' */ ++#define kDTDF_Creator 0x444D4752 /* 'DMGR' */ + + #define kDTDB_FileID 17 + #define kDTDB_Name "Desktop DB" + #define kDTDB_Chars 10 +-#define kDTDB_Type 'BTFL' +-#define kDTDB_Creator 'DMGR' ++#define kDTDB_Type 0x4254464C /* 'BTFL' */ ++#define kDTDB_Creator 0x444D4752 /* 'DMGR' */ + #define kDTDB_Size 1024 + + #define kReadMe_FileID 18 + #define kReadMe_Name "ReadMe" + #define kReadMe_Chars 6 +-#define kReadMe_Type 'ttro' +-#define kReadMe_Creator 'ttxt' ++#define kReadMe_Type 0x7474726F /* 'ttro' */ ++#define kReadMe_Creator 0x74747974 /* 'ttxt' */ + + #define kFinder_FileID 19 + #define kFinder_Name "Finder" + #define kFinder_Chars 6 +-#define kFinder_Type 'FNDR' +-#define kFinder_Creator 'MACS' ++#define kFinder_Type 0x464E4452 /* 'FNDR' */ ++#define kFinder_Creator 0x4D414353 /* 'MACS' */ + + #define kSystem_FileID 20 + #define kSystem_Name "System" + #define kSystem_Chars 6 +-#define kSystem_Type 'zsys' +-#define kSystem_Creator 'MACS' ++#define kSystem_Type 0x7A737973 /* 'zsys' */ ++#define kSystem_Creator 0x4D414353 /* 'MACS' */ + + + diff --git a/hfstools-332.14-fix_link_with_gold.patch b/hfstools-332.14-fix_link_with_gold.patch new file mode 100644 index 0000000..5edac56 --- /dev/null +++ b/hfstools-332.14-fix_link_with_gold.patch @@ -0,0 +1,22 @@ +diff -Nru diskdev_cmds-332.14.orig/Makefile.lnx diskdev_cmds-332.14/Makefile.lnx +--- diskdev_cmds-332.14.orig/Makefile.lnx 2012-02-25 21:05:44.270333659 +0100 ++++ diskdev_cmds-332.14/Makefile.lnx 2012-02-25 21:06:29.687822523 +0100 +@@ -1,5 +1,5 @@ + CC := gcc +-CFLAGS := -g3 -Wall -I$(PWD)/include -DDEBUG_BUILD=0 -D_FILE_OFFSET_BITS=64 -D LINUX=1 -D BSD=1 ++CFLAGS := -g3 -Wall -Wl,--as-needed -I$(PWD)/include -DDEBUG_BUILD=0 -D_FILE_OFFSET_BITS=64 -D LINUX=1 -D BSD=1 + SUBDIRS := newfs_hfs.tproj fsck_hfs.tproj + + all clean: +diff -Nru diskdev_cmds-332.14.orig/newfs_hfs.tproj/Makefile.lnx diskdev_cmds-332.14/newfs_hfs.tproj/Makefile.lnx +--- diskdev_cmds-332.14.orig/newfs_hfs.tproj/Makefile.lnx 2012-02-25 21:05:44.336332916 +0100 ++++ diskdev_cmds-332.14/newfs_hfs.tproj/Makefile.lnx 2012-02-25 21:07:03.048447076 +0100 +@@ -4,7 +4,7 @@ + all: newfs_hfs + + newfs_hfs: $(OFILES) +- ${CC} ${CFLAGS} -o newfs_hfs ${OFILES} -lssl ++ ${CC} ${CFLAGS} -o newfs_hfs ${OFILES} -lssl -lcrypto + + clean: + $(RM) newfs_hfs $(OFILES) diff --git a/hfstools-332.14-fsck_checkfs.patch b/hfstools-332.14-fsck_checkfs.patch new file mode 100644 index 0000000..35d77e3 --- /dev/null +++ b/hfstools-332.14-fsck_checkfs.patch @@ -0,0 +1,36 @@ +diff -Nru diskdev_cmds-332.14.orig//fsck_hfs.tproj/fsck_hfs.c diskdev_cmds-332.14/fsck_hfs.tproj/fsck_hfs.c +--- diskdev_cmds-332.14.orig//fsck_hfs.tproj/fsck_hfs.c 2011-04-07 20:08:14.141449714 +0200 ++++ diskdev_cmds-332.14/fsck_hfs.tproj/fsck_hfs.c 2011-04-07 20:14:46.938645360 +0200 +@@ -109,7 +109,7 @@ + else + progname = *argv; + +- while ((ch = getopt(argc, argv, "dfglm:npqruy")) != EOF) { ++ while ((ch = getopt(argc, argv, "dfglm:napqruy")) != EOF) { + switch (ch) { + case 'd': + debug++; +@@ -146,6 +146,7 @@ + break; + + case 'p': ++ case 'a': + preen++; + break; + +@@ -529,13 +530,14 @@ + static void + usage() + { +- (void) fprintf(stderr, "usage: %s [-dfl m [mode] npqruy] special-device\n", progname); ++ (void) fprintf(stderr, "usage: %s [-dfl m [mode] npaqruy] special-device\n", progname); + (void) fprintf(stderr, " d = output debugging info\n"); + (void) fprintf(stderr, " f = force fsck even if clean (preen only) \n"); + (void) fprintf(stderr, " l = live fsck (lock down and test-only)\n"); + (void) fprintf(stderr, " m arg = octal mode used when creating lost+found directory \n"); + (void) fprintf(stderr, " n = assume a no response \n"); + (void) fprintf(stderr, " p = just fix normal inconsistencies \n"); ++ (void) fprintf(stderr, " a = like -p for compatibility \n"); + (void) fprintf(stderr, " q = quick check returns clean, dirty, or failure \n"); + (void) fprintf(stderr, " r = rebuild catalog btree \n"); + (void) fprintf(stderr, " u = usage \n"); diff --git a/hfstools.spec b/hfstools.spec new file mode 100644 index 0000000..f503a26 --- /dev/null +++ b/hfstools.spec @@ -0,0 +1,69 @@ +Name: hfstools +Version: 332.14 +Release: 5mamba +Summary: Tools to initialize and repair HFS and HFS+ filesystems +Group: System/Tools +Vendor: openmamba +Distribution: openmamba +Packager: Silvan Calarco +URL: http://opensource.apple.com +Source: http://opensource.apple.com/tarballs/diskdev_cmds/diskdev_cmds-%{version}.tar.gz +Patch0: http://www.ecl.udel.edu/%7Emcgee/diskdev_cmds/diskdev_cmds-332.14.patch.bz2 +Patch1: %{name}-332.14-fsck_checkfs.patch +Patch2: %{name}-332.14-fix_link_with_gold.patch +License: BSD +## AUTOBUILDREQ-BEGIN +BuildRequires: glibc-devel +BuildRequires: libopenssl-devel +## AUTOBUILDREQ-END +BuildRequires: libopenssl-devel >= 0.9.7h +BuildRoot: %{_tmppath}/%{name}-%{version}-root + +%description +Tools to initialize and repair HFS and HFS+ filesystems. + +%prep +%setup -q -n diskdev_cmds-%{version} +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 + +%build +%make -f Makefile.lnx + +%install +[ "%{buildroot}" != / ] && rm -rf %{buildroot} +install -D -m 0755 newfs_hfs.tproj/newfs_hfs %{buildroot}/sbin/mkfs.hfsplus +install -D -m 0644 newfs_hfs.tproj/newfs_hfs.8 %{buildroot}%{_mandir}/man8/mkfs.hfsplus.8 +install -D -m 0755 fsck_hfs.tproj/fsck_hfs %{buildroot}/sbin/fsck.hfsplus +install -D -m 0644 fsck_hfs.tproj/fsck_hfs.8 %{buildroot}%{_mandir}/man8/fsck.hfsplus.8 +ln -s mkfs.hfsplus %{buildroot}/sbin/mkfs.hfs +ln -s fsck.hfsplus %{buildroot}/sbin/fsck.hfs + +%clean +[ "%{buildroot}" != / ] && rm -rf %{buildroot} + +%files +%defattr(-,root,root) +/sbin/mkfs.hfsplus +/sbin/fsck.hfsplus +/sbin/mkfs.hfs +/sbin/fsck.hfs +%{_mandir}/man8/mkfs.hfsplus.8.gz +%{_mandir}/man8/fsck.hfsplus.8.gz + +%changelog +* Sat Feb 25 2012 Silvan Calarco 332.14-5mamba +- added a patch to fix build using binutils gold linker + +* Thu Apr 07 2011 Silvan Calarco 332.14-4mamba +- fsck.hfs: added patch to support -a switch for compatibility with linux fsck + +* Thu Nov 11 2010 Silvan Calarco 332.14-3mamba +- rebuilt with openssl 1.0.0 + +* Fri Oct 16 2009 Silvan Calarco 332.14-2mamba +- rebuilt with openssl 0.9.8 + +* Wed May 24 2006 Silvan Calarco 332.14-1qilnx +- package created by autospec