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