]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/install-printf.c
tree-wide: use "hostname" spelling everywhere
[thirdparty/systemd.git] / src / shared / install-printf.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <errno.h>
4 #include <stdio.h>
5 #include <unistd.h>
6
7 #include "format-util.h"
8 #include "install-printf.h"
9 #include "install.h"
10 #include "macro.h"
11 #include "specifier.h"
12 #include "string-util.h"
13 #include "unit-name.h"
14 #include "user-util.h"
15
16 static int specifier_prefix_and_instance(char specifier, const void *data, const void *userdata, char **ret) {
17 const UnitFileInstallInfo *i = userdata;
18 _cleanup_free_ char *prefix = NULL;
19 int r;
20
21 assert(i);
22
23 r = unit_name_to_prefix_and_instance(i->name, &prefix);
24 if (r < 0)
25 return r;
26
27 if (endswith(prefix, "@") && i->default_instance) {
28 char *ans;
29
30 ans = strjoin(prefix, i->default_instance);
31 if (!ans)
32 return -ENOMEM;
33 *ret = ans;
34 } else
35 *ret = TAKE_PTR(prefix);
36
37 return 0;
38 }
39
40 static int specifier_name(char specifier, const void *data, const void *userdata, char **ret) {
41 const UnitFileInstallInfo *i = userdata;
42 char *ans;
43
44 assert(i);
45
46 if (unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE) && i->default_instance)
47 return unit_name_replace_instance(i->name, i->default_instance, ret);
48
49 ans = strdup(i->name);
50 if (!ans)
51 return -ENOMEM;
52 *ret = ans;
53 return 0;
54 }
55
56 static int specifier_prefix(char specifier, const void *data, const void *userdata, char **ret) {
57 const UnitFileInstallInfo *i = userdata;
58
59 assert(i);
60
61 return unit_name_to_prefix(i->name, ret);
62 }
63
64 static int specifier_instance(char specifier, const void *data, const void *userdata, char **ret) {
65 const UnitFileInstallInfo *i = userdata;
66 char *instance;
67 int r;
68
69 assert(i);
70
71 r = unit_name_to_instance(i->name, &instance);
72 if (r < 0)
73 return r;
74
75 if (isempty(instance)) {
76 r = free_and_strdup(&instance, strempty(i->default_instance));
77 if (r < 0)
78 return r;
79 }
80
81 *ret = instance;
82 return 0;
83 }
84
85 static int specifier_last_component(char specifier, const void *data, const void *userdata, char **ret) {
86 _cleanup_free_ char *prefix = NULL;
87 char *dash;
88 int r;
89
90 r = specifier_prefix(specifier, data, userdata, &prefix);
91 if (r < 0)
92 return r;
93
94 dash = strrchr(prefix, '-');
95 if (dash) {
96 dash = strdup(dash + 1);
97 if (!dash)
98 return -ENOMEM;
99 *ret = dash;
100 } else
101 *ret = TAKE_PTR(prefix);
102
103 return 0;
104 }
105
106 int install_full_printf(const UnitFileInstallInfo *i, const char *format, char **ret) {
107 /* This is similar to unit_full_printf() but does not support
108 * anything path-related.
109 *
110 * %n: the full id of the unit (foo@bar.waldo)
111 * %N: the id of the unit without the suffix (foo@bar)
112 * %p: the prefix (foo)
113 * %i: the instance (bar)
114
115 * %U the UID of the running user
116 * %u the username of running user
117 * %m the machine ID of the running system
118 * %H the hostname of the running system
119 * %b the boot ID of the running system
120 * %v `uname -r` of the running system
121 */
122
123 const Specifier table[] = {
124 { 'n', specifier_name, NULL },
125 { 'N', specifier_prefix_and_instance, NULL },
126 { 'p', specifier_prefix, NULL },
127 { 'i', specifier_instance, NULL },
128 { 'j', specifier_last_component, NULL },
129
130 { 'g', specifier_group_name, NULL },
131 { 'G', specifier_group_id, NULL },
132 { 'U', specifier_user_id, NULL },
133 { 'u', specifier_user_name, NULL },
134
135 { 'm', specifier_machine_id, NULL },
136 { 'H', specifier_host_name, NULL },
137 { 'b', specifier_boot_id, NULL },
138 { 'v', specifier_kernel_release, NULL },
139 {}
140 };
141
142 assert(i);
143 assert(format);
144 assert(ret);
145
146 return specifier_printf(format, table, i, ret);
147 }