Skip to content

Instantly share code, notes, and snippets.

@atr000
Created October 12, 2010 02:24
Show Gist options
  • Save atr000/621561 to your computer and use it in GitHub Desktop.
Save atr000/621561 to your computer and use it in GitHub Desktop.
/*
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