X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibudev-enumerate.c;h=034d96feba1da962bc453974bba5516420f3da83;hp=f14d5c8f57cf168a806c4438624b47c1e7f4dae4;hb=746b5152cc15eb8c67bdfb5e17f8fc836cde9759;hpb=ad29a9f14fa8b1932c0e418bfcf1c10ce6a35a33 diff --git a/src/libudev-enumerate.c b/src/libudev-enumerate.c index f14d5c8f5..034d96feb 100644 --- a/src/libudev-enumerate.c +++ b/src/libudev-enumerate.c @@ -33,8 +33,8 @@ */ struct syspath { - char *syspath; - size_t len; + char *syspath; + size_t len; }; /** @@ -43,22 +43,22 @@ struct syspath { * Opaque object representing one device lookup/sort context. */ struct udev_enumerate { - struct udev *udev; - int refcount; - struct udev_list sysattr_match_list; - struct udev_list sysattr_nomatch_list; - struct udev_list subsystem_match_list; - struct udev_list subsystem_nomatch_list; - struct udev_list sysname_match_list; - struct udev_list properties_match_list; - struct udev_list tags_match_list; - struct udev_device *parent_match; - struct udev_list devices_list; - struct syspath *devices; - unsigned int devices_cur; - unsigned int devices_max; - bool devices_uptodate:1; - bool match_is_initialized; + struct udev *udev; + int refcount; + struct udev_list sysattr_match_list; + struct udev_list sysattr_nomatch_list; + struct udev_list subsystem_match_list; + struct udev_list subsystem_nomatch_list; + struct udev_list sysname_match_list; + struct udev_list properties_match_list; + struct udev_list tags_match_list; + struct udev_device *parent_match; + struct udev_list devices_list; + struct syspath *devices; + unsigned int devices_cur; + unsigned int devices_max; + bool devices_uptodate:1; + bool match_is_initialized; }; /** @@ -69,22 +69,22 @@ struct udev_enumerate { **/ UDEV_EXPORT struct udev_enumerate *udev_enumerate_new(struct udev *udev) { - struct udev_enumerate *udev_enumerate; + struct udev_enumerate *udev_enumerate; - udev_enumerate = calloc(1, sizeof(struct udev_enumerate)); - if (udev_enumerate == NULL) - return NULL; - udev_enumerate->refcount = 1; - udev_enumerate->udev = udev; - udev_list_init(udev, &udev_enumerate->sysattr_match_list, false); - udev_list_init(udev, &udev_enumerate->sysattr_nomatch_list, false); - udev_list_init(udev, &udev_enumerate->subsystem_match_list, true); - udev_list_init(udev, &udev_enumerate->subsystem_nomatch_list, true); - udev_list_init(udev, &udev_enumerate->sysname_match_list, true); - udev_list_init(udev, &udev_enumerate->properties_match_list, false); - udev_list_init(udev, &udev_enumerate->tags_match_list, true); - udev_list_init(udev, &udev_enumerate->devices_list, false); - return udev_enumerate; + udev_enumerate = calloc(1, sizeof(struct udev_enumerate)); + if (udev_enumerate == NULL) + return NULL; + udev_enumerate->refcount = 1; + udev_enumerate->udev = udev; + udev_list_init(udev, &udev_enumerate->sysattr_match_list, false); + udev_list_init(udev, &udev_enumerate->sysattr_nomatch_list, false); + udev_list_init(udev, &udev_enumerate->subsystem_match_list, true); + udev_list_init(udev, &udev_enumerate->subsystem_nomatch_list, true); + udev_list_init(udev, &udev_enumerate->sysname_match_list, true); + udev_list_init(udev, &udev_enumerate->properties_match_list, false); + udev_list_init(udev, &udev_enumerate->tags_match_list, true); + udev_list_init(udev, &udev_enumerate->devices_list, false); + return udev_enumerate; } /** @@ -97,10 +97,10 @@ UDEV_EXPORT struct udev_enumerate *udev_enumerate_new(struct udev *udev) **/ UDEV_EXPORT struct udev_enumerate *udev_enumerate_ref(struct udev_enumerate *udev_enumerate) { - if (udev_enumerate == NULL) - return NULL; - udev_enumerate->refcount++; - return udev_enumerate; + if (udev_enumerate == NULL) + return NULL; + udev_enumerate->refcount++; + return udev_enumerate; } /** @@ -112,26 +112,26 @@ UDEV_EXPORT struct udev_enumerate *udev_enumerate_ref(struct udev_enumerate *ude **/ UDEV_EXPORT void udev_enumerate_unref(struct udev_enumerate *udev_enumerate) { - unsigned int i; - - if (udev_enumerate == NULL) - return; - udev_enumerate->refcount--; - if (udev_enumerate->refcount > 0) - return; - udev_list_cleanup(&udev_enumerate->sysattr_match_list); - udev_list_cleanup(&udev_enumerate->sysattr_nomatch_list); - udev_list_cleanup(&udev_enumerate->subsystem_match_list); - udev_list_cleanup(&udev_enumerate->subsystem_nomatch_list); - udev_list_cleanup(&udev_enumerate->sysname_match_list); - udev_list_cleanup(&udev_enumerate->properties_match_list); - udev_list_cleanup(&udev_enumerate->tags_match_list); - udev_device_unref(udev_enumerate->parent_match); - udev_list_cleanup(&udev_enumerate->devices_list); - for (i = 0; i < udev_enumerate->devices_cur; i++) - free(udev_enumerate->devices[i].syspath); - free(udev_enumerate->devices); - free(udev_enumerate); + unsigned int i; + + if (udev_enumerate == NULL) + return; + udev_enumerate->refcount--; + if (udev_enumerate->refcount > 0) + return; + udev_list_cleanup(&udev_enumerate->sysattr_match_list); + udev_list_cleanup(&udev_enumerate->sysattr_nomatch_list); + udev_list_cleanup(&udev_enumerate->subsystem_match_list); + udev_list_cleanup(&udev_enumerate->subsystem_nomatch_list); + udev_list_cleanup(&udev_enumerate->sysname_match_list); + udev_list_cleanup(&udev_enumerate->properties_match_list); + udev_list_cleanup(&udev_enumerate->tags_match_list); + udev_device_unref(udev_enumerate->parent_match); + udev_list_cleanup(&udev_enumerate->devices_list); + for (i = 0; i < udev_enumerate->devices_cur; i++) + free(udev_enumerate->devices[i].syspath); + free(udev_enumerate->devices); + free(udev_enumerate); } /** @@ -142,79 +142,79 @@ UDEV_EXPORT void udev_enumerate_unref(struct udev_enumerate *udev_enumerate) */ UDEV_EXPORT struct udev *udev_enumerate_get_udev(struct udev_enumerate *udev_enumerate) { - if (udev_enumerate == NULL) - return NULL; - return udev_enumerate->udev; + if (udev_enumerate == NULL) + return NULL; + return udev_enumerate->udev; } static int syspath_add(struct udev_enumerate *udev_enumerate, const char *syspath) { - char *path; - struct syspath *entry; - - /* double array size if needed */ - if (udev_enumerate->devices_cur >= udev_enumerate->devices_max) { - struct syspath *buf; - unsigned int add; - - add = udev_enumerate->devices_max; - if (add < 1024) - add = 1024; - buf = realloc(udev_enumerate->devices, (udev_enumerate->devices_max + add) * sizeof(struct syspath)); - if (buf == NULL) - return -ENOMEM; - udev_enumerate->devices = buf; - udev_enumerate->devices_max += add; - } - - path = strdup(syspath); - if (path == NULL) - return -ENOMEM; - entry = &udev_enumerate->devices[udev_enumerate->devices_cur]; - entry->syspath = path; - entry->len = strlen(path); - udev_enumerate->devices_cur++; - udev_enumerate->devices_uptodate = false; - return 0; + char *path; + struct syspath *entry; + + /* double array size if needed */ + if (udev_enumerate->devices_cur >= udev_enumerate->devices_max) { + struct syspath *buf; + unsigned int add; + + add = udev_enumerate->devices_max; + if (add < 1024) + add = 1024; + buf = realloc(udev_enumerate->devices, (udev_enumerate->devices_max + add) * sizeof(struct syspath)); + if (buf == NULL) + return -ENOMEM; + udev_enumerate->devices = buf; + udev_enumerate->devices_max += add; + } + + path = strdup(syspath); + if (path == NULL) + return -ENOMEM; + entry = &udev_enumerate->devices[udev_enumerate->devices_cur]; + entry->syspath = path; + entry->len = strlen(path); + udev_enumerate->devices_cur++; + udev_enumerate->devices_uptodate = false; + return 0; } static int syspath_cmp(const void *p1, const void *p2) { - const struct syspath *path1 = p1; - const struct syspath *path2 = p2; - size_t len; - int ret; + const struct syspath *path1 = p1; + const struct syspath *path2 = p2; + size_t len; + int ret; - len = MIN(path1->len, path2->len); - ret = memcmp(path1->syspath, path2->syspath, len); - if (ret == 0) { - if (path1->len < path2->len) - ret = -1; - else if (path1->len > path2->len) - ret = 1; - } - return ret; + len = MIN(path1->len, path2->len); + ret = memcmp(path1->syspath, path2->syspath, len); + if (ret == 0) { + if (path1->len < path2->len) + ret = -1; + else if (path1->len > path2->len) + ret = 1; + } + return ret; } /* For devices that should be moved to the absolute end of the list */ static bool devices_delay_end(struct udev *udev, const char *syspath) { - static const char *delay_device_list[] = { - "/block/md", - "/block/dm-", - NULL - }; - size_t len; - int i; + static const char *delay_device_list[] = { + "/block/md", + "/block/dm-", + NULL + }; + size_t len; + int i; - len = strlen(udev_get_sys_path(udev)); - for (i = 0; delay_device_list[i] != NULL; i++) { - if (strstr(&syspath[len], delay_device_list[i]) != NULL) { - dbg(udev, "delaying: %s\n", syspath); - return true; - } - } - return false; + len = strlen(udev_get_sys_path(udev)); + for (i = 0; delay_device_list[i] != NULL; i++) { + if (strstr(&syspath[len], delay_device_list[i]) != NULL) { + dbg(udev, "delaying: %s\n", syspath); + return true; + } + } + return false; } /* For devices that should just be moved a little bit later, just @@ -222,25 +222,25 @@ static bool devices_delay_end(struct udev *udev, const char *syspath) * number of characters that make up that common prefix */ static size_t devices_delay_later(struct udev *udev, const char *syspath) { - const char *c; + const char *c; - /* For sound cards the control device must be enumerated last - * to make sure it's the final device node that gets ACLs - * applied. Applications rely on this fact and use ACL changes - * on the control node as an indicator that the ACL change of - * the entire sound card completed. The kernel makes this - * guarantee when creating those devices, and hence we should - * too when enumerating them. */ + /* For sound cards the control device must be enumerated last + * to make sure it's the final device node that gets ACLs + * applied. Applications rely on this fact and use ACL changes + * on the control node as an indicator that the ACL change of + * the entire sound card completed. The kernel makes this + * guarantee when creating those devices, and hence we should + * too when enumerating them. */ - if ((c = strstr(syspath, "/sound/card"))) { - c += 11; - c += strcspn(c, "/"); + if ((c = strstr(syspath, "/sound/card"))) { + c += 11; + c += strcspn(c, "/"); - if (strncmp(c, "/controlC", 9) == 0) - return c - syspath + 1; - } + if (strncmp(c, "/controlC", 9) == 0) + return c - syspath + 1; + } - return 0; + return 0; } /** @@ -251,73 +251,73 @@ static size_t devices_delay_later(struct udev *udev, const char *syspath) */ UDEV_EXPORT struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate) { - if (udev_enumerate == NULL) - return NULL; - if (!udev_enumerate->devices_uptodate) { - unsigned int i; - unsigned int max; - struct syspath *prev = NULL, *move_later = NULL; - size_t move_later_prefix = 0; - - udev_list_cleanup(&udev_enumerate->devices_list); - qsort(udev_enumerate->devices, udev_enumerate->devices_cur, sizeof(struct syspath), syspath_cmp); - - max = udev_enumerate->devices_cur; - for (i = 0; i < max; i++) { - struct syspath *entry = &udev_enumerate->devices[i]; - - /* skip duplicated entries */ - if (prev != NULL && - entry->len == prev->len && - memcmp(entry->syspath, prev->syspath, entry->len) == 0) - continue; - prev = entry; - - /* skip to be delayed devices, and add them to the end of the list */ - if (devices_delay_end(udev_enumerate->udev, entry->syspath)) { - syspath_add(udev_enumerate, entry->syspath); - /* need to update prev here for the case realloc() gives a different address */ - prev = &udev_enumerate->devices[i]; - continue; - } - - /* skip to be delayed devices, and move the to - * the point where the prefix changes. We can - * only move one item at a time. */ - if (!move_later) { - move_later_prefix = devices_delay_later(udev_enumerate->udev, entry->syspath); - - if (move_later_prefix > 0) { - move_later = entry; - continue; - } - } - - if (move_later && - strncmp(entry->syspath, move_later->syspath, move_later_prefix) != 0) { - - udev_list_entry_add(&udev_enumerate->devices_list, move_later->syspath, NULL); - move_later = NULL; - } - - udev_list_entry_add(&udev_enumerate->devices_list, entry->syspath, NULL); - } - - if (move_later) - udev_list_entry_add(&udev_enumerate->devices_list, move_later->syspath, NULL); - - /* add and cleanup delayed devices from end of list */ - for (i = max; i < udev_enumerate->devices_cur; i++) { - struct syspath *entry = &udev_enumerate->devices[i]; - - udev_list_entry_add(&udev_enumerate->devices_list, entry->syspath, NULL); - free(entry->syspath); - } - udev_enumerate->devices_cur = max; - - udev_enumerate->devices_uptodate = true; - } - return udev_list_get_entry(&udev_enumerate->devices_list); + if (udev_enumerate == NULL) + return NULL; + if (!udev_enumerate->devices_uptodate) { + unsigned int i; + unsigned int max; + struct syspath *prev = NULL, *move_later = NULL; + size_t move_later_prefix = 0; + + udev_list_cleanup(&udev_enumerate->devices_list); + qsort(udev_enumerate->devices, udev_enumerate->devices_cur, sizeof(struct syspath), syspath_cmp); + + max = udev_enumerate->devices_cur; + for (i = 0; i < max; i++) { + struct syspath *entry = &udev_enumerate->devices[i]; + + /* skip duplicated entries */ + if (prev != NULL && + entry->len == prev->len && + memcmp(entry->syspath, prev->syspath, entry->len) == 0) + continue; + prev = entry; + + /* skip to be delayed devices, and add them to the end of the list */ + if (devices_delay_end(udev_enumerate->udev, entry->syspath)) { + syspath_add(udev_enumerate, entry->syspath); + /* need to update prev here for the case realloc() gives a different address */ + prev = &udev_enumerate->devices[i]; + continue; + } + + /* skip to be delayed devices, and move the to + * the point where the prefix changes. We can + * only move one item at a time. */ + if (!move_later) { + move_later_prefix = devices_delay_later(udev_enumerate->udev, entry->syspath); + + if (move_later_prefix > 0) { + move_later = entry; + continue; + } + } + + if (move_later && + strncmp(entry->syspath, move_later->syspath, move_later_prefix) != 0) { + + udev_list_entry_add(&udev_enumerate->devices_list, move_later->syspath, NULL); + move_later = NULL; + } + + udev_list_entry_add(&udev_enumerate->devices_list, entry->syspath, NULL); + } + + if (move_later) + udev_list_entry_add(&udev_enumerate->devices_list, move_later->syspath, NULL); + + /* add and cleanup delayed devices from end of list */ + for (i = max; i < udev_enumerate->devices_cur; i++) { + struct syspath *entry = &udev_enumerate->devices[i]; + + udev_list_entry_add(&udev_enumerate->devices_list, entry->syspath, NULL); + free(entry->syspath); + } + udev_enumerate->devices_cur = max; + + udev_enumerate->devices_uptodate = true; + } + return udev_list_get_entry(&udev_enumerate->devices_list); } /** @@ -329,13 +329,13 @@ UDEV_EXPORT struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_en */ UDEV_EXPORT int udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem) { - if (udev_enumerate == NULL) - return -EINVAL; - if (subsystem == NULL) - return 0; - if (udev_list_entry_add(&udev_enumerate->subsystem_match_list, subsystem, NULL) == NULL) - return -ENOMEM; - return 0; + if (udev_enumerate == NULL) + return -EINVAL; + if (subsystem == NULL) + return 0; + if (udev_list_entry_add(&udev_enumerate->subsystem_match_list, subsystem, NULL) == NULL) + return -ENOMEM; + return 0; } /** @@ -347,13 +347,13 @@ UDEV_EXPORT int udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_e */ UDEV_EXPORT int udev_enumerate_add_nomatch_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem) { - if (udev_enumerate == NULL) - return -EINVAL; - if (subsystem == NULL) - return 0; - if (udev_list_entry_add(&udev_enumerate->subsystem_nomatch_list, subsystem, NULL) == NULL) - return -ENOMEM; - return 0; + if (udev_enumerate == NULL) + return -EINVAL; + if (subsystem == NULL) + return 0; + if (udev_list_entry_add(&udev_enumerate->subsystem_nomatch_list, subsystem, NULL) == NULL) + return -ENOMEM; + return 0; } /** @@ -366,13 +366,13 @@ UDEV_EXPORT int udev_enumerate_add_nomatch_subsystem(struct udev_enumerate *udev */ UDEV_EXPORT int udev_enumerate_add_match_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value) { - if (udev_enumerate == NULL) - return -EINVAL; - if (sysattr == NULL) - return 0; - if (udev_list_entry_add(&udev_enumerate->sysattr_match_list, sysattr, value) == NULL) - return -ENOMEM; - return 0; + if (udev_enumerate == NULL) + return -EINVAL; + if (sysattr == NULL) + return 0; + if (udev_list_entry_add(&udev_enumerate->sysattr_match_list, sysattr, value) == NULL) + return -ENOMEM; + return 0; } /** @@ -385,33 +385,33 @@ UDEV_EXPORT int udev_enumerate_add_match_sysattr(struct udev_enumerate *udev_enu */ UDEV_EXPORT int udev_enumerate_add_nomatch_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value) { - if (udev_enumerate == NULL) - return -EINVAL; - if (sysattr == NULL) - return 0; - if (udev_list_entry_add(&udev_enumerate->sysattr_nomatch_list, sysattr, value) == NULL) - return -ENOMEM; - return 0; + if (udev_enumerate == NULL) + return -EINVAL; + if (sysattr == NULL) + return 0; + if (udev_list_entry_add(&udev_enumerate->sysattr_nomatch_list, sysattr, value) == NULL) + return -ENOMEM; + return 0; } static int match_sysattr_value(struct udev_device *dev, const char *sysattr, const char *match_val) { - const char *val = NULL; - bool match = false; - - val = udev_device_get_sysattr_value(dev, sysattr); - if (val == NULL) - goto exit; - if (match_val == NULL) { - match = true; - goto exit; - } - if (fnmatch(match_val, val, 0) == 0) { - match = true; - goto exit; - } + const char *val = NULL; + bool match = false; + + val = udev_device_get_sysattr_value(dev, sysattr); + if (val == NULL) + goto exit; + if (match_val == NULL) { + match = true; + goto exit; + } + if (fnmatch(match_val, val, 0) == 0) { + match = true; + goto exit; + } exit: - return match; + return match; } /** @@ -424,13 +424,13 @@ exit: */ UDEV_EXPORT int udev_enumerate_add_match_property(struct udev_enumerate *udev_enumerate, const char *property, const char *value) { - if (udev_enumerate == NULL) - return -EINVAL; - if (property == NULL) - return 0; - if (udev_list_entry_add(&udev_enumerate->properties_match_list, property, value) == NULL) - return -ENOMEM; - return 0; + if (udev_enumerate == NULL) + return -EINVAL; + if (property == NULL) + return 0; + if (udev_list_entry_add(&udev_enumerate->properties_match_list, property, value) == NULL) + return -ENOMEM; + return 0; } /** @@ -442,13 +442,13 @@ UDEV_EXPORT int udev_enumerate_add_match_property(struct udev_enumerate *udev_en */ UDEV_EXPORT int udev_enumerate_add_match_tag(struct udev_enumerate *udev_enumerate, const char *tag) { - if (udev_enumerate == NULL) - return -EINVAL; - if (tag == NULL) - return 0; - if (udev_list_entry_add(&udev_enumerate->tags_match_list, tag, NULL) == NULL) - return -ENOMEM; - return 0; + if (udev_enumerate == NULL) + return -EINVAL; + if (tag == NULL) + return 0; + if (udev_list_entry_add(&udev_enumerate->tags_match_list, tag, NULL) == NULL) + return -ENOMEM; + return 0; } /** @@ -466,14 +466,14 @@ UDEV_EXPORT int udev_enumerate_add_match_tag(struct udev_enumerate *udev_enumera */ UDEV_EXPORT int udev_enumerate_add_match_parent(struct udev_enumerate *udev_enumerate, struct udev_device *parent) { - if (udev_enumerate == NULL) - return -EINVAL; - if (parent == NULL) - return 0; - if (udev_enumerate->parent_match != NULL) - udev_device_unref(udev_enumerate->parent_match); - udev_enumerate->parent_match = udev_device_ref(parent); - return 0; + if (udev_enumerate == NULL) + return -EINVAL; + if (parent == NULL) + return 0; + if (udev_enumerate->parent_match != NULL) + udev_device_unref(udev_enumerate->parent_match); + udev_enumerate->parent_match = udev_device_ref(parent); + return 0; } /** @@ -496,10 +496,10 @@ UDEV_EXPORT int udev_enumerate_add_match_parent(struct udev_enumerate *udev_enum */ UDEV_EXPORT int udev_enumerate_add_match_is_initialized(struct udev_enumerate *udev_enumerate) { - if (udev_enumerate == NULL) - return -EINVAL; - udev_enumerate->match_is_initialized = true; - return 0; + if (udev_enumerate == NULL) + return -EINVAL; + udev_enumerate->match_is_initialized = true; + return 0; } /** @@ -511,223 +511,223 @@ UDEV_EXPORT int udev_enumerate_add_match_is_initialized(struct udev_enumerate *u */ UDEV_EXPORT int udev_enumerate_add_match_sysname(struct udev_enumerate *udev_enumerate, const char *sysname) { - if (udev_enumerate == NULL) - return -EINVAL; - if (sysname == NULL) - return 0; - if (udev_list_entry_add(&udev_enumerate->sysname_match_list, sysname, NULL) == NULL) - return -ENOMEM; - return 0; + if (udev_enumerate == NULL) + return -EINVAL; + if (sysname == NULL) + return 0; + if (udev_list_entry_add(&udev_enumerate->sysname_match_list, sysname, NULL) == NULL) + return -ENOMEM; + return 0; } static bool match_sysattr(struct udev_enumerate *udev_enumerate, struct udev_device *dev) { - struct udev_list_entry *list_entry; - - /* skip list */ - udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->sysattr_nomatch_list)) { - if (match_sysattr_value(dev, udev_list_entry_get_name(list_entry), - udev_list_entry_get_value(list_entry))) - return false; - } - /* include list */ - if (udev_list_get_entry(&udev_enumerate->sysattr_match_list) != NULL) { - udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->sysattr_match_list)) { - /* anything that does not match, will make it FALSE */ - if (!match_sysattr_value(dev, udev_list_entry_get_name(list_entry), - udev_list_entry_get_value(list_entry))) - return false; - } - return true; - } - return true; + struct udev_list_entry *list_entry; + + /* skip list */ + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->sysattr_nomatch_list)) { + if (match_sysattr_value(dev, udev_list_entry_get_name(list_entry), + udev_list_entry_get_value(list_entry))) + return false; + } + /* include list */ + if (udev_list_get_entry(&udev_enumerate->sysattr_match_list) != NULL) { + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->sysattr_match_list)) { + /* anything that does not match, will make it FALSE */ + if (!match_sysattr_value(dev, udev_list_entry_get_name(list_entry), + udev_list_entry_get_value(list_entry))) + return false; + } + return true; + } + return true; } static bool match_property(struct udev_enumerate *udev_enumerate, struct udev_device *dev) { - struct udev_list_entry *list_entry; - bool match = false; - - /* no match always matches */ - if (udev_list_get_entry(&udev_enumerate->properties_match_list) == NULL) - return true; - - /* loop over matches */ - udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->properties_match_list)) { - const char *match_key = udev_list_entry_get_name(list_entry); - const char *match_value = udev_list_entry_get_value(list_entry); - struct udev_list_entry *property_entry; - - /* loop over device properties */ - udev_list_entry_foreach(property_entry, udev_device_get_properties_list_entry(dev)) { - const char *dev_key = udev_list_entry_get_name(property_entry); - const char *dev_value = udev_list_entry_get_value(property_entry); - - if (fnmatch(match_key, dev_key, 0) != 0) - continue; - if (match_value == NULL && dev_value == NULL) { - match = true; - goto out; - } - if (match_value == NULL || dev_value == NULL) - continue; - if (fnmatch(match_value, dev_value, 0) == 0) { - match = true; - goto out; - } - } - } + struct udev_list_entry *list_entry; + bool match = false; + + /* no match always matches */ + if (udev_list_get_entry(&udev_enumerate->properties_match_list) == NULL) + return true; + + /* loop over matches */ + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->properties_match_list)) { + const char *match_key = udev_list_entry_get_name(list_entry); + const char *match_value = udev_list_entry_get_value(list_entry); + struct udev_list_entry *property_entry; + + /* loop over device properties */ + udev_list_entry_foreach(property_entry, udev_device_get_properties_list_entry(dev)) { + const char *dev_key = udev_list_entry_get_name(property_entry); + const char *dev_value = udev_list_entry_get_value(property_entry); + + if (fnmatch(match_key, dev_key, 0) != 0) + continue; + if (match_value == NULL && dev_value == NULL) { + match = true; + goto out; + } + if (match_value == NULL || dev_value == NULL) + continue; + if (fnmatch(match_value, dev_value, 0) == 0) { + match = true; + goto out; + } + } + } out: - return match; + return match; } static bool match_tag(struct udev_enumerate *udev_enumerate, struct udev_device *dev) { - struct udev_list_entry *list_entry; + struct udev_list_entry *list_entry; - /* no match always matches */ - if (udev_list_get_entry(&udev_enumerate->tags_match_list) == NULL) - return true; + /* no match always matches */ + if (udev_list_get_entry(&udev_enumerate->tags_match_list) == NULL) + return true; - /* loop over matches */ - udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->tags_match_list)) - if (!udev_device_has_tag(dev, udev_list_entry_get_name(list_entry))) - return false; + /* loop over matches */ + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->tags_match_list)) + if (!udev_device_has_tag(dev, udev_list_entry_get_name(list_entry))) + return false; - return true; + return true; } static bool match_parent(struct udev_enumerate *udev_enumerate, struct udev_device *dev) { - const char *parent; + const char *parent; - if (udev_enumerate->parent_match == NULL) - return true; + if (udev_enumerate->parent_match == NULL) + return true; - parent = udev_device_get_devpath(udev_enumerate->parent_match); - return strncmp(parent, udev_device_get_devpath(dev), strlen(parent)) == 0; + parent = udev_device_get_devpath(udev_enumerate->parent_match); + return strncmp(parent, udev_device_get_devpath(dev), strlen(parent)) == 0; } static bool match_sysname(struct udev_enumerate *udev_enumerate, const char *sysname) { - struct udev_list_entry *list_entry; + struct udev_list_entry *list_entry; - if (udev_list_get_entry(&udev_enumerate->sysname_match_list) == NULL) - return true; + if (udev_list_get_entry(&udev_enumerate->sysname_match_list) == NULL) + return true; - udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->sysname_match_list)) { - if (fnmatch(udev_list_entry_get_name(list_entry), sysname, 0) != 0) - continue; - return true; - } - return false; + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->sysname_match_list)) { + if (fnmatch(udev_list_entry_get_name(list_entry), sysname, 0) != 0) + continue; + return true; + } + return false; } static int scan_dir_and_add_devices(struct udev_enumerate *udev_enumerate, - const char *basedir, const char *subdir1, const char *subdir2) -{ - struct udev *udev = udev_enumerate_get_udev(udev_enumerate); - char path[UTIL_PATH_SIZE]; - size_t l; - char *s; - DIR *dir; - struct dirent *dent; - - s = path; - l = util_strpcpyl(&s, sizeof(path), udev_get_sys_path(udev), "/", basedir, NULL); - if (subdir1 != NULL) - l = util_strpcpyl(&s, l, "/", subdir1, NULL); - if (subdir2 != NULL) - util_strpcpyl(&s, l, "/", subdir2, NULL); - dir = opendir(path); - if (dir == NULL) - return -ENOENT; - for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { - char syspath[UTIL_PATH_SIZE]; - struct udev_device *dev; - - if (dent->d_name[0] == '.') - continue; - - if (!match_sysname(udev_enumerate, dent->d_name)) - continue; - - util_strscpyl(syspath, sizeof(syspath), path, "/", dent->d_name, NULL); - dev = udev_device_new_from_syspath(udev_enumerate->udev, syspath); - if (dev == NULL) - continue; - - if (udev_enumerate->match_is_initialized) { - /* - * All devices with a device node or network interfaces - * possibly need udev to adjust the device node permission - * or context, or rename the interface before it can be - * reliably used from other processes. - * - * For now, we can only check these types of devices, we - * might not store a database, and have no way to find out - * for all other types of devices. - */ - if (!udev_device_get_is_initialized(dev) && - (major(udev_device_get_devnum(dev)) > 0 || udev_device_get_ifindex(dev) > 0)) - goto nomatch; - } - if (!match_parent(udev_enumerate, dev)) - goto nomatch; - if (!match_tag(udev_enumerate, dev)) - goto nomatch; - if (!match_property(udev_enumerate, dev)) - goto nomatch; - if (!match_sysattr(udev_enumerate, dev)) - goto nomatch; - - syspath_add(udev_enumerate, udev_device_get_syspath(dev)); + const char *basedir, const char *subdir1, const char *subdir2) +{ + struct udev *udev = udev_enumerate_get_udev(udev_enumerate); + char path[UTIL_PATH_SIZE]; + size_t l; + char *s; + DIR *dir; + struct dirent *dent; + + s = path; + l = util_strpcpyl(&s, sizeof(path), udev_get_sys_path(udev), "/", basedir, NULL); + if (subdir1 != NULL) + l = util_strpcpyl(&s, l, "/", subdir1, NULL); + if (subdir2 != NULL) + util_strpcpyl(&s, l, "/", subdir2, NULL); + dir = opendir(path); + if (dir == NULL) + return -ENOENT; + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char syspath[UTIL_PATH_SIZE]; + struct udev_device *dev; + + if (dent->d_name[0] == '.') + continue; + + if (!match_sysname(udev_enumerate, dent->d_name)) + continue; + + util_strscpyl(syspath, sizeof(syspath), path, "/", dent->d_name, NULL); + dev = udev_device_new_from_syspath(udev_enumerate->udev, syspath); + if (dev == NULL) + continue; + + if (udev_enumerate->match_is_initialized) { + /* + * All devices with a device node or network interfaces + * possibly need udev to adjust the device node permission + * or context, or rename the interface before it can be + * reliably used from other processes. + * + * For now, we can only check these types of devices, we + * might not store a database, and have no way to find out + * for all other types of devices. + */ + if (!udev_device_get_is_initialized(dev) && + (major(udev_device_get_devnum(dev)) > 0 || udev_device_get_ifindex(dev) > 0)) + goto nomatch; + } + if (!match_parent(udev_enumerate, dev)) + goto nomatch; + if (!match_tag(udev_enumerate, dev)) + goto nomatch; + if (!match_property(udev_enumerate, dev)) + goto nomatch; + if (!match_sysattr(udev_enumerate, dev)) + goto nomatch; + + syspath_add(udev_enumerate, udev_device_get_syspath(dev)); nomatch: - udev_device_unref(dev); - } - closedir(dir); - return 0; + udev_device_unref(dev); + } + closedir(dir); + return 0; } static bool match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem) { - struct udev_list_entry *list_entry; + struct udev_list_entry *list_entry; - udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->subsystem_nomatch_list)) { - if (fnmatch(udev_list_entry_get_name(list_entry), subsystem, 0) == 0) - return false; - } - if (udev_list_get_entry(&udev_enumerate->subsystem_match_list) != NULL) { - udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->subsystem_match_list)) { - if (fnmatch(udev_list_entry_get_name(list_entry), subsystem, 0) == 0) - return true; - } - return false; - } - return true; + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->subsystem_nomatch_list)) { + if (fnmatch(udev_list_entry_get_name(list_entry), subsystem, 0) == 0) + return false; + } + if (udev_list_get_entry(&udev_enumerate->subsystem_match_list) != NULL) { + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->subsystem_match_list)) { + if (fnmatch(udev_list_entry_get_name(list_entry), subsystem, 0) == 0) + return true; + } + return false; + } + return true; } static int scan_dir(struct udev_enumerate *udev_enumerate, const char *basedir, const char *subdir, const char *subsystem) { - struct udev *udev = udev_enumerate_get_udev(udev_enumerate); + struct udev *udev = udev_enumerate_get_udev(udev_enumerate); - char path[UTIL_PATH_SIZE]; - DIR *dir; - struct dirent *dent; + char path[UTIL_PATH_SIZE]; + DIR *dir; + struct dirent *dent; - util_strscpyl(path, sizeof(path), udev_get_sys_path(udev), "/", basedir, NULL); - dir = opendir(path); - if (dir == NULL) - return -1; - for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { - if (dent->d_name[0] == '.') - continue; - if (!match_subsystem(udev_enumerate, subsystem != NULL ? subsystem : dent->d_name)) - continue; - scan_dir_and_add_devices(udev_enumerate, basedir, dent->d_name, subdir); - } - closedir(dir); - return 0; + util_strscpyl(path, sizeof(path), udev_get_sys_path(udev), "/", basedir, NULL); + dir = opendir(path); + if (dir == NULL) + return -1; + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + if (dent->d_name[0] == '.') + continue; + if (!match_subsystem(udev_enumerate, subsystem != NULL ? subsystem : dent->d_name)) + continue; + scan_dir_and_add_devices(udev_enumerate, basedir, dent->d_name, subdir); + } + closedir(dir); + return 0; } /** @@ -741,144 +741,144 @@ static int scan_dir(struct udev_enumerate *udev_enumerate, const char *basedir, */ UDEV_EXPORT int udev_enumerate_add_syspath(struct udev_enumerate *udev_enumerate, const char *syspath) { - struct udev_device *udev_device; + struct udev_device *udev_device; - if (udev_enumerate == NULL) - return -EINVAL; - if (syspath == NULL) - return 0; - /* resolve to real syspath */ - udev_device = udev_device_new_from_syspath(udev_enumerate->udev, syspath); - if (udev_device == NULL) - return -EINVAL; - syspath_add(udev_enumerate, udev_device_get_syspath(udev_device)); - udev_device_unref(udev_device); - return 0; + if (udev_enumerate == NULL) + return -EINVAL; + if (syspath == NULL) + return 0; + /* resolve to real syspath */ + udev_device = udev_device_new_from_syspath(udev_enumerate->udev, syspath); + if (udev_device == NULL) + return -EINVAL; + syspath_add(udev_enumerate, udev_device_get_syspath(udev_device)); + udev_device_unref(udev_device); + return 0; } static int scan_devices_tags(struct udev_enumerate *udev_enumerate) { - struct udev *udev = udev_enumerate_get_udev(udev_enumerate); - struct udev_list_entry *list_entry; - - /* scan only tagged devices, use tags reverse-index, instead of searching all devices in /sys */ - udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->tags_match_list)) { - DIR *dir; - struct dirent *dent; - char path[UTIL_PATH_SIZE]; - - util_strscpyl(path, sizeof(path), udev_get_run_path(udev), "/tags/", - udev_list_entry_get_name(list_entry), NULL); - dir = opendir(path); - if (dir == NULL) - continue; - for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { - struct udev_device *dev; - - if (dent->d_name[0] == '.') - continue; - - dev = udev_device_new_from_id_filename(udev_enumerate->udev, dent->d_name); - if (dev == NULL) - continue; - - if (!match_subsystem(udev_enumerate, udev_device_get_subsystem(dev))) - goto nomatch; - if (!match_sysname(udev_enumerate, udev_device_get_sysname(dev))) - goto nomatch; - if (!match_parent(udev_enumerate, dev)) - goto nomatch; - if (!match_property(udev_enumerate, dev)) - goto nomatch; - if (!match_sysattr(udev_enumerate, dev)) - goto nomatch; - - syspath_add(udev_enumerate, udev_device_get_syspath(dev)); + struct udev *udev = udev_enumerate_get_udev(udev_enumerate); + struct udev_list_entry *list_entry; + + /* scan only tagged devices, use tags reverse-index, instead of searching all devices in /sys */ + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->tags_match_list)) { + DIR *dir; + struct dirent *dent; + char path[UTIL_PATH_SIZE]; + + util_strscpyl(path, sizeof(path), udev_get_run_path(udev), "/tags/", + udev_list_entry_get_name(list_entry), NULL); + dir = opendir(path); + if (dir == NULL) + continue; + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + struct udev_device *dev; + + if (dent->d_name[0] == '.') + continue; + + dev = udev_device_new_from_id_filename(udev_enumerate->udev, dent->d_name); + if (dev == NULL) + continue; + + if (!match_subsystem(udev_enumerate, udev_device_get_subsystem(dev))) + goto nomatch; + if (!match_sysname(udev_enumerate, udev_device_get_sysname(dev))) + goto nomatch; + if (!match_parent(udev_enumerate, dev)) + goto nomatch; + if (!match_property(udev_enumerate, dev)) + goto nomatch; + if (!match_sysattr(udev_enumerate, dev)) + goto nomatch; + + syspath_add(udev_enumerate, udev_device_get_syspath(dev)); nomatch: - udev_device_unref(dev); - } - closedir(dir); - } - return 0; + udev_device_unref(dev); + } + closedir(dir); + } + return 0; } static int parent_add_child(struct udev_enumerate *enumerate, const char *path) { - struct udev_device *dev; + struct udev_device *dev; - dev = udev_device_new_from_syspath(enumerate->udev, path); - if (dev == NULL) - return -ENODEV; + dev = udev_device_new_from_syspath(enumerate->udev, path); + if (dev == NULL) + return -ENODEV; - if (!match_subsystem(enumerate, udev_device_get_subsystem(dev))) - return 0; - if (!match_sysname(enumerate, udev_device_get_sysname(dev))) - return 0; - if (!match_property(enumerate, dev)) - return 0; - if (!match_sysattr(enumerate, dev)) - return 0; + if (!match_subsystem(enumerate, udev_device_get_subsystem(dev))) + return 0; + if (!match_sysname(enumerate, udev_device_get_sysname(dev))) + return 0; + if (!match_property(enumerate, dev)) + return 0; + if (!match_sysattr(enumerate, dev)) + return 0; - syspath_add(enumerate, udev_device_get_syspath(dev)); - udev_device_unref(dev); - return 1; + syspath_add(enumerate, udev_device_get_syspath(dev)); + udev_device_unref(dev); + return 1; } static int parent_crawl_children(struct udev_enumerate *enumerate, const char *path, int maxdepth) { - DIR *d; - struct dirent *dent; + DIR *d; + struct dirent *dent; - d = opendir(path); - if (d == NULL) - return -errno; + d = opendir(path); + if (d == NULL) + return -errno; - for (dent = readdir(d); dent != NULL; dent = readdir(d)) { - char *child; + for (dent = readdir(d); dent != NULL; dent = readdir(d)) { + char *child; - if (dent->d_name[0] == '.') - continue; - if (dent->d_type != DT_DIR) - continue; - if (asprintf(&child, "%s/%s", path, dent->d_name) < 0) - continue; - parent_add_child(enumerate, child); - if (maxdepth > 0) - parent_crawl_children(enumerate, child, maxdepth-1); - free(child); - } + if (dent->d_name[0] == '.') + continue; + if (dent->d_type != DT_DIR) + continue; + if (asprintf(&child, "%s/%s", path, dent->d_name) < 0) + continue; + parent_add_child(enumerate, child); + if (maxdepth > 0) + parent_crawl_children(enumerate, child, maxdepth-1); + free(child); + } - closedir(d); - return 0; + closedir(d); + return 0; } static int scan_devices_children(struct udev_enumerate *enumerate) { - const char *path; + const char *path; - path = udev_device_get_syspath(enumerate->parent_match); - parent_add_child(enumerate, path); - return parent_crawl_children(enumerate, path, 256); + path = udev_device_get_syspath(enumerate->parent_match); + parent_add_child(enumerate, path); + return parent_crawl_children(enumerate, path, 256); } static int scan_devices_all(struct udev_enumerate *udev_enumerate) { - struct udev *udev = udev_enumerate_get_udev(udev_enumerate); - char base[UTIL_PATH_SIZE]; - struct stat statbuf; + struct udev *udev = udev_enumerate_get_udev(udev_enumerate); + char base[UTIL_PATH_SIZE]; + struct stat statbuf; - util_strscpyl(base, sizeof(base), udev_get_sys_path(udev), "/subsystem", NULL); - if (stat(base, &statbuf) == 0) { - /* we have /subsystem/, forget all the old stuff */ - dbg(udev, "searching '/subsystem/*/devices/*' dir\n"); - scan_dir(udev_enumerate, "subsystem", "devices", NULL); - } else { - dbg(udev, "searching '/bus/*/devices/*' dir\n"); - scan_dir(udev_enumerate, "bus", "devices", NULL); - dbg(udev, "searching '/class/*' dir\n"); - scan_dir(udev_enumerate, "class", NULL, NULL); - } - return 0; + util_strscpyl(base, sizeof(base), udev_get_sys_path(udev), "/subsystem", NULL); + if (stat(base, &statbuf) == 0) { + /* we have /subsystem/, forget all the old stuff */ + dbg(udev, "searching '/subsystem/*/devices/*' dir\n"); + scan_dir(udev_enumerate, "subsystem", "devices", NULL); + } else { + dbg(udev, "searching '/bus/*/devices/*' dir\n"); + scan_dir(udev_enumerate, "bus", "devices", NULL); + dbg(udev, "searching '/class/*' dir\n"); + scan_dir(udev_enumerate, "class", NULL, NULL); + } + return 0; } /** @@ -889,19 +889,19 @@ static int scan_devices_all(struct udev_enumerate *udev_enumerate) **/ UDEV_EXPORT int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate) { - if (udev_enumerate == NULL) - return -EINVAL; + if (udev_enumerate == NULL) + return -EINVAL; - /* efficiently lookup tags only, we maintain a reverse-index */ - if (udev_list_get_entry(&udev_enumerate->tags_match_list) != NULL) - return scan_devices_tags(udev_enumerate); + /* efficiently lookup tags only, we maintain a reverse-index */ + if (udev_list_get_entry(&udev_enumerate->tags_match_list) != NULL) + return scan_devices_tags(udev_enumerate); - /* walk the subtree of one parent device only */ - if (udev_enumerate->parent_match != NULL) - return scan_devices_children(udev_enumerate); + /* walk the subtree of one parent device only */ + if (udev_enumerate->parent_match != NULL) + return scan_devices_children(udev_enumerate); - /* scan devices of all subsystems */ - return scan_devices_all(udev_enumerate); + /* scan devices of all subsystems */ + return scan_devices_all(udev_enumerate); } /** @@ -912,36 +912,36 @@ UDEV_EXPORT int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerat **/ UDEV_EXPORT int udev_enumerate_scan_subsystems(struct udev_enumerate *udev_enumerate) { - struct udev *udev = udev_enumerate_get_udev(udev_enumerate); - char base[UTIL_PATH_SIZE]; - struct stat statbuf; - const char *subsysdir; - - if (udev_enumerate == NULL) - return -EINVAL; - - /* all kernel modules */ - if (match_subsystem(udev_enumerate, "module")) { - dbg(udev, "searching '%s/modules/*' dir\n", subsysdir); - scan_dir_and_add_devices(udev_enumerate, "module", NULL, NULL); - } - - util_strscpyl(base, sizeof(base), udev_get_sys_path(udev), "/subsystem", NULL); - if (stat(base, &statbuf) == 0) - subsysdir = "subsystem"; - else - subsysdir = "bus"; - - /* all subsystems (only buses support coldplug) */ - if (match_subsystem(udev_enumerate, "subsystem")) { - dbg(udev, "searching '%s/*' dir\n", subsysdir); - scan_dir_and_add_devices(udev_enumerate, subsysdir, NULL, NULL); - } - - /* all subsystem drivers */ - if (match_subsystem(udev_enumerate, "drivers")) { - dbg(udev, "searching '%s/*/drivers/*' dir\n", subsysdir); - scan_dir(udev_enumerate, subsysdir, "drivers", "drivers"); - } - return 0; + struct udev *udev = udev_enumerate_get_udev(udev_enumerate); + char base[UTIL_PATH_SIZE]; + struct stat statbuf; + const char *subsysdir; + + if (udev_enumerate == NULL) + return -EINVAL; + + /* all kernel modules */ + if (match_subsystem(udev_enumerate, "module")) { + dbg(udev, "searching 'modules/*' dir\n"); + scan_dir_and_add_devices(udev_enumerate, "module", NULL, NULL); + } + + util_strscpyl(base, sizeof(base), udev_get_sys_path(udev), "/subsystem", NULL); + if (stat(base, &statbuf) == 0) + subsysdir = "subsystem"; + else + subsysdir = "bus"; + + /* all subsystems (only buses support coldplug) */ + if (match_subsystem(udev_enumerate, "subsystem")) { + dbg(udev, "searching '%s/*' dir\n", subsysdir); + scan_dir_and_add_devices(udev_enumerate, subsysdir, NULL, NULL); + } + + /* all subsystem drivers */ + if (match_subsystem(udev_enumerate, "drivers")) { + dbg(udev, "searching '%s/*/drivers/*' dir\n", subsysdir); + scan_dir(udev_enumerate, subsysdir, "drivers", "drivers"); + } + return 0; }