|
|
|
#define _DEFAULT_SOURCE
|
|
|
|
|
|
|
|
#include "disks.h"
|
|
|
|
#include <Ecore.h>
|
|
|
|
#include <Ecore_File.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#if defined(__linux__)
|
|
|
|
#include <sys/vfs.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(__APPLE__) && defined(__MACH__)
|
|
|
|
# define __MacOS__
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined (__MacOS__) || defined(__FreeBSD__) || defined(__DragonFly__)
|
|
|
|
# include <sys/types.h>
|
|
|
|
# include <sys/sysctl.h>
|
|
|
|
# include <sys/param.h>
|
|
|
|
# include <sys/ucred.h>
|
|
|
|
# include <sys/mount.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(__OpenBSD__) || defined(__NetBSD__)
|
|
|
|
# include <sys/param.h>
|
|
|
|
# include <sys/sysctl.h>
|
|
|
|
# include <sys/mount.h>
|
|
|
|
#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);
|
|
|
|
|
|
|
|
list = eina_list_sort(list, eina_list_count(list), _cmp_cb);
|
|
|
|
|
|
|
|
return list;
|
|
|
|
#else
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|