Lines Matching defs:hwdb
30 #include "sd-hwdb.h"
35 #include "hwdb-internal.h"
36 #include "hwdb-util.h"
100 static const struct trie_child_entry_f *trie_node_children(sd_hwdb *hwdb, const struct trie_node_f *node) {
101 return (const struct trie_child_entry_f *)((const char *)node + le64toh(hwdb->head->node_size));
104 static const struct trie_value_entry_f *trie_node_values(sd_hwdb *hwdb, const struct trie_node_f *node) {
107 base += le64toh(hwdb->head->node_size);
108 base += node->children_count * le64toh(hwdb->head->child_entry_size);
112 static const struct trie_node_f *trie_node_from_off(sd_hwdb *hwdb, le64_t off) {
113 return (const struct trie_node_f *)(hwdb->map + le64toh(off));
116 static const char *trie_string(sd_hwdb *hwdb, le64_t off) {
117 return hwdb->map + le64toh(off);
127 static const struct trie_node_f *node_lookup_f(sd_hwdb *hwdb, const struct trie_node_f *node, uint8_t c) {
132 child = bsearch(&search, trie_node_children(hwdb, node), node->children_count,
133 le64toh(hwdb->head->child_entry_size), trie_children_cmp_f);
135 return trie_node_from_off(hwdb, child->child_off);
139 static int hwdb_add_property(sd_hwdb *hwdb, const char *key, const char *value) {
142 assert(hwdb);
155 r = ordered_hashmap_ensure_allocated(&hwdb->properties, &string_hash_ops);
159 r = ordered_hashmap_replace(hwdb->properties, key, (char*)value);
163 hwdb->properties_modified = true;
168 static int trie_fnmatch_f(sd_hwdb *hwdb, const struct trie_node_f *node, size_t p,
175 prefix = trie_string(hwdb, node->prefix_off);
180 const struct trie_child_entry_f *child = &trie_node_children(hwdb, node)[i];
183 err = trie_fnmatch_f(hwdb, trie_node_from_off(hwdb, child->child_off), 0, buf, search);
191 err = hwdb_add_property(hwdb, trie_string(hwdb, trie_node_values(hwdb, node)[i].key_off),
192 trie_string(hwdb, trie_node_values(hwdb, node)[i].value_off));
201 static int trie_search_f(sd_hwdb *hwdb, const char *search) {
209 node = trie_node_from_off(hwdb, hwdb->head->nodes_root_off);
217 for (; (c = trie_string(hwdb, node->prefix_off)[p]); p++) {
219 return trie_fnmatch_f(hwdb, node, p, &buf, search + i + p);
226 child = node_lookup_f(hwdb, node, '*');
229 err = trie_fnmatch_f(hwdb, child, 0, &buf, search + i);
235 child = node_lookup_f(hwdb, node, '?');
238 err = trie_fnmatch_f(hwdb, child, 0, &buf, search + i);
244 child = node_lookup_f(hwdb, node, '[');
247 err = trie_fnmatch_f(hwdb, child, 0, &buf, search + i);
257 err = hwdb_add_property(hwdb, trie_string(hwdb, trie_node_values(hwdb, node)[n].key_off),
258 trie_string(hwdb, trie_node_values(hwdb, node)[n].value_off));
265 child = node_lookup_f(hwdb, node, search[i]);
273 "/etc/systemd/hwdb/hwdb.bin\0"
274 "/etc/udev/hwdb.bin\0"
275 "/usr/lib/systemd/hwdb/hwdb.bin\0"
277 "/lib/systemd/hwdb/hwdb.bin\0"
279 UDEVLIBEXECDIR "/hwdb.bin\0";
282 _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL;
288 hwdb = new0(sd_hwdb, 1);
289 if (!hwdb)
292 hwdb->n_ref = REFCNT_INIT;
294 /* find hwdb.bin in hwdb_bin_paths */
296 hwdb->f = fopen(hwdb_bin_path, "re");
297 if (hwdb->f)
305 if (!hwdb->f) {
306 log_debug("hwdb.bin does not exist, please run udevadm hwdb --update");
310 if (fstat(fileno(hwdb->f), &hwdb->st) < 0 ||
311 (size_t)hwdb->st.st_size < offsetof(struct trie_header_f, strings_len) + 8)
314 hwdb->map = mmap(0, hwdb->st.st_size, PROT_READ, MAP_SHARED, fileno(hwdb->f), 0);
315 if (hwdb->map == MAP_FAILED)
318 if (memcmp(hwdb->map, sig, sizeof(hwdb->head->signature)) != 0 ||
319 (size_t)hwdb->st.st_size != le64toh(hwdb->head->file_size)) {
325 log_debug("tool version: %"PRIu64, le64toh(hwdb->head->tool_version));
326 log_debug("file size: %8"PRIi64" bytes", hwdb->st.st_size);
327 log_debug("header size %8"PRIu64" bytes", le64toh(hwdb->head->header_size));
328 log_debug("strings %8"PRIu64" bytes", le64toh(hwdb->head->strings_len));
329 log_debug("nodes %8"PRIu64" bytes", le64toh(hwdb->head->nodes_len));
331 *ret = hwdb;
332 hwdb = NULL;
337 _public_ sd_hwdb *sd_hwdb_ref(sd_hwdb *hwdb) {
338 assert_return(hwdb, NULL);
340 assert_se(REFCNT_INC(hwdb->n_ref) >= 2);
342 return hwdb;
345 _public_ sd_hwdb *sd_hwdb_unref(sd_hwdb *hwdb) {
346 if (hwdb && REFCNT_DEC(hwdb->n_ref) == 0) {
347 if (hwdb->map)
348 munmap((void *)hwdb->map, hwdb->st.st_size);
349 safe_fclose(hwdb->f);
350 free(hwdb->modalias);
351 ordered_hashmap_free(hwdb->properties);
352 free(hwdb);
358 bool hwdb_validate(sd_hwdb *hwdb) {
363 if (!hwdb)
365 if (!hwdb->f)
368 /* if hwdb.bin doesn't exist anywhere, we need to update */
378 if (timespec_load(&hwdb->st.st_mtim) != timespec_load(&st.st_mtim))
383 static int properties_prepare(sd_hwdb *hwdb, const char *modalias) {
387 assert(hwdb);
390 if (streq_ptr(modalias, hwdb->modalias))
397 ordered_hashmap_clear(hwdb->properties);
399 hwdb->properties_modified = true;
401 r = trie_search_f(hwdb, modalias);
405 free(hwdb->modalias);
406 hwdb->modalias = mod;
412 _public_ int sd_hwdb_get(sd_hwdb *hwdb, const char *modalias, const char *key, const char **_value) {
416 assert_return(hwdb, -EINVAL);
417 assert_return(hwdb->f, -EINVAL);
421 r = properties_prepare(hwdb, modalias);
425 value = ordered_hashmap_get(hwdb->properties, key);
434 _public_ int sd_hwdb_seek(sd_hwdb *hwdb, const char *modalias) {
437 assert_return(hwdb, -EINVAL);
438 assert_return(hwdb->f, -EINVAL);
441 r = properties_prepare(hwdb, modalias);
445 hwdb->properties_modified = false;
446 hwdb->properties_iterator = ITERATOR_FIRST;
451 _public_ int sd_hwdb_enumerate(sd_hwdb *hwdb, const char **key, const char **value) {
455 assert_return(hwdb, -EINVAL);
459 if (hwdb->properties_modified)
462 ordered_hashmap_iterate(hwdb->properties, &hwdb->properties_iterator, &v, &k);