]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libudev/libudev-hwdb.c
d2665278c1ff3d305758bedd22c530315a7f7fb3
[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 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include "sd-hwdb.h"
22
23 #include "alloc-util.h"
24 #include "hwdb-util.h"
25 #include "libudev-private.h"
26
27 /**
28 * SECTION:libudev-hwdb
29 * @short_description: retrieve properties from the hardware database
30 *
31 * Libudev hardware database interface.
32 */
33
34 /**
35 * udev_hwdb:
36 *
37 * Opaque object representing the hardware database.
38 */
39 struct udev_hwdb {
40 struct udev *udev;
41 int refcount;
42
43 sd_hwdb *hwdb;
44
45 struct udev_list properties_list;
46 };
47
48 /**
49 * udev_hwdb_new:
50 * @udev: udev library context
51 *
52 * Create a hardware database context to query properties for devices.
53 *
54 * Returns: a hwdb context.
55 **/
56 _public_ struct udev_hwdb *udev_hwdb_new(struct udev *udev) {
57 _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb_internal = NULL;
58 struct udev_hwdb *hwdb;
59 int r;
60
61 assert_return_errno(udev, NULL, EINVAL);
62
63 r = sd_hwdb_new(&hwdb_internal);
64 if (r < 0) {
65 errno = -r;
66 return NULL;
67 }
68
69 hwdb = new0(struct udev_hwdb, 1);
70 if (!hwdb) {
71 errno = ENOMEM;
72 return NULL;
73 }
74
75 hwdb->refcount = 1;
76 hwdb->hwdb = hwdb_internal;
77 hwdb_internal = NULL;
78
79 udev_list_init(udev, &hwdb->properties_list, true);
80
81 return hwdb;
82 }
83
84 /**
85 * udev_hwdb_ref:
86 * @hwdb: context
87 *
88 * Take a reference of a hwdb context.
89 *
90 * Returns: the passed enumeration context
91 **/
92 _public_ struct udev_hwdb *udev_hwdb_ref(struct udev_hwdb *hwdb) {
93 if (!hwdb)
94 return NULL;
95 hwdb->refcount++;
96 return hwdb;
97 }
98
99 /**
100 * udev_hwdb_unref:
101 * @hwdb: context
102 *
103 * Drop a reference of a hwdb context. If the refcount reaches zero,
104 * all resources of the hwdb context will be released.
105 *
106 * Returns: #NULL
107 **/
108 _public_ struct udev_hwdb *udev_hwdb_unref(struct udev_hwdb *hwdb) {
109 if (!hwdb)
110 return NULL;
111 hwdb->refcount--;
112 if (hwdb->refcount > 0)
113 return NULL;
114 sd_hwdb_unref(hwdb->hwdb);
115 udev_list_cleanup(&hwdb->properties_list);
116 return mfree(hwdb);
117 }
118
119 /**
120 * udev_hwdb_get_properties_list_entry:
121 * @hwdb: context
122 * @modalias: modalias string
123 * @flags: (unused)
124 *
125 * Lookup a matching device in the hardware database. The lookup key is a
126 * modalias string, whose formats are defined for the Linux kernel modules.
127 * Examples are: pci:v00008086d00001C2D*, usb:v04F2pB221*. The first entry
128 * of a list of retrieved properties is returned.
129 *
130 * Returns: a udev_list_entry.
131 */
132 _public_ struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev_hwdb *hwdb, const char *modalias, unsigned int flags) {
133 const char *key, *value;
134 struct udev_list_entry *e;
135
136 if (!hwdb || !modalias) {
137 errno = EINVAL;
138 return NULL;
139 }
140
141 udev_list_cleanup(&hwdb->properties_list);
142
143 SD_HWDB_FOREACH_PROPERTY(hwdb->hwdb, modalias, key, value) {
144 if (udev_list_entry_add(&hwdb->properties_list, key, value) == NULL) {
145 errno = ENOMEM;
146 return NULL;
147 }
148 }
149
150 e = udev_list_get_entry(&hwdb->properties_list);
151 if (!e)
152 errno = ENODATA;
153
154 return e;
155 }