int catalog_update(const char* database, const char* root, const char* const* dirs) { _cleanup_strv_free_ char **files = NULL; char **f; struct strbuf *sb = NULL; _cleanup_hashmap_free_free_ Hashmap *h = NULL; _cleanup_free_ CatalogItem *items = NULL; CatalogItem *i; Iterator j; unsigned n; long r; h = hashmap_new(catalog_hash_func, catalog_compare_func); sb = strbuf_new(); if (!h || !sb) { r = log_oom(); goto finish; } r = conf_files_list_strv(&files, ".catalog", root, dirs); if (r < 0) { log_error("Failed to get catalog files: %s", strerror(-r)); goto finish; } STRV_FOREACH(f, files) { log_debug("Reading file '%s'", *f); r = catalog_import_file(h, sb, *f); if (r < 0) { log_error("Failed to import file '%s': %s.", *f, strerror(-r)); goto finish; } }
int main(int argc, char *argv[]) { int r, k; r = parse_argv(argc, argv); if (r <= 0) return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; log_set_target(LOG_TARGET_AUTO); log_parse_environment(); log_open(); umask(0022); r = 0; if (argc > optind) { int i; for (i = optind; i < argc; i++) { k = apply_file(argv[i], false); if (k < 0 && r == 0) r = k; } } else { _cleanup_strv_free_ char **files = NULL; char **f; r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char**) CONF_PATHS_STRV("binfmt.d")); if (r < 0) { log_error_errno(r, "Failed to enumerate binfmt.d files: %m"); goto finish; } if (arg_cat_config) { (void) pager_open(arg_no_pager, false); r = cat_files(NULL, files, 0); goto finish; } /* Flush out all rules */ write_string_file("/proc/sys/fs/binfmt_misc/status", "-1", 0); STRV_FOREACH(f, files) { k = apply_file(*f, true); if (k < 0 && r == 0) r = k; } }
static int load_and_print(void) { _cleanup_strv_free_ char **dirs = NULL, **files = NULL, **env = NULL; char **i; int r; r = environment_dirs(&dirs); if (r < 0) return r; r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char **) dirs); if (r < 0) return r; /* This will mutate the existing environment, based on the presumption * that in case of failure, a partial update is better than none. */ STRV_FOREACH(i, files) { r = merge_env_file(&env, NULL, *i); if (r == -ENOMEM) return r; }
int link_config_load(link_config_ctx *ctx) { int r; _cleanup_strv_free_ char **files; char **f; link_configs_free(ctx); if (!enable_name_policy()) { ctx->enable_name_policy = false; log_info("Network interface NamePolicy= disabled on kernel command line, ignoring."); } /* update timestamp */ paths_check_timestamp(link_dirs, &ctx->link_dirs_ts_usec, true); r = conf_files_list_strv(&files, ".link", NULL, link_dirs); if (r < 0) return log_error_errno(r, "failed to enumerate link files: %m"); STRV_FOREACH_BACKWARDS(f, files) { r = load_link(ctx, *f); if (r < 0) return r; }
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 *root = ""; char *udev_hwdb_path = UDEV_HWDB_BIN; bool update = false; struct trie *trie = NULL; int err; int rc = EXIT_SUCCESS; for (;;) { int option; option = getopt_long(argc, argv, "ut:r:h", options, NULL); if (option == -1) break; switch (option) { case 'u': update = true; break; case 't': test = optarg; break; case 'r': root = optarg; break; case 'h': help(); return EXIT_SUCCESS; } } if (!update && !test) { help(); return EXIT_SUCCESS; } if (update) { char **files, **f; trie = calloc(sizeof(struct trie), 1); if (!trie) { rc = EXIT_FAILURE; goto out; } /* string store */ trie->strings = strbuf_new(); if (!trie->strings) { rc = EXIT_FAILURE; goto out; } /* index */ trie->root = calloc(sizeof(struct trie_node), 1); if (!trie->root) { rc = EXIT_FAILURE; goto out; } trie->nodes_count++; err = conf_files_list_strv(&files, ".hwdb", root, conf_file_dirs); if (err < 0) { log_error("failed to enumerate hwdb files: %s\n", strerror(-err)); rc = EXIT_FAILURE; goto out; } STRV_FOREACH(f, files) { log_debug("reading file '%s'", *f); import_file(udev, trie, *f); } strv_free(files); strbuf_complete(trie->strings); log_debug("=== trie in-memory ===\n"); log_debug("nodes: %8zu bytes (%8zu)\n", trie->nodes_count * sizeof(struct trie_node), trie->nodes_count); log_debug("children arrays: %8zu bytes (%8zu)\n", trie->children_count * sizeof(struct trie_child_entry), trie->children_count); log_debug("values arrays: %8zu bytes (%8zu)\n", trie->values_count * sizeof(struct trie_value_entry), trie->values_count); log_debug("strings: %8zu bytes\n", trie->strings->len); log_debug("strings incoming: %8zu bytes (%8zu)\n", trie->strings->in_len, trie->strings->in_count); log_debug("strings dedup'ed: %8zu bytes (%8zu)\n", trie->strings->dedup_len, trie->strings->dedup_count); if (root) { if (asprintf(&udev_hwdb_path, "%s/%s", root, udev_hwdb_path) < 0) { rc = EXIT_FAILURE; goto out; } } mkdir_parents(udev_hwdb_path, 0755); err = trie_store(trie, udev_hwdb_path); if (root) { free(udev_hwdb_path); } if (err < 0) { log_error("Failure writing database %s: %s", udev_hwdb_path, strerror(-err)); rc = EXIT_FAILURE; } }
static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { static const struct option options[] = { { "update", no_argument, NULL, 'u' }, { "test", required_argument, NULL, 't' }, { "root", required_argument, NULL, 'r' }, { "help", no_argument, NULL, 'h' }, {} }; const char *test = NULL; const char *root = ""; bool update = false; struct trie *trie = NULL; int err, c; int rc = EXIT_SUCCESS; while ((c = getopt_long(argc, argv, "ut:r:h", options, NULL)) >= 0) switch(c) { case 'u': update = true; break; case 't': test = optarg; break; case 'r': root = optarg; break; case 'h': help(); return EXIT_SUCCESS; case '?': return EXIT_FAILURE; default: assert_not_reached("Unknown option"); } if (!update && !test) { log_error("Either --update or --test must be used"); return EXIT_FAILURE; } if (update) { char **files, **f; _cleanup_free_ char *hwdb_bin = UDEV_HWDB_BIN; trie = calloc(sizeof(struct trie), 1); if (!trie) { rc = EXIT_FAILURE; goto out; } /* string store */ trie->strings = strbuf_new(); if (!trie->strings) { rc = EXIT_FAILURE; goto out; } /* index */ trie->root = calloc(sizeof(struct trie_node), 1); if (!trie->root) { rc = EXIT_FAILURE; goto out; } trie->nodes_count++; err = conf_files_list_strv(&files, ".hwdb", root, conf_file_dirs); if (err < 0) { log_error("failed to enumerate hwdb files: %s", strerror(-err)); rc = EXIT_FAILURE; goto out; } STRV_FOREACH(f, files) { log_debug("reading file '%s'", *f); import_file(udev, trie, *f); } strv_free(files); strbuf_complete(trie->strings); log_debug("=== trie in-memory ==="); log_debug("nodes: %8zu bytes (%8zu)", trie->nodes_count * sizeof(struct trie_node), trie->nodes_count); log_debug("children arrays: %8zu bytes (%8zu)", trie->children_count * sizeof(struct trie_child_entry), trie->children_count); log_debug("values arrays: %8zu bytes (%8zu)", trie->values_count * sizeof(struct trie_value_entry), trie->values_count); log_debug("strings: %8zu bytes", trie->strings->len); log_debug("strings incoming: %8zu bytes (%8zu)", trie->strings->in_len, trie->strings->in_count); log_debug("strings dedup'ed: %8zu bytes (%8zu)", trie->strings->dedup_len, trie->strings->dedup_count); if (asprintf(&hwdb_bin, "%s/%s", root, hwdb_bin) < 0) { 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)); rc = EXIT_FAILURE; } }
static int do_execute( char **directories, usec_t timeout, gather_stdout_callback_t const callbacks[_STDOUT_CONSUME_MAX], void* const callback_args[_STDOUT_CONSUME_MAX], int output_fd, char *argv[], char *envp[], ExecDirFlags flags) { _cleanup_hashmap_free_free_ Hashmap *pids = NULL; _cleanup_strv_free_ char **paths = NULL; char **path, **e; int r; bool parallel_execution; /* We fork this all off from a child process so that we can somewhat cleanly make * use of SIGALRM to set a time limit. * * We attempt to perform parallel execution if configured by the user, however * if `callbacks` is nonnull, execution must be serial. */ parallel_execution = FLAGS_SET(flags, EXEC_DIR_PARALLEL) && !callbacks; r = conf_files_list_strv(&paths, NULL, NULL, CONF_FILES_EXECUTABLE|CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED, (const char* const*) directories); if (r < 0) return log_error_errno(r, "Failed to enumerate executables: %m"); if (parallel_execution) { pids = hashmap_new(NULL); if (!pids) return log_oom(); } /* Abort execution of this process after the timout. We simply rely on SIGALRM as * default action terminating the process, and turn on alarm(). */ if (timeout != USEC_INFINITY) alarm(DIV_ROUND_UP(timeout, USEC_PER_SEC)); STRV_FOREACH(e, envp) if (putenv(*e) != 0) return log_error_errno(errno, "Failed to set environment variable: %m"); STRV_FOREACH(path, paths) { _cleanup_free_ char *t = NULL; _cleanup_close_ int fd = -1; pid_t pid; t = strdup(*path); if (!t) return log_oom(); if (callbacks) { fd = open_serialization_fd(basename(*path)); if (fd < 0) return log_error_errno(fd, "Failed to open serialization file: %m"); } r = do_spawn(t, argv, fd, &pid); if (r <= 0) continue; if (parallel_execution) { r = hashmap_put(pids, PID_TO_PTR(pid), t); if (r < 0) return log_oom(); t = NULL; } else { r = wait_for_terminate_and_check(t, pid, WAIT_LOG); if (FLAGS_SET(flags, EXEC_DIR_IGNORE_ERRORS)) { if (r < 0) continue; } else if (r > 0) return r; if (callbacks) { if (lseek(fd, 0, SEEK_SET) < 0) return log_error_errno(errno, "Failed to seek on serialization fd: %m"); r = callbacks[STDOUT_GENERATE](fd, callback_args[STDOUT_GENERATE]); fd = -1; if (r < 0) return log_error_errno(r, "Failed to process output from %s: %m", *path); } } }