#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"); while ((fgets(buf, sizeof(buf), f)) != NULL) { start = &buf[0]; end = strchr(start, ' '); if (!end) continue; *end = 0x0; if (!strcmp(path, start)) { start = end + 1; if (!start) continue; end = strchr(start, ' '); if (!end) continue; *end = 0x0; fclose(f); return strdup(start); } } fclose(f); return NULL; #else #endif return NULL; } Eina_Bool disk_usage_get(const char *mountpoint, unsigned long *total, unsigned long *used) { struct statfs stats; if (statfs(mountpoint, &stats) < 0) return EINA_FALSE; *total = stats.f_bsize * stats.f_blocks; *used = *total - (stats.f_bsize * stats.f_bfree); return EINA_TRUE; } 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) { #if defined(__FreeBSD__) || defined(__DragonFly__) struct statfs *mounts; int i, count; char *drives, *dev, *end; char buf[4096]; 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; } Eina_List *list = NULL; dev = drives; while (dev) { end = strchr(dev, ' '); if (!end) break; *end = '\0'; snprintf(buf, sizeof(buf), "/dev/%s", dev); list = eina_list_append(list, strdup(buf)); dev = end + 1; } free(drives); count = getmntinfo(&mounts, MNT_WAIT); for (i = 0; i < count; i++) { list = eina_list_append(list, strdup(mounts[i].f_mntfromname)); } list = eina_list_sort(list, eina_list_count(list), _cmp_cb); return list; #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; char buf[4096]; size_t len; int i, 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; } Eina_List *list = NULL; dev = drives; while (dev) { end = strchr(dev, ':'); if (!end) break; *end = '\0'; if (dev[0] == ',') dev++; snprintf(buf, sizeof(buf), "/dev/%s", dev); list = eina_list_append(list, strdup(buf)); end++; dev = strchr(end, ','); if (!dev) break; } free(drives); count = getmntinfo(&mounts, MNT_WAIT); for (i = 0; i < count; i++) { list = eina_list_append(list, strdup(mounts[i].f_mntfromname)); } list = eina_list_sort(list, eina_list_count(list), _cmp_cb); return list; #elif defined(__MacOS__) char *name; char buf[4096]; Eina_List *devs, *list; list = NULL; devs = ecore_file_ls("/dev"); EINA_LIST_FREE(devs, name) { if (!strncmp(name, "disk", 4)) { snprintf(buf, sizeof(buf), "/dev/%s", name); list = eina_list_append(list, strdup(buf)); } free(name); } if (devs) eina_list_free(devs); list = eina_list_sort(list, eina_list_count(list), _cmp_cb); return list; #elif defined(__linux__) char *name; Eina_List *devs, *list; char buf[4096]; 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); } list = NULL; EINA_LIST_FREE(devs, name) { snprintf(buf, sizeof(buf), "%s/%s", disk_search, name); char *real = realpath(buf, NULL); if (real) { list = eina_list_append(list, real); } free(name); } if (devs) eina_list_free(devs); devs = ecore_file_ls("/dev/mapper"); EINA_LIST_FREE(devs, name) { snprintf(buf, sizeof(buf), "/dev/mapper/%s", name); list = eina_list_append(list, strdup(name)); free(name); } if (devs) eina_list_free(devs); list = eina_list_sort(list, eina_list_count(list), _cmp_cb); return list; #else return NULL; #endif }