#define _DEFAULT_SOURCE #include "disks.h" #include #include #include #include #include #include #if defined(__linux__) #include #endif #if defined(__APPLE__) && defined(__MACH__) # define __MacOS__ #endif #if defined (__MacOS__) || defined(__FreeBSD__) || defined(__DragonFly__) # include # include # include # include # include #endif #if defined(__OpenBSD__) || defined(__NetBSD__) # include # include # include #endif char * disk_mount_point_get(const char *path) { #if defined(__MacOS__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) struct statfs *mounts; int i, count; count = getmntinfo(&mounts, MNT_WAIT); for (i = 0; i < count; i++) { if (!strcmp(path, mounts[i].f_mntfromname)) { return strdup(mounts[i].f_mntonname); } } #elif defined(__linux__) char buf[4096]; char *start, *end; FILE *f = fopen("/proc/mounts", "r"); if (!f) return NULL; while ((fgets(buf, sizeof(buf), f)) != NULL) { start = &buf[0]; end = strchr(start, ' '); if (!end) continue; *end = '\0'; if (!strcmp(path, start)) { start = end + 1; if (!start) continue; end = strchr(start, ' '); if (!end) continue; *end = '\0'; fclose(f); return strdup(start); } } fclose(f); #endif return NULL; } static int _cmp_cb(const void *p1, const void *p2) { const char *s1, *s2; s1 = p1; s2 = p2; return strcmp(s1, s2); } Eina_List * disks_get(void) { Eina_List *list = NULL; #if defined(__FreeBSD__) || defined(__DragonFly__) struct statfs *mounts; char *drives, *dev, *end; int count; size_t len; if ((sysctlbyname("kern.disks", NULL, &len, NULL, 0)) == -1) return NULL; drives = malloc(len + 1); if ((sysctlbyname("kern.disks", drives, &len, NULL, 0)) == -1) { free(drives); return NULL; } dev = drives; while (dev) { end = strchr(dev, ' '); if (!end) break; *end = '\0'; list = eina_list_append(list, strdup(eina_slstr_printf("/dev/%s", dev))); dev = end + 1; } free(drives); count = getmntinfo(&mounts, MNT_WAIT); for (int i = 0; i < count; i++) { list = eina_list_append(list, strdup(mounts[i].f_mntfromname)); } #elif defined(__OpenBSD__) || defined(__NetBSD__) static const int mib[] = { CTL_HW, HW_DISKNAMES }; static const unsigned int miblen = 2; struct statfs *mounts; char *drives, *dev, *end; size_t len; int count; if ((sysctl(mib, miblen, NULL, &len, NULL, 0)) == -1) return NULL; drives = malloc(len + 1); if ((sysctl(mib, miblen, drives, &len, NULL, 0)) == -1) { free(drives); return NULL; } dev = drives; while (dev) { end = strchr(dev, ':'); if (!end) break; *end = '\0'; if (dev[0] == ',') dev++; list = eina_list_append(list, strdup(eina_slstr_printf("/dev/%s", dev))); end++; dev = strchr(end, ','); if (!dev) break; } free(drives); count = getmntinfo(&mounts, MNT_WAIT); for (int i = 0; i < count; i++) { list = eina_list_append(list, strdup(mounts[i].f_mntfromname)); } #elif defined(__MacOS__) Eina_List *devs; char *name; devs = ecore_file_ls("/dev"); EINA_LIST_FREE(devs, name) { if (!strncmp(name, "disk", 4)) { list = eina_list_append(list, strdup(eina_slstr_printf("/dev/%s", name))); } free(name); } #elif defined(__linux__) Eina_List *devs; char *name; const char *disk_search = "/dev/disk/by-uuid"; devs = ecore_file_ls(disk_search); if (!devs) { disk_search = "/dev/disk/by-path"; devs = ecore_file_ls(disk_search); } EINA_LIST_FREE(devs, name) { char *real = realpath(eina_slstr_printf("%s/%s", disk_search, name), NULL); if (real) { list = eina_list_append(list, real); } free(name); } devs = ecore_file_ls("/dev/mapper"); EINA_LIST_FREE(devs, name) { list = eina_list_append(list, strdup(eina_slstr_printf("/dev/mapper/%s", name))); free(name); } #endif return eina_list_sort(list, eina_list_count(list), _cmp_cb); }