/*
- * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2009 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#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 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);
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 */
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 = 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);
cfstr = CFStringCreateWithPascalString(kCFAllocatorDefault,
mdbPtr->drVN, encoding);
+ if (cfstr == NULL) {
+ result = FSUR_INVAL;
+ goto Return;
+ }
cfOK = _CFStringGetFileSystemRepresentation(cfstr, volnameUTF8, NAME_MAX);
CFRelease(cfstr);
}
if (FSUR_IO_SUCCESS == result) {
- unsigned 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((char *)volnameUTF8));
result = FSUR_RECOGNIZED;
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;
uuid_t uuid;
unsigned char rawUUID[8];
- if ((result = GetVolumeUUID(theDeviceNamePtr, &targetVolumeUUID, FALSE)) != FSUR_IO_SUCCESS) goto Err_Exit;
+ 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);
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_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 (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");
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;
+ }
}
/*
*/
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;
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 */
{
} /* GetNameFromHFSPlusVolumeStartingAt */
-#pragma options align=mac68k
typedef struct {
BTNodeDescriptor node;
BTHeaderRec header;
-} HeaderRec, *HeaderPtr;
-#pragma options align=reset
+} __attribute__((aligned(2), packed)) HeaderRec, *HeaderPtr;
/*
--
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')) {