This file is part of systemd.
Copyright 2011 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty <of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <dirent.h>
#define UNIT_FILE_FOLLOW_SYMLINK_MAX 64
typedef enum SearchFlags {
- SEARCH_LOAD = 1,
- SEARCH_FOLLOW_CONFIG_SYMLINKS = 2,
+ SEARCH_LOAD = 1U << 0,
+ SEARCH_FOLLOW_CONFIG_SYMLINKS = 1U << 1,
+ SEARCH_DROPIN = 1U << 2,
} SearchFlags;
typedef struct {
p->n_rules = 0;
}
-static int unit_file_lookup_state(UnitFileScope scope, const LookupPaths *paths, const char *name, UnitFileState *ret);
-
bool unit_type_may_alias(UnitType type) {
return IN_SET(type,
UNIT_SERVICE,
int unit_file_changes_add(
UnitFileChange **changes,
- unsigned *n_changes,
+ size_t *n_changes,
UnitFileChangeType type,
const char *path,
const char *source) {
if (!changes)
return 0;
- c = realloc(*changes, (*n_changes + 1) * sizeof(UnitFileChange));
+ c = reallocarray(*changes, *n_changes + 1, sizeof(UnitFileChange));
if (!c)
return -ENOMEM;
*changes = c;
if (!p || (source && !s))
return -ENOMEM;
- path_kill_slashes(p);
+ path_simplify(p, false);
if (s)
- path_kill_slashes(s);
+ path_simplify(s, false);
c[*n_changes] = (UnitFileChange) { type, p, s };
p = s = NULL;
return 0;
}
-void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes) {
- unsigned i;
+void unit_file_changes_free(UnitFileChange *changes, size_t n_changes) {
+ size_t i;
assert(changes || n_changes == 0);
free(changes);
}
-void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *changes, unsigned n_changes, bool quiet) {
- unsigned i;
+void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *changes, size_t n_changes, bool quiet) {
+ size_t i;
bool logged = false;
assert(changes || n_changes == 0);
const char *new_path,
bool force,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
_cleanup_free_ char *dest = NULL, *dirname = NULL;
const char *rp;
assert(p);
- r = set_ensure_allocated(remove_symlinks_to, &string_hash_ops);
+ r = set_ensure_allocated(remove_symlinks_to, &path_hash_ops);
if (r < 0)
return r;
if (!n)
return -ENOMEM;
- path_kill_slashes(n);
+ path_simplify(n, false);
r = set_consume(*remove_symlinks_to, n);
if (r == -EEXIST)
bool dry_run,
bool *restart,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
_cleanup_closedir_ DIR *d = NULL;
struct dirent *de;
p = path_make_absolute(de->d_name, path);
if (!p)
return -ENOMEM;
- path_kill_slashes(p);
+ path_simplify(p, false);
q = readlink_malloc(p, &dest);
if (q == -ENOENT)
const LookupPaths *lp,
bool dry_run,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
_cleanup_close_ int fd = -1;
bool restart;
if (r > 0) {
/* We found symlinks in this dir? Yay! Let's see where precisely it is enabled. */
- r = path_is_config(paths, *p, false);
- if (r < 0)
- return r;
- if (r > 0) {
+ if (path_equal_ptr(*p, paths->persistent_config)) {
/* This is the best outcome, let's return it immediately. */
*state = UNIT_FILE_ENABLED;
return 1;
}
- /* look for globally enablement of user units */
+ /* look for global enablement of user units */
if (scope == UNIT_FILE_USER && path_is_user_config_dir(*p)) {
*state = UNIT_FILE_ENABLED;
return 1;
enabled_at_all = true;
} else if (same_name_link) {
-
- r = path_is_config(paths, *p, false);
- if (r < 0)
- return r;
- if (r > 0)
+ if (path_equal_ptr(*p, paths->persistent_config))
same_name_link_config = true;
else {
r = path_is_runtime(paths, *p, false);
free(i);
}
-static OrderedHashmap* install_info_hashmap_free(OrderedHashmap *m) {
- UnitFileInstallInfo *i;
-
- if (!m)
- return NULL;
-
- while ((i = ordered_hashmap_steal_first(m)))
- install_info_free(i);
-
- return ordered_hashmap_free(m);
-}
-
static void install_context_done(InstallContext *c) {
assert(c);
- c->will_process = install_info_hashmap_free(c->will_process);
- c->have_processed = install_info_hashmap_free(c->have_processed);
+ c->will_process = ordered_hashmap_free_with_destructor(c->will_process, install_info_free);
+ c->have_processed = ordered_hashmap_free_with_destructor(c->have_processed, install_info_free);
}
static UnitFileInstallInfo *install_info_find(InstallContext *c, const char *name) {
UnitFileInstallInfo *i,
const LookupPaths *paths,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
assert(i);
assert(paths);
InstallContext *c,
UnitFileInstallInfo *info,
const char *path,
+ const char *root_dir,
SearchFlags flags) {
const ConfigTableItem items[] = {
assert(info);
assert(path);
- type = unit_name_to_type(info->name);
- if (unit_name_is_valid(info->name, UNIT_NAME_TEMPLATE|UNIT_NAME_INSTANCE) &&
- !unit_type_may_template(type))
- return log_error_errno(EINVAL, "Unit type %s cannot be templated.", unit_type_to_string(type));
+ if (!(flags & SEARCH_DROPIN)) {
+ /* Loading or checking for the main unit fileā¦ */
- if (!(flags & SEARCH_LOAD)) {
- r = lstat(path, &st);
- if (r < 0)
+ type = unit_name_to_type(info->name);
+ if (type < 0)
+ return -EINVAL;
+ if (unit_name_is_valid(info->name, UNIT_NAME_TEMPLATE|UNIT_NAME_INSTANCE) && !unit_type_may_template(type)) {
+ log_error("Unit type %s cannot be templated.", unit_type_to_string(type));
+ return -EINVAL;
+ }
+
+ if (!(flags & SEARCH_LOAD)) {
+ r = lstat(path, &st);
+ if (r < 0)
+ return -errno;
+
+ if (null_or_empty(&st))
+ info->type = UNIT_FILE_TYPE_MASKED;
+ else if (S_ISREG(st.st_mode))
+ info->type = UNIT_FILE_TYPE_REGULAR;
+ else if (S_ISLNK(st.st_mode))
+ return -ELOOP;
+ else if (S_ISDIR(st.st_mode))
+ return -EISDIR;
+ else
+ return -ENOTTY;
+
+ return 0;
+ }
+
+ fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
+ if (fd < 0)
return -errno;
+ } else {
+ /* Operating on a drop-in file. If we aren't supposed to load the unit file drop-ins don't matter, let's hence shortcut this. */
- if (null_or_empty(&st))
- info->type = UNIT_FILE_TYPE_MASKED;
- else if (S_ISREG(st.st_mode))
- info->type = UNIT_FILE_TYPE_REGULAR;
- else if (S_ISLNK(st.st_mode))
- return -ELOOP;
- else if (S_ISDIR(st.st_mode))
- return -EISDIR;
- else
- return -ENOTTY;
+ if (!(flags & SEARCH_LOAD))
+ return 0;
- return 0;
+ fd = chase_symlinks_and_open(path, root_dir, 0, O_RDONLY|O_CLOEXEC|O_NOCTTY, NULL);
+ if (fd < 0)
+ return fd;
}
- /* c is only needed if we actually load the file */
- assert(c);
-
- fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
- if (fd < 0)
- return -errno;
if (fstat(fd, &st) < 0)
return -errno;
+
if (null_or_empty(&st)) {
- info->type = UNIT_FILE_TYPE_MASKED;
+ if ((flags & SEARCH_DROPIN) == 0)
+ info->type = UNIT_FILE_TYPE_MASKED;
+
return 0;
}
- if (S_ISDIR(st.st_mode))
- return -EISDIR;
- if (!S_ISREG(st.st_mode))
- return -ENOTTY;
+
+ r = stat_verify_regular(&st);
+ if (r < 0)
+ return r;
f = fdopen(fd, "re");
if (!f)
return -errno;
fd = -1;
+ /* c is only needed if we actually load the file (it's referenced from items[] btw, in case you wonder.) */
+ assert(c);
+
r = config_parse(info->name, path, f,
NULL,
config_item_table_lookup, items,
if (r < 0)
return log_debug_errno(r, "Failed to parse %s: %m", info->name);
- info->type = UNIT_FILE_TYPE_REGULAR;
+ if ((flags & SEARCH_DROPIN) == 0)
+ info->type = UNIT_FILE_TYPE_REGULAR;
return
(int) strv_length(info->aliases) +
_cleanup_free_ char *target = NULL;
int r;
- r = unit_file_load(c, info, path, flags);
- if (r != -ELOOP)
+ r = unit_file_load(c, info, path, root_dir, flags);
+ if (r != -ELOOP || (flags & SEARCH_DROPIN))
return r;
/* This is a symlink, let's read it. */
const LookupPaths *paths,
SearchFlags flags) {
+ const char *dropin_dir_name = NULL, *dropin_template_dir_name = NULL;
+ _cleanup_strv_free_ char **dirs = NULL, **files = NULL;
_cleanup_free_ char *template = NULL;
- _cleanup_strv_free_ char **dirs = NULL;
- _cleanup_strv_free_ char **files = NULL;
- const char *dropin_dir_name = NULL;
- const char *dropin_template_dir_name = NULL;
-
- char **p;
- int r;
- int result;
bool found_unit = false;
+ int r, result;
+ char **p;
assert(info);
assert(paths);
return -ENOMEM;
r = unit_file_load_or_readlink(c, info, path, paths->root_dir, flags);
-
if (r >= 0) {
- info->path = path;
- path = NULL;
+ info->path = TAKE_PTR(path);
result = r;
found_unit = true;
break;
r = unit_file_load_or_readlink(c, info, path, paths->root_dir, flags);
if (r >= 0) {
- info->path = path;
- path = NULL;
+ info->path = TAKE_PTR(path);
result = r;
found_unit = true;
break;
return -ENOENT;
}
+ if (info->type == UNIT_FILE_TYPE_MASKED)
+ return result;
+
/* Search for drop-in directories */
dropin_dir_name = strjoina(info->name, ".d");
return log_debug_errno(r, "Failed to get list of conf files: %m");
STRV_FOREACH(p, files) {
- r = unit_file_load_or_readlink(c, info, *p, paths->root_dir, flags);
+ r = unit_file_load_or_readlink(c, info, *p, paths->root_dir, flags | SEARCH_DROPIN);
if (r < 0)
return log_debug_errno(r, "Failed to load conf file %s: %m", *p);
}
SearchFlags flags,
UnitFileInstallInfo **ret,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
UnitFileInstallInfo *i;
int r;
const char *config_path,
bool force,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
char **s;
int r = 0, q;
char **list,
const char *suffix,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
_cleanup_free_ char *buf = NULL;
const char *n;
if (r < 0)
return r;
- path = instance.path;
- instance.path = NULL;
+ path = TAKE_PTR(instance.path);
if (instance.type == UNIT_FILE_TYPE_MASKED) {
unit_file_changes_add(changes, n_changes, -ERFKILL, path, NULL);
const char *config_path,
bool force,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
_cleanup_free_ char *path = NULL;
int r;
const char *config_path,
bool force,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
int r, q;
bool force,
SearchFlags flags,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
UnitFileInstallInfo *i;
int r;
InstallContext *c,
const LookupPaths *paths,
Set **remove_symlinks_to,
- const char *config_path,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
UnitFileInstallInfo *i;
int r;
assert(c);
assert(paths);
- assert(config_path);
/* Marks all items for removal */
const char *root_dir,
char **files,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
+ _cleanup_(lookup_paths_free) LookupPaths paths = {};
const char *config_path;
char **i;
int r;
const char *root_dir,
char **files,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
+ _cleanup_(lookup_paths_free) LookupPaths paths = {};
_cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
_cleanup_strv_free_ char **todo = NULL;
size_t n_todo = 0, n_allocated = 0;
const char *config_path;
char **i;
- bool dry_run;
+ bool dry_run = !!(flags & UNIT_FILE_DRY_RUN);
int r, q;
assert(scope >= 0);
if (r < 0)
return r;
- config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
- if (!config_path)
- return -ENXIO;
-
- dry_run = !!(flags & UNIT_FILE_DRY_RUN);
-
STRV_FOREACH(i, files) {
- _cleanup_free_ char *path = NULL;
-
if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
return -EINVAL;
- path = path_make_absolute(*i, config_path);
- if (!path)
- return -ENOMEM;
+ FOREACH_STRING(config_path, paths.runtime_config, paths.persistent_config) {
+ _cleanup_free_ char *path = NULL;
- r = null_or_empty_path(path);
- if (r == -ENOENT)
- continue;
- if (r < 0)
- return r;
- if (r == 0)
- continue;
+ path = path_make_absolute(*i, config_path);
+ if (!path)
+ return -ENOMEM;
- if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
- return -ENOMEM;
+ r = null_or_empty_path(path);
+ if (r == -ENOENT)
+ continue;
+ if (r < 0)
+ return r;
+ if (r == 0)
+ continue;
- todo[n_todo] = strdup(*i);
- if (!todo[n_todo])
- return -ENOMEM;
+ if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
+ return -ENOMEM;
- n_todo++;
+ todo[n_todo] = strdup(*i);
+ if (!todo[n_todo])
+ return -ENOMEM;
+
+ n_todo++;
+ }
}
strv_uniq(todo);
r = 0;
- STRV_FOREACH(i, todo) {
- _cleanup_free_ char *path = NULL;
- const char *rp;
+ FOREACH_STRING(config_path, paths.runtime_config, paths.persistent_config) {
+ STRV_FOREACH(i, todo) {
+ _cleanup_free_ char *path = NULL;
+ const char *rp;
- path = path_make_absolute(*i, config_path);
- if (!path)
- return -ENOMEM;
+ path = path_make_absolute(*i, config_path);
+ if (!path)
+ return -ENOMEM;
- if (!dry_run && unlink(path) < 0) {
- if (errno != ENOENT) {
- if (r >= 0)
- r = -errno;
- unit_file_changes_add(changes, n_changes, -errno, path, NULL);
+ if (!dry_run && unlink(path) < 0) {
+ if (errno != ENOENT) {
+ if (r >= 0)
+ r = -errno;
+ unit_file_changes_add(changes, n_changes, -errno, path, NULL);
+ }
+
+ continue;
}
- continue;
- }
+ unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
- unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
+ rp = skip_root(&paths, path);
+ q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: path);
+ if (q < 0)
+ return q;
+ }
- rp = skip_root(&paths, path);
- q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: path);
- if (q < 0)
- return q;
+ q = remove_marked_symlinks(remove_symlinks_to, config_path, &paths, dry_run, changes, n_changes);
+ if (r >= 0)
+ r = q;
}
- q = remove_marked_symlinks(remove_symlinks_to, config_path, &paths, dry_run, changes, n_changes);
- if (r >= 0)
- r = q;
-
return r;
}
const char *root_dir,
char **files,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
+ _cleanup_(lookup_paths_free) LookupPaths paths = {};
_cleanup_strv_free_ char **todo = NULL;
size_t n_todo = 0, n_allocated = 0;
const char *config_path;
if (lstat(full, &st) < 0)
return -errno;
- if (S_ISLNK(st.st_mode))
- return -ELOOP;
- if (S_ISDIR(st.st_mode))
- return -EISDIR;
- if (!S_ISREG(st.st_mode))
- return -ENOTTY;
+ r = stat_verify_regular(&st);
+ if (r < 0)
+ return r;
q = in_search_path(&paths, *i);
if (q < 0)
const char *root_dir,
char **files,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
_cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
+ _cleanup_(lookup_paths_free) LookupPaths paths = {};
_cleanup_strv_free_ char **todo = NULL;
size_t n_todo = 0, n_allocated = 0;
char **i;
if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
return -ENOMEM;
- todo[n_todo++] = dropin;
- dropin = NULL;
+ todo[n_todo++] = TAKE_PTR(dropin);
}
}
}
if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
return -ENOMEM;
- todo[n_todo++] = path;
- path = NULL;
+ todo[n_todo++] = TAKE_PTR(path);
}
}
}
const char *target,
UnitDependency dep,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
+ _cleanup_(lookup_paths_free) LookupPaths paths = {};
_cleanup_(install_context_done) InstallContext c = {};
UnitFileInstallInfo *i, *target_info;
const char *config_path;
const char *root_dir,
char **files,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
+ _cleanup_(lookup_paths_free) LookupPaths paths = {};
_cleanup_(install_context_done) InstallContext c = {};
const char *config_path;
UnitFileInstallInfo *i;
const char *root_dir,
char **files,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
+ _cleanup_(lookup_paths_free) LookupPaths paths = {};
_cleanup_(install_context_done) InstallContext c = {};
_cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
+ bool dry_run = !!(flags & UNIT_FILE_DRY_RUN);
const char *config_path;
char **i;
int r;
if (r < 0)
return r;
- config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
- if (!config_path)
- return -ENXIO;
-
STRV_FOREACH(i, files) {
if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
return -EINVAL;
return r;
}
- r = install_context_mark_for_removal(scope, &c, &paths, &remove_symlinks_to, config_path, changes, n_changes);
+ r = install_context_mark_for_removal(scope, &c, &paths, &remove_symlinks_to, changes, n_changes);
if (r < 0)
return r;
- return remove_marked_symlinks(remove_symlinks_to, config_path, &paths, !!(flags & UNIT_FILE_DRY_RUN), changes, n_changes);
+ FOREACH_STRING(config_path, paths.runtime_config, paths.persistent_config) {
+ r = remove_marked_symlinks(remove_symlinks_to, config_path, &paths, dry_run, changes, n_changes);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
}
int unit_file_reenable(
const char *root_dir,
char **files,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
char **n;
int r;
const char *root_dir,
const char *name,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
+ _cleanup_(lookup_paths_free) LookupPaths paths = {};
_cleanup_(install_context_done) InstallContext c = {};
UnitFileInstallInfo *i;
const char *new_path;
const char *root_dir,
char **name) {
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
+ _cleanup_(lookup_paths_free) LookupPaths paths = {};
_cleanup_(install_context_done) InstallContext c = {};
UnitFileInstallInfo *i;
char *n;
return 0;
}
-static int unit_file_lookup_state(
+int unit_file_lookup_state(
UnitFileScope scope,
const LookupPaths *paths,
const char *name,
const char *name,
UnitFileState *ret) {
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
+ _cleanup_(lookup_paths_free) LookupPaths paths = {};
int r;
assert(scope >= 0);
assert(scope < _UNIT_FILE_SCOPE_MAX);
assert(presets);
- if (scope == UNIT_FILE_SYSTEM)
+ switch (scope) {
+ case UNIT_FILE_SYSTEM:
r = conf_files_list(&files, ".preset", root_dir, 0,
"/etc/systemd/system-preset",
+ "/run/systemd/system-preset",
"/usr/local/lib/systemd/system-preset",
"/usr/lib/systemd/system-preset",
#if HAVE_SPLIT_USR
"/lib/systemd/system-preset",
#endif
NULL);
- else if (scope == UNIT_FILE_GLOBAL)
+ break;
+
+ case UNIT_FILE_GLOBAL:
+ case UNIT_FILE_USER:
r = conf_files_list(&files, ".preset", root_dir, 0,
"/etc/systemd/user-preset",
+ "/run/systemd/user-preset",
"/usr/local/lib/systemd/user-preset",
"/usr/lib/systemd/user-preset",
NULL);
- else {
- *presets = (Presets){};
+ break;
- return 0;
+ default:
+ assert_not_reached("Invalid unit file scope");
}
if (r < 0)
static int execute_preset(
UnitFileScope scope,
+ UnitFileFlags flags,
InstallContext *plus,
InstallContext *minus,
const LookupPaths *paths,
- const char *config_path,
char **files,
UnitFilePresetMode mode,
- bool force,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
- int r;
+ const char *config_path;
+ bool force = !!(flags & UNIT_FILE_FORCE);
+ bool runtime = !!(flags & UNIT_FILE_RUNTIME);
+ int r = 0, q;
assert(plus);
assert(minus);
assert(paths);
- assert(config_path);
if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
_cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
- r = install_context_mark_for_removal(scope, minus, paths, &remove_symlinks_to, config_path, changes, n_changes);
- if (r < 0)
- return r;
+ q = install_context_mark_for_removal(scope, minus, paths, &remove_symlinks_to, changes, n_changes);
+ if (q < 0)
+ return q;
- r = remove_marked_symlinks(remove_symlinks_to, config_path, paths, false, changes, n_changes);
- } else
- r = 0;
+ FOREACH_STRING(config_path, paths->runtime_config, paths->persistent_config) {
+ q = remove_marked_symlinks(remove_symlinks_to, config_path, paths, false, changes, n_changes);
+ if (r == 0)
+ r = q;
+ }
+ }
if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
- int q;
-
/* Returns number of symlinks that where supposed to be installed. */
- q = install_context_apply(scope, plus, paths, config_path, force, SEARCH_LOAD, changes, n_changes);
- if (r >= 0) {
- if (q < 0)
- r = q;
- else
- r += q;
- }
+ q = install_context_apply(scope, plus, paths,
+ runtime ? paths->runtime_config : paths->persistent_config,
+ force, SEARCH_LOAD, changes, n_changes);
+ if (r == 0)
+ r = q;
}
return r;
const char *name,
Presets presets,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
_cleanup_(install_context_done) InstallContext tmp = {};
UnitFileInstallInfo *i;
char **files,
UnitFilePresetMode mode,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
_cleanup_(install_context_done) InstallContext plus = {}, minus = {};
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
+ _cleanup_(lookup_paths_free) LookupPaths paths = {};
_cleanup_(presets_freep) Presets presets = {};
- const char *config_path;
char **i;
int r;
if (r < 0)
return r;
- config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
- if (!config_path)
- return -ENXIO;
-
r = read_presets(scope, root_dir, &presets);
if (r < 0)
return r;
return r;
}
- return execute_preset(scope, &plus, &minus, &paths, config_path, files, mode, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
+ return execute_preset(scope, flags, &plus, &minus, &paths, files, mode, changes, n_changes);
}
int unit_file_preset_all(
const char *root_dir,
UnitFilePresetMode mode,
UnitFileChange **changes,
- unsigned *n_changes) {
+ size_t *n_changes) {
_cleanup_(install_context_done) InstallContext plus = {}, minus = {};
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
+ _cleanup_(lookup_paths_free) LookupPaths paths = {};
_cleanup_(presets_freep) Presets presets = {};
- const char *config_path = NULL;
char **i;
int r;
if (r < 0)
return r;
- config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
- if (!config_path)
- return -ENXIO;
-
r = read_presets(scope, root_dir, &presets);
if (r < 0)
return r;
}
FOREACH_DIRENT(de, d, return -errno) {
-
if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
continue;
}
}
- return execute_preset(scope, &plus, &minus, &paths, config_path, NULL, mode, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
+ return execute_preset(scope, flags, &plus, &minus, &paths, NULL, mode, changes, n_changes);
}
static void unit_file_list_free_one(UnitFileList *f) {
}
Hashmap* unit_file_list_free(Hashmap *h) {
- UnitFileList *i;
-
- while ((i = hashmap_steal_first(h)))
- unit_file_list_free_one(i);
-
- return hashmap_free(h);
+ return hashmap_free_with_destructor(h, unit_file_list_free_one);
}
DEFINE_TRIVIAL_CLEANUP_FUNC(UnitFileList*, unit_file_list_free_one);
char **states,
char **patterns) {
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
+ _cleanup_(lookup_paths_free) LookupPaths paths = {};
char **i;
int r;