]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libudev/libudev-hwdb.c
c32aeb5205f0bc781a08d215744450788b412cef
[thirdparty/systemd.git] / src / libudev / libudev-hwdb.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright Tom Gundersen <teg@jklm.no>
6 ***/
7
8 #include "sd-hwdb.h"
9
10 #include "alloc-util.h"
11 #include "hwdb-util.h"
12 #include "libudev-private.h"
13
14 /**
15 * SECTION:libudev-hwdb
16 * @short_description: retrieve properties from the hardware database
17 *
18 * Libudev hardware database interface.
19 */
20
21 /**
22 * udev_hwdb:
23 *
24 * Opaque object representing the hardware database.
25 */
26 struct udev_hwdb {
27 struct udev *udev;
28 int refcount;
29
30 sd_hwdb *hwdb;
31
32 struct udev_list properties_list;
33 };
34
35 /**
36 * udev_hwdb_new:
37 * @udev: udev library context
38 *
39 * Create a hardware database context to query properties for devices.
40 *
41 * Returns: a hwdb context.
42 **/
43 _public_ struct udev_hwdb *udev_hwdb_new(struct udev *udev) {
44 _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb_internal = NULL;
45 struct udev_hwdb *hwdb;
46 int r;
47
48 assert_return_errno(udev, NULL, EINVAL);
49
50 r = sd_hwdb_new(&hwdb_internal);
51 if (r < 0) {
52 errno = -r;
53 return NULL;
54 }
55
56 hwdb = new0(struct udev_hwdb, 1);
57 if (!hwdb) {
58 errno = ENOMEM;
59 return NULL;
60 }
61
62 hwdb->refcount = 1;
63 hwdb->hwdb = TAKE_PTR(hwdb_internal);
64
65 udev_list_init(udev, &hwdb->properties_list, true);
66
67 return hwdb;
68 }
69
70 /**
71 * udev_hwdb_ref:
72 * @hwdb: context
73 *
74 * Take a reference of a hwdb context.
75 *
76 * Returns: the passed enumeration context
77 **/
78 _public_ struct udev_hwdb *udev_hwdb_ref(struct udev_hwdb *hwdb) {
79 if (!hwdb)
80 return NULL;
81 hwdb->refcount++;
82 return hwdb;
83 }
84
85 /**
86 * udev_hwdb_unref:
87 * @hwdb: context
88 *
89 * Drop a reference of a hwdb context. If the refcount reaches zero,
90 * all resources of the hwdb context will be released.
91 *
92 * Returns: #NULL
93 **/
94 _public_ struct udev_hwdb *udev_hwdb_unref(struct udev_hwdb *hwdb) {
95 if (!hwdb)
96 return NULL;
97 hwdb->refcount--;
98 if (hwdb->refcount > 0)
99 return NULL;
100 sd_hwdb_unref(hwdb->hwdb);
101 udev_list_cleanup(&hwdb->properties_list);
102 return mfree(hwdb);
103 }
104
105 /**
106 * udev_hwdb_get_properties_list_entry:
107 * @hwdb: context
108 * @modalias: modalias string
109 * @flags: (unused)
110 *
111 * Lookup a matching device in the hardware database. The lookup key is a
112 * modalias string, whose formats are defined for the Linux kernel modules.
113 * Examples are: pci:v00008086d00001C2D*, usb:v04F2pB221*. The first entry
114 * of a list of retrieved properties is returned.
115 *
116 * Returns: a udev_list_entry.
117 */
118 _public_ struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev_hwdb *hwdb, const char *modalias, unsigned int flags) {
119 const char *key, *value;
120 struct udev_list_entry *e;
121
122 if (!hwdb || !modalias) {
123 errno = EINVAL;
124 return NULL;
125 }
126
127 udev_list_cleanup(&hwdb->properties_list);
128
129 SD_HWDB_FOREACH_PROPERTY(hwdb->hwdb, modalias, key, value) {
130 if (udev_list_entry_add(&hwdb->properties_list, key, value) == NULL) {
131 errno = ENOMEM;
132 return NULL;
133 }
134 }
135
136 e = udev_list_get_entry(&hwdb->properties_list);
137 if (!e)
138 errno = ENODATA;
139
140 return e;
141 }