summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--unit.c39
-rw-r--r--unit.h1
2 files changed, 40 insertions, 0 deletions
diff --git a/unit.c b/unit.c
index 2f39d887fe..c8a6f66961 100644
--- a/unit.c
+++ b/unit.c
@@ -887,3 +887,42 @@ int set_unit_path(const char *p) {
return 0;
}
+
+char *unit_name_escape_path(const char *path, const char *suffix) {
+ char *r, *t;
+ const char *f;
+ size_t a, b;
+
+ assert(path);
+ assert(suffix);
+
+ /* Takes a path and a util suffix and makes a nice unit name
+ * of it, escaping all weird chars on the way.
+ *
+ * / becomes _, and all chars not alloweed in a unit name get
+ * escaped as \xFF, including the _ and the \ itself, of
+ * course. This escaping is hence reversible.
+ */
+
+ a = strlen(path);
+ b = strlen(suffix);
+
+ if (!(r = new(char, a*4+b+1)))
+ return NULL;
+
+ for (f = path, t = r; *f; f++) {
+ if (*f == '/')
+ *(t++) = '_';
+ else if (*f == '_' || *f == '\\' || !strchr(VALID_CHARS, *f)) {
+ *(t++) = '\\';
+ *(t++) = 'x';
+ *(t++) = hexchar(*f > 4);
+ *(t++) = hexchar(*f);
+ } else
+ *(t++) = *f;
+ }
+
+ memcpy(t, suffix, b+1);
+
+ return r;
+}
diff --git a/unit.h b/unit.h
index 5321d5f1a3..f9d96c7efc 100644
--- a/unit.h
+++ b/unit.h
@@ -235,5 +235,6 @@ bool unit_job_is_applicable(Unit *u, JobType j);
const char *unit_path(void);
int set_unit_path(const char *p);
+char *unit_name_escape_path(const char *path, const char *suffix);
#endif