/*
- * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2009 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.2 (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 file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
+ * 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@
*/
#include <unistd.h>
#include <syslog.h>
-#include <openssl/sha.h>
+/*
+ * CommonCrypto provides a more stable API than OpenSSL guarantees;
+ * the #define causes it to use the same API for MD5 and SHA1, so the rest of
+ * the code need not change.
+ */
+#define COMMON_DIGEST_FOR_OPENSSL
+#include <CommonCrypto/CommonDigest.h>
-#include <architecture/byte_order.h>
+#include <libkern/OSByteOrder.h>
#include <CoreFoundation/CFString.h>
+#include <System/uuid/uuid.h>
+#include <System/uuid/namespace.h>
+
#define READ_DEFAULT_ENCODING 1
#ifndef FSUC_ADOPT
#define FSUC_UNJNL 'U'
#endif
+#ifndef FSUC_UNJNL_RAW
+#define FSUC_UNJNL_RAW 'N'
+#endif
+
+#ifndef FSUC_JNLINFS_RAW
+#define FSUC_JNLINFS_RAW 'e'
+#endif
+
+#ifndef FSUC_EXTJNL_RAW
+#define FSUC_EXTJNL_RAW 'E'
+#endif
+
#ifndef FSUC_JNLINFO
#define FSUC_JNLINFO 'I'
#endif
struct FinderAttrBuf {
- unsigned long info_length;
- unsigned long finderinfo[8];
+ u_int32_t info_length;
+ u_int32_t finderinfo[8];
};
#define VOLUMEUUIDVALUESIZE 2
typedef union VolumeUUID {
- unsigned long value[VOLUMEUUIDVALUESIZE];
+ u_int32_t value[VOLUMEUUIDVALUESIZE];
struct {
- unsigned long high;
- unsigned long low;
+ u_int32_t high;
+ u_int32_t low;
} v;
} VolumeUUID;
/* ************************************ P R O T O T Y P E S *************************************** */
static void DoDisplayUsage( const char * argv[] );
-static int DoMount( char * theDeviceNamePtr, const char * theMountPointPtr, boolean_t isLocked, boolean_t isSetuid, boolean_t isDev );
-static int DoProbe( char * theDeviceNamePtr );
+static int DoMount( char * theDeviceNamePtr, const char *rawName, const char * theMountPointPtr,
+ boolean_t isLocked, boolean_t isSetuid, boolean_t isDev );
+static int DoProbe( char * rawDeviceNamePtr, char * blockDeviceNamePtr );
static int DoUnmount( const char * theMountPointPtr );
-static int DoGetUUIDKey( const char * theDeviceNamePtr );
+static int DoGetUUIDKey( const char * theDeviceNamePtr, const char *rawName );
static int DoChangeUUIDKey( const char * theDeviceNamePtr );
-static int DoAdopt( const char * theDeviceNamePtr );
-static int DoDisown( const char * theDeviceNamePtr );
+static int DoAdopt( const char * theDeviceNamePtr, const char *rawName);
+static int DoDisown( const char * theDeviceNamePtr, const char *rawName);
extern int DoMakeJournaled( const char * volNamePtr, int journalSize ); // XXXdbg
extern int DoUnJournal( const char * volNamePtr ); // XXXdbg
extern int DoGetJournalInfo( const char * volNamePtr );
+extern int RawDisableJournaling( const char *devname );
+extern int SetJournalInFSState( const char *devname, int journal_in_fs);
static int ParseArgs( int argc, const char * argv[], const char ** actionPtr, const char ** mountPointPtr, boolean_t * isEjectablePtr, boolean_t * isLockedPtr, boolean_t * isSetuidPtr, boolean_t * isDevPtr );
static int GetHFSMountPoint(const char *deviceNamePtr, char **pathPtr);
static int ReadHeaderBlock(int fd, void *bufptr, off_t *startOffset, VolumeUUID **finderInfoUUIDPtr);
-static int GetVolumeUUIDRaw(const char *deviceNamePtr, VolumeUUID *volumeUUIDPtr);
+static int GetVolumeUUIDRaw(const char *deviceNamePtr, const char *rawName, VolumeUUID *volumeUUIDPtr);
static int GetVolumeUUIDAttr(const char *path, VolumeUUID *volumeUUIDPtr);
-static int GetVolumeUUID(const char *deviceNamePtr, VolumeUUID *volumeUUIDPtr, boolean_t generate);
+static int GetVolumeUUID(const char *deviceNamePtr, const char *rawName, VolumeUUID *volumeUUIDPtr, boolean_t generate);
static int SetVolumeUUIDRaw(const char *deviceNamePtr, VolumeUUID *volumeUUIDPtr);
static int SetVolumeUUIDAttr(const char *path, VolumeUUID *volumeUUIDPtr);
static int SetVolumeUUID(const char *deviceNamePtr, VolumeUUID *volumeUUIDPtr);
static int GetEmbeddedHFSPlusVol(HFSMasterDirectoryBlock * hfsMasterDirectoryBlockPtr, off_t * startOffsetPtr);
-static int GetNameFromHFSPlusVolumeStartingAt(int fd, off_t hfsPlusVolumeOffset, char * name_o);
+static int GetNameFromHFSPlusVolumeStartingAt(int fd, off_t hfsPlusVolumeOffset, unsigned char * name_o);
static int GetBTreeNodeInfo(int fd, off_t hfsPlusVolumeOffset, u_int32_t blockSize,
u_int32_t extentCount, const HFSPlusExtentDescriptor *extentList,
u_int32_t *nodeSize, u_int32_t *firstLeafNode);
CF_EXPORT Boolean _CFStringGetFileSystemRepresentation(CFStringRef string, UInt8 *buffer, CFIndex maxBufLen);
+static void uuid_create_md5_from_name(uuid_t result_uuid, const uuid_t namespace, const void *name, int namelen);
+
/*
* The fuction CFStringGetSystemEncoding does not work correctly in
* our context (autodiskmount deamon). We include a local copy here
char buffer[MAXPATHLEN + 1];
int fd;
- strcpy(buffer, passwdp->pw_dir);
- strcat(buffer, __kCFUserEncodingFileName);
+ strlcpy(buffer, passwdp->pw_dir, sizeof(buffer));
+ strlcat(buffer, __kCFUserEncodingFileName, sizeof(buffer));
if ((fd = open(buffer, O_RDONLY, 0)) > 0) {
size_t readSize;
return FSUR_LOADERR;
}
- sprintf(kmodfile, "%sHFS_Mac%s.kext", ENCODING_MODULE_PATH, encodingName);
+ snprintf(kmodfile, sizeof(kmodfile), "%sHFS_Mac%s.kext", ENCODING_MODULE_PATH, encodingName);
if (stat(kmodfile, &sb) == -1)
{
/* We recognized the encoding, but couldn't find the KEXT */
-- "/dev/disk0s2"
*/
- sprintf(rawDeviceName, "/dev/r%s", argv[2]);
- sprintf(blockDeviceName, "/dev/%s", argv[2]);
+ snprintf(rawDeviceName, sizeof(rawDeviceName), "/dev/r%s", argv[2]);
+ snprintf(blockDeviceName, sizeof(blockDeviceName), "/dev/%s", argv[2]);
/* call the appropriate routine to handle the given action argument after becoming root */
switch( * actionPtr ) {
case FSUC_PROBE:
- result = DoProbe(rawDeviceName);
+ result = DoProbe(rawDeviceName, blockDeviceName);
break;
case FSUC_MOUNT:
case FSUC_MOUNT_FORCE:
- result = DoMount(blockDeviceName, mountPointPtr, isLocked, isSetuid, isDev);
+ result = DoMount(blockDeviceName, rawDeviceName, mountPointPtr, isLocked, isSetuid, isDev);
break;
case FSUC_UNMOUNT:
result = DoUnmount( mountPointPtr );
break;
case FSUC_GETUUID:
- result = DoGetUUIDKey( blockDeviceName );
+ result = DoGetUUIDKey( blockDeviceName, rawDeviceName);
break;
case FSUC_SETUUID:
result = DoChangeUUIDKey( blockDeviceName );
break;
case FSUC_ADOPT:
- result = DoAdopt( blockDeviceName );
+ result = DoAdopt( blockDeviceName, rawDeviceName);
break;
case FSUC_DISOWN:
- result = DoDisown( blockDeviceName );
+ result = DoDisown( blockDeviceName, rawDeviceName );
break;
case FSUC_MKJNL:
result = DoUnJournal( argv[2] );
break;
+ case FSUC_UNJNL_RAW:
+ result = RawDisableJournaling( argv[2] );
+ break;
+
+ case FSUC_JNLINFS_RAW:
+ // argv[2] has the device for the external journal. however
+ // we don't need it so we ignore it and just pass argv[3]
+ // which is the hfs volume whose state we're going to change
+ //
+ result = SetJournalInFSState( argv[3], 1 );
+ break;
+
+ case FSUC_EXTJNL_RAW:
+ // see the comment for FSUC_JNLINFS_RAW
+ result = SetJournalInFSState( argv[3], 0 );
+ break;
+
case FSUC_JNLINFO:
result = DoGetJournalInfo( argv[2] );
break;
returns FSUR_IO_SUCCESS everything is cool else one of several other FSUR_xyz error codes.
*********************************************************************** */
static int
-DoMount(char *deviceNamePtr, const char *mountPointPtr, boolean_t isLocked, boolean_t isSetuid, boolean_t isDev)
+DoMount(char *deviceNamePtr, const char *rawName, const char *mountPointPtr,
+ boolean_t isLocked, boolean_t isSetuid, boolean_t isDev)
{
int pid;
char *isLockedstr;
/* get the volume UUID to check if permissions should be used: */
targetVolumeStatus = 0;
- if (((result = GetVolumeUUID(deviceNamePtr, &targetVolumeUUID, FALSE)) != FSUR_IO_SUCCESS) ||
+ if (((result = GetVolumeUUID(deviceNamePtr, rawName, &targetVolumeUUID, FALSE)) != FSUR_IO_SUCCESS) ||
(targetVolumeUUID.v.high ==0) ||
(targetVolumeUUID.v.low == 0)) {
#if TRACE_HFS_UTIL
#endif
#if AUTO_ADOPT_FIXED
if (gIsEjectable == 0) {
- result = DoAdopt( deviceNamePtr );
+ result = DoAdopt( deviceNamePtr, rawName);
#if TRACE_HFS_UTIL
fprintf(stderr, "hfs.util: DoMount: Auto-adopting %s; result = %d.\n", deviceNamePtr, result);
#endif
#endif
#if AUTO_ENTER_FIXED
if (gIsEjectable == 0) {
- result = DoAdopt( deviceNamePtr );
+ result = DoAdopt( deviceNamePtr, rawName );
#if TRACE_HFS_UTIL
fprintf(stderr, "hfs.util: DoMount: Auto-adopting %s; result = %d.\n", deviceNamePtr, result);
#endif
#else
encoding = CFStringGetSystemEncoding();
#endif
- sprintf(encodeopt, "-e=%d", (int)encoding);
+ snprintf(encodeopt, sizeof(encodeopt), "-e=%d", (int)encoding);
#if TRACE_HFS_UTIL
fprintf(stderr, "hfs.util: %s %s -o -x -o %s -o %s -o -u=unknown,-g=unknown,-m=0777 -t %s %s %s ...\n",
gMountCommand, isLockedstr, encodeopt, permissionsOption, gHFS_FS_NAME, deviceNamePtr, mountPointPtr);
} /* DoUnmount */
+/*
+ PrintVolumeNameAttr
+
+ Get the volume name of the volume mounted at "path". Print that volume
+ name to standard out.
+
+ Returns: FSUR_RECOGNIZED, FSUR_IO_FAIL
+*/
+struct VolumeNameBuf {
+ u_int32_t info_length;
+ attrreference_t name_ref;
+ char buffer[1024];
+};
+
+static int
+PrintVolumeNameAttr(const char *path)
+{
+ struct attrlist alist;
+ struct VolumeNameBuf volNameInfo;
+ int result;
+
+ /* Set up the attrlist structure to get the volume's Finder Info */
+ alist.bitmapcount = 5;
+ alist.reserved = 0;
+ alist.commonattr = 0;
+ alist.volattr = ATTR_VOL_INFO | ATTR_VOL_NAME;
+ alist.dirattr = 0;
+ alist.fileattr = 0;
+ alist.forkattr = 0;
+
+ /* Get the Finder Info */
+ result = getattrlist(path, &alist, &volNameInfo, sizeof(volNameInfo), 0);
+ if (result) {
+ result = FSUR_IO_FAIL;
+ goto Err_Exit;
+ }
+
+ /* Print the name to standard out */
+ printf("%.*s", (int) volNameInfo.name_ref.attr_length, ((char *) &volNameInfo.name_ref) + volNameInfo.name_ref.attr_dataoffset);
+ result = FSUR_RECOGNIZED;
+
+Err_Exit:
+ return result;
+}
+
+
/* ******************************************* DoProbe **********************************************
Purpose -
- This routine will open the given raw device and check to make sure there is media that looks
- like an HFS.
+ This routine will open the given device and check to make sure there is media that looks
+ like an HFS. If it is HFS, then print the volume name to standard output.
Input -
- theDeviceNamePtr - pointer to the device name (full path, like /dev/disk0s2).
+ rawDeviceNamePtr - pointer to the full path of the raw device (like /dev/rdisk0s2).
+ blockDeviceNamePtr - pointer to the full path of the non-raw device (like /dev/disk0s2).
Output -
returns FSUR_RECOGNIZED if we can handle the media else one of the FSUR_xyz error codes.
*************************************************************************************************** */
static int
-DoProbe(char *deviceNamePtr)
+DoProbe(char *rawDeviceNamePtr, char *blockDeviceNamePtr)
{
int result = FSUR_UNRECOGNIZED;
int fd = 0;
HFSPlusVolumeHeader * volHdrPtr;
u_char volnameUTF8[NAME_MAX+1];
+ /*
+ * Determine if there is a volume already mounted from this device. If
+ * there is, and it is HFS, then we need to get the volume name via
+ * getattrlist.
+ *
+ * NOTE: We're using bufPtr to hold a pointer to a path.
+ */
+ bufPtr = NULL;
+ result = GetHFSMountPoint(blockDeviceNamePtr, &bufPtr);
+ if (result != FSUR_IO_SUCCESS) {
+ goto Err_Exit;
+ }
+ if (bufPtr != NULL) {
+ /* There is an HFS volume mounted from the device. */
+ result = PrintVolumeNameAttr(bufPtr);
+ goto Err_Exit;
+ }
+
+ /*
+ * If we get here, there is no volume mounted from this device, so
+ * go probe the raw device directly.
+ */
+
bufPtr = (char *)malloc(HFS_BLOCK_SIZE);
if ( ! bufPtr ) {
result = FSUR_UNRECOGNIZED;
mdbPtr = (HFSMasterDirectoryBlock *) bufPtr;
volHdrPtr = (HFSPlusVolumeHeader *) bufPtr;
- fd = open( deviceNamePtr, O_RDONLY, 0 );
+ fd = open( rawDeviceNamePtr, O_RDONLY, 0 );
if( fd <= 0 ) {
result = FSUR_IO_FAIL;
goto Return;
goto Return;
/* get classic HFS volume name (from MDB) */
- if (NXSwapBigShortToHost(mdbPtr->drSigWord) == kHFSSigWord &&
- NXSwapBigShortToHost(mdbPtr->drEmbedSigWord) != kHFSPlusSigWord) {
+ if (OSSwapBigToHostInt16(mdbPtr->drSigWord) == kHFSSigWord &&
+ OSSwapBigToHostInt16(mdbPtr->drEmbedSigWord) != kHFSPlusSigWord) {
Boolean cfOK;
CFStringRef cfstr;
CFStringEncoding encoding;
/* Some poorly mastered HFS CDs have an empty MDB name field! */
if (mdbPtr->drVN[0] == '\0') {
- strcpy(&mdbPtr->drVN[1], gHFS_FS_NAME_NAME);
+ strcpy((char *)&mdbPtr->drVN[1], gHFS_FS_NAME_NAME);
mdbPtr->drVN[0] = strlen(gHFS_FS_NAME_NAME);
}
/* Check for an encoding hint in the Finder Info (field 4). */
- encoding = GET_HFS_TEXT_ENCODING(NXSwapBigLongToHost(mdbPtr->drFndrInfo[4]));
+ encoding = GET_HFS_TEXT_ENCODING(OSSwapBigToHostInt32(mdbPtr->drFndrInfo[4]));
if (encoding == kCFStringEncodingInvalidId) {
/* Next try the encoding bias in the kernel. */
encoding = GetEncodingBias();
cfstr = CFStringCreateWithPascalString(kCFAllocatorDefault,
mdbPtr->drVN, encoding);
+ if (cfstr == NULL) {
+ result = FSUR_INVAL;
+ goto Return;
+ }
cfOK = _CFStringGetFileSystemRepresentation(cfstr, volnameUTF8, NAME_MAX);
CFRelease(cfstr);
}
/* Preload the encoding converter so mount_hfs can run as an ordinary user. */
- if (encoding != kCFStringEncodingMacRoman)
- result = load_encoding(encoding);
+ if (encoding != kCFStringEncodingMacRoman) {
+ if (load_encoding(encoding) != FSUR_IO_SUCCESS) {
+ encoding = kCFStringEncodingMacRoman;
+ cfstr = CFStringCreateWithPascalString(kCFAllocatorDefault, mdbPtr->drVN, encoding);
+ _CFStringGetFileSystemRepresentation(cfstr, volnameUTF8, NAME_MAX);
+ CFRelease(cfstr);
+ }
+ }
/* get HFS Plus volume name (from Catalog) */
- } else if ((NXSwapBigShortToHost(volHdrPtr->signature) == kHFSPlusSigWord) ||
- (NXSwapBigShortToHost(volHdrPtr->signature) == kHFSXSigWord) ||
- (NXSwapBigShortToHost(mdbPtr->drSigWord) == kHFSSigWord &&
- NXSwapBigShortToHost(mdbPtr->drEmbedSigWord) == kHFSPlusSigWord)) {
+ } else if ((OSSwapBigToHostInt16(volHdrPtr->signature) == kHFSPlusSigWord) ||
+ (OSSwapBigToHostInt16(volHdrPtr->signature) == kHFSXSigWord) ||
+ (OSSwapBigToHostInt16(mdbPtr->drSigWord) == kHFSSigWord &&
+ OSSwapBigToHostInt16(mdbPtr->drEmbedSigWord) == kHFSPlusSigWord)) {
off_t startOffset;
- if (NXSwapBigShortToHost(volHdrPtr->signature) == kHFSSigWord) {
+ if (OSSwapBigToHostInt16(volHdrPtr->signature) == kHFSSigWord) {
/* embedded volume, first find offset */
result = GetEmbeddedHFSPlusVol(mdbPtr, &startOffset);
if ( result != FSUR_IO_SUCCESS )
}
if (FSUR_IO_SUCCESS == result) {
- char *s;
-
- /* Change slashes to colons in the volume name */
- for (s=volnameUTF8; *s; ++s) {
- if (*s == '/')
- *s = ':';
- }
-
/* Print the volume name to standard output */
- write(1, volnameUTF8, strlen(volnameUTF8));
+ write(1, volnameUTF8, strlen((char *)volnameUTF8));
result = FSUR_RECOGNIZED;
}
if (fd > 0)
close(fd);
-
+Err_Exit:
return result;
} /* DoProbe */
+/*
+ * Create a version 3 UUID from a unique "name" in the given "name space".
+ * Version 3 UUID are derived using "name" via MD5 checksum.
+ *
+ * Parameters:
+ * result_uuid - resulting UUID.
+ * namespace - namespace in which given name exists and UUID should be created.
+ * name - unique string used to create version 3 UUID.
+ * namelen - length of the name string.
+ */
+static void
+uuid_create_md5_from_name(uuid_t result_uuid, const uuid_t namespace, const void *name, int namelen)
+{
+ MD5_CTX c;
+
+ MD5_Init(&c);
+ MD5_Update(&c, namespace, sizeof(uuid_t));
+ MD5_Update(&c, name, namelen);
+ MD5_Final(result_uuid, &c);
+
+ result_uuid[6] = (result_uuid[6] & 0x0F) | 0x30;
+ result_uuid[8] = (result_uuid[8] & 0x3F) | 0x80;
+}
/* **************************************** DoGetUUIDKey *******************************************
Purpose -
- This routine will open the given block device and return the volume UUID in text form written to stdout.
+ This routine will open the given block device and return the 128-bit volume UUID in text form written to stdout.
Input -
theDeviceNamePtr - pointer to the device name (full path, like /dev/disk0s2).
Output -
returns FSUR_IO_SUCCESS or else one of the FSUR_xyz error codes.
*************************************************************************************************** */
static int
-DoGetUUIDKey( const char * theDeviceNamePtr ) {
+DoGetUUIDKey( const char * theDeviceNamePtr, const char *rawName) {
int result;
VolumeUUID targetVolumeUUID;
- VolumeUUIDString UUIDString;
- char uuidLine[VOLUMEUUIDLENGTH+2];
-
- if ((result = GetVolumeUUID(theDeviceNamePtr, &targetVolumeUUID, FALSE)) != FSUR_IO_SUCCESS) goto Err_Exit;
-
- ConvertVolumeUUIDToString( &targetVolumeUUID, UUIDString);
- strncpy(uuidLine, UUIDString, VOLUMEUUIDLENGTH+1);
+ uuid_t uuid;
+ char uuidLine[40];
+
+ unsigned char rawUUID[8];
+
+ if ((result = GetVolumeUUID(theDeviceNamePtr, rawName, &targetVolumeUUID, FALSE)) != FSUR_IO_SUCCESS) goto Err_Exit;
+
+ ((uint32_t *)rawUUID)[0] = OSSwapHostToBigInt32(targetVolumeUUID.v.high);
+ ((uint32_t *)rawUUID)[1] = OSSwapHostToBigInt32(targetVolumeUUID.v.low);
+
+ uuid_create_md5_from_name(uuid, kFSUUIDNamespaceSHA1, rawUUID, sizeof(rawUUID));
+ uuid_unparse(uuid, uuidLine);
write(1, uuidLine, strlen(uuidLine));
result = FSUR_IO_SUCCESS;
returns FSUR_IO_SUCCESS or else one of the FSUR_xyz error codes.
*************************************************************************************************** */
static int
-DoAdopt( const char * theDeviceNamePtr ) {
+DoAdopt( const char * theDeviceNamePtr, const char *rawName) {
int result, closeresult;
VolumeUUID targetVolumeUUID;
VolumeStatusDBHandle vsdbhandle = NULL;
unsigned long targetVolumeStatus;
- if ((result = GetVolumeUUID(theDeviceNamePtr, &targetVolumeUUID, TRUE)) != FSUR_IO_SUCCESS) goto Err_Return;
+ if ((result = GetVolumeUUID(theDeviceNamePtr, rawName, &targetVolumeUUID, TRUE)) != FSUR_IO_SUCCESS) goto Err_Return;
if ((result = OpenVolumeStatusDB(&vsdbhandle)) != 0) goto Err_Exit;
if ((result = GetVolumeStatusDBEntry(vsdbhandle, &targetVolumeUUID, &targetVolumeStatus)) != 0) {
returns FSUR_IO_SUCCESS or else one of the FSUR_xyz error codes.
*************************************************************************************************** */
static int
-DoDisown( const char * theDeviceNamePtr ) {
+DoDisown( const char * theDeviceNamePtr, const char *rawName) {
int result, closeresult;
VolumeUUID targetVolumeUUID;
VolumeStatusDBHandle vsdbhandle = NULL;
unsigned long targetVolumeStatus;
- if ((result = GetVolumeUUID(theDeviceNamePtr, &targetVolumeUUID, TRUE)) != FSUR_IO_SUCCESS) goto Err_Return;
+ if ((result = GetVolumeUUID(theDeviceNamePtr, rawName, &targetVolumeUUID, TRUE)) != FSUR_IO_SUCCESS) goto Err_Return;
if ((result = OpenVolumeStatusDB(&vsdbhandle)) != 0) goto Err_Exit;
if ((result = GetVolumeStatusDBEntry(vsdbhandle, &targetVolumeUUID, &targetVolumeStatus)) != 0) {
doLengthCheck = 0;
break;
+ case FSUC_UNJNL_RAW:
+ index = 0;
+ doLengthCheck = 0;
+ break;
+
+ case FSUC_JNLINFS_RAW:
+ index = 0;
+ doLengthCheck = 0;
+ break;
+
+ case FSUC_EXTJNL_RAW:
+ index = 0;
+ doLengthCheck = 0;
+ break;
+
case FSUC_JNLINFO:
index = 0;
doLengthCheck = 0;
printf(" -%c (Adopt permissions)\n", FSUC_ADOPT);
printf(" -%c (Make a file system journaled)\n", FSUC_MKJNL);
printf(" -%c (Turn off journaling on a file system)\n", FSUC_UNJNL);
+ printf(" -%c (Turn off journaling on a raw device)\n", FSUC_UNJNL_RAW);
+ printf(" -%c (Disable use of an external journal on a raw device)\n", FSUC_JNLINFS_RAW);
+ printf(" -%c (Enable the use of an external journal on a raw device)\n", FSUC_EXTJNL_RAW);
printf(" -%c (Get size & location of journaling on a file system)\n", FSUC_JNLINFO);
printf("device_arg:\n");
printf(" device we are acting upon (for example, 'disk0s2')\n");
* If this is a wrapped HFS Plus volume, read the Volume Header from
* sector 2 of the embedded volume.
*/
- if (NXSwapBigShortToHost(mdbPtr->drSigWord) == kHFSSigWord &&
- NXSwapBigShortToHost(mdbPtr->drEmbedSigWord) == kHFSPlusSigWord) {
+ if (OSSwapBigToHostInt16(mdbPtr->drSigWord) == kHFSSigWord &&
+ OSSwapBigToHostInt16(mdbPtr->drEmbedSigWord) == kHFSPlusSigWord) {
result = GetEmbeddedHFSPlusVol(mdbPtr, startOffset);
if (result != FSUR_IO_SUCCESS)
goto Err_Exit;
* volumes (including wrapped HFS Plus). Verify the signature and grab the
* UUID from the Finder Info.
*/
- if (NXSwapBigShortToHost(mdbPtr->drSigWord) == kHFSSigWord) {
+ if (OSSwapBigToHostInt16(mdbPtr->drSigWord) == kHFSSigWord) {
*finderInfoUUIDPtr = (VolumeUUID *)(&mdbPtr->drFndrInfo[6]);
- } else if (NXSwapBigShortToHost(volHdrPtr->signature) == kHFSPlusSigWord ||
- NXSwapBigShortToHost(volHdrPtr->signature) == kHFSXSigWord) {
+ } else if (OSSwapBigToHostInt16(volHdrPtr->signature) == kHFSPlusSigWord ||
+ OSSwapBigToHostInt16(volHdrPtr->signature) == kHFSXSigWord) {
*finderInfoUUIDPtr = (VolumeUUID *)&volHdrPtr->finderInfo[24];
} else {
result = FSUR_UNRECOGNIZED;
Returns: FSUR_IO_SUCCESS, FSUR_IO_FAIL, FSUR_UNRECOGNIZED
*/
static int
-GetVolumeUUIDRaw(const char *deviceNamePtr, VolumeUUID *volumeUUIDPtr)
+GetVolumeUUIDRaw(const char *deviceNamePtr, const char *rawName, VolumeUUID *volumeUUIDPtr)
{
int fd = 0;
char * bufPtr;
off_t startOffset;
VolumeUUID *finderInfoUUIDPtr;
int result;
+ int error;
bufPtr = (char *)malloc(HFS_BLOCK_SIZE);
if ( ! bufPtr ) {
fd = open( deviceNamePtr, O_RDONLY, 0);
if (fd <= 0) {
+ error = errno;
#if TRACE_HFS_UTIL
- fprintf(stderr, "hfs.util: GetVolumeUUIDRaw: device open failed (errno = %d).\n", errno);
+ fprintf(stderr, "hfs.util: GetVolumeUUIDRaw: device (%s) open failed (errno = %d).\n", deviceNamePtr, errno);
#endif
- result = FSUR_IO_FAIL;
- goto Err_Exit;
+ if (error == EBUSY) {
+ /* If it was busy, then retry, this time using the raw device */
+ fd = open (rawName, O_RDONLY, 0);
+ if (fd <= 0) {
+#if TRACE_HFS_UTIL
+ fprintf(stderr, "hfs.util: GetVolumeUUIDRaw: device (%s) open failed (errno = %d).\n", rawName, errno);
+#endif
+ result = FSUR_IO_FAIL;
+ goto Err_Exit;
+ }
+ }
+ else {
+ result = FSUR_IO_FAIL;
+ goto Err_Exit;
+ }
}
/*
/*
* Copy the volume UUID out of the Finder Info
*/
- volumeUUIDPtr->v.high = NXSwapBigLongToHost(finderInfoUUIDPtr->v.high);
- volumeUUIDPtr->v.low = NXSwapBigLongToHost(finderInfoUUIDPtr->v.low);
+ volumeUUIDPtr->v.high = OSSwapBigToHostInt32(finderInfoUUIDPtr->v.high);
+ volumeUUIDPtr->v.low = OSSwapBigToHostInt32(finderInfoUUIDPtr->v.low);
Err_Exit:
if (fd > 0) close(fd);
/*
* Update the UUID in the Finder Info
*/
- finderInfoUUIDPtr->v.high = NXSwapHostLongToBig(volumeUUIDPtr->v.high);
- finderInfoUUIDPtr->v.low = NXSwapHostLongToBig(volumeUUIDPtr->v.low);
+ finderInfoUUIDPtr->v.high = OSSwapHostToBigInt32(volumeUUIDPtr->v.high);
+ finderInfoUUIDPtr->v.low = OSSwapHostToBigInt32(volumeUUIDPtr->v.low);
/*
* Write the modified MDB or VHB back to disk
/* Copy the UUID from the Finder Into to caller's buffer */
finderInfoUUIDPtr = (VolumeUUID *)(&volFinderInfo.finderinfo[6]);
- volumeUUIDPtr->v.high = NXSwapBigLongToHost(finderInfoUUIDPtr->v.high);
- volumeUUIDPtr->v.low = NXSwapBigLongToHost(finderInfoUUIDPtr->v.low);
+ volumeUUIDPtr->v.high = OSSwapBigToHostInt32(finderInfoUUIDPtr->v.high);
+ volumeUUIDPtr->v.low = OSSwapBigToHostInt32(finderInfoUUIDPtr->v.low);
result = FSUR_IO_SUCCESS;
Err_Exit:
/* Update the UUID in the Finder Info */
finderInfoUUIDPtr = (VolumeUUID *)(&volFinderInfo.finderinfo[6]);
- finderInfoUUIDPtr->v.high = NXSwapHostLongToBig(volumeUUIDPtr->v.high);
- finderInfoUUIDPtr->v.low = NXSwapHostLongToBig(volumeUUIDPtr->v.low);
+ finderInfoUUIDPtr->v.high = OSSwapHostToBigInt32(volumeUUIDPtr->v.high);
+ finderInfoUUIDPtr->v.low = OSSwapHostToBigInt32(volumeUUIDPtr->v.low);
/* Write the Finder Info back to the volume */
result = setattrlist(path, &alist, &volFinderInfo.finderinfo, sizeof(volFinderInfo.finderinfo), 0);
*/
static int
-GetVolumeUUID(const char *deviceNamePtr, VolumeUUID *volumeUUIDPtr, boolean_t generate)
+GetVolumeUUID(const char *deviceNamePtr, const char *rawName, VolumeUUID *volumeUUIDPtr, boolean_t generate)
{
int result;
char *path = NULL;
if (path)
result = GetVolumeUUIDAttr(path, volumeUUIDPtr);
else
- result = GetVolumeUUIDRaw(deviceNamePtr, volumeUUIDPtr);
+ result = GetVolumeUUIDRaw(deviceNamePtr, rawName, volumeUUIDPtr);
if (result != FSUR_IO_SUCCESS)
goto Err_Exit;
int result = FSUR_IO_SUCCESS;
u_int32_t allocationBlockSize, firstAllocationBlock, startBlock, blockCount;
- if (NXSwapBigShortToHost(hfsMasterDirectoryBlockPtr->drSigWord) != kHFSSigWord) {
+ if (OSSwapBigToHostInt16(hfsMasterDirectoryBlockPtr->drSigWord) != kHFSSigWord) {
result = FSUR_UNRECOGNIZED;
goto Return;
}
- allocationBlockSize = NXSwapBigLongToHost(hfsMasterDirectoryBlockPtr->drAlBlkSiz);
- firstAllocationBlock = NXSwapBigShortToHost(hfsMasterDirectoryBlockPtr->drAlBlSt);
+ allocationBlockSize = OSSwapBigToHostInt32(hfsMasterDirectoryBlockPtr->drAlBlkSiz);
+ firstAllocationBlock = OSSwapBigToHostInt16(hfsMasterDirectoryBlockPtr->drAlBlSt);
- if (NXSwapBigShortToHost(hfsMasterDirectoryBlockPtr->drEmbedSigWord) != kHFSPlusSigWord) {
+ if (OSSwapBigToHostInt16(hfsMasterDirectoryBlockPtr->drEmbedSigWord) != kHFSPlusSigWord) {
result = FSUR_UNRECOGNIZED;
goto Return;
}
- startBlock = NXSwapBigShortToHost(hfsMasterDirectoryBlockPtr->drEmbedExtent.startBlock);
- blockCount = NXSwapBigShortToHost(hfsMasterDirectoryBlockPtr->drEmbedExtent.blockCount);
+ startBlock = OSSwapBigToHostInt16(hfsMasterDirectoryBlockPtr->drEmbedExtent.startBlock);
+ blockCount = OSSwapBigToHostInt16(hfsMasterDirectoryBlockPtr->drEmbedExtent.blockCount);
if ( startOffsetPtr )
*startOffsetPtr = ((u_int64_t)startBlock * (u_int64_t)allocationBlockSize) +
*/
static int
-GetNameFromHFSPlusVolumeStartingAt(int fd, off_t hfsPlusVolumeOffset, char * name_o)
+GetNameFromHFSPlusVolumeStartingAt(int fd, off_t hfsPlusVolumeOffset, unsigned char * name_o)
{
int result = FSUR_IO_SUCCESS;
u_int32_t blockSize;
/* Verify that it is an HFS+ volume. */
- if (NXSwapBigShortToHost(volHdrPtr->signature) != kHFSPlusSigWord &&
- NXSwapBigShortToHost(volHdrPtr->signature) != kHFSXSigWord) {
+ if (OSSwapBigToHostInt16(volHdrPtr->signature) != kHFSPlusSigWord &&
+ OSSwapBigToHostInt16(volHdrPtr->signature) != kHFSXSigWord) {
result = FSUR_IO_FAIL;
#if TRACE_HFS_UTIL
fprintf(stderr, "hfs.util: GetNameFromHFSPlusVolumeStartingAt: volHdrPtr->signature != kHFSPlusSigWord\n");
goto Return;
}
- blockSize = NXSwapBigLongToHost(volHdrPtr->blockSize);
+ blockSize = OSSwapBigToHostInt32(volHdrPtr->blockSize);
catalogExtents = (HFSPlusExtentDescriptor *) malloc(sizeof(HFSPlusExtentRecord));
if ( ! catalogExtents ) {
result = FSUR_IO_FAIL;
catalogExtCount = kHFSPlusExtentDensity;
/* if there are overflow catalog extents, then go get them */
- if (NXSwapBigLongToHost(catalogExtents[7].blockCount) != 0) {
+ if (OSSwapBigToHostInt32(catalogExtents[7].blockCount) != 0) {
result = GetCatalogOverflowExtents(fd, hfsPlusVolumeOffset, volHdrPtr, &catalogExtents, &catalogExtCount);
if (result != FSUR_IO_SUCCESS)
goto Return;
HFSPlusCatalogKey * k;
CFStringRef cfstr;
- if ( bTreeNodeDescriptorPtr->numRecords < 1) {
+ if ( OSSwapBigToHostInt16(bTreeNodeDescriptorPtr->numRecords) < 1) {
result = FSUR_IO_FAIL;
#if TRACE_HFS_UTIL
fprintf(stderr, "hfs.util: ERROR: bTreeNodeDescriptorPtr->numRecords < 1\n");
// Get a pointer to the first record.
- p = bufPtr + NXSwapBigShortToHost(*v); // pointer arithmetic in bytes
+ p = bufPtr + OSSwapBigToHostInt16(*v); // pointer arithmetic in bytes
k = (HFSPlusCatalogKey *)p;
// There should be only one record whose parent is the root parent. It should be the first record.
- if (NXSwapBigLongToHost(k->parentID) != kHFSRootParentID) {
+ if (OSSwapBigToHostInt32(k->parentID) != kHFSRootParentID) {
result = FSUR_IO_FAIL;
#if TRACE_HFS_UTIL
fprintf(stderr, "hfs.util: ERROR: k->parentID != kHFSRootParentID\n");
goto Return;
}
+ if ((OSSwapBigToHostInt16(k->nodeName.length) >
+ (sizeof(k->nodeName.unicode) / sizeof(k->nodeName.unicode[0]))) ||
+ OSSwapBigToHostInt16(k->nodeName.length) > 255) {
+ result = FSUR_IO_FAIL;
+#if TRACE_HFS_UTIL
+ fprintf(stderr, "hfs.util: ERROR: k->nodeName.length is a bad size (%d)\n", OSSwapBigToHostInt16(k->nodeName.length));
+#endif
+ goto Return;
+ }
+
/* Extract the name of the root directory */
{
result = FSUR_IO_FAIL;
goto Return;
}
- swapped->length = NXSwapBigShortToHost(k->nodeName.length);
+ swapped->length = OSSwapBigToHostInt16(k->nodeName.length);
for (i=0; i<swapped->length; i++) {
- swapped->unicode[i] = NXSwapBigShortToHost(k->nodeName.unicode[i]);
+ swapped->unicode[i] = OSSwapBigToHostInt16(k->nodeName.unicode[i]);
}
swapped->unicode[i] = 0;
cfstr = CFStringCreateWithCharacters(kCFAllocatorDefault, swapped->unicode, swapped->length);
- (void) CFStringGetCString(cfstr, name_o, NAME_MAX, kCFStringEncodingUTF8);
+ (void) CFStringGetCString(cfstr, (char *)name_o, NAME_MAX, kCFStringEncodingUTF8);
CFRelease(cfstr);
free(swapped);
}
} /* GetNameFromHFSPlusVolumeStartingAt */
-#pragma options align=mac68k
typedef struct {
BTNodeDescriptor node;
BTHeaderRec header;
-} HeaderRec, *HeaderPtr;
-#pragma options align=reset
+} __attribute__((aligned(2), packed)) HeaderRec, *HeaderPtr;
/*
--
goto free;
}
- *nodeSize = NXSwapBigShortToHost(bTreeHeaderPtr->header.nodeSize);
+ *nodeSize = OSSwapBigToHostInt16(bTreeHeaderPtr->header.nodeSize);
- if (NXSwapBigLongToHost(bTreeHeaderPtr->header.leafRecords) == 0)
+ if (OSSwapBigToHostInt32(bTreeHeaderPtr->header.leafRecords) == 0)
*firstLeafNode = 0;
else
- *firstLeafNode = NXSwapBigLongToHost(bTreeHeaderPtr->header.firstLeafNode);
+ *firstLeafNode = OSSwapBigToHostInt32(bTreeHeaderPtr->header.firstLeafNode);
free:;
free((char*) bTreeHeaderPtr);
u_int32_t *catalogExtCount)
{
off_t offset;
+ u_int32_t numRecords;
u_int32_t nodeSize;
u_int32_t leafNode;
+ u_int32_t blockSize;
BTNodeDescriptor * bTreeNodeDescriptorPtr;
HFSPlusExtentDescriptor * extents;
size_t listsize;
int i;
int result;
+ blockSize = OSSwapBigToHostInt32(volHdrPtr->blockSize);
listsize = *catalogExtCount * sizeof(HFSPlusExtentDescriptor);
extents = *catalogExtents;
- offset = (off_t)volHdrPtr->extentsFile.extents[0].startBlock *
- (off_t)volHdrPtr->blockSize;
+ offset = (off_t)OSSwapBigToHostInt32(volHdrPtr->extentsFile.extents[0].startBlock) *
+ (off_t)blockSize;
/* Read the header node of the extents B-Tree */
- result = GetBTreeNodeInfo(fd, hfsPlusVolumeOffset, volHdrPtr->blockSize,
+ result = GetBTreeNodeInfo(fd, hfsPlusVolumeOffset, blockSize,
kHFSPlusExtentDensity, volHdrPtr->extentsFile.extents,
&nodeSize, &leafNode);
if (result != FSUR_IO_SUCCESS || leafNode == 0)
again:
result = ReadFile(fd, bufPtr, offset, nodeSize,
- hfsPlusVolumeOffset, volHdrPtr->blockSize,
+ hfsPlusVolumeOffset, blockSize,
kHFSPlusExtentDensity, volHdrPtr->extentsFile.extents);
if ( result == FSUR_IO_FAIL ) {
#if TRACE_HFS_UTIL
goto Return;
}
- for (i = 1; i <= bTreeNodeDescriptorPtr->numRecords; ++i) {
+ numRecords = OSSwapBigToHostInt16(bTreeNodeDescriptorPtr->numRecords);
+ for (i = 1; i <= numRecords; ++i) {
u_int16_t * v;
char * p;
HFSPlusExtentKey * k;
/* Get a pointer to the record */
- p = bufPtr + NXSwapBigShortToHost(*v); /* pointer arithmetic in bytes */
+ p = bufPtr + OSSwapBigToHostInt16(*v); /* pointer arithmetic in bytes */
k = (HFSPlusExtentKey *)p;
- if (NXSwapBigLongToHost(k->fileID) != kHFSCatalogFileID)
+ if (OSSwapBigToHostInt32(k->fileID) != kHFSCatalogFileID)
goto Return;
/* grow list and copy additional extents */
listsize += sizeof(HFSPlusExtentRecord);
extents = (HFSPlusExtentDescriptor *) realloc(extents, listsize);
- bcopy(p + k->keyLength + sizeof(u_int16_t),
+ bcopy(p + OSSwapBigToHostInt16(k->keyLength) + sizeof(u_int16_t),
&extents[*catalogExtCount], sizeof(HFSPlusExtentRecord));
*catalogExtCount += kHFSPlusExtentDensity;
*catalogExtents = extents;
}
- if ((leafNode = bTreeNodeDescriptorPtr->fLink) != 0) {
+ if ((leafNode = OSSwapBigToHostInt32(bTreeNodeDescriptorPtr->fLink)) != 0) {
offset = (off_t) leafNode * (off_t) nodeSize;
/* Find the extent containing logicalBlock */
for (extent = 0; extent < extentCount; ++extent)
{
- blockCount = NXSwapBigLongToHost(extentList[extent].blockCount);
+ blockCount = OSSwapBigToHostInt32(extentList[extent].blockCount);
if (blockCount == 0)
return FSUR_IO_FAIL; /* Tried to map past physical end of file */
*/
/* Compute the physical starting position */
- temp = NXSwapBigLongToHost(extentList[extent].startBlock) + logicalBlock; /* First physical block */
+ temp = OSSwapBigToHostInt32(extentList[extent].startBlock) + logicalBlock; /* First physical block */
temp *= blockSize; /* Byte offset of first physical block */
*physicalOffset = temp + offset;
int sysdata;
char sysctlstring[128];
size_t datalen;
- struct loadavg sysloadavg;
+ double sysloadavg[3];
struct vmtotal sysvmtotal;
do {
SHA1_Update(&context, sysctlstring, datalen);
/* The system's load average: */
- mib[0] = CTL_VM;
- mib[1] = VM_LOADAVG;
datalen = sizeof(sysloadavg);
- sysctl(mib, 2, &sysloadavg, &datalen, NULL, 0);
+ getloadavg(sysloadavg, 3);
SHA1_Update(&context, &sysloadavg, datalen);
/* The system's VM statistics: */
void ConvertVolumeUUIDStringToUUID(const char *UUIDString, VolumeUUID *volumeID) {
int i;
char c;
- unsigned long nextdigit;
- unsigned long high = 0;
- unsigned long low = 0;
- unsigned long carry;
+ u_int32_t nextdigit;
+ u_int32_t high = 0;
+ u_int32_t low = 0;
+ u_int32_t carry;
for (i = 0; (i < VOLUMEUUIDLENGTH) && ((c = UUIDString[i]) != (char)0) ; ++i) {
if ((c >= '0') && (c <= '9')) {