summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/install.c151
-rw-r--r--src/shared/install.h14
2 files changed, 151 insertions, 14 deletions
diff --git a/src/shared/install.c b/src/shared/install.c
index 40dc7bebe8..7e0e20c603 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -1831,12 +1831,12 @@ int unit_file_preset(
bool runtime,
const char *root_dir,
char **files,
+ UnitFilePresetMode mode,
bool force,
UnitFileChange **changes,
unsigned *n_changes) {
_cleanup_install_context_done_ InstallContext plus = {}, minus = {};
- _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
_cleanup_lookup_paths_free_ LookupPaths paths = {};
_cleanup_free_ char *config_path = NULL;
char **i;
@@ -1844,6 +1844,7 @@ int unit_file_preset(
assert(scope >= 0);
assert(scope < _UNIT_FILE_SCOPE_MAX);
+ assert(mode < _UNIT_FILE_PRESET_MODE_MAX);
r = lookup_paths_init_from_scope(&paths, scope, root_dir);
if (r < 0)
@@ -1862,25 +1863,141 @@ int unit_file_preset(
if (r < 0)
return r;
- if (r)
+ if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
r = install_info_add_auto(&plus, *i);
- else
+ else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
r = install_info_add_auto(&minus, *i);
+ else
+ r = 0;
if (r < 0)
return r;
}
- r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
+ r = 0;
- q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
- if (r == 0)
- r = q;
+ if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
+ _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
- /* Returns number of symlinks that where supposed to be installed. */
- q = install_context_apply(&plus, &paths, config_path, root_dir, force,
- changes, n_changes);
- if (r == 0)
- r = q;
+ 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, files);
+ if (r == 0)
+ r = q;
+ }
+
+ if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
+ /* Returns number of symlinks that where supposed to be installed. */
+ q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
+ if (r == 0)
+ r = q;
+ }
+
+ return r;
+}
+
+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_MODE_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 *buf = NULL;
+ const char *units_dir;
+
+ if (!isempty(root_dir)) {
+ buf = strjoin(root_dir, "/", *i, NULL);
+ if (!buf)
+ return -ENOMEM;
+
+ units_dir = buf;
+ } else
+ units_dir = *i;
+
+ 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 (ignore_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, 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;
}
@@ -1937,8 +2054,8 @@ int unit_file_get_list(
}
for (;;) {
- struct dirent *de;
_cleanup_unitfilelist_free_ UnitFileList *f = NULL;
+ struct dirent *de;
errno = 0;
de = readdir(d);
@@ -2031,3 +2148,11 @@ static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX]
};
DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
+
+static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MODE_MAX] = {
+ [UNIT_FILE_PRESET_FULL] = "full",
+ [UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
+ [UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode, UnitFilePresetMode);
diff --git a/src/shared/install.h b/src/shared/install.h
index 5d57b1b025..230cfe1150 100644
--- a/src/shared/install.h
+++ b/src/shared/install.h
@@ -45,6 +45,14 @@ typedef enum UnitFileState {
_UNIT_FILE_STATE_INVALID = -1
} UnitFileState;
+typedef enum UnitFilePresetMode {
+ UNIT_FILE_PRESET_FULL,
+ UNIT_FILE_PRESET_ENABLE_ONLY,
+ UNIT_FILE_PRESET_DISABLE_ONLY,
+ _UNIT_FILE_PRESET_MODE_MAX,
+ _UNIT_FILE_PRESET_INVALID = -1
+} UnitFilePresetMode;
+
typedef enum UnitFileChangeType {
UNIT_FILE_SYMLINK,
UNIT_FILE_UNLINK,
@@ -77,7 +85,8 @@ int unit_file_enable(UnitFileScope scope, bool runtime, const char *root_dir, ch
int unit_file_disable(UnitFileScope scope, bool runtime, const char *root_dir, char **files, UnitFileChange **changes, unsigned *n_changes);
int unit_file_reenable(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes);
int unit_file_link(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes);
-int unit_file_preset(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes);
+int unit_file_preset(UnitFileScope scope, bool runtime, const char *root_dir, char **files, UnitFilePresetMode mode, bool force, UnitFileChange **changes, unsigned *n_changes);
+int unit_file_preset_all(UnitFileScope scope, bool runtime, const char *root_dir, UnitFilePresetMode mode, bool force, UnitFileChange **changes, unsigned *n_changes);
int unit_file_mask(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes);
int unit_file_unmask(UnitFileScope scope, bool runtime, const char *root_dir, char **files, UnitFileChange **changes, unsigned *n_changes);
int unit_file_set_default(UnitFileScope scope, const char *root_dir, const char *file, bool force, UnitFileChange **changes, unsigned *n_changes);
@@ -97,3 +106,6 @@ UnitFileState unit_file_state_from_string(const char *s) _pure_;
const char *unit_file_change_type_to_string(UnitFileChangeType s) _const_;
UnitFileChangeType unit_file_change_type_from_string(const char *s) _pure_;
+
+const char *unit_file_preset_mode_to_string(UnitFilePresetMode m) _const_;
+UnitFilePresetMode unit_file_preset_mode_from_string(const char *s) _pure_;