CFStringRef _DAFileSystemCopyName( DAFileSystemRef filesystem, CFURLRef mountpoint ) { struct attr_name_t { uint32_t size; attrreference_t data; char name[MAXNAMLEN + 1]; }; struct attr_name_t attr = { 0 }; struct attrlist attrlist = { 0 }; CFStringRef name = NULL; char * path = NULL; int status = 0; attrlist.bitmapcount = ATTR_BIT_MAP_COUNT; attrlist.volattr = ATTR_VOL_INFO | ATTR_VOL_NAME; path = ___CFURLCopyFileSystemRepresentation( mountpoint ); if ( path == NULL ) goto _DAFileSystemCopyNameErr; status = getattrlist( path, &attrlist, &attr, sizeof( attr ), 0 ); if ( status == -1 ) goto _DAFileSystemCopyNameErr; if ( attr.data.attr_length ) { name = CFStringCreateWithCString( kCFAllocatorDefault, ( ( char * ) &attr.data ) + attr.data.attr_dataoffset, kCFStringEncodingUTF8 ); } _DAFileSystemCopyNameErr: if ( path ) free( path ); return name; }
static int __DAFileSystemSetAdoption( DAFileSystemRef filesystem, CFURLRef mountpoint, Boolean adoption ) { char * path = NULL; int status = 0; path = ___CFURLCopyFileSystemRepresentation( mountpoint ); if ( path == NULL ) { status = EINVAL; goto __DAFileSystemSetAdoptionErr; } status = fork( ); if ( status == -1 ) { status = errno; goto __DAFileSystemSetAdoptionErr; } if ( status == 0 ) { execle( "/usr/sbin/vsdbutil", "/usr/sbin/vsdbutil", adoption ? "-a" : "-d", path, NULL, NULL ); exit( EX_OSERR ); } waitpid( status, &status, 0 ); status = WIFEXITED( status ) ? ( ( char ) WEXITSTATUS( status ) ) : status; if ( status ) { goto __DAFileSystemSetAdoptionErr; } __DAFileSystemSetAdoptionErr: if ( path ) free( path ); return status; }
void DAFileSystemRename( DAFileSystemRef filesystem, CFURLRef mountpoint, CFStringRef name, DAFileSystemCallback callback, void * callbackContext ) { /* * Rename the specified volume. A status of 0 indicates success. */ struct attrlist attributes = { 0 }; __DAFileSystemRenameBuffer * buffer = NULL; char * mountpointPath = NULL; int status = 0; /* * Prepare to set the name. */ attributes.bitmapcount = ATTR_BIT_MAP_COUNT; attributes.commonattr = 0; attributes.dirattr = 0; attributes.fileattr = 0; attributes.forkattr = 0; attributes.volattr = ATTR_VOL_INFO | ATTR_VOL_NAME; buffer = malloc( sizeof( __DAFileSystemRenameBuffer ) ); if ( buffer == NULL ) { status = ENOMEM; goto DAFileSystemRenameErr; } mountpointPath = ___CFURLCopyFileSystemRepresentation( mountpoint ); if ( mountpointPath == NULL ) { status = EINVAL; goto DAFileSystemRenameErr; } /* * Set the name. */ status = CFStringGetCString( name, buffer->name, sizeof( buffer->name ), kCFStringEncodingUTF8 ); if ( status == FALSE ) { status = EINVAL; goto DAFileSystemRenameErr; } buffer->data.attr_dataoffset = sizeof( buffer->data ); buffer->data.attr_length = strlen( buffer->name ) + 1; status = setattrlist( mountpointPath, &attributes, buffer, sizeof( __DAFileSystemRenameBuffer ), 0 ); if ( status == -1 ) { status = errno; goto DAFileSystemRenameErr; } DAFileSystemRenameErr: if ( buffer ) free( buffer ); if ( mountpointPath ) free( mountpointPath ); if ( callback ) { ( callback )( status, callbackContext ); } }
static int __DAFileSystemSetEncoding( DAFileSystemRef filesystem, CFURLRef mountpoint, CFStringEncoding encoding ) { struct statfs fs = { 0 }; char * path = NULL; int status = 0; path = ___CFURLCopyFileSystemRepresentation( mountpoint ); if ( path == NULL ) { status = EINVAL; goto __DAFileSystemSetEncodingErr; } status = ___statfs( path, &fs, MNT_NOWAIT ); if ( status == -1 ) { status = errno; goto __DAFileSystemSetEncodingErr; } status = fork( ); if ( status == -1 ) { status = errno; goto __DAFileSystemSetEncodingErr; } if ( status == 0 ) { char option[16]; snprintf( option, sizeof( option ), "-o-e=%d", ( int ) encoding ); execle( "/sbin/mount", "/sbin/mount", "-t", fs.f_fstypename, "-u", option, ( fs.f_flags & MNT_NODEV ) ? "-onodev" : "-odev", ( fs.f_flags & MNT_NOEXEC ) ? "-onoexec" : "-oexec", ( fs.f_flags & MNT_NOSUID ) ? "-onosuid" : "-osuid", ( fs.f_flags & MNT_RDONLY ) ? "-ordonly" : "-orw", ( fs.f_flags & MNT_IGNORE_OWNERSHIP ) ? "-onoowners" : "-oowners", fs.f_mntfromname, fs.f_mntonname, NULL, NULL ); exit( EX_OSERR ); } waitpid( status, &status, 0 ); status = WIFEXITED( status ) ? ( ( char ) WEXITSTATUS( status ) ) : status; if ( status ) { goto __DAFileSystemSetEncodingErr; } __DAFileSystemSetEncodingErr: if ( path ) free( path ); return status; }
void DACommandExecute( CFURLRef executable, DACommandExecuteOptions options, uid_t userUID, gid_t userGID, DACommandExecuteCallback callback, void * callbackContext, ... ) { /* * Execute a command as the specified user. The argument list maps to argv[1] and up. All * arguments in the argument list shall be of type CFTypeRef, which are converted to string * form via CFCopyDescription(). The argument list must be NULL terminated. */ int argc = 0; char ** argv = NULL; CFTypeRef argument = NULL; va_list arguments; int status = EX_OK; /* * Construct the list of arguments -- compute argc. */ va_start( arguments, callbackContext ); for ( argc = 1; va_arg( arguments, CFTypeRef ); argc++ ) { } va_end( arguments ); /* * Construct the list of arguments -- allocate argv. */ argv = malloc( ( argc + 1 ) * sizeof( char * ) ); if ( argv == NULL ) { status = EX_SOFTWARE; goto DACommandExecuteErr; } memset( argv, 0, ( argc + 1 ) * sizeof( char * ) ); /* * Construct the list of arguments -- fill out argv[0]. */ argv[0] = ___CFURLCopyFileSystemRepresentation( executable ); if ( argv[0] == NULL ) { status = EX_DATAERR; goto DACommandExecuteErr; } /* * Construct the list of arguments -- fill out argv[1] through argv[argc]. */ va_start( arguments, callbackContext ); for ( argc = 1; ( argument = va_arg( arguments, CFTypeRef ) ); argc++ ) { CFStringRef string; string = CFStringCreateWithFormat( kCFAllocatorDefault, 0, CFSTR( "%@" ), argument ); if ( string ) { argv[argc] = ___CFStringCopyCString( string ); CFRelease( string ); } if ( argv[argc] == NULL ) break; } va_end( arguments ); if ( argument ) { status = EX_SOFTWARE; goto DACommandExecuteErr; } /* * Run the executable. */ __DACommandExecute( argv, options, userUID, userGID, callback, callbackContext ); /* * Release our resources. */ DACommandExecuteErr: if ( argv ) { for ( argc = 0; argv[argc]; argc++ ) { free( argv[argc] ); } free( argv ); } /* * Complete the call in case we had a local failure. */ if ( status ) { if ( callback ) { ( callback )( status, NULL, callbackContext ); } } }
void DADiskMountWithArguments( DADiskRef disk, CFURLRef path, DADiskMountOptions options, DADiskMountCallback callback, void * context, CFStringRef arguments[] ) { CFMutableStringRef argument; DAReturn status; argument = NULL; if ( arguments ) { if ( arguments[0] ) { if ( arguments[1] ) { argument = CFStringCreateMutableCopy( kCFAllocatorDefault, 0, arguments[0] ); if ( argument ) { CFIndex index; for ( index = 1; arguments[index]; index++ ) { CFStringAppend( argument, CFSTR( "," ) ); CFStringAppend( argument, arguments[index] ); } } } else { argument = ( void * ) CFRetain( arguments[0] ); } } } if ( path ) { char * _path; _path = ___CFURLCopyFileSystemRepresentation( path ); if ( _path ) { char name[MAXPATHLEN]; if ( realpath( _path, name ) ) { path = CFURLCreateFromFileSystemRepresentation( kCFAllocatorDefault, ( void * ) name, strlen( name ), TRUE ); } else { CFRetain( path ); } free( _path ); } else { CFRetain( path ); } } status = kDAReturnBadArgument; if ( disk ) { status = _DAAuthorize( _DADiskGetSession( disk ), _kDAAuthorizeOptionIsOwner, disk, _kDAAuthorizeRightMount ); if ( status == kDAReturnSuccess ) { status = __DAQueueRequest( _DADiskGetSession( disk ), _kDADiskMount, disk, options, path ? CFURLGetString( path ) : NULL, argument, callback, context ); } } if ( argument ) { CFRelease( argument ); } if ( path ) { CFRelease( path ); } if ( status ) { if ( callback ) { DADissenterRef dissenter; dissenter = DADissenterCreate( kCFAllocatorDefault, status, NULL ); ( callback )( disk, dissenter, context ); CFRelease( dissenter ); } } }