X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Finstall.c;h=03c7a9da2eb08e91031f51085f77a4a759bf1b7b;hb=be754d5443e5fe44ead733ad509b127409cdb0f0;hp=54fbfe8a9ee25b3ca3441409bc0942363cfc061e;hpb=559367add5e22bf32d14fa1496512c68488f48b0;p=elogind.git diff --git a/src/shared/install.c b/src/shared/install.c index 54fbfe8a9..03c7a9da2 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -47,6 +47,19 @@ typedef struct { #define _cleanup_install_context_done_ _cleanup_(install_context_done) +static int in_search_path(const char *path, char **search) { + _cleanup_free_ char *parent = NULL; + int r; + + assert(path); + + r = path_get_parent(path, &parent); + if (r < 0) + return r; + + return strv_contains(search, parent); +} + static int lookup_paths_init_from_scope(LookupPaths *paths, UnitFileScope scope, const char *root_dir) { @@ -75,15 +88,10 @@ static int get_config_path(UnitFileScope scope, bool runtime, const char *root_d case UNIT_FILE_SYSTEM: - if (root_dir && runtime) - asprintf(&p, "%s/run/systemd/system", root_dir); - else if (runtime) - p = strdup("/run/systemd/system"); - else if (root_dir) - asprintf(&p, "%s/%s", root_dir, SYSTEM_CONFIG_UNIT_PATH); + if (runtime) + p = path_join(root_dir, "/run/systemd/system", NULL); else - p = strdup(SYSTEM_CONFIG_UNIT_PATH); - + p = path_join(root_dir, SYSTEM_CONFIG_UNIT_PATH, NULL); break; case UNIT_FILE_GLOBAL: @@ -147,12 +155,16 @@ static int add_file_change( if (!c[i].path) return -ENOMEM; + path_kill_slashes(c[i].path); + if (source) { c[i].source = strdup(source); if (!c[i].source) { free(c[i].path); return -ENOMEM; } + + path_kill_slashes(c[i].path); } else c[i].source = NULL; @@ -934,20 +946,19 @@ static int config_parse_also( void *data, void *userdata) { - char *w; size_t l; - char *state; + const char *word, *state; InstallContext *c = data; assert(filename); assert(lvalue); assert(rvalue); - FOREACH_WORD_QUOTED(w, l, rvalue, state) { + FOREACH_WORD_QUOTED(word, l, rvalue, state) { _cleanup_free_ char *n; int r; - n = strndup(w, l); + n = strndup(word, l); if (!n) return -ENOMEM; @@ -955,6 +966,9 @@ static int config_parse_also( if (r < 0) return r; } + if (!isempty(state)) + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Trailing garbage, ignoring."); return 0; } @@ -1026,6 +1040,7 @@ static int unit_file_load( InstallContext *c, InstallInfo *info, const char *path, + const char *root_dir, bool allow_symlink) { const ConfigTableItem items[] = { @@ -1038,14 +1053,16 @@ static int unit_file_load( {} }; - int fd; _cleanup_fclose_ FILE *f = NULL; - int r; + int fd, r; assert(c); assert(info); assert(path); + if (!isempty(root_dir)) + path = strappenda(root_dir, "/", path); + fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|(allow_symlink ? 0 : O_NOFOLLOW)); if (fd < 0) return -errno; @@ -1056,7 +1073,10 @@ static int unit_file_load( return -ENOMEM; } - r = config_parse(NULL, path, f, NULL, config_item_table_lookup, (void*) items, true, true, info); + r = config_parse(NULL, path, f, + NULL, + config_item_table_lookup, items, + true, true, false, info); if (r < 0) return r; @@ -1080,30 +1100,19 @@ static int unit_file_search( assert(info); assert(paths); - if (info->path) { - const char *path; - - if (isempty(root_dir)) - path = info->path; - else - path = strappenda(root_dir, info->path); - - return unit_file_load(c, info, path, allow_symlink); - } + if (info->path) + return unit_file_load(c, info, info->path, root_dir, allow_symlink); assert(info->name); STRV_FOREACH(p, paths->unit_path) { _cleanup_free_ char *path = NULL; - if (isempty(root_dir)) - path = strjoin(*p, "/", info->name, NULL); - else - path = strjoin(root_dir, "/", *p, "/", info->name, NULL); + path = strjoin(*p, "/", info->name, NULL); if (!path) return -ENOMEM; - r = unit_file_load(c, info, path, allow_symlink); + r = unit_file_load(c, info, path, root_dir, allow_symlink); if (r >= 0) { info->path = path; path = NULL; @@ -1119,7 +1128,7 @@ static int unit_file_search( * enablement was requested. We will check if it is * possible to load template unit file. */ - _cleanup_free_ char *template = NULL, *template_dir = NULL; + _cleanup_free_ char *template = NULL; template = unit_name_template(info->name); if (!template) @@ -1128,14 +1137,11 @@ static int unit_file_search( STRV_FOREACH(p, paths->unit_path) { _cleanup_free_ char *path = NULL; - if (isempty(root_dir)) - path = strjoin(*p, "/", template, NULL); - else - path = strjoin(root_dir, "/", *p, "/", template, NULL); + path = strjoin(*p, "/", template, NULL); if (!path) return -ENOMEM; - r = unit_file_load(c, info, path, allow_symlink); + r = unit_file_load(c, info, path, root_dir, allow_symlink); if (r >= 0) { info->path = path; path = NULL; @@ -1271,7 +1277,14 @@ static int install_info_symlink_wants( assert(i); assert(config_path); - if (unit_name_is_template(i->name) && i->default_instance) { + if (unit_name_is_template(i->name)) { + + /* Don't install any symlink if there's no default + * instance configured */ + + if (!i->default_instance) + return 0; + buf = unit_name_replace_instance(i->name, i->default_instance); if (!buf) return -ENOMEM; @@ -1308,6 +1321,7 @@ static int install_info_symlink_link( InstallInfo *i, LookupPaths *paths, const char *config_path, + const char *root_dir, bool force, UnitFileChange **changes, unsigned *n_changes) { @@ -1335,6 +1349,7 @@ static int install_info_apply( InstallInfo *i, LookupPaths *paths, const char *config_path, + const char *root_dir, bool force, UnitFileChange **changes, unsigned *n_changes) { @@ -1355,7 +1370,7 @@ static int install_info_apply( if (r == 0) r = q; - q = install_info_symlink_link(i, paths, config_path, force, changes, n_changes); + q = install_info_symlink_link(i, paths, config_path, root_dir, force, changes, n_changes); if (r == 0) r = q; @@ -1395,7 +1410,7 @@ static int install_context_apply( } else if (r >= 0) r += q; - q = install_info_apply(i, paths, config_path, force, changes, n_changes); + q = install_info_apply(i, paths, config_path, root_dir, force, changes, n_changes); if (r >= 0 && q < 0) r = q; } @@ -1643,11 +1658,7 @@ int unit_file_get_default( _cleanup_free_ char *path = NULL, *tmp = NULL; char *n; - if (isempty(root_dir)) - path = strappend(*p, "/" SPECIAL_DEFAULT_TARGET); - else - path = strjoin(root_dir, "/", *p, "/" SPECIAL_DEFAULT_TARGET, NULL); - + path = path_join(root_dir, *p, SPECIAL_DEFAULT_TARGET); if (!path) return -ENOMEM; @@ -1704,15 +1715,12 @@ UnitFileState unit_file_get_state( free(path); path = NULL; - if (root_dir) - asprintf(&path, "%s/%s/%s", root_dir, *i, name); - else - asprintf(&path, "%s/%s", *i, name); + path = path_join(root_dir, *i, name); if (!path) return -ENOMEM; if (root_dir) - partial = path + strlen(root_dir) + 1; + partial = path + strlen(root_dir); else partial = path; @@ -1761,7 +1769,7 @@ UnitFileState unit_file_get_state( int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name) { _cleanup_strv_free_ char **files = NULL; - char **i; + char **p; int r; assert(scope >= 0); @@ -1789,17 +1797,10 @@ int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char if (r < 0) return r; - STRV_FOREACH(i, files) { - _cleanup_free_ char *buf = NULL; + STRV_FOREACH(p, files) { _cleanup_fclose_ FILE *f; - const char *p; - - if (root_dir) - p = buf = strjoin(root_dir, "/", *i, NULL); - else - p = *i; - f = fopen(p, "re"); + f = fopen(*p, "re"); if (!f) { if (errno == ENOENT) continue; @@ -1866,7 +1867,7 @@ int unit_file_preset( assert(scope >= 0); assert(scope < _UNIT_FILE_SCOPE_MAX); - assert(mode < _UNIT_FILE_PRESET_MODE_MAX); + assert(mode < _UNIT_FILE_PRESET_MAX); r = lookup_paths_init_from_scope(&paths, scope, root_dir); if (r < 0) @@ -1934,7 +1935,7 @@ int unit_file_preset_all( assert(scope >= 0); assert(scope < _UNIT_FILE_SCOPE_MAX); - assert(mode < _UNIT_FILE_PRESET_MODE_MAX); + assert(mode < _UNIT_FILE_PRESET_MAX); r = lookup_paths_init_from_scope(&paths, scope, root_dir); if (r < 0) @@ -1946,17 +1947,11 @@ int unit_file_preset_all( STRV_FOREACH(i, paths.unit_path) { _cleanup_closedir_ DIR *d = NULL; - _cleanup_free_ char *buf = NULL; - const char *units_dir; + _cleanup_free_ char *units_dir; - if (!isempty(root_dir)) { - buf = strjoin(root_dir, "/", *i, NULL); - if (!buf) - return -ENOMEM; - - units_dir = buf; - } else - units_dir = *i; + units_dir = path_join(root_dir, *i, NULL); + if (!units_dir) + return -ENOMEM; d = opendir(units_dir); if (!d) { @@ -2049,23 +2044,23 @@ int unit_file_get_list( if (root_dir && scope != UNIT_FILE_SYSTEM) return -EINVAL; + if (root_dir) { + r = access(root_dir, F_OK); + if (r < 0) + return -errno; + } + r = lookup_paths_init_from_scope(&paths, scope, root_dir); 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; + _cleanup_free_ char *units_dir; - units_dir = buf; - } else - units_dir = *i; + units_dir = path_join(root_dir, *i, NULL); + if (!units_dir) + return -ENOMEM; d = opendir(units_dir); if (!d) { @@ -2171,7 +2166,7 @@ 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] = { +static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = { [UNIT_FILE_PRESET_FULL] = "full", [UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only", [UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",