X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fudev%2Fudevadm-hwdb.c;h=a5870d1cee3e091ba5bbbd0d940127acd062b519;hb=73ae2b7dade339c8a258dcf4fa2b302e238117e1;hp=16abbe8d2f3b29349d43c5670029a5ecec6fa609;hpb=955d98c9c1104d469c2989dbfb58f58ee6fe9bdc;p=elogind.git diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c index 16abbe8d2..a5870d1ce 100644 --- a/src/udev/udevadm-hwdb.c +++ b/src/udev/udevadm-hwdb.c @@ -341,7 +341,7 @@ static int trie_store(struct trie *trie, const char *filename) { struct trie_f t = { .trie = trie, }; - char *filename_tmp; + _cleanup_free_ char *filename_tmp = NULL; int64_t pos; int64_t root_off; int64_t size; @@ -365,7 +365,12 @@ static int trie_store(struct trie *trie, const char *filename) { fchmod(fileno(t.f), 0444); /* write nodes */ - fseeko(t.f, sizeof(struct trie_header_f), SEEK_SET); + err = fseeko(t.f, sizeof(struct trie_header_f), SEEK_SET); + if (err < 0) { + fclose(t.f); + unlink_noerrno(filename_tmp); + return -errno; + } root_off = trie_store_nodes(&t, trie->root); h.nodes_root_off = htole64(root_off); pos = ftello(t.f); @@ -378,15 +383,20 @@ static int trie_store(struct trie *trie, const char *filename) { /* write header */ size = ftello(t.f); h.file_size = htole64(size); - fseeko(t.f, 0, SEEK_SET); + err = fseeko(t.f, 0, SEEK_SET); + if (err < 0) { + fclose(t.f); + unlink_noerrno(filename_tmp); + return -errno; + } fwrite(&h, sizeof(struct trie_header_f), 1, t.f); err = ferror(t.f); if (err) err = -errno; fclose(t.f); if (err < 0 || rename(filename_tmp, filename) < 0) { - unlink(filename_tmp); - goto out; + unlink_noerrno(filename_tmp); + return err < 0 ? err : -errno; } log_debug("=== trie on-disk ==="); @@ -400,9 +410,8 @@ static int trie_store(struct trie *trie, const char *filename) { t.values_count * sizeof(struct trie_value_entry_f), t.values_count); log_debug("string store: %8zu bytes", trie->strings->len); log_debug("strings start: %8"PRIu64, t.strings_off); -out: - free(filename_tmp); - return err; + + return 0; } static int insert_data(struct trie *trie, struct udev_list *match_list, @@ -419,6 +428,10 @@ static int insert_data(struct trie *trie, struct udev_list *match_list, value[0] = '\0'; value++; + /* libudev requires properties to start with a space */ + while (isblank(line[0]) && isblank(line[1])) + line++; + if (line[0] == '\0' || value[0] == '\0') { log_error("Error, empty key or value '%s' in '%s':", line, filename); return -EINVAL; @@ -527,14 +540,20 @@ static int import_file(struct udev *udev, struct trie *trie, const char *filenam static void help(void) { printf("Usage: udevadm hwdb OPTIONS\n" " -u,--update update the hardware database\n" + " --usr generate in " UDEVLIBEXECDIR " instead of /etc/udev\n" " -t,--test=MODALIAS query database and print result\n" " -r,--root=PATH alternative root path in the filesystem\n" " -h,--help\n\n"); } static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { + enum { + ARG_USR = 0x100, + }; + static const struct option options[] = { { "update", no_argument, NULL, 'u' }, + { "usr", no_argument, NULL, ARG_USR }, { "test", required_argument, NULL, 't' }, { "root", required_argument, NULL, 'r' }, { "help", no_argument, NULL, 'h' }, @@ -542,6 +561,7 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { }; const char *test = NULL; const char *root = ""; + const char *hwdb_bin_dir = "/etc/udev"; bool update = false; struct trie *trie = NULL; int err, c; @@ -552,6 +572,9 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { case 'u': update = true; break; + case ARG_USR: + hwdb_bin_dir = UDEVLIBEXECDIR; + break; case 't': test = optarg; break; @@ -599,7 +622,7 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { err = conf_files_list_strv(&files, ".hwdb", root, conf_file_dirs); if (err < 0) { - log_error("failed to enumerate hwdb files: %s", strerror(-err)); + log_error_errno(err, "failed to enumerate hwdb files: %m"); rc = EXIT_FAILURE; goto out; } @@ -625,14 +648,15 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { log_debug("strings dedup'ed: %8zu bytes (%8zu)", trie->strings->dedup_len, trie->strings->dedup_count); - if (asprintf(&hwdb_bin, "%s/etc/udev/hwdb.bin", root) < 0) { + hwdb_bin = strjoin(root, "/", hwdb_bin_dir, "/hwdb.bin", NULL); + if (!hwdb_bin) { rc = EXIT_FAILURE; goto out; } mkdir_parents(hwdb_bin, 0755); err = trie_store(trie, hwdb_bin); if (err < 0) { - log_error("Failure writing database %s: %s", hwdb_bin, strerror(-err)); + log_error_errno(err, "Failure writing database %s: %m", hwdb_bin); rc = EXIT_FAILURE; } }