+int unit_file_preset_all(
+ UnitFileScope scope,
+ bool runtime,
+ const char *root_dir,
+ UnitFilePresetMode mode,
+ bool force,
+ UnitFileChange **changes,
+ unsigned *n_changes) {
+
+ _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
+ _cleanup_lookup_paths_free_ LookupPaths paths = {};
+ _cleanup_free_ char *config_path = NULL;
+ char **i;
+ int r, q;
+
+ assert(scope >= 0);
+ assert(scope < _UNIT_FILE_SCOPE_MAX);
+ assert(mode < _UNIT_FILE_PRESET_MAX);
+
+ r = lookup_paths_init_from_scope(&paths, scope, root_dir);
+ if (r < 0)
+ return r;
+
+ r = get_config_path(scope, runtime, root_dir, &config_path);
+ if (r < 0)
+ return r;
+
+ STRV_FOREACH(i, paths.unit_path) {
+ _cleanup_closedir_ DIR *d = NULL;
+ _cleanup_free_ char *units_dir;
+
+ units_dir = path_join(root_dir, *i, NULL);
+ if (!units_dir)
+ return -ENOMEM;
+
+ d = opendir(units_dir);
+ if (!d) {
+ if (errno == ENOENT)
+ continue;
+
+ return -errno;
+ }
+
+ for (;;) {
+ struct dirent *de;
+
+ errno = 0;
+ de = readdir(d);
+ if (!de && errno != 0)
+ return -errno;
+
+ if (!de)
+ break;
+
+ if (hidden_file(de->d_name))
+ continue;
+
+ if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
+ continue;
+
+ dirent_ensure_type(d, de);
+
+ if (de->d_type != DT_REG)
+ continue;
+
+ r = unit_file_query_preset(scope, root_dir, de->d_name);
+ if (r < 0)
+ return r;
+
+ if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
+ r = install_info_add_auto(&plus, de->d_name);
+ else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
+ r = install_info_add_auto(&minus, de->d_name);
+ else
+ r = 0;
+ if (r < 0)
+ return r;
+ }
+ }
+
+ r = 0;
+
+ if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
+ _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
+
+ r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
+
+ q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, NULL);
+ if (r == 0)
+ r = q;
+ }
+
+ if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
+ q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
+ if (r == 0)
+ r = q;
+ }
+
+ return r;
+}
+
+static void unit_file_list_free_one(UnitFileList *f) {
+ if (!f)
+ return;
+
+ free(f->path);
+ free(f);
+}
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(UnitFileList*, unit_file_list_free_one);
+