unit-name.c revision ede3a7967560506486e1e25d09ef4e74600851ff
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt/***
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt This file is part of systemd.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt Copyright 2010 Lennart Poettering
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt systemd is free software; you can redistribute it and/or modify it
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt under the terms of the GNU Lesser General Public License as published by
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt the Free Software Foundation; either version 2.1 of the License, or
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt (at your option) any later version.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt systemd is distributed in the hope that it will be useful, but
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt WITHOUT ANY WARRANTY; without even the implied warranty of
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt Lesser General Public License for more details.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt You should have received a copy of the GNU Lesser General Public License
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt along with systemd; If not, see <http://www.gnu.org/licenses/>.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt***/
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include <errno.h>
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include <string.h>
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt#include <assert.h>
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt#include "path-util.h"
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt#include "util.h"
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt#include "unit-name.h"
a276e6d68606861b552140cbcc003f4af10626fcTom Gundersen
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#define VALID_CHARS \
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt "0123456789" \
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt "abcdefghijklmnopqrstuvwxyz" \
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt ":-_.\\"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flyktstatic const char* const unit_type_table[_UNIT_TYPE_MAX] = {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt [UNIT_SERVICE] = "service",
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt [UNIT_SOCKET] = "socket",
a276e6d68606861b552140cbcc003f4af10626fcTom Gundersen [UNIT_TARGET] = "target",
a276e6d68606861b552140cbcc003f4af10626fcTom Gundersen [UNIT_DEVICE] = "device",
a276e6d68606861b552140cbcc003f4af10626fcTom Gundersen [UNIT_MOUNT] = "mount",
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt [UNIT_AUTOMOUNT] = "automount",
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt [UNIT_SNAPSHOT] = "snapshot",
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt [UNIT_TIMER] = "timer",
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt [UNIT_SWAP] = "swap",
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt [UNIT_PATH] = "path",
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt [UNIT_SLICE] = "slice",
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt [UNIT_SCOPE] = "scope"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt};
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik FlyktDEFINE_STRING_TABLE_LOOKUP(unit_type, UnitType);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flyktstatic const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt [UNIT_STUB] = "stub",
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt [UNIT_LOADED] = "loaded",
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt [UNIT_NOT_FOUND] = "not-found",
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt [UNIT_ERROR] = "error",
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt [UNIT_MERGED] = "merged",
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt [UNIT_MASKED] = "masked"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt};
a276e6d68606861b552140cbcc003f4af10626fcTom Gundersen
a276e6d68606861b552140cbcc003f4af10626fcTom GundersenDEFINE_STRING_TABLE_LOOKUP(unit_load_state, UnitLoadState);
a276e6d68606861b552140cbcc003f4af10626fcTom Gundersen
a276e6d68606861b552140cbcc003f4af10626fcTom Gundersenbool unit_name_is_valid(const char *n, bool template_ok) {
a276e6d68606861b552140cbcc003f4af10626fcTom Gundersen const char *e, *i, *at;
a276e6d68606861b552140cbcc003f4af10626fcTom Gundersen
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt /* Valid formats:
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt *
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt * string@instance.suffix
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt * string.suffix
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt */
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt assert(n);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (strlen(n) >= UNIT_NAME_MAX)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return false;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt e = strrchr(n, '.');
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (!e || e == n)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return false;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (unit_type_from_string(e + 1) < 0)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return false;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt for (i = n, at = NULL; i < e; i++) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (*i == '@' && !at)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt at = i;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (!strchr("@" VALID_CHARS, *i))
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return false;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (at) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (at == n)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return false;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt if (!template_ok && at+1 == e)
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt return false;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt }
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return true;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt}
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktbool unit_instance_is_valid(const char *i) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt assert(i);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt /* The max length depends on the length of the string, so we
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * don't really check this here. */
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (i[0] == 0)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return false;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt /* We allow additional @ in the instance string, we do not
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * allow them in the prefix! */
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt for (; *i; i++)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (!strchr("@" VALID_CHARS, *i))
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return false;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return true;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt}
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktbool unit_prefix_is_valid(const char *p) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt /* We don't allow additional @ in the instance string */
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (p[0] == 0)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return false;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt for (; *p; p++)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (!strchr(VALID_CHARS, *p))
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return false;
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt return true;
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt}
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flyktint unit_name_to_instance(const char *n, char **instance) {
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt const char *p, *d;
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt char *i;
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt assert(n);
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt assert(instance);
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt /* Everything past the first @ and before the last . is the instance */
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt p = strchr(n, '@');
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (!p) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt *instance = NULL;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return 0;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt }
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt assert_se(d = strrchr(n, '.'));
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt assert(p < d);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt i = strndup(p+1, d-p-1);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (!i)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return -ENOMEM;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt *instance = i;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return 0;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt}
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flyktchar *unit_name_to_prefix_and_instance(const char *n) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt const char *d;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt assert(n);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt assert_se(d = strrchr(n, '.'));
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt return strndup(n, d - n);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt}
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktchar *unit_name_to_prefix(const char *n) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt const char *p;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt p = strchr(n, '@');
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (p)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return strndup(n, p - n);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return unit_name_to_prefix_and_instance(n);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt}
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktchar *unit_name_change_suffix(const char *n, const char *suffix) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt char *e, *r;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt size_t a, b;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt assert(n);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt assert(unit_name_is_valid(n, true));
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt assert(suffix);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt assert(suffix[0] == '.');
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt assert_se(e = strrchr(n, '.'));
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt a = e - n;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt b = strlen(suffix);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt r = new(char, a + b + 1);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (!r)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return NULL;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt memcpy(r, n, a);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt memcpy(r+a, suffix, b+1);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return r;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt}
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flyktchar *unit_name_build(const char *prefix, const char *instance, const char *suffix) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt assert(prefix);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt assert(unit_prefix_is_valid(prefix));
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt assert(!instance || unit_instance_is_valid(instance));
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt assert(suffix);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (!instance)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return strappend(prefix, suffix);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return strjoin(prefix, "@", instance, suffix, NULL);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt}
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flyktstatic char *do_escape_char(char c, char *t) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt *(t++) = '\\';
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt *(t++) = 'x';
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt *(t++) = hexchar(c >> 4);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt *(t++) = hexchar(c);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt return t;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt}
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flyktstatic char *do_escape(const char *f, char *t) {
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt assert(f);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt assert(t);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt /* do not create units with a leading '.', like for "/.dotdir" mount points */
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (*f == '.') {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt t = do_escape_char(*f, t);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt f++;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt }
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt for (; *f; f++) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (*f == '/')
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt *(t++) = '-';
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt else if (*f == '-' || *f == '\\' || !strchr(VALID_CHARS, *f))
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt t = do_escape_char(*f, t);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt else
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt *(t++) = *f;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt }
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt return t;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt}
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flyktchar *unit_name_escape(const char *f) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt char *r, *t;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt r = new(char, strlen(f)*4+1);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (!r)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return NULL;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt t = do_escape(f, r);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt *t = 0;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return r;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt}
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktchar *unit_name_unescape(const char *f) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt char *r, *t;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt assert(f);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt r = strdup(f);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (!r)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return NULL;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt for (t = r; *f; f++) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (*f == '-')
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt *(t++) = '/';
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt else if (*f == '\\') {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt int a, b;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (f[1] != 'x' ||
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt (a = unhexchar(f[2])) < 0 ||
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt (b = unhexchar(f[3])) < 0) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt /* Invalid escape code, let's take it literal then */
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt *(t++) = '\\';
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt } else {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt *(t++) = (char) ((a << 4) | b);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt f += 3;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt }
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt } else
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt *(t++) = *f;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt }
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt *t = 0;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return r;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt}
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktchar *unit_name_path_escape(const char *f) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt char *p, *e;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(f);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt p = strdup(f);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (!p)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return NULL;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt path_kill_slashes(p);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (streq(p, "/")) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt free(p);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return strdup("-");
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt e = unit_name_escape(p[0] == '/' ? p + 1 : p);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt free(p);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return e;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt}
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktchar *unit_name_path_unescape(const char *f) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt char *e;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(f);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt e = unit_name_unescape(f);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (!e)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return NULL;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (e[0] != '/') {
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt char *w;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt w = strappend("/", e);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt free(e);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt return w;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return e;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt}
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktbool unit_name_is_template(const char *n) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt const char *p;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt assert(n);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt p = strchr(n, '@');
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (!p)
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt return false;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt return p[1] == '.';
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt}
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktbool unit_name_is_instance(const char *n) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt const char *p;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(n);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt p = strchr(n, '@');
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (!p)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return false;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return p[1] != '.';
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt}
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flyktchar *unit_name_replace_instance(const char *f, const char *i) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt const char *p, *e;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt char *r, *k;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt size_t a, b;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(f);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt p = strchr(f, '@');
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (!p)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return strdup(f);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt e = strrchr(f, '.');
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (!e)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt assert_se(e = strchr(f, 0));
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt a = p - f;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt b = strlen(i);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = new(char, a + 1 + b + strlen(e) + 1);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (!r)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return NULL;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt k = mempcpy(r, f, a + 1);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt k = mempcpy(k, i, b);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt strcpy(k, e);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return r;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt}
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktchar *unit_name_template(const char *f) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt const char *p, *e;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt char *r;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt size_t a;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt p = strchr(f, '@');
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (!p)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return strdup(f);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert_se(e = strrchr(f, '.'));
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt a = p - f + 1;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = new(char, a + strlen(e) + 1);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (!r)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return NULL;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt strcpy(mempcpy(r, f, a), e);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return r;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt}
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktchar *unit_name_from_path(const char *path, const char *suffix) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt char *p, *r;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(path);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(suffix);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt p = unit_name_path_escape(path);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (!p)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return NULL;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = strappend(p, suffix);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt free(p);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return r;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt}
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktchar *unit_name_from_path_instance(const char *prefix, const char *path, const char *suffix) {
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt char *p, *r;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt assert(prefix);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt assert(path);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt assert(suffix);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt p = unit_name_path_escape(path);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt if (!p)
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt return NULL;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt r = strjoin(prefix, "@", p, suffix, NULL);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt free(p);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt return r;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt}
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flyktchar *unit_name_to_path(const char *name) {
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt char *w, *e;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt assert(name);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt w = unit_name_to_prefix(name);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt if (!w)
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt return NULL;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt e = unit_name_path_unescape(w);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt free(w);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt return e;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt}
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flyktchar *unit_dbus_path_from_name(const char *name) {
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt _cleanup_free_ char *e = NULL;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt assert(name);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt e = bus_path_escape(name);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt if (!e)
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt return NULL;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt return strappend("/org/freedesktop/systemd1/unit/", e);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt}
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flyktint unit_name_from_dbus_path(const char *path, char **name) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt const char *e;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt char *n;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt e = startswith(path, "/org/freedesktop/systemd1/unit/");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (!e)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return -EINVAL;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt n = bus_path_unescape(e);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (!n)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return -ENOMEM;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt *name = n;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktchar *unit_name_mangle(const char *name) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt char *r, *t;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt const char *f;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(name);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* Try to turn a string that might not be a unit name into a
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt * sensible unit name. */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (is_device_path(name))
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return unit_name_from_path(name, ".device");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (path_is_absolute(name))
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return unit_name_from_path(name, ".mount");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* We'll only escape the obvious characters here, to play
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt * safe. */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt r = new(char, strlen(name) * 4 + 1 + sizeof(".service")-1);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (!r)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return NULL;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt for (f = name, t = r; *f; f++) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (*f == '/')
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt *(t++) = '-';
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt else if (!strchr("@" VALID_CHARS, *f))
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt t = do_escape_char(*f, t);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt else
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt *(t++) = *f;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (unit_name_to_type(name) < 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt strcpy(t, ".service");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt else
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt *t = 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return r;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktchar *unit_name_mangle_with_suffix(const char *name, const char *suffix) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt char *r, *t;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt const char *f;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(name);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(suffix);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(suffix[0] == '.');
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* Similar to unit_name_mangle(), but is called when we know
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt * that this is about snapshot units. */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt r = new(char, strlen(name) * 4 + strlen(suffix) + 1);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (!r)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return NULL;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt for (f = name, t = r; *f; f++) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (*f == '/')
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt *(t++) = '-';
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt else if (!strchr(VALID_CHARS, *f))
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt t = do_escape_char(*f, t);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt else
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt *(t++) = *f;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (!endswith(name, suffix))
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt strcpy(t, suffix);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt else
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt *t = 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return r;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik FlyktUnitType unit_name_to_type(const char *n) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt const char *e;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(n);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt e = strrchr(n, '.');
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (!e)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return _UNIT_TYPE_INVALID;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return unit_type_from_string(e + 1);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt