static Eeze_Disk_Type
_eeze_disk_type_find(Eeze_Disk *disk)
{
- const char *bus;
- bus = udev_device_get_property_value(disk->device, "ID_BUS");
- if (!bus)
- return EEZE_DISK_TYPE_UNKNOWN;
-
- if (!strcmp(bus, "ata") || !strcmp(bus, "scsi"))
- { /* FIXME: I think some other types of devices fall into this, check later */
- if (udev_device_get_property_value(disk->device, "ID_CDROM"))
- return EEZE_DISK_TYPE_CDROM;
- else
- return EEZE_DISK_TYPE_INTERNAL;
+ const char *test;
+ Eeze_Disk_Type ret;
+ Eina_Bool filesystem = EINA_FALSE; /* this will have no children */
+
+ if (udev_device_get_property_value(disk->device, "ID_CDROM"))
+ return EEZE_DISK_TYPE_CDROM;
+ test = udev_device_get_property_value(disk->device, "ID_FS_USAGE");
+ if ((!test) || strcmp(test, "filesystem"))
+ {
+ test = _walk_children_get_attr(disk->syspath, "ID_CDROM", "block", EINA_TRUE);
+ if (test)
+ {
+ eina_stringshare_del(test);
+ return EEZE_DISK_TYPE_CDROM;
+ }
+ }
+ else
+ filesystem = EINA_TRUE;
+ if (udev_device_get_property_value(disk->device, "ID_ATA"))
+ return EEZE_DISK_TYPE_INTERNAL;
+ if (!filesystem)
+ {
+ test = _walk_children_get_attr(disk->syspath, "ID_ATA", "block", EINA_TRUE);
+ if (test)
+ {
+ eina_stringshare_del(test);
+ return EEZE_DISK_TYPE_INTERNAL;
+ }
+ }
+ test = udev_device_get_property_value(disk->device, "ID_BUS");
+ if (test)
+ {
+ if (!strcmp(test, "ata")) return EEZE_DISK_TYPE_INTERNAL;
+ if (!strcmp(test, "usb")) return EEZE_DISK_TYPE_USB;
+ return EEZE_DISK_TYPE_UNKNOWN; /* FIXME */
}
- else if (!strcmp(bus, "usb"))
- return EEZE_DISK_TYPE_USB;
+ if ((!test) && (!filesystem))
+ test = _walk_children_get_attr(disk->syspath, "ID_BUS", "block", EINA_TRUE);
+ if (!test)
+ return EEZE_DISK_TYPE_UNKNOWN; /* FIXME */
+
+ if (!strcmp(test, "ata")) ret = EEZE_DISK_TYPE_INTERNAL;
+ else if (!strcmp(test, "usb")) ret = EEZE_DISK_TYPE_USB;
+ else ret = EEZE_DISK_TYPE_UNKNOWN;
+
+ eina_stringshare_del(test);
- return EEZE_DISK_TYPE_UNKNOWN;
+ return ret;
}
static _udev_device *
EAPI void
eeze_disk_scan(Eeze_Disk *disk)
{
+ const char *test;
EINA_SAFETY_ON_NULL_RETURN(disk);
/* never rescan; if these values change then something is seriously wrong */
if (disk->cache.filled) return;
disk->cache.type = _eeze_disk_type_find(disk);
if (!disk->cache.label)
disk->cache.label = udev_device_get_property_value(disk->device, "ID_FS_LABEL");
- disk->cache.removable = !!strtol(udev_device_get_sysattr_value(disk->device, "removable"), NULL, 10);
+ test = udev_device_get_sysattr_value(disk->device, "removable");
+ if (test) disk->cache.removable = !!strtol(test, NULL, 10);
+ else
+ test = _walk_children_get_attr(disk->syspath, "removable", "block", EINA_FALSE);
+ if (test)
+ {
+ disk->cache.removable = !!strtol(test, NULL, 10);
+ eina_stringshare_del(test);
+ }
disk->cache.filled = EINA_TRUE;
}
EAPI Eina_Bool
eeze_disk_removable_get(Eeze_Disk *disk)
{
+ const char *test;
EINA_SAFETY_ON_NULL_RETURN_VAL(disk, EINA_FALSE);
if (disk->cache.filled)
return disk->cache.removable;
- disk->cache.removable = !!strtol(udev_device_get_sysattr_value(disk->device, "removable"), NULL, 10);
+ test = udev_device_get_sysattr_value(disk->device, "removable");
+ if (test) disk->cache.removable = !!strtol(test, NULL, 10);
+ else
+ test = _walk_children_get_attr(disk->syspath, "removable", "block", EINA_FALSE);
+ if (test)
+ {
+ disk->cache.removable = !!strtol(test, NULL, 10);
+ eina_stringshare_del(test);
+ }
return disk->cache.removable;
}
const char *
_walk_parents_get_attr(_udev_device *device,
- const char *sysattr)
+ const char *sysattr,
+ Eina_Bool property)
{
_udev_device *parent, *child = device;
const char *test;
- if ((test = udev_device_get_sysattr_value(device, sysattr)))
- return eina_stringshare_add(test);
+ if (property)
+ test = udev_device_get_property_value(device, sysattr);
+ else
+ test = udev_device_get_sysattr_value(device, sysattr);
+ if (test) return eina_stringshare_add(test);
parent = udev_device_get_parent(child);
for (; parent; child = parent, parent = udev_device_get_parent(child))
{
- if ((test = udev_device_get_sysattr_value(parent, sysattr)))
- return eina_stringshare_add(test);
+ if (property)
+ test = udev_device_get_property_value(parent, sysattr);
+ else
+ test = udev_device_get_sysattr_value(parent, sysattr);
+ if (test) return eina_stringshare_add(test);
}
return NULL;
}
+const char *
+_walk_children_get_attr(const char *syspath,
+ const char *sysattr,
+ const char *subsystem,
+ Eina_Bool property)
+{
+ char buf[PATH_MAX];
+ const char *path, *ret = NULL;
+ _udev_enumerate *en;
+ _udev_list_entry *devs, *cur;
+
+ en = udev_enumerate_new((udev));
+ EINA_SAFETY_ON_NULL_RETURN_VAL(en, NULL);
+ path = strrchr(syspath, '/');
+ if (path) path++;
+ else path = syspath;
+ snprintf(buf, sizeof(buf), "%s*", path);
+ udev_enumerate_add_match_sysname(en, buf);
+ if (subsystem) udev_enumerate_add_match_subsystem(en, subsystem);
+ udev_enumerate_scan_devices(en);
+ devs = udev_enumerate_get_list_entry(en);
+ udev_list_entry_foreach(cur, devs)
+ {
+ const char *devname, *test;
+ _udev_device *device;
+
+ devname = udev_list_entry_get_name(cur);
+ device = _new_device(devname);
+ if (property)
+ test = udev_device_get_property_value(device, sysattr);
+ else
+ test = udev_device_get_sysattr_value(device, sysattr);
+ if (test)
+ {
+ ret = eina_stringshare_add(test);
+ udev_device_unref(device);
+ break;
+ }
+ udev_device_unref(device);
+ }
+ udev_enumerate_unref(en);
+ return ret;
+}
+
/*
* check a list for all parents of a device,
* stringshare adding all devices that are not in the list