From b0193f1c1f1540bfccbdca02df82669b9308e4e2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 22 Jun 2012 13:08:48 +0200 Subject: [PATCH] systemctl: automatically turn paths and unescaped unit names into proper unit names This makes sure that systemctl status /home is implicitly translated to: systemctl status /home.mount Similar, /dev/foobar becomes dev-foobar.device. Also, all characters that cannot be part of a unit name are implicitly escaped. --- .gitignore | 1 + Makefile.am | 9 +- TODO | 4 - src/core/device.c | 6 +- src/shared/unit-name.c | 73 +++++++++-- src/shared/unit-name.h | 2 + src/systemctl/systemctl.c | 249 ++++++++++++++++++++++++-------------- src/test/test-hostname.c | 3 +- src/test/test-unit-name.c | 82 +++++++++++++ 9 files changed, 317 insertions(+), 112 deletions(-) create mode 100644 src/test/test-unit-name.c diff --git a/.gitignore b/.gitignore index 7d04930a2..07321768a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/test-unit-name /systemd-system-update-generator /systemd-fstab-generator /systemd-delta diff --git a/Makefile.am b/Makefile.am index e1e02b728..276c2265d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -906,7 +906,8 @@ noinst_PROGRAMS += \ test-env-replace \ test-strv \ test-install \ - test-watchdog + test-watchdog \ + test-unit-name TESTS += \ test-job-type \ @@ -955,6 +956,12 @@ test_hostname_SOURCES = \ test_hostname_LDADD = \ libsystemd-core.la +test_unit_name_SOURCES = \ + src/test/test-unit-name.c + +test_unit_name_LDADD = \ + libsystemd-core.la + test_daemon_SOURCES = \ src/test/test-daemon.c diff --git a/TODO b/TODO index f301ac121..7785e32c9 100644 --- a/TODO +++ b/TODO @@ -32,14 +32,10 @@ Features: * support rd.luks.allow-discards= kernel cmdline params in cryptsetup generator -* support rd.driver= kernel cmdline params in modules load - * systemctl: when stopping a service which has triggres and warning about it actually check the TriggeredBy= deps fields * journal: hook up with EFI firmware log, new kmsg logic -* falconindy: allow unescaped pathes for mount units, like "systmectl status /.mount"? - * handle C-A-Del in logind, like the power/suspend buttons? * nspawn: make use of device cgroup contrller by default diff --git a/src/core/device.c b/src/core/device.c index cd0a09954..f4c59b3a5 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -144,7 +144,8 @@ static int device_add_escaped_name(Unit *u, const char *dn) { assert(dn); assert(dn[0] == '/'); - if (!(e = unit_name_from_path(dn, ".device"))) + e = unit_name_from_path(dn, ".device"); + if (!e) return -ENOMEM; r = unit_add_name(u, e); @@ -165,7 +166,8 @@ static int device_find_escape_name(Manager *m, const char *dn, Unit **_u) { assert(dn[0] == '/'); assert(_u); - if (!(e = unit_name_from_path(dn, ".device"))) + e = unit_name_from_path(dn, ".device"); + if (!e) return -ENOMEM; u = manager_get_unit(m, e); diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c index 91f464ee9..8c8e592ab 100644 --- a/src/shared/unit-name.c +++ b/src/shared/unit-name.c @@ -140,7 +140,8 @@ char *unit_name_to_prefix_and_instance(const char *n) { char *unit_name_to_prefix(const char *n) { const char *p; - if ((p = strchr(n, '@'))) + p = strchr(n, '@'); + if (p) return strndup(n, p - n); return unit_name_to_prefix_and_instance(n); @@ -158,7 +159,8 @@ char *unit_name_change_suffix(const char *n, const char *suffix) { a = e - n; b = strlen(suffix); - if (!(r = new(char, a + b + 1))) + r = new(char, a + b + 1); + if (!r) return NULL; memcpy(r, n, a); @@ -234,7 +236,8 @@ char *unit_name_build_escape(const char *prefix, const char *instance, const cha if (instance) { b = strlen(instance); - if (!(r = new(char, a*4 + 1 + b*4 + c + 1))) + r = new(char, a*4 + 1 + b*4 + c + 1); + if (!r) return NULL; t = do_escape(prefix, r); @@ -255,14 +258,14 @@ char *unit_name_build_escape(const char *prefix, const char *instance, const cha char *unit_name_escape(const char *f) { char *r, *t; - if (!(r = new(char, strlen(f)*4+1))) + r = new(char, strlen(f)*4+1); + if (!r) return NULL; t = do_escape(f, r); *t = 0; return r; - } char *unit_name_unescape(const char *f) { @@ -270,7 +273,8 @@ char *unit_name_unescape(const char *f) { assert(f); - if (!(r = strdup(f))) + r = strdup(f); + if (!r) return NULL; for (t = r; *f; f++) { @@ -347,13 +351,15 @@ char *unit_name_template(const char *f) { char *r; size_t a; - if (!(p = strchr(f, '@'))) + p = strchr(f, '@'); + if (!p) return strdup(f); assert_se(e = strrchr(f, '.')); a = p - f + 1; - if (!(r = new(char, a + strlen(e) + 1))) + r = new(char, a + strlen(e) + 1); + if (!r) return NULL; strcpy(mempcpy(r, f, a), e); @@ -367,7 +373,8 @@ char *unit_name_from_path(const char *path, const char *suffix) { assert(path); assert(suffix); - if (!(p = strdup(path))) + p = strdup(path); + if (!p) return NULL; path_kill_slashes(p); @@ -414,7 +421,8 @@ char *unit_name_to_path(const char *name) { assert(name); - if (!(w = unit_name_to_prefix(name))) + w = unit_name_to_prefix(name); + if (!w) return NULL; e = unit_name_unescape(w); @@ -430,7 +438,7 @@ char *unit_name_to_path(const char *name) { if (!w) return NULL; - e = w; + return w; } return e; @@ -441,7 +449,8 @@ char *unit_name_path_unescape(const char *f) { assert(f); - if (!(e = unit_name_unescape(f))) + e = unit_name_unescape(f); + if (!e) return NULL; if (e[0] != '/') { @@ -453,7 +462,7 @@ char *unit_name_path_unescape(const char *f) { if (!w) return NULL; - e = w; + return w; } return e; @@ -471,3 +480,41 @@ char *unit_dbus_path_from_name(const char *name) { return p; } + +char *unit_name_mangle(const char *name) { + char *r, *t; + const char *f; + + assert(name); + + /* Try to turn a string that might not be a unit name into a + * sensible unit name. */ + + if (path_startswith(name, "/dev/") || + path_startswith(name, "/sys/")) + return unit_name_from_path(name, ".device"); + + if (path_is_absolute(name)) + return unit_name_from_path(name, ".mount"); + + /* We'll only escape the obvious characters here, to play + * safe. */ + + r = new(char, strlen(name) * 4 + 1); + if (!r) + return NULL; + + for (f = name, t = r; *f; f++) { + + if (*f == '/') + *(t++) = '-'; + else if (!strchr("@" VALID_CHARS, *f)) + t = do_escape_char(*f, t); + else + *(t++) = *f; + } + + *t = 0; + + return r; +} diff --git a/src/shared/unit-name.h b/src/shared/unit-name.h index 7aab2e557..64bb24890 100644 --- a/src/shared/unit-name.h +++ b/src/shared/unit-name.h @@ -56,4 +56,6 @@ char *unit_name_to_path(const char *name); char *unit_dbus_path_from_name(const char *name); +char *unit_name_mangle(const char *name); + #endif diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index ad0cd17e1..b8b9ed095 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -1123,6 +1123,8 @@ static int load_unit(DBusConnection *bus, char **args) { STRV_FOREACH(name, args+1) { DBusMessage *reply; + bool b; + char *n; if (!(m = dbus_message_new_method_call( "org.freedesktop.systemd1", @@ -1134,15 +1136,19 @@ static int load_unit(DBusConnection *bus, char **args) { goto finish; } - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, name, - DBUS_TYPE_INVALID)) { + n = unit_name_mangle(*name); + b = dbus_message_append_args(m, + DBUS_TYPE_STRING, n ? &n : name, + DBUS_TYPE_INVALID); + free(n); + if (!b) { log_error("Could not append arguments to message."); r = -ENOMEM; goto finish; } - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { log_error("Failed to issue method call: %s", bus_error_message(&error)); r = -EIO; goto finish; @@ -1266,22 +1272,29 @@ static bool need_daemon_reload(DBusConnection *bus, const char *unit) { *interface = "org.freedesktop.systemd1.Unit", *property = "NeedDaemonReload", *path; + char *n; + bool k; /* We ignore all errors here, since this is used to show a warning only */ - if (!(m = dbus_message_new_method_call( + m = dbus_message_new_method_call( "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", - "GetUnit"))) + "GetUnit"); + if (!m) goto finish; - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, &unit, - DBUS_TYPE_INVALID)) + n = unit_name_mangle(unit); + k = dbus_message_append_args(m, + DBUS_TYPE_STRING, n ? (const char**) &n : &unit, + DBUS_TYPE_INVALID); + free(n); + if (!k) goto finish; - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, NULL))) + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, NULL); + if (!reply) goto finish; if (!dbus_message_get_args(reply, NULL, @@ -1290,11 +1303,12 @@ static bool need_daemon_reload(DBusConnection *bus, const char *unit) { goto finish; dbus_message_unref(m); - if (!(m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - path, - "org.freedesktop.DBus.Properties", - "Get"))) + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "Get"); + if (!m) goto finish; if (!dbus_message_append_args(m, @@ -1305,7 +1319,8 @@ static bool need_daemon_reload(DBusConnection *bus, const char *unit) { } dbus_message_unref(reply); - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, NULL))) + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, NULL); + if (!reply) goto finish; if (!dbus_message_iter_init(reply, &iter) || @@ -1510,6 +1525,8 @@ static int check_one_unit(DBusConnection *bus, char *name, bool quiet) { const char *path = NULL; const char *state; int r = 3; /* According to LSB: "program is not running" */ + char *n; + bool b; assert(bus); assert(name); @@ -1527,9 +1544,12 @@ static int check_one_unit(DBusConnection *bus, char *name, bool quiet) { goto finish; } - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID)) { + n = unit_name_mangle(name); + b = dbus_message_append_args(m, + DBUS_TYPE_STRING, n ? &n : &name, + DBUS_TYPE_INVALID); + free(n); + if (!b) { log_error("Could not append arguments to message."); r = -ENOMEM; goto finish; @@ -1627,12 +1647,14 @@ static void check_triggering_units( const char *interface = "org.freedesktop.systemd1.Unit", *triggered_by_property = "TriggeredBy"; - char *unit_path = NULL; + char *unit_path = NULL, *n = NULL; bool print_warning_label = true; dbus_error_init(&error); - unit_path = unit_dbus_path_from_name(unit_name); + n = unit_name_mangle(unit_name); + unit_path = unit_dbus_path_from_name(n ? n : unit_name); + free(n); if (!unit_path) { log_error("Could not allocate dbus path."); goto finish; @@ -1718,6 +1740,8 @@ static int start_unit_one( DBusMessage *m = NULL, *reply = NULL; const char *path; int r; + char *n; + bool b; assert(bus); assert(method); @@ -1726,26 +1750,31 @@ static int start_unit_one( assert(error); assert(arg_no_block || s); - if (!(m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - method))) { + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + method); + if (!m) { log_error("Could not allocate message."); r = -ENOMEM; goto finish; } - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_STRING, &mode, - DBUS_TYPE_INVALID)) { + n = unit_name_mangle(name); + b = dbus_message_append_args(m, + DBUS_TYPE_STRING, n ? (const char **) &n : &name, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID); + free(n); + if (!b) { log_error("Could not append arguments to message."); r = -ENOMEM; goto finish; } - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error))) { + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error); + if (!reply) { if (arg_action != ACTION_SYSTEMCTL && error_is_no_service(error)) { /* There's always a fallback possible for @@ -2113,29 +2142,36 @@ static int kill_unit(DBusConnection *bus, char **args) { STRV_FOREACH(name, args+1) { DBusMessage *reply; + char *n; + bool b; - if (!(m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "KillUnit"))) { + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "KillUnit"); + if (!m) { log_error("Could not allocate message."); r = -ENOMEM; goto finish; } - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, name, - DBUS_TYPE_STRING, &arg_kill_who, - DBUS_TYPE_STRING, &arg_kill_mode, - DBUS_TYPE_INT32, &arg_signal, - DBUS_TYPE_INVALID)) { + n = unit_name_mangle(*name); + b = dbus_message_append_args(m, + DBUS_TYPE_STRING, n ? &n : name, + DBUS_TYPE_STRING, &arg_kill_who, + DBUS_TYPE_STRING, &arg_kill_mode, + DBUS_TYPE_INT32, &arg_signal, + DBUS_TYPE_INVALID); + free(n); + if (!b) { log_error("Could not append arguments to message."); r = -ENOMEM; goto finish; } - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { log_error("Failed to issue method call: %s", bus_error_message(&error)); dbus_error_free(&error); r = -EIO; @@ -3237,12 +3273,16 @@ static int show(DBusConnection *bus, char **args) { uint32_t id; if (safe_atou32(*name, &id) < 0) { - + char *p, *n; /* Interpret as unit name */ - char *p = unit_dbus_path_from_name(*name); - if (!p) + n = unit_name_mangle(*name); + p = unit_dbus_path_from_name(n ? n : *name); + free(n); + if (!p) { + log_error("Out of memory"); return -ENOMEM; + } r = show_one(args[0], bus, p, show_properties, &new_line); free(p); @@ -3255,8 +3295,10 @@ static int show(DBusConnection *bus, char **args) { /* Interpret as job id */ char *p; - if (asprintf(&p, "/org/freedesktop/systemd1/job/%u", id) < 0) + if (asprintf(&p, "/org/freedesktop/systemd1/job/%u", id) < 0) { + log_error("Out of memory"); return -ENOMEM; + } r = show_one(args[0], bus, p, show_properties, &new_line); free(p); @@ -3336,14 +3378,17 @@ static int snapshot(DBusConnection *bus, char **args) { const char *interface = "org.freedesktop.systemd1.Unit", *property = "Id"; + char *n; + bool b; dbus_error_init(&error); - if (!(m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "CreateSnapshot"))) { + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "CreateSnapshot"); + if (!m) { log_error("Could not allocate message."); return -ENOMEM; } @@ -3351,16 +3396,20 @@ static int snapshot(DBusConnection *bus, char **args) { if (strv_length(args) > 1) name = args[1]; - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_BOOLEAN, &cleanup, - DBUS_TYPE_INVALID)) { + n = unit_name_mangle(name); + b = dbus_message_append_args(m, + DBUS_TYPE_STRING, n ? (const char**) &n : &name, + DBUS_TYPE_BOOLEAN, &cleanup, + DBUS_TYPE_INVALID); + free(n); + if (!b) { log_error("Could not append arguments to message."); r = -ENOMEM; goto finish; } - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { log_error("Failed to issue method call: %s", bus_error_message(&error)); r = -EIO; goto finish; @@ -3375,11 +3424,12 @@ static int snapshot(DBusConnection *bus, char **args) { } dbus_message_unref(m); - if (!(m = dbus_message_new_method_call( + m = dbus_message_new_method_call( "org.freedesktop.systemd1", path, "org.freedesktop.DBus.Properties", - "Get"))) { + "Get"); + if (!m) { log_error("Could not allocate message."); return -ENOMEM; } @@ -3394,7 +3444,8 @@ static int snapshot(DBusConnection *bus, char **args) { } dbus_message_unref(reply); - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { log_error("Failed to issue method call: %s", bus_error_message(&error)); r = -EIO; goto finish; @@ -3446,26 +3497,33 @@ static int delete_snapshot(DBusConnection *bus, char **args) { STRV_FOREACH(name, args+1) { const char *path = NULL; + char *n; + bool b; - if (!(m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "GetUnit"))) { + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnit"); + if (!m) { log_error("Could not allocate message."); r = -ENOMEM; goto finish; } - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, name, - DBUS_TYPE_INVALID)) { + n = unit_name_mangle(*name); + b = dbus_message_append_args(m, + DBUS_TYPE_STRING, n ? &n : name, + DBUS_TYPE_INVALID); + free(n); + if (!b) { log_error("Could not append arguments to message."); r = -ENOMEM; goto finish; } - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { log_error("Failed to issue method call: %s", bus_error_message(&error)); r = -EIO; goto finish; @@ -3480,18 +3538,20 @@ static int delete_snapshot(DBusConnection *bus, char **args) { } dbus_message_unref(m); - if (!(m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - path, - "org.freedesktop.systemd1.Snapshot", - "Remove"))) { + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + path, + "org.freedesktop.systemd1.Snapshot", + "Remove"); + if (!m) { log_error("Could not allocate message."); r = -ENOMEM; goto finish; } dbus_message_unref(reply); - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { log_error("Failed to issue method call: %s", bus_error_message(&error)); r = -EIO; goto finish; @@ -3602,26 +3662,33 @@ static int reset_failed(DBusConnection *bus, char **args) { STRV_FOREACH(name, args+1) { DBusMessage *reply; + char *n; + bool b; - if (!(m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "ResetFailedUnit"))) { + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "ResetFailedUnit"); + if (!m) { log_error("Could not allocate message."); r = -ENOMEM; goto finish; } - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, name, - DBUS_TYPE_INVALID)) { + n = unit_name_mangle(*name); + b = dbus_message_append_args(m, + DBUS_TYPE_STRING, n ? &n : name, + DBUS_TYPE_INVALID); + free(n); + if (!b) { log_error("Could not append arguments to message."); r = -ENOMEM; goto finish; } - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { log_error("Failed to issue method call: %s", bus_error_message(&error)); r = -EIO; goto finish; @@ -4735,7 +4802,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { return -EINVAL; default: - log_error("Unknown option code %c", c); + log_error("Unknown option code '%c'.", c); return -EINVAL; } } @@ -4828,7 +4895,7 @@ static int halt_parse_argv(int argc, char *argv[]) { return -EINVAL; default: - log_error("Unknown option code %c", c); + log_error("Unknown option code '%c'.", c); return -EINVAL; } } @@ -4965,7 +5032,7 @@ static int shutdown_parse_argv(int argc, char *argv[]) { return -EINVAL; default: - log_error("Unknown option code %c", c); + log_error("Unknown option code '%c'.", c); return -EINVAL; } } @@ -5041,7 +5108,7 @@ static int telinit_parse_argv(int argc, char *argv[]) { return -EINVAL; default: - log_error("Unknown option code %c", c); + log_error("Unknown option code '%c'.", c); return -EINVAL; } } @@ -5066,7 +5133,7 @@ static int telinit_parse_argv(int argc, char *argv[]) { break; if (i >= ELEMENTSOF(table)) { - log_error("Unknown command %s.", argv[optind]); + log_error("Unknown command '%s'.", argv[optind]); return -EINVAL; } @@ -5104,7 +5171,7 @@ static int runlevel_parse_argv(int argc, char *argv[]) { return -EINVAL; default: - log_error("Unknown option code %c", c); + log_error("Unknown option code '%c'.", c); return -EINVAL; } } @@ -5405,7 +5472,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError break; if (i >= ELEMENTSOF(verbs)) { - log_error("Unknown operation %s", argv[optind]); + log_error("Unknown operation '%s'.", argv[optind]); return -EINVAL; } } diff --git a/src/test/test-hostname.c b/src/test/test-hostname.c index 8c1a60f94..ad4f28561 100644 --- a/src/test/test-hostname.c +++ b/src/test/test-hostname.c @@ -30,7 +30,8 @@ int main(int argc, char* argv[]) { int r; - if ((r = hostname_setup()) < 0) + r = hostname_setup(); + if (r < 0) fprintf(stderr, "hostname: %s\n", strerror(-r)); return 0; diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c new file mode 100644 index 000000000..9d636afe1 --- /dev/null +++ b/src/test/test-unit-name.c @@ -0,0 +1,82 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "unit-name.h" +#include "util.h" + +int main(int argc, char* argv[]) { + char *t, *k; + + assert_se(t = unit_name_mangle("/home")); + assert_se(k = unit_name_mangle(t)); + puts(t); + assert_se(streq(t, k)); + free(t); + free(k); + + assert_se(t = unit_name_mangle("/dev/sda")); + assert_se(k = unit_name_mangle(t)); + puts(t); + assert_se(streq(t, k)); + free(t); + free(k); + + assert_se(t = unit_name_mangle("üxknürz.service")); + assert_se(k = unit_name_mangle(t)); + puts(t); + assert_se(streq(t, k)); + free(t); + free(k); + + assert_se(t = unit_name_mangle("foobar-meh...waldi.service")); + assert_se(k = unit_name_mangle(t)); + puts(t); + assert_se(streq(t, k)); + free(t); + free(k); + + assert_se(t = unit_name_mangle("_____####----.....service")); + assert_se(k = unit_name_mangle(t)); + puts(t); + assert_se(streq(t, k)); + free(t); + free(k); + + assert_se(t = unit_name_mangle("_____##@;;;,,,##----.....service")); + assert_se(k = unit_name_mangle(t)); + puts(t); + assert_se(streq(t, k)); + free(t); + free(k); + + assert_se(t = unit_name_mangle("xxx@@@@/////\\\\\\\\\\yyy.service")); + assert_se(k = unit_name_mangle(t)); + puts(t); + assert_se(streq(t, k)); + free(t); + free(k); + + return 0; +} -- 2.30.2