diff options
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/install.c | 151 | ||||
-rw-r--r-- | src/shared/install.h | 14 |
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_; |