if (b < 0)
return -EINVAL;
- *(t++) = (char) ((a << 4) | b);
+ *(t++) = (char) (((uint8_t) a << 4U) | (uint8_t) b);
f += 3;
} else
*(t++) = *f;
}
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;
}
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;
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))
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)
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",
[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",