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