diff --git a/legacy/eeze/src/lib/eeze_disk.c b/legacy/eeze/src/lib/eeze_disk.c index 72aa21c3a4..44f81d3e38 100644 --- a/legacy/eeze/src/lib/eeze_disk.c +++ b/legacy/eeze/src/lib/eeze_disk.c @@ -14,22 +14,54 @@ Eina_List *_eeze_disks = NULL; 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; + const char *test; + Eeze_Disk_Type ret; + Eina_Bool filesystem = EINA_FALSE; /* this will have no children */ - 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; + 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 if (!strcmp(bus, "usb")) - return EEZE_DISK_TYPE_USB; + 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 */ + } + if ((!test) && (!filesystem)) + test = _walk_children_get_attr(disk->syspath, "ID_BUS", "block", EINA_TRUE); + if (!test) + return EEZE_DISK_TYPE_UNKNOWN; /* FIXME */ - return EEZE_DISK_TYPE_UNKNOWN; + 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 ret; } static _udev_device * @@ -209,6 +241,7 @@ eeze_disk_free(Eeze_Disk *disk) 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; @@ -229,7 +262,15 @@ eeze_disk_scan(Eeze_Disk *disk) 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; } @@ -350,11 +391,20 @@ eeze_disk_type_get(Eeze_Disk *disk) 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; } diff --git a/legacy/eeze/src/lib/eeze_udev_private.c b/legacy/eeze/src/lib/eeze_udev_private.c index b9989182af..a2a91119de 100644 --- a/legacy/eeze/src/lib/eeze_udev_private.c +++ b/legacy/eeze/src/lib/eeze_udev_private.c @@ -77,25 +77,76 @@ _walk_parents_test_attr(_udev_device *device, 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 diff --git a/legacy/eeze/src/lib/eeze_udev_private.h b/legacy/eeze/src/lib/eeze_udev_private.h index c17251a0d2..654027cd49 100644 --- a/legacy/eeze/src/lib/eeze_udev_private.h +++ b/legacy/eeze/src/lib/eeze_udev_private.h @@ -34,8 +34,9 @@ typedef struct udev_monitor _udev_monitor; extern _udev *udev; _udev_device *_new_device(const char *syspath); +const char *_walk_children_get_attr(const char *syspath, const char *sysattr, const char *subsystem, Eina_Bool property); Eina_Bool _walk_parents_test_attr(_udev_device *device, const char *sysattr, const char* value); -const char *_walk_parents_get_attr(_udev_device *device, const char *sysattr); +const char *_walk_parents_get_attr(_udev_device *device, const char *sysattr, Eina_Bool property); Eina_List *_get_unlisted_parents(Eina_List *list, _udev_device *device); _udev_device *_copy_device(_udev_device *device);