]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libudev/libudev-hwdb.c
eb71e6ebde8fc52a9413435599146c2f192ab410
[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 = TAKE_PTR(hwdb_internal);
77
78 udev_list_init(udev, &hwdb->properties_list, true);
79
80 return hwdb;
81 }
82
83 /**
84 * udev_hwdb_ref:
85 * @hwdb: context
86 *
87 * Take a reference of a hwdb context.
88 *
89 * Returns: the passed enumeration context
90 **/
91 _public_ struct udev_hwdb *udev_hwdb_ref(struct udev_hwdb *hwdb) {
92 if (!hwdb)
93 return NULL;
94 hwdb->refcount++;
95 return hwdb;
96 }
97
98 /**
99 * udev_hwdb_unref:
100 * @hwdb: context
101 *
102 * Drop a reference of a hwdb context. If the refcount reaches zero,
103 * all resources of the hwdb context will be released.
104 *
105 * Returns: #NULL
106 **/
107 _public_ struct udev_hwdb *udev_hwdb_unref(struct udev_hwdb *hwdb) {
108 if (!hwdb)
109 return NULL;
110 hwdb->refcount--;
111 if (hwdb->refcount > 0)
112 return NULL;
113 sd_hwdb_unref(hwdb->hwdb);
114 udev_list_cleanup(&hwdb->properties_list);
115 return mfree(hwdb);
116 }
117
118 /**
119 * udev_hwdb_get_properties_list_entry:
120 * @hwdb: context
121 * @modalias: modalias string
122 * @flags: (unused)
123 *
124 * Lookup a matching device in the hardware database. The lookup key is a
125 * modalias string, whose formats are defined for the Linux kernel modules.
126 * Examples are: pci:v00008086d00001C2D*, usb:v04F2pB221*. The first entry
127 * of a list of retrieved properties is returned.
128 *
129 * Returns: a udev_list_entry.
130 */
131 _public_ struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev_hwdb *hwdb, const char *modalias, unsigned int flags) {
132 const char *key, *value;
133 struct udev_list_entry *e;
134
135 if (!hwdb || !modalias) {
136 errno = EINVAL;
137 return NULL;
138 }
139
140 udev_list_cleanup(&hwdb->properties_list);
141
142 SD_HWDB_FOREACH_PROPERTY(hwdb->hwdb, modalias, key, value) {
143 if (udev_list_entry_add(&hwdb->properties_list, key, value) == NULL) {
144 errno = ENOMEM;
145 return NULL;
146 }
147 }
148
149 e = udev_list_get_entry(&hwdb->properties_list);
150 if (!e)
151 errno = ENODATA;
152
153 return e;
154 }