add helper udev function to browse children devices, use helper functions to get...
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Sat, 21 May 2011 19:33:55 +0000 (19:33 +0000)
committerMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Sat, 21 May 2011 19:33:55 +0000 (19:33 +0000)
SVN revision: 59566

legacy/eeze/src/lib/eeze_disk.c
legacy/eeze/src/lib/eeze_udev_private.c
legacy/eeze/src/lib/eeze_udev_private.h

index 72aa21c3a45f714c2ad4c2c84956bcc9e9478b9f..44f81d3e3843eb5608229aed90094f7308166201 100644 (file)
@@ -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;
-
-   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 *
@@ -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;
 }
index b9989182affad34c691953b211f3003118d73efa..a2a91119def793b34c10a846e66dd4623bfabe9b 100644 (file)
@@ -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
index c17251a0d218d8ee6521d36b92e91a868f34f3d9..654027cd494a598252c67e680d75a7fe64ec76e3 100644 (file)
@@ -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);