]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/unit-printf.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / core / unit-printf.c
index f11df42af389ff9a415b626592941e65f179b6bd..c8896c41e28da8029fa92a651befa884cf3e47f0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -19,7 +20,7 @@
 
 #include "alloc-util.h"
 #include "cgroup-util.h"
-#include "formats-util.h"
+#include "format-util.h"
 #include "macro.h"
 #include "specifier.h"
 #include "string-util.h"
@@ -78,12 +79,18 @@ static int specifier_filename(char specifier, void *data, void *userdata, char *
                 return unit_name_to_path(u->id, ret);
 }
 
+static void bad_specifier(Unit *u, char specifier) {
+        log_unit_warning(u, "Specifier '%%%c' used in unit configuration, which is deprecated. Please update your unit file, as it does not work as intended.", specifier);
+}
+
 static int specifier_cgroup(char specifier, void *data, void *userdata, char **ret) {
         Unit *u = userdata;
         char *n;
 
         assert(u);
 
+        bad_specifier(u, specifier);
+
         if (u->cgroup_path)
                 n = strdup(u->cgroup_path);
         else
@@ -101,6 +108,8 @@ static int specifier_cgroup_root(char specifier, void *data, void *userdata, cha
 
         assert(u);
 
+        bad_specifier(u, specifier);
+
         n = strdup(u->manager->cgroup_root);
         if (!n)
                 return -ENOMEM;
@@ -115,6 +124,8 @@ static int specifier_cgroup_slice(char specifier, void *data, void *userdata, ch
 
         assert(u);
 
+        bad_specifier(u, specifier);
+
         if (UNIT_ISSET(u->slice)) {
                 Unit *slice;
 
@@ -133,17 +144,13 @@ static int specifier_cgroup_slice(char specifier, void *data, void *userdata, ch
         return 0;
 }
 
-static int specifier_runtime(char specifier, void *data, void *userdata, char **ret) {
+static int specifier_special_directory(char specifier, void *data, void *userdata, char **ret) {
         Unit *u = userdata;
-        const char *e;
         char *n = NULL;
 
         assert(u);
 
-        e = manager_get_runtime_prefix(u->manager);
-        if (!e)
-                return -EOPNOTSUPP;
-        n = strdup(e);
+        n = strdup(u->manager->prefix[PTR_TO_UINT(data)]);
         if (!n)
                 return -ENOMEM;
 
@@ -194,13 +201,20 @@ static int specifier_user_shell(char specifier, void *data, void *userdata, char
 int unit_name_printf(Unit *u, const char* format, char **ret) {
 
         /*
-         * This will use the passed string as format string and
-         * replace the following specifiers:
+         * This will use the passed string as format string and replace the following specifiers (which should all be
+         * safe for inclusion in unit names):
          *
          * %n: the full id of the unit                 (foo@bar.waldo)
          * %N: the id of the unit without the suffix   (foo@bar)
          * %p: the prefix                              (foo)
          * %i: the instance                            (bar)
+         *
+         * %U: the UID of the running user
+         * %u: the username of the running user
+         *
+         * %m: the machine ID of the running system
+         * %H: the host name of the running system
+         * %b: the boot ID of the running system
          */
 
         const Specifier table[] = {
@@ -208,7 +222,14 @@ int unit_name_printf(Unit *u, const char* format, char **ret) {
                 { 'N', specifier_prefix_and_instance, NULL },
                 { 'p', specifier_prefix,              NULL },
                 { 'i', specifier_string,              u->instance },
-                { 0, NULL, NULL }
+
+                { 'U', specifier_user_id,             NULL },
+                { 'u', specifier_user_name,           NULL },
+
+                { 'm', specifier_machine_id,          NULL },
+                { 'H', specifier_host_name,           NULL },
+                { 'b', specifier_boot_id,             NULL },
+                {}
         };
 
         assert(u);
@@ -220,22 +241,28 @@ int unit_name_printf(Unit *u, const char* format, char **ret) {
 
 int unit_full_printf(Unit *u, const char *format, char **ret) {
 
-        /* This is similar to unit_name_printf() but also supports
-         * unescaping. Also, adds a couple of additional codes:
+        /* This is similar to unit_name_printf() but also supports unescaping. Also, adds a couple of additional codes
+         * (which are likely not suitable for unescaped inclusion in unit names):
+         *
+         * %f: the unescaped instance if set, otherwise the id unescaped as path
+         *
+         * %c: cgroup path of unit (deprecated)
+         * %r: where units in this slice are placed in the cgroup tree (deprecated)
+         * %R: the root of this systemd's instance tree (deprecated)
+         *
+         * %t: the runtime directory root (e.g. /run or $XDG_RUNTIME_DIR)
+         * %S: the state directory root (e.g. /var/lib or $XDG_CONFIG_HOME)
+         * %C: the cache directory root (e.g. /var/cache or $XDG_CACHE_HOME)
+         * %L: the log directory root (e.g. /var/log or $XDG_CONFIG_HOME/log)
+         *
+         * %h: the homedir of the running user
+         * %s: the shell of the running user
+         *
+         * %v: `uname -r` of the running system
          *
-         * %f the instance if set, otherwise the id
-         * %c cgroup path of unit
-         * %r where units in this slice are placed in the cgroup tree
-         * %R the root of this systemd's instance tree
-         * %t the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR)
-         * %U the UID of the running user
-         * %u the username of the running user
-         * %h the homedir of the running user
-         * %s the shell of the running user
-         * %m the machine ID of the running system
-         * %H the host name of the running system
-         * %b the boot ID of the running system
-         * %v `uname -r` of the running system
+         * NOTICE: When you add new entries here, please be careful: specifiers which depend on settings of the unit
+         * file itself are broken by design, as they would resolve differently depending on whether they are used
+         * before or after the relevant configuration setting. Hence: don't add them.
          */
 
         const Specifier table[] = {
@@ -250,7 +277,10 @@ int unit_full_printf(Unit *u, const char *format, char **ret) {
                 { 'c', specifier_cgroup,              NULL },
                 { 'r', specifier_cgroup_slice,        NULL },
                 { 'R', specifier_cgroup_root,         NULL },
-                { 't', specifier_runtime,             NULL },
+                { 't', specifier_special_directory,   UINT_TO_PTR(EXEC_DIRECTORY_RUNTIME) },
+                { 'S', specifier_special_directory,   UINT_TO_PTR(EXEC_DIRECTORY_STATE) },
+                { 'C', specifier_special_directory,   UINT_TO_PTR(EXEC_DIRECTORY_CACHE) },
+                { 'L', specifier_special_directory,   UINT_TO_PTR(EXEC_DIRECTORY_LOGS) },
 
                 { 'U', specifier_user_id,             NULL },
                 { 'u', specifier_user_name,           NULL },