From: Yu Watanabe Date: Sun, 13 Jul 2025 01:36:08 +0000 (+0900) Subject: sysupdate: use conf_files_list_strv_full() to enumerate components X-Git-Tag: v259-rc1~536^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5035e4a4f878ee824b72a561195a1f1de44d0f7f;p=thirdparty%2Fsystemd.git sysupdate: use conf_files_list_strv_full() to enumerate components With this change, root directory is correctly supported, and symlinked components are also correctly enumerated. --- diff --git a/src/sysupdate/sysupdate.c b/src/sysupdate/sysupdate.c index 692291fcfee..0b0e4e9fe36 100644 --- a/src/sysupdate/sysupdate.c +++ b/src/sysupdate/sysupdate.c @@ -1542,8 +1542,6 @@ static int verb_components(int argc, char **argv, void *userdata) { _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL; _cleanup_(umount_and_rmdir_and_freep) char *mounted_dir = NULL; _cleanup_set_free_ Set *names = NULL; - _cleanup_free_ char **z = NULL; /* We use simple free() rather than strv_free() here, since set_free() will free the strings for us */ - char **l = CONF_PATHS_STRV(""); bool has_default_component = false; int r; @@ -1553,65 +1551,49 @@ static int verb_components(int argc, char **argv, void *userdata) { if (r < 0) return r; - STRV_FOREACH(i, l) { - _cleanup_closedir_ DIR *d = NULL; - _cleanup_free_ char *p = NULL; + ConfFile **directories = NULL; + size_t n_directories = 0; - r = chase_and_opendir(*i, arg_root, CHASE_PREFIX_ROOT, &p, &d); - if (r == -ENOENT) - continue; - if (r < 0) - return log_error_errno(r, "Failed to open directory '%s': %m", *i); - - for (;;) { - _cleanup_free_ char *n = NULL; - struct dirent *de; - const char *e, *a; - - de = readdir_ensure_type(d); - if (!de) { - if (errno != 0) - return log_error_errno(errno, "Failed to enumerate directory '%s': %m", p); - - break; - } + CLEANUP_ARRAY(directories, n_directories, conf_file_free_many); - if (de->d_type != DT_DIR) - continue; + r = conf_files_list_strv_full(".d", arg_root, CONF_FILES_DIRECTORY, (const char * const *) CONF_PATHS_STRV(""), &directories, &n_directories); + if (r < 0) + return log_error_errno(r, "Failed to enumerate directories: %m"); - if (dot_or_dot_dot(de->d_name)) - continue; + FOREACH_ARRAY(i, directories, n_directories) { + ConfFile *e = *i; - if (streq(de->d_name, "sysupdate.d")) { - has_default_component = true; - continue; - } + if (streq(e->name, "sysupdate.d")) { + has_default_component = true; + continue; + } - e = startswith(de->d_name, "sysupdate."); - if (!e) - continue; + const char *s = startswith(e->name, "sysupdate."); + if (!s) + continue; - a = endswith(e, ".d"); - if (!a) - continue; + const char *a = endswith(s, ".d"); + if (!a) + continue; - n = strndup(e, a - e); - if (!n) - return log_oom(); + _cleanup_free_ char *n = strndup(s, a - s); + if (!n) + return log_oom(); - r = component_name_valid(n); - if (r < 0) - return log_error_errno(r, "Unable to validate component name: %m"); - if (r == 0) - continue; + r = component_name_valid(n); + if (r < 0) + return log_error_errno(r, "Unable to validate component name '%s': %m", n); + if (r == 0) + continue; - r = set_ensure_consume(&names, &string_hash_ops_free, TAKE_PTR(n)); - if (r < 0 && r != -EEXIST) - return log_error_errno(r, "Failed to add component to set: %m"); - } + r = set_ensure_put(&names, &string_hash_ops_free, n); + if (r < 0 && r != -EEXIST) + return log_error_errno(r, "Failed to add component '%s' to set: %m", n); + TAKE_PTR(n); } - z = set_get_strv(names); + /* We use simple free() rather than strv_free() here, since set_free() will free the strings for us */ + _cleanup_free_ char **z = set_get_strv(names); if (!z) return log_oom();