Created
October 12, 2010 02:24
-
-
Save atr000/621561 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
usbdevs - list mounted USB devices & their volume paths on Mac OS X | |
References: | |
- http://stackoverflow.com/questions/2459414/osx-how-to-get-a-volume-name-or-bsd-name-from-a-iousbdeviceinterface-or-locati | |
- http://superuser.com/questions/103755/whats-up-with-stat-on-mac-os-x-darwin-or-filesystems-without-names | |
- http://stackoverflow.com/questions/1698124/how-to-tell-if-a-given-path-is-mounted-removable-media-in-mac-os-x | |
- http://developer.apple.com/mac/library/samplecode/VolumeToBSDNode/Introduction/Intro.html | |
compile with: | |
gcc -Wall -O3 -x objective-c -fobjc-exceptions -framework Foundation -framework CoreFoundation -framework IOKit -o usbdevs usbdevs.c | |
usage: | |
./usbdevs | |
./usbdevs -z | xargs -0 printf "%s\n" | |
*/ | |
#import <stdio.h> | |
#import <stdlib.h> | |
#import <string.h> | |
#import <sys/param.h> | |
#import <sys/ucred.h> | |
#import <sys/mount.h> | |
#import <Foundation/Foundation.h> | |
#import <CoreFoundation/CoreFoundation.h> | |
#import <IOKit/IOKitLib.h> | |
#import <IOKit/IOMessage.h> | |
#import <IOKit/IOCFPlugIn.h> | |
#import <IOKit/usb/IOUSBLib.h> | |
#import <IOKit/IOBSD.h> | |
int main(int argc, char *argv[]) { | |
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; | |
mach_port_t master_port; | |
kern_return_t k_result = KERN_FAILURE; | |
io_iterator_t iterator = 0; | |
io_service_t usb_device_ref; | |
CFMutableDictionaryRef matching_dictionary = NULL; | |
char devicePath[MAXPATHLEN*2] = {0}; | |
int print0 = 0; | |
size_t pathlen = 0; | |
const char *deviceName = 0; | |
CFStringRef bsdName = NULL; | |
if (argc > 2) return 1; | |
if (argc == 2) | |
{ | |
if ( (strcmp(argv[1], "-z") == 0) ) | |
{ | |
print0 = 1; | |
} | |
else if ( (strcmp(argv[1], "-h") == 0) ) | |
{ | |
fprintf(stdout, "usage: %s [-hz]\n\t-z: null-terminate output (ASCII nul character)\n", argv[0]); | |
return 0; | |
}else{ | |
fprintf(stderr, "usage: %s [-hz]\n", argv[0]); | |
return 1; | |
} | |
} | |
// man 2 getfsstat | |
// getfsstat -- get list of all mounted file systems | |
struct statfs *buf; | |
int flags = MNT_NOWAIT, num_fs, num_stat, i; | |
unsigned bufsz; | |
num_fs = getfsstat(NULL, 0, flags); | |
if (num_fs < 0) { | |
perror("unable to count mounted filesystems: getfsstat"); | |
exit(1); | |
} | |
bufsz = sizeof(*buf) * num_fs; | |
buf = malloc(bufsz); | |
if (!buf) { | |
perror("unable to allocate %u statfs structs"); | |
exit(1); | |
} | |
//fprintf(stderr, "p=%p\n", buf); | |
num_stat = getfsstat(buf, bufsz, flags); | |
if (num_stat < 0) { | |
perror("unable to getfsstat"); | |
exit(1); | |
} | |
if (num_stat != num_fs) { | |
fprintf(stderr, "Hmm, expected %u, got %d.\n", num_fs, num_stat); | |
} | |
// first create a master_port | |
k_result = IOMasterPort(MACH_PORT_NULL, &master_port); | |
if (KERN_SUCCESS != k_result) | |
{ | |
fprintf(stderr, "could not create master port, err = %d\n", k_result); | |
} | |
if ((matching_dictionary = IOServiceMatching(kIOUSBDeviceClassName)) == NULL) | |
{ | |
fprintf(stderr, "could not create matching dictionary, err = %d\n", k_result); | |
} | |
k_result = IOServiceGetMatchingServices(master_port, matching_dictionary, &iterator); | |
if (KERN_SUCCESS != k_result) | |
{ | |
fprintf(stderr, "could not find any matching services, err = %d\n", k_result); | |
} | |
while ((usb_device_ref = IOIteratorNext(iterator))) | |
{ | |
bsdName = (CFStringRef) IORegistryEntrySearchCFProperty (usb_device_ref, | |
kIOServicePlane, | |
CFSTR ( kIOBSDNameKey ), | |
kCFAllocatorDefault, | |
kIORegistryIterateRecursively ); | |
if (!bsdName) continue; | |
deviceName = [[NSString stringWithFormat: @"%@", bsdName] UTF8String]; | |
//printf("%s\n", deviceName); | |
devicePath[0] = '\0'; | |
strcat(devicePath, "/dev/"); | |
strcat(devicePath, deviceName); | |
pathlen = strlen(devicePath); | |
//printf("pathlen: %zu\n", pathlen); | |
//printf("devicePath: %s\n", devicePath); | |
for (i = 0; i < num_stat; i++) { | |
if (strncmp(buf[i].f_mntfromname, devicePath, pathlen) == 0) | |
{ | |
if ( print0 == 0 ) | |
fprintf(stdout, "%s %s\n", buf[i].f_mntfromname, buf[i].f_mntonname); | |
else | |
fprintf(stdout, "%s %s%c", buf[i].f_mntfromname, buf[i].f_mntonname, 0); | |
// null-terminate output (ASCII nul character) | |
} | |
} | |
CFRelease(bsdName); | |
IOObjectRelease(usb_device_ref); // no longer need this reference | |
} // while | |
[pool release]; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment