]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libudev/libudev-hwdb.c
Add SPDX license identifiers to source files under the LGPL
[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 free(hwdb);
117 return NULL;
118 }
119
120 /**
121 * udev_hwdb_get_properties_list_entry:
122 * @hwdb: context
123 * @modalias: modalias string
124 * @flags: (unused)
125 *
126 * Lookup a matching device in the hardware database. The lookup key is a
127 * modalias string, whose formats are defined for the Linux kernel modules.
128 * Examples are: pci:v00008086d00001C2D*, usb:v04F2pB221*. The first entry
129 * of a list of retrieved properties is returned.
130 *
131 * Returns: a udev_list_entry.
132 */
133 _public_ struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev_hwdb *hwdb, const char *modalias, unsigned int flags) {
134 const char *key, *value;
135 struct udev_list_entry *e;
136
137 if (!hwdb || !modalias) {
138 errno = EINVAL;
139 return NULL;
140 }
141
142 udev_list_cleanup(&hwdb->properties_list);
143
144 SD_HWDB_FOREACH_PROPERTY(hwdb->hwdb, modalias, key, value) {
145 if (udev_list_entry_add(&hwdb->properties_list, key, value) == NULL) {
146 errno = ENOMEM;
147 return NULL;
148 }
149 }
150
151 e = udev_list_get_entry(&hwdb->properties_list);
152 if (!e)
153 errno = ENODATA;
154
155 return e;
156 }