X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Funit-name.c;h=bf52463d81855fb36fc0848c260e0b96d4a39099;hb=30ab6a0fc1bb950c4dcd90dcd3dfe00a810c7fc1;hp=c41d7d86a74de87b7489b04f9a94233c0584b444;hpb=0eb4b7f2e7ed1dda0511b440ec002c668de99fb9;p=elogind.git diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c index c41d7d86a..bf52463d8 100644 --- a/src/shared/unit-name.c +++ b/src/shared/unit-name.c @@ -339,7 +339,7 @@ int unit_name_unescape(const char *f, char **ret) { if (b < 0) return -EINVAL; - *(t++) = (char) ((a << 4) | b); + *(t++) = (char) (((uint8_t) a << 4U) | (uint8_t) b); f += 3; } else *(t++) = *f; @@ -392,42 +392,48 @@ int unit_name_path_escape(const char *f, char **ret) { } int unit_name_path_unescape(const char *f, char **ret) { - char *s, *w; + char *s; int r; assert(f); + if (isempty(f)) + return -EINVAL; + if (streq(f, "-")) { s = strdup("/"); if (!s) return -ENOMEM; + } else { + char *w; - *ret = s; - return 0; - } - - r = unit_name_unescape(f, &s); - if (r < 0) - return r; - - /* Don't accept trailing or leading slashes */ - if (startswith(s, "/") || endswith(s, "/")) { - free(s); - return -EINVAL; - } + r = unit_name_unescape(f, &w); + if (r < 0) + return r; - /* Prefix a slash again */ - w = strappend("/", s); - free(s); - if (!w) - return -ENOMEM; + /* Don't accept trailing or leading slashes */ + if (startswith(w, "/") || endswith(w, "/")) { + free(w); + return -EINVAL; + } - if (!path_is_safe(w)) { + /* Prefix a slash again */ + s = strappend("/", w); free(w); - return -EINVAL; + if (!s) + return -ENOMEM; + + if (!path_is_safe(s)) { + free(s); + return -EINVAL; + } } - *ret = w; + if (ret) + *ret = s; + else + free(s); + return 0; } @@ -665,6 +671,39 @@ int unit_name_mangle_with_suffix(const char *name, UnitNameMangle allow_globs, c return 1; } +int slice_build_parent_slice(const char *slice, char **ret) { + char *s, *dash; + + assert(slice); + assert(ret); + + if (!slice_name_is_valid(slice)) + return -EINVAL; + + if (streq(slice, "-.slice")) { + *ret = NULL; + return 0; + } + + s = strdup(slice); + if (!s) + return -ENOMEM; + + dash = strrchr(s, '-'); + if (dash) + strcpy(dash, ".slice"); + else { + free(s); + + s = strdup("-.slice"); + if (!s) + return -ENOMEM; + } + + *ret = s; + return 1; +} + int slice_build_subslice(const char *slice, const char*name, char **ret) { char *subslice; @@ -672,7 +711,7 @@ int slice_build_subslice(const char *slice, const char*name, char **ret) { assert(name); assert(ret); - if (!unit_name_is_valid(slice, UNIT_NAME_PLAIN)) + if (!slice_name_is_valid(slice)) return -EINVAL; if (!unit_prefix_is_valid(name)) @@ -683,9 +722,7 @@ int slice_build_subslice(const char *slice, const char*name, char **ret) { else { char *e; - e = endswith(slice, ".slice"); - if (!e) - return -EINVAL; + assert_se(e = endswith(slice, ".slice")); subslice = new(char, (e - slice) + 1 + strlen(name) + 6 + 1); if (!subslice) @@ -698,6 +735,44 @@ int slice_build_subslice(const char *slice, const char*name, char **ret) { return 0; } +bool slice_name_is_valid(const char *name) { + const char *p, *e; + bool dash = false; + + if (!unit_name_is_valid(name, UNIT_NAME_PLAIN)) + return false; + + if (streq(name, "-.slice")) + return true; + + e = endswith(name, ".slice"); + if (!e) + return false; + + for (p = name; p < e; p++) { + + if (*p == '-') { + + /* Don't allow initial dash */ + if (p == name) + return false; + + /* Don't allow multiple dashes */ + if (dash) + return false; + + dash = true; + } else + dash = false; + } + + /* Don't allow trailing hash */ + if (dash) + return false; + + return true; +} + static const char* const unit_type_table[_UNIT_TYPE_MAX] = { [UNIT_SERVICE] = "service", [UNIT_SOCKET] = "socket", @@ -737,6 +812,8 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = { [UNIT_PART_OF] = "PartOf", [UNIT_REQUIRED_BY] = "RequiredBy", [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable", + [UNIT_REQUISITE_OF] = "RequisiteOf", + [UNIT_REQUISITE_OF_OVERRIDABLE] = "RequisiteOfOverridable", [UNIT_WANTED_BY] = "WantedBy", [UNIT_BOUND_BY] = "BoundBy", [UNIT_CONSISTS_OF] = "ConsistsOf",