Lines Matching refs:hwdb
32 #include "libudev-hwdb-def.h"
35 * SECTION:libudev-hwdb
103 static const struct trie_child_entry_f *trie_node_children(struct udev_hwdb *hwdb, const struct trie_node_f *node) {
104 return (const struct trie_child_entry_f *)((const char *)node + le64toh(hwdb->head->node_size));
107 static const struct trie_value_entry_f *trie_node_values(struct udev_hwdb *hwdb, const struct trie_node_f *node) {
110 base += le64toh(hwdb->head->node_size);
111 base += node->children_count * le64toh(hwdb->head->child_entry_size);
115 static const struct trie_node_f *trie_node_from_off(struct udev_hwdb *hwdb, le64_t off) {
116 return (const struct trie_node_f *)(hwdb->map + le64toh(off));
119 static const char *trie_string(struct udev_hwdb *hwdb, le64_t off) {
120 return hwdb->map + le64toh(off);
130 static const struct trie_node_f *node_lookup_f(struct udev_hwdb *hwdb, const struct trie_node_f *node, uint8_t c) {
135 child = bsearch(&search, trie_node_children(hwdb, node), node->children_count,
136 le64toh(hwdb->head->child_entry_size), trie_children_cmp_f);
138 return trie_node_from_off(hwdb, child->child_off);
142 static int hwdb_add_property(struct udev_hwdb *hwdb, const char *key, const char *value) {
150 if (udev_list_entry_add(&hwdb->properties_list, key+1, value) == NULL)
155 static int trie_fnmatch_f(struct udev_hwdb *hwdb, const struct trie_node_f *node, size_t p,
162 prefix = trie_string(hwdb, node->prefix_off);
167 const struct trie_child_entry_f *child = &trie_node_children(hwdb, node)[i];
170 err = trie_fnmatch_f(hwdb, trie_node_from_off(hwdb, child->child_off), 0, buf, search);
178 err = hwdb_add_property(hwdb, trie_string(hwdb, trie_node_values(hwdb, node)[i].key_off),
179 trie_string(hwdb, trie_node_values(hwdb, node)[i].value_off));
188 static int trie_search_f(struct udev_hwdb *hwdb, const char *search) {
196 node = trie_node_from_off(hwdb, hwdb->head->nodes_root_off);
204 for (; (c = trie_string(hwdb, node->prefix_off)[p]); p++) {
206 return trie_fnmatch_f(hwdb, node, p, &buf, search + i + p);
213 child = node_lookup_f(hwdb, node, '*');
216 err = trie_fnmatch_f(hwdb, child, 0, &buf, search + i);
222 child = node_lookup_f(hwdb, node, '?');
225 err = trie_fnmatch_f(hwdb, child, 0, &buf, search + i);
231 child = node_lookup_f(hwdb, node, '[');
234 err = trie_fnmatch_f(hwdb, child, 0, &buf, search + i);
244 err = hwdb_add_property(hwdb, trie_string(hwdb, trie_node_values(hwdb, node)[n].key_off),
245 trie_string(hwdb, trie_node_values(hwdb, node)[n].value_off));
252 child = node_lookup_f(hwdb, node, search[i]);
265 * Returns: a hwdb context.
268 struct udev_hwdb *hwdb;
271 hwdb = new0(struct udev_hwdb, 1);
272 if (!hwdb)
275 hwdb->refcount = 1;
276 udev_list_init(udev, &hwdb->properties_list, true);
278 hwdb->f = fopen(UDEV_HWDB_BIN, "re");
279 if (!hwdb->f) {
280 log_debug(UDEV_HWDB_BIN " does not exist, please run udevadm hwdb --update");
281 udev_hwdb_unref(hwdb);
285 if (fstat(fileno(hwdb->f), &hwdb->st) < 0 ||
286 (size_t)hwdb->st.st_size < offsetof(struct trie_header_f, strings_len) + 8) {
288 udev_hwdb_unref(hwdb);
292 hwdb->map = mmap(0, hwdb->st.st_size, PROT_READ, MAP_SHARED, fileno(hwdb->f), 0);
293 if (hwdb->map == MAP_FAILED) {
295 udev_hwdb_unref(hwdb);
299 if (memcmp(hwdb->map, sig, sizeof(hwdb->head->signature)) != 0 ||
300 (size_t)hwdb->st.st_size != le64toh(hwdb->head->file_size)) {
302 udev_hwdb_unref(hwdb);
307 log_debug("tool version: %"PRIu64, le64toh(hwdb->head->tool_version));
308 log_debug("file size: %8"PRIu64" bytes", hwdb->st.st_size);
309 log_debug("header size %8"PRIu64" bytes", le64toh(hwdb->head->header_size));
310 log_debug("strings %8"PRIu64" bytes", le64toh(hwdb->head->strings_len));
311 log_debug("nodes %8"PRIu64" bytes", le64toh(hwdb->head->nodes_len));
312 return hwdb;
317 * @hwdb: context
319 * Take a reference of a hwdb context.
323 _public_ struct udev_hwdb *udev_hwdb_ref(struct udev_hwdb *hwdb) {
324 if (!hwdb)
326 hwdb->refcount++;
327 return hwdb;
332 * @hwdb: context
334 * Drop a reference of a hwdb context. If the refcount reaches zero,
335 * all resources of the hwdb context will be released.
339 _public_ struct udev_hwdb *udev_hwdb_unref(struct udev_hwdb *hwdb) {
340 if (!hwdb)
342 hwdb->refcount--;
343 if (hwdb->refcount > 0)
345 if (hwdb->map)
346 munmap((void *)hwdb->map, hwdb->st.st_size);
347 if (hwdb->f)
348 fclose(hwdb->f);
349 udev_list_cleanup(&hwdb->properties_list);
350 free(hwdb);
354 bool udev_hwdb_validate(struct udev_hwdb *hwdb) {
357 if (!hwdb)
359 if (!hwdb->f)
361 if (stat("/etc/udev/hwdb.bin", &st) < 0)
364 if (timespec_load(&hwdb->st.st_mtim) != timespec_load(&st.st_mtim))
371 * @hwdb: context
382 _public_ struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev_hwdb *hwdb, const char *modalias, unsigned int flags) {
385 if (!hwdb || !hwdb->f) {
390 udev_list_cleanup(&hwdb->properties_list);
391 err = trie_search_f(hwdb, modalias);
396 return udev_list_get_entry(&hwdb->properties_list);