summaryrefslogtreecommitdiff
path: root/udev_sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'udev_sysfs.c')
-rw-r--r--udev_sysfs.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/udev_sysfs.c b/udev_sysfs.c
index 1846a42f6a..8525620a09 100644
--- a/udev_sysfs.c
+++ b/udev_sysfs.c
@@ -429,3 +429,95 @@ char *sysfs_attr_get_value(const char *devpath, const char *attr_name)
out:
return attr->value;
}
+
+int sysfs_lookup_devpath_by_subsys_id(char *devpath_full, size_t len, const char *subsystem, const char *id)
+{
+ size_t sysfs_len;
+ char path_full[PATH_SIZE];
+ char *path;
+ struct stat statbuf;
+
+ sysfs_len = strlcpy(path_full, sysfs_path, sizeof(path_full));
+ path = &path_full[sysfs_len];
+
+ if (strcmp(subsystem, "subsystem") == 0) {
+ strlcpy(path, "/subsystem/", sizeof(path_full) - sysfs_len);
+ strlcat(path, id, sizeof(path_full) - sysfs_len);
+ if (stat(path_full, &statbuf) == 0)
+ goto found;
+
+ strlcpy(path, "/class/", sizeof(path_full) - sysfs_len);
+ strlcat(path, id, sizeof(path_full) - sysfs_len);
+ if (stat(path_full, &statbuf) == 0)
+ goto found;
+
+ strlcpy(path, "/bus/", sizeof(path_full) - sysfs_len);
+ strlcat(path, id, sizeof(path_full) - sysfs_len);
+ if (stat(path_full, &statbuf) == 0)
+ goto found;
+ goto out;
+ }
+
+ if (strcmp(subsystem, "module") == 0) {
+ strlcpy(path, "/module/", sizeof(path_full) - sysfs_len);
+ strlcat(path, id, sizeof(path_full) - sysfs_len);
+ if (stat(path_full, &statbuf) == 0)
+ goto found;
+ goto out;
+ }
+
+ if (strcmp(subsystem, "drivers") == 0) {
+ char subsys[NAME_SIZE];
+ char *driver;
+
+ strlcpy(subsys, id, sizeof(subsys));
+ driver = strchr(subsys, ':');
+ if (driver != NULL) {
+ driver[0] = '\0';
+ driver = &driver[1];
+ strlcpy(path, "/subsystem/", sizeof(path_full) - sysfs_len);
+ strlcat(path, subsys, sizeof(path_full) - sysfs_len);
+ strlcat(path, "/drivers/", sizeof(path_full) - sysfs_len);
+ strlcat(path, driver, sizeof(path_full) - sysfs_len);
+ if (stat(path_full, &statbuf) == 0)
+ goto found;
+
+ strlcpy(path, "/bus/", sizeof(path_full) - sysfs_len);
+ strlcat(path, subsys, sizeof(path_full) - sysfs_len);
+ strlcat(path, "/drivers/", sizeof(path_full) - sysfs_len);
+ strlcat(path, driver, sizeof(path_full) - sysfs_len);
+ if (stat(path_full, &statbuf) == 0)
+ goto found;
+ }
+ goto out;
+ }
+
+ strlcpy(path, "/subsystem/", sizeof(path_full) - sysfs_len);
+ strlcat(path, subsystem, sizeof(path_full) - sysfs_len);
+ strlcat(path, "/devices/", sizeof(path_full) - sysfs_len);
+ strlcat(path, id, sizeof(path_full) - sysfs_len);
+ if (stat(path_full, &statbuf) == 0)
+ goto found;
+
+ strlcpy(path, "/class/", sizeof(path_full) - sysfs_len);
+ strlcat(path, subsystem, sizeof(path_full) - sysfs_len);
+ strlcat(path, "/", sizeof(path_full) - sysfs_len);
+ strlcat(path, id, sizeof(path_full) - sysfs_len);
+ if (stat(path_full, &statbuf) == 0)
+ goto found;
+
+ strlcpy(path, "/bus/", sizeof(path_full) - sysfs_len);
+ strlcat(path, subsystem, sizeof(path_full) - sysfs_len);
+ strlcat(path, "/devices/", sizeof(path_full) - sysfs_len);
+ strlcat(path, id, sizeof(path_full) - sysfs_len);
+ if (stat(path_full, &statbuf) == 0)
+ goto found;
+out:
+ return 0;
+
+found:
+ if (S_ISLNK(statbuf.st_mode))
+ sysfs_resolve_link(path, sizeof(path_full) - sysfs_len);
+ strlcpy(devpath_full, path, len);
+ return 1;
+}