http://github.com/lu-zero/eudev/commit/96da532526fec9bbfc9f53f2c5819520b971710c --- src/shared/conf-files.c +++ src/shared/conf-files.c @@ -37,11 +37,27 @@ #include "hashmap.h" #include "conf-files.h" -static int files_add(Hashmap *h, const char *path, const char *suffix) { +static int files_add(Hashmap *h, + const char *prefix, + const char *path, + const char *suffix) { DIR *dir; int r = 0; - dir = opendir(path); + if (prefix) { + char *p = NULL; + + if (asprintf(&p, "%s/%s", prefix, path) < 0) { + r = -ENOMEM; + goto finish; + } + + dir = opendir(p); + free(p); + } else { + dir = opendir(path); + } + if (!dir) { if (errno == ENOENT) return 0; @@ -90,7 +106,10 @@ return strcmp(path_get_file_name(s1), path_get_file_name(s2)); } -int conf_files_list_strv(char ***strv, const char *suffix, const char **dirs) { +int conf_files_list_strv(char ***strv, + const char *prefix, + const char *suffix, + const char **dirs) { Hashmap *fh = NULL; char **files = NULL; const char **p; @@ -105,7 +124,7 @@ } STRV_FOREACH(p, dirs) { - r = files_add(fh, *p, suffix); + r = files_add(fh, prefix, *p, suffix); if (r < 0) log_warning("Failed to search for files in %s: %s", *p, strerror(-r)); @@ -126,7 +145,10 @@ return r; } -int conf_files_list(char ***strv, const char *suffix, const char *dir, ...) { +int conf_files_list(char ***strv, + const char *prefix, + const char *suffix, + const char *dir, ...) { char **dirs = NULL; va_list ap; int r; @@ -145,7 +167,7 @@ } strv_uniq(dirs); - r = conf_files_list_strv(strv, suffix, (const char **)dirs); + r = conf_files_list_strv(strv, prefix, suffix, (const char **)dirs); finish: strv_free(dirs); --- src/shared/conf-files.h +++ src/shared/conf-files.h @@ -25,7 +25,13 @@ #include "macro.h" -int conf_files_list(char ***strv, const char *suffix, const char *dir, ...); -int conf_files_list_strv(char ***strv, const char *suffix, const char **dirs); +int conf_files_list(char ***strv, + const char *prefix, + const char *suffix, + const char *dir, ...); +int conf_files_list_strv(char ***strv, + const char *prefix, + const char *suffix, + const char **dirs); #endif --- src/udev/udevadm-hwdb.c +++ src/udev/udevadm-hwdb.c @@ -472,17 +472,20 @@ printf("Usage: udevadm hwdb OPTIONS\n" " --update update the hardware database\n" " --test query database and print result\n" + " --root define custom root path\n" " --help\n\n"); } static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { static const struct option options[] = { { "update", no_argument, NULL, 'u' }, + { "root", required_argument, NULL, 'r' }, { "test", required_argument, NULL, 't' }, { "help", no_argument, NULL, 'h' }, {} }; - const char *test = NULL; + const char *test = NULL, *root_path = NULL; + char *udev_hwdb_path = HWDB_BIN; bool update = false; struct trie *trie = NULL; int err; @@ -491,7 +494,7 @@ for (;;) { int option; - option = getopt_long(argc, argv, "ut:h", options, NULL); + option = getopt_long(argc, argv, "ut:r:h", options, NULL); if (option == -1) break; @@ -502,6 +505,9 @@ case 't': test = optarg; break; + case 'r': + root_path = optarg; + break; case 'h': help(); return EXIT_SUCCESS; @@ -537,7 +543,7 @@ } trie->nodes_count++; - err = conf_files_list_strv(&files, ".hwdb", (const char **)conf_file_dirs); + err = conf_files_list_strv(&files, root_path, ".hwdb", (const char **)conf_file_dirs); if (err < 0) { log_error("failed to enumerate hwdb files: %s\n", strerror(-err)); rc = EXIT_FAILURE; @@ -565,11 +571,24 @@ log_debug("strings dedup'ed: %8zu bytes (%8zu)\n", trie->strings->dedup_len, trie->strings->dedup_count); - mkdir_parents(HWDB_BIN, 0755); - err = trie_store(trie, HWDB_BIN); + if (root_path) { + if (asprintf(&udev_hwdb_path, + "%s/%s", root_path, udev_hwdb_path) < 0) { + rc = EXIT_FAILURE; + goto out; + } + } + + mkdir_parents(udev_hwdb_path, 0755); + err = trie_store(trie, udev_hwdb_path); + + if (root_path) { + free(udev_hwdb_path); + } + if (err < 0) { log_error("Failure writing hardware database '%s': %s", - HWDB_BIN, strerror(-err)); + udev_hwdb_path, strerror(-err)); rc = EXIT_FAILURE; } } --- src/udev/udev-rules.c +++ src/udev/udev-rules.c @@ -1619,7 +1619,7 @@ return udev_rules_unref(rules); udev_rules_check_timestamp(rules); - r = conf_files_list_strv(&files, ".rules", (const char **)rules->dirs); + r = conf_files_list_strv(&files, NULL, ".rules", (const char **)rules->dirs); if (r < 0) { log_error("failed to enumerate rules files: %s\n", strerror(-r)); return udev_rules_unref(rules);