chiark / gitweb /
udev: remove configuration options for /dev, /sys, /run directories
[elogind.git] / src / libudev / libudev-enumerate.c
1 /*
2  * libudev - interface to udev device information
3  *
4  * Copyright (C) 2008-2010 Kay Sievers <kay.sievers@vrfy.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <stddef.h>
15 #include <unistd.h>
16 #include <errno.h>
17 #include <string.h>
18 #include <dirent.h>
19 #include <fnmatch.h>
20 #include <stdbool.h>
21 #include <sys/stat.h>
22 #include <sys/param.h>
23
24 #include "libudev.h"
25 #include "libudev-private.h"
26
27 /**
28  * SECTION:libudev-enumerate
29  * @short_description: lookup and sort sys devices
30  *
31  * Lookup devices in the sys filesystem, filter devices by properties,
32  * and return a sorted list of devices.
33  */
34
35 struct syspath {
36         char *syspath;
37         size_t len;
38 };
39
40 /**
41  * udev_enumerate:
42  *
43  * Opaque object representing one device lookup/sort context.
44  */
45 struct udev_enumerate {
46         struct udev *udev;
47         int refcount;
48         struct udev_list sysattr_match_list;
49         struct udev_list sysattr_nomatch_list;
50         struct udev_list subsystem_match_list;
51         struct udev_list subsystem_nomatch_list;
52         struct udev_list sysname_match_list;
53         struct udev_list properties_match_list;
54         struct udev_list tags_match_list;
55         struct udev_device *parent_match;
56         struct udev_list devices_list;
57         struct syspath *devices;
58         unsigned int devices_cur;
59         unsigned int devices_max;
60         bool devices_uptodate:1;
61         bool match_is_initialized;
62 };
63
64 /**
65  * udev_enumerate_new:
66  * @udev: udev library context
67  *
68  * Returns: an enumeration context
69  **/
70 _public_ struct udev_enumerate *udev_enumerate_new(struct udev *udev)
71 {
72         struct udev_enumerate *udev_enumerate;
73
74         udev_enumerate = calloc(1, sizeof(struct udev_enumerate));
75         if (udev_enumerate == NULL)
76                 return NULL;
77         udev_enumerate->refcount = 1;
78         udev_enumerate->udev = udev;
79         udev_list_init(udev, &udev_enumerate->sysattr_match_list, false);
80         udev_list_init(udev, &udev_enumerate->sysattr_nomatch_list, false);
81         udev_list_init(udev, &udev_enumerate->subsystem_match_list, true);
82         udev_list_init(udev, &udev_enumerate->subsystem_nomatch_list, true);
83         udev_list_init(udev, &udev_enumerate->sysname_match_list, true);
84         udev_list_init(udev, &udev_enumerate->properties_match_list, false);
85         udev_list_init(udev, &udev_enumerate->tags_match_list, true);
86         udev_list_init(udev, &udev_enumerate->devices_list, false);
87         return udev_enumerate;
88 }
89
90 /**
91  * udev_enumerate_ref:
92  * @udev_enumerate: context
93  *
94  * Take a reference of a enumeration context.
95  *
96  * Returns: the passed enumeration context
97  **/
98 _public_ struct udev_enumerate *udev_enumerate_ref(struct udev_enumerate *udev_enumerate)
99 {
100         if (udev_enumerate == NULL)
101                 return NULL;
102         udev_enumerate->refcount++;
103         return udev_enumerate;
104 }
105
106 /**
107  * udev_enumerate_unref:
108  * @udev_enumerate: context
109  *
110  * Drop a reference of an enumeration context. If the refcount reaches zero,
111  * all resources of the enumeration context will be released.
112  **/
113 _public_ void udev_enumerate_unref(struct udev_enumerate *udev_enumerate)
114 {
115         unsigned int i;
116
117         if (udev_enumerate == NULL)
118                 return;
119         udev_enumerate->refcount--;
120         if (udev_enumerate->refcount > 0)
121                 return;
122         udev_list_cleanup(&udev_enumerate->sysattr_match_list);
123         udev_list_cleanup(&udev_enumerate->sysattr_nomatch_list);
124         udev_list_cleanup(&udev_enumerate->subsystem_match_list);
125         udev_list_cleanup(&udev_enumerate->subsystem_nomatch_list);
126         udev_list_cleanup(&udev_enumerate->sysname_match_list);
127         udev_list_cleanup(&udev_enumerate->properties_match_list);
128         udev_list_cleanup(&udev_enumerate->tags_match_list);
129         udev_device_unref(udev_enumerate->parent_match);
130         udev_list_cleanup(&udev_enumerate->devices_list);
131         for (i = 0; i < udev_enumerate->devices_cur; i++)
132                 free(udev_enumerate->devices[i].syspath);
133         free(udev_enumerate->devices);
134         free(udev_enumerate);
135 }
136
137 /**
138  * udev_enumerate_get_udev:
139  * @udev_enumerate: context
140  *
141  * Returns: the udev library context.
142  */
143 _public_ struct udev *udev_enumerate_get_udev(struct udev_enumerate *udev_enumerate)
144 {
145         if (udev_enumerate == NULL)
146                 return NULL;
147         return udev_enumerate->udev;
148 }
149
150 static int syspath_add(struct udev_enumerate *udev_enumerate, const char *syspath)
151 {
152         char *path;
153         struct syspath *entry;
154
155         /* double array size if needed */
156         if (udev_enumerate->devices_cur >= udev_enumerate->devices_max) {
157                 struct syspath *buf;
158                 unsigned int add;
159
160                 add = udev_enumerate->devices_max;
161                 if (add < 1024)
162                         add = 1024;
163                 buf = realloc(udev_enumerate->devices, (udev_enumerate->devices_max + add) * sizeof(struct syspath));
164                 if (buf == NULL)
165                         return -ENOMEM;
166                 udev_enumerate->devices = buf;
167                 udev_enumerate->devices_max += add;
168         }
169
170         path = strdup(syspath);
171         if (path == NULL)
172                 return -ENOMEM;
173         entry = &udev_enumerate->devices[udev_enumerate->devices_cur];
174         entry->syspath = path;
175         entry->len = strlen(path);
176         udev_enumerate->devices_cur++;
177         udev_enumerate->devices_uptodate = false;
178         return 0;
179 }
180
181 static int syspath_cmp(const void *p1, const void *p2)
182 {
183         const struct syspath *path1 = p1;
184         const struct syspath *path2 = p2;
185         size_t len;
186         int ret;
187
188         len = MIN(path1->len, path2->len);
189         ret = memcmp(path1->syspath, path2->syspath, len);
190         if (ret == 0) {
191                 if (path1->len < path2->len)
192                         ret = -1;
193                 else if (path1->len > path2->len)
194                         ret = 1;
195         }
196         return ret;
197 }
198
199 /* For devices that should be moved to the absolute end of the list */
200 static bool devices_delay_end(struct udev *udev, const char *syspath)
201 {
202         static const char *delay_device_list[] = {
203                 "/block/md",
204                 "/block/dm-",
205                 NULL
206         };
207         int i;
208
209         for (i = 0; delay_device_list[i] != NULL; i++) {
210                 if (strstr(syspath + strlen("/sys"), delay_device_list[i]) != NULL)
211                         return true;
212         }
213         return false;
214 }
215
216 /* For devices that should just be moved a little bit later, just
217  * before the point where some common path prefix changes. Returns the
218  * number of characters that make up that common prefix */
219 static size_t devices_delay_later(struct udev *udev, const char *syspath)
220 {
221         const char *c;
222
223         /* For sound cards the control device must be enumerated last
224          * to make sure it's the final device node that gets ACLs
225          * applied. Applications rely on this fact and use ACL changes
226          * on the control node as an indicator that the ACL change of
227          * the entire sound card completed. The kernel makes this
228          * guarantee when creating those devices, and hence we should
229          * too when enumerating them. */
230
231         if ((c = strstr(syspath, "/sound/card"))) {
232                 c += 11;
233                 c += strcspn(c, "/");
234
235                 if (strncmp(c, "/controlC", 9) == 0)
236                         return c - syspath + 1;
237         }
238
239         return 0;
240 }
241
242 /**
243  * udev_enumerate_get_list_entry:
244  * @udev_enumerate: context
245  *
246  * Returns: the first entry of the sorted list of device paths.
247  */
248 _public_ struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate)
249 {
250         if (udev_enumerate == NULL)
251                 return NULL;
252         if (!udev_enumerate->devices_uptodate) {
253                 unsigned int i;
254                 unsigned int max;
255                 struct syspath *prev = NULL, *move_later = NULL;
256                 size_t move_later_prefix = 0;
257
258                 udev_list_cleanup(&udev_enumerate->devices_list);
259                 qsort(udev_enumerate->devices, udev_enumerate->devices_cur, sizeof(struct syspath), syspath_cmp);
260
261                 max = udev_enumerate->devices_cur;
262                 for (i = 0; i < max; i++) {
263                         struct syspath *entry = &udev_enumerate->devices[i];
264
265                         /* skip duplicated entries */
266                         if (prev != NULL &&
267                             entry->len == prev->len &&
268                             memcmp(entry->syspath, prev->syspath, entry->len) == 0)
269                                 continue;
270                         prev = entry;
271
272                         /* skip to be delayed devices, and add them to the end of the list */
273                         if (devices_delay_end(udev_enumerate->udev, entry->syspath)) {
274                                 syspath_add(udev_enumerate, entry->syspath);
275                                 /* need to update prev here for the case realloc() gives a different address */
276                                 prev = &udev_enumerate->devices[i];
277                                 continue;
278                         }
279
280                         /* skip to be delayed devices, and move the to
281                          * the point where the prefix changes. We can
282                          * only move one item at a time. */
283                         if (!move_later) {
284                                 move_later_prefix = devices_delay_later(udev_enumerate->udev, entry->syspath);
285
286                                 if (move_later_prefix > 0) {
287                                         move_later = entry;
288                                         continue;
289                                 }
290                         }
291
292                         if (move_later &&
293                             strncmp(entry->syspath, move_later->syspath, move_later_prefix) != 0) {
294
295                                 udev_list_entry_add(&udev_enumerate->devices_list, move_later->syspath, NULL);
296                                 move_later = NULL;
297                         }
298
299                         udev_list_entry_add(&udev_enumerate->devices_list, entry->syspath, NULL);
300                 }
301
302                 if (move_later)
303                         udev_list_entry_add(&udev_enumerate->devices_list, move_later->syspath, NULL);
304
305                 /* add and cleanup delayed devices from end of list */
306                 for (i = max; i < udev_enumerate->devices_cur; i++) {
307                         struct syspath *entry = &udev_enumerate->devices[i];
308
309                         udev_list_entry_add(&udev_enumerate->devices_list, entry->syspath, NULL);
310                         free(entry->syspath);
311                 }
312                 udev_enumerate->devices_cur = max;
313
314                 udev_enumerate->devices_uptodate = true;
315         }
316         return udev_list_get_entry(&udev_enumerate->devices_list);
317 }
318
319 /**
320  * udev_enumerate_add_match_subsystem:
321  * @udev_enumerate: context
322  * @subsystem: filter for a subsystem of the device to include in the list
323  *
324  * Returns: 0 on success, otherwise a negative error value.
325  */
326 _public_ int udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem)
327 {
328         if (udev_enumerate == NULL)
329                 return -EINVAL;
330         if (subsystem == NULL)
331                 return 0;
332         if (udev_list_entry_add(&udev_enumerate->subsystem_match_list, subsystem, NULL) == NULL)
333                 return -ENOMEM;
334         return 0;
335 }
336
337 /**
338  * udev_enumerate_add_nomatch_subsystem:
339  * @udev_enumerate: context
340  * @subsystem: filter for a subsystem of the device to exclude from the list
341  *
342  * Returns: 0 on success, otherwise a negative error value.
343  */
344 _public_ int udev_enumerate_add_nomatch_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem)
345 {
346         if (udev_enumerate == NULL)
347                 return -EINVAL;
348         if (subsystem == NULL)
349                 return 0;
350         if (udev_list_entry_add(&udev_enumerate->subsystem_nomatch_list, subsystem, NULL) == NULL)
351                 return -ENOMEM;
352         return 0;
353 }
354
355 /**
356  * udev_enumerate_add_match_sysattr:
357  * @udev_enumerate: context
358  * @sysattr: filter for a sys attribute at the device to include in the list
359  * @value: optional value of the sys attribute
360  *
361  * Returns: 0 on success, otherwise a negative error value.
362  */
363 _public_ int udev_enumerate_add_match_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value)
364 {
365         if (udev_enumerate == NULL)
366                 return -EINVAL;
367         if (sysattr == NULL)
368                 return 0;
369         if (udev_list_entry_add(&udev_enumerate->sysattr_match_list, sysattr, value) == NULL)
370                 return -ENOMEM;
371         return 0;
372 }
373
374 /**
375  * udev_enumerate_add_nomatch_sysattr:
376  * @udev_enumerate: context
377  * @sysattr: filter for a sys attribute at the device to exclude from the list
378  * @value: optional value of the sys attribute
379  *
380  * Returns: 0 on success, otherwise a negative error value.
381  */
382 _public_ int udev_enumerate_add_nomatch_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value)
383 {
384         if (udev_enumerate == NULL)
385                 return -EINVAL;
386         if (sysattr == NULL)
387                 return 0;
388         if (udev_list_entry_add(&udev_enumerate->sysattr_nomatch_list, sysattr, value) == NULL)
389                 return -ENOMEM;
390         return 0;
391 }
392
393 static int match_sysattr_value(struct udev_device *dev, const char *sysattr, const char *match_val)
394 {
395         const char *val = NULL;
396         bool match = false;
397
398         val = udev_device_get_sysattr_value(dev, sysattr);
399         if (val == NULL)
400                 goto exit;
401         if (match_val == NULL) {
402                 match = true;
403                 goto exit;
404         }
405         if (fnmatch(match_val, val, 0) == 0) {
406                 match = true;
407                 goto exit;
408         }
409 exit:
410         return match;
411 }
412
413 /**
414  * udev_enumerate_add_match_property:
415  * @udev_enumerate: context
416  * @property: filter for a property of the device to include in the list
417  * @value: value of the property
418  *
419  * Returns: 0 on success, otherwise a negative error value.
420  */
421 _public_ int udev_enumerate_add_match_property(struct udev_enumerate *udev_enumerate, const char *property, const char *value)
422 {
423         if (udev_enumerate == NULL)
424                 return -EINVAL;
425         if (property == NULL)
426                 return 0;
427         if (udev_list_entry_add(&udev_enumerate->properties_match_list, property, value) == NULL)
428                 return -ENOMEM;
429         return 0;
430 }
431
432 /**
433  * udev_enumerate_add_match_tag:
434  * @udev_enumerate: context
435  * @tag: filter for a tag of the device to include in the list
436  *
437  * Returns: 0 on success, otherwise a negative error value.
438  */
439 _public_ int udev_enumerate_add_match_tag(struct udev_enumerate *udev_enumerate, const char *tag)
440 {
441         if (udev_enumerate == NULL)
442                 return -EINVAL;
443         if (tag == NULL)
444                 return 0;
445         if (udev_list_entry_add(&udev_enumerate->tags_match_list, tag, NULL) == NULL)
446                 return -ENOMEM;
447         return 0;
448 }
449
450 /**
451  * udev_enumerate_add_match_parent:
452  * @udev_enumerate: context
453  * @parent: parent device where to start searching
454  *
455  * Return the devices on the subtree of one given device. The parent
456  * itself is included in the list.
457  *
458  * A reference for the device is held until the udev_enumerate context
459  * is cleaned up.
460  *
461  * Returns: 0 on success, otherwise a negative error value.
462  */
463 _public_ int udev_enumerate_add_match_parent(struct udev_enumerate *udev_enumerate, struct udev_device *parent)
464 {
465         if (udev_enumerate == NULL)
466                 return -EINVAL;
467         if (parent == NULL)
468                 return 0;
469         if (udev_enumerate->parent_match != NULL)
470                 udev_device_unref(udev_enumerate->parent_match);
471         udev_enumerate->parent_match = udev_device_ref(parent);
472         return 0;
473 }
474
475 /**
476  * udev_enumerate_add_match_is_initialized:
477  * @udev_enumerate: context
478  *
479  * Match only devices which udev has set up already. This makes
480  * sure, that the device node permissions and context are properly set
481  * and that network devices are fully renamed.
482  *
483  * Usually, devices which are found in the kernel but not already
484  * handled by udev, have still pending events. Services should subscribe
485  * to monitor events and wait for these devices to become ready, instead
486  * of using uninitialized devices.
487  *
488  * For now, this will not affect devices which do not have a device node
489  * and are not network interfaces.
490  *
491  * Returns: 0 on success, otherwise a negative error value.
492  */
493 _public_ int udev_enumerate_add_match_is_initialized(struct udev_enumerate *udev_enumerate)
494 {
495         if (udev_enumerate == NULL)
496                 return -EINVAL;
497         udev_enumerate->match_is_initialized = true;
498         return 0;
499 }
500
501 /**
502  * udev_enumerate_add_match_sysname:
503  * @udev_enumerate: context
504  * @sysname: filter for the name of the device to include in the list
505  *
506  * Returns: 0 on success, otherwise a negative error value.
507  */
508 _public_ int udev_enumerate_add_match_sysname(struct udev_enumerate *udev_enumerate, const char *sysname)
509 {
510         if (udev_enumerate == NULL)
511                 return -EINVAL;
512         if (sysname == NULL)
513                 return 0;
514         if (udev_list_entry_add(&udev_enumerate->sysname_match_list, sysname, NULL) == NULL)
515                 return -ENOMEM;
516         return 0;
517 }
518
519 static bool match_sysattr(struct udev_enumerate *udev_enumerate, struct udev_device *dev)
520 {
521         struct udev_list_entry *list_entry;
522
523         /* skip list */
524         udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->sysattr_nomatch_list)) {
525                 if (match_sysattr_value(dev, udev_list_entry_get_name(list_entry),
526                                         udev_list_entry_get_value(list_entry)))
527                         return false;
528         }
529         /* include list */
530         if (udev_list_get_entry(&udev_enumerate->sysattr_match_list) != NULL) {
531                 udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->sysattr_match_list)) {
532                         /* anything that does not match, will make it FALSE */
533                         if (!match_sysattr_value(dev, udev_list_entry_get_name(list_entry),
534                                                  udev_list_entry_get_value(list_entry)))
535                                 return false;
536                 }
537                 return true;
538         }
539         return true;
540 }
541
542 static bool match_property(struct udev_enumerate *udev_enumerate, struct udev_device *dev)
543 {
544         struct udev_list_entry *list_entry;
545         bool match = false;
546
547         /* no match always matches */
548         if (udev_list_get_entry(&udev_enumerate->properties_match_list) == NULL)
549                 return true;
550
551         /* loop over matches */
552         udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->properties_match_list)) {
553                 const char *match_key = udev_list_entry_get_name(list_entry);
554                 const char *match_value = udev_list_entry_get_value(list_entry);
555                 struct udev_list_entry *property_entry;
556
557                 /* loop over device properties */
558                 udev_list_entry_foreach(property_entry, udev_device_get_properties_list_entry(dev)) {
559                         const char *dev_key = udev_list_entry_get_name(property_entry);
560                         const char *dev_value = udev_list_entry_get_value(property_entry);
561
562                         if (fnmatch(match_key, dev_key, 0) != 0)
563                                 continue;
564                         if (match_value == NULL && dev_value == NULL) {
565                                 match = true;
566                                 goto out;
567                         }
568                         if (match_value == NULL || dev_value == NULL)
569                                 continue;
570                         if (fnmatch(match_value, dev_value, 0) == 0) {
571                                 match = true;
572                                 goto out;
573                         }
574                 }
575         }
576 out:
577         return match;
578 }
579
580 static bool match_tag(struct udev_enumerate *udev_enumerate, struct udev_device *dev)
581 {
582         struct udev_list_entry *list_entry;
583
584         /* no match always matches */
585         if (udev_list_get_entry(&udev_enumerate->tags_match_list) == NULL)
586                 return true;
587
588         /* loop over matches */
589         udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->tags_match_list))
590                 if (!udev_device_has_tag(dev, udev_list_entry_get_name(list_entry)))
591                         return false;
592
593         return true;
594 }
595
596 static bool match_parent(struct udev_enumerate *udev_enumerate, struct udev_device *dev)
597 {
598         const char *parent;
599
600         if (udev_enumerate->parent_match == NULL)
601                 return true;
602
603         parent = udev_device_get_devpath(udev_enumerate->parent_match);
604         return strncmp(parent, udev_device_get_devpath(dev), strlen(parent)) == 0;
605 }
606
607 static bool match_sysname(struct udev_enumerate *udev_enumerate, const char *sysname)
608 {
609         struct udev_list_entry *list_entry;
610
611         if (udev_list_get_entry(&udev_enumerate->sysname_match_list) == NULL)
612                 return true;
613
614         udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->sysname_match_list)) {
615                 if (fnmatch(udev_list_entry_get_name(list_entry), sysname, 0) != 0)
616                         continue;
617                 return true;
618         }
619         return false;
620 }
621
622 static int scan_dir_and_add_devices(struct udev_enumerate *udev_enumerate,
623                                     const char *basedir, const char *subdir1, const char *subdir2)
624 {
625         char path[UTIL_PATH_SIZE];
626         size_t l;
627         char *s;
628         DIR *dir;
629         struct dirent *dent;
630
631         s = path;
632         l = util_strpcpyl(&s, sizeof(path), "/sys/", basedir, NULL);
633         if (subdir1 != NULL)
634                 l = util_strpcpyl(&s, l, "/", subdir1, NULL);
635         if (subdir2 != NULL)
636                 util_strpcpyl(&s, l, "/", subdir2, NULL);
637         dir = opendir(path);
638         if (dir == NULL)
639                 return -ENOENT;
640         for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
641                 char syspath[UTIL_PATH_SIZE];
642                 struct udev_device *dev;
643
644                 if (dent->d_name[0] == '.')
645                         continue;
646
647                 if (!match_sysname(udev_enumerate, dent->d_name))
648                         continue;
649
650                 util_strscpyl(syspath, sizeof(syspath), path, "/", dent->d_name, NULL);
651                 dev = udev_device_new_from_syspath(udev_enumerate->udev, syspath);
652                 if (dev == NULL)
653                         continue;
654
655                 if (udev_enumerate->match_is_initialized) {
656                         /*
657                          * All devices with a device node or network interfaces
658                          * possibly need udev to adjust the device node permission
659                          * or context, or rename the interface before it can be
660                          * reliably used from other processes.
661                          *
662                          * For now, we can only check these types of devices, we
663                          * might not store a database, and have no way to find out
664                          * for all other types of devices.
665                          */
666                         if (!udev_device_get_is_initialized(dev) &&
667                             (major(udev_device_get_devnum(dev)) > 0 || udev_device_get_ifindex(dev) > 0))
668                                 goto nomatch;
669                 }
670                 if (!match_parent(udev_enumerate, dev))
671                         goto nomatch;
672                 if (!match_tag(udev_enumerate, dev))
673                         goto nomatch;
674                 if (!match_property(udev_enumerate, dev))
675                         goto nomatch;
676                 if (!match_sysattr(udev_enumerate, dev))
677                         goto nomatch;
678
679                 syspath_add(udev_enumerate, udev_device_get_syspath(dev));
680 nomatch:
681                 udev_device_unref(dev);
682         }
683         closedir(dir);
684         return 0;
685 }
686
687 static bool match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem)
688 {
689         struct udev_list_entry *list_entry;
690
691         udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->subsystem_nomatch_list)) {
692                 if (fnmatch(udev_list_entry_get_name(list_entry), subsystem, 0) == 0)
693                         return false;
694         }
695         if (udev_list_get_entry(&udev_enumerate->subsystem_match_list) != NULL) {
696                 udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->subsystem_match_list)) {
697                         if (fnmatch(udev_list_entry_get_name(list_entry), subsystem, 0) == 0)
698                                 return true;
699                 }
700                 return false;
701         }
702         return true;
703 }
704
705 static int scan_dir(struct udev_enumerate *udev_enumerate, const char *basedir, const char *subdir, const char *subsystem)
706 {
707         char path[UTIL_PATH_SIZE];
708         DIR *dir;
709         struct dirent *dent;
710
711         util_strscpyl(path, sizeof(path), "/sys/", basedir, NULL);
712         dir = opendir(path);
713         if (dir == NULL)
714                 return -1;
715         for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
716                 if (dent->d_name[0] == '.')
717                         continue;
718                 if (!match_subsystem(udev_enumerate, subsystem != NULL ? subsystem : dent->d_name))
719                         continue;
720                 scan_dir_and_add_devices(udev_enumerate, basedir, dent->d_name, subdir);
721         }
722         closedir(dir);
723         return 0;
724 }
725
726 /**
727  * udev_enumerate_add_syspath:
728  * @udev_enumerate: context
729  * @syspath: path of a device
730  *
731  * Add a device to the list of devices, to retrieve it back sorted in dependency order.
732  *
733  * Returns: 0 on success, otherwise a negative error value.
734  */
735 _public_ int udev_enumerate_add_syspath(struct udev_enumerate *udev_enumerate, const char *syspath)
736 {
737         struct udev_device *udev_device;
738
739         if (udev_enumerate == NULL)
740                 return -EINVAL;
741         if (syspath == NULL)
742                 return 0;
743         /* resolve to real syspath */
744         udev_device = udev_device_new_from_syspath(udev_enumerate->udev, syspath);
745         if (udev_device == NULL)
746                 return -EINVAL;
747         syspath_add(udev_enumerate, udev_device_get_syspath(udev_device));
748         udev_device_unref(udev_device);
749         return 0;
750 }
751
752 static int scan_devices_tags(struct udev_enumerate *udev_enumerate)
753 {
754         struct udev_list_entry *list_entry;
755
756         /* scan only tagged devices, use tags reverse-index, instead of searching all devices in /sys */
757         udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->tags_match_list)) {
758                 DIR *dir;
759                 struct dirent *dent;
760                 char path[UTIL_PATH_SIZE];
761
762                 util_strscpyl(path, sizeof(path), "/run/udev/tags/", udev_list_entry_get_name(list_entry), NULL);
763                 dir = opendir(path);
764                 if (dir == NULL)
765                         continue;
766                 for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
767                         struct udev_device *dev;
768
769                         if (dent->d_name[0] == '.')
770                                 continue;
771
772                         dev = udev_device_new_from_id_filename(udev_enumerate->udev, dent->d_name);
773                         if (dev == NULL)
774                                 continue;
775
776                         if (!match_subsystem(udev_enumerate, udev_device_get_subsystem(dev)))
777                                 goto nomatch;
778                         if (!match_sysname(udev_enumerate, udev_device_get_sysname(dev)))
779                                 goto nomatch;
780                         if (!match_parent(udev_enumerate, dev))
781                                 goto nomatch;
782                         if (!match_property(udev_enumerate, dev))
783                                 goto nomatch;
784                         if (!match_sysattr(udev_enumerate, dev))
785                                 goto nomatch;
786
787                         syspath_add(udev_enumerate, udev_device_get_syspath(dev));
788 nomatch:
789                         udev_device_unref(dev);
790                 }
791                 closedir(dir);
792         }
793         return 0;
794 }
795
796 static int parent_add_child(struct udev_enumerate *enumerate, const char *path)
797 {
798         struct udev_device *dev;
799
800         dev = udev_device_new_from_syspath(enumerate->udev, path);
801         if (dev == NULL)
802                 return -ENODEV;
803
804         if (!match_subsystem(enumerate, udev_device_get_subsystem(dev)))
805                 return 0;
806         if (!match_sysname(enumerate, udev_device_get_sysname(dev)))
807                 return 0;
808         if (!match_property(enumerate, dev))
809                 return 0;
810         if (!match_sysattr(enumerate, dev))
811                 return 0;
812
813         syspath_add(enumerate, udev_device_get_syspath(dev));
814         udev_device_unref(dev);
815         return 1;
816 }
817
818 static int parent_crawl_children(struct udev_enumerate *enumerate, const char *path, int maxdepth)
819 {
820         DIR *d;
821         struct dirent *dent;
822
823         d = opendir(path);
824         if (d == NULL)
825                 return -errno;
826
827         for (dent = readdir(d); dent != NULL; dent = readdir(d)) {
828                 char *child;
829
830                 if (dent->d_name[0] == '.')
831                         continue;
832                 if (dent->d_type != DT_DIR)
833                         continue;
834                 if (asprintf(&child, "%s/%s", path, dent->d_name) < 0)
835                         continue;
836                 parent_add_child(enumerate, child);
837                 if (maxdepth > 0)
838                         parent_crawl_children(enumerate, child, maxdepth-1);
839                 free(child);
840         }
841
842         closedir(d);
843         return 0;
844 }
845
846 static int scan_devices_children(struct udev_enumerate *enumerate)
847 {
848         const char *path;
849
850         path = udev_device_get_syspath(enumerate->parent_match);
851         parent_add_child(enumerate, path);
852         return parent_crawl_children(enumerate, path, 256);
853 }
854
855 static int scan_devices_all(struct udev_enumerate *udev_enumerate)
856 {
857         struct stat statbuf;
858
859         if (stat("/sys/subsystem", &statbuf) == 0) {
860                 /* we have /subsystem/, forget all the old stuff */
861                 scan_dir(udev_enumerate, "subsystem", "devices", NULL);
862         } else {
863                 scan_dir(udev_enumerate, "bus", "devices", NULL);
864                 scan_dir(udev_enumerate, "class", NULL, NULL);
865         }
866         return 0;
867 }
868
869 /**
870  * udev_enumerate_scan_devices:
871  * @udev_enumerate: udev enumeration context
872  *
873  * Returns: 0 on success, otherwise a negative error value.
874  **/
875 _public_ int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate)
876 {
877         if (udev_enumerate == NULL)
878                 return -EINVAL;
879
880         /* efficiently lookup tags only, we maintain a reverse-index */
881         if (udev_list_get_entry(&udev_enumerate->tags_match_list) != NULL)
882                 return scan_devices_tags(udev_enumerate);
883
884         /* walk the subtree of one parent device only */
885         if (udev_enumerate->parent_match != NULL)
886                 return scan_devices_children(udev_enumerate);
887
888         /* scan devices of all subsystems */
889         return scan_devices_all(udev_enumerate);
890 }
891
892 /**
893  * udev_enumerate_scan_subsystems:
894  * @udev_enumerate: udev enumeration context
895  *
896  * Returns: 0 on success, otherwise a negative error value.
897  **/
898 _public_ int udev_enumerate_scan_subsystems(struct udev_enumerate *udev_enumerate)
899 {
900         struct stat statbuf;
901         const char *subsysdir;
902
903         if (udev_enumerate == NULL)
904                 return -EINVAL;
905
906         /* all kernel modules */
907         if (match_subsystem(udev_enumerate, "module"))
908                 scan_dir_and_add_devices(udev_enumerate, "module", NULL, NULL);
909
910         if (stat("/sys/subsystem", &statbuf) == 0)
911                 subsysdir = "subsystem";
912         else
913                 subsysdir = "bus";
914
915         /* all subsystems (only buses support coldplug) */
916         if (match_subsystem(udev_enumerate, "subsystem"))
917                 scan_dir_and_add_devices(udev_enumerate, subsysdir, NULL, NULL);
918
919         /* all subsystem drivers */
920         if (match_subsystem(udev_enumerate, "drivers"))
921                 scan_dir(udev_enumerate, subsysdir, "drivers", "drivers");
922         return 0;
923 }