]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/install-printf.c
81a5e4a73e6e355e81bff57f66fffd70b070ed26
[thirdparty/systemd.git] / src / shared / install-printf.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "alloc-util.h"
4 #include "install.h"
5 #include "install-printf.h"
6 #include "specifier.h"
7 #include "string-util.h"
8 #include "unit-name.h"
9
10 static int specifier_prefix_and_instance(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
11 const InstallInfo *i = ASSERT_PTR(userdata);
12 _cleanup_free_ char *prefix = NULL;
13 int r;
14
15 r = unit_name_to_prefix_and_instance(i->name, &prefix);
16 if (r < 0)
17 return r;
18
19 if (endswith(prefix, "@") && i->default_instance) {
20 char *ans;
21
22 ans = strjoin(prefix, i->default_instance);
23 if (!ans)
24 return -ENOMEM;
25 *ret = ans;
26 } else
27 *ret = TAKE_PTR(prefix);
28
29 return 0;
30 }
31
32 static int specifier_name(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
33 const InstallInfo *i = ASSERT_PTR(userdata);
34
35 if (unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE) && i->default_instance)
36 return unit_name_replace_instance(i->name, i->default_instance, ret);
37
38 return strdup_to(ret, i->name);
39 }
40
41 static int specifier_prefix(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
42 const InstallInfo *i = ASSERT_PTR(userdata);
43
44 return unit_name_to_prefix(i->name, ret);
45 }
46
47 static int specifier_instance(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
48 const InstallInfo *i = ASSERT_PTR(userdata);
49 char *instance;
50 int r;
51
52 r = unit_name_to_instance(i->name, &instance);
53 if (r < 0)
54 return r;
55
56 if (isempty(instance)) {
57 r = free_and_strdup(&instance, strempty(i->default_instance));
58 if (r < 0)
59 return r;
60 }
61
62 *ret = instance;
63 return 0;
64 }
65
66 static int specifier_last_component(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
67 _cleanup_free_ char *prefix = NULL;
68 char *dash;
69 int r;
70
71 assert(ret);
72
73 r = specifier_prefix(specifier, data, root, userdata, &prefix);
74 if (r < 0)
75 return r;
76
77 dash = strrchr(prefix, '-');
78 if (dash)
79 return strdup_to(ret, dash + 1);
80
81 *ret = TAKE_PTR(prefix);
82 return 0;
83 }
84
85 int install_name_printf(
86 RuntimeScope scope,
87 const InstallInfo *info,
88 const char *format,
89 char **ret) {
90 /* This is similar to unit_name_printf() */
91
92 const Specifier table[] = {
93 { 'i', specifier_instance, NULL },
94 { 'j', specifier_last_component, NULL },
95 { 'n', specifier_name, NULL },
96 { 'N', specifier_prefix_and_instance, NULL },
97 { 'p', specifier_prefix, NULL },
98
99 COMMON_SYSTEM_SPECIFIERS,
100
101 COMMON_CREDS_SPECIFIERS(scope),
102 {}
103 };
104
105 assert(info);
106 assert(format);
107 assert(ret);
108
109 return specifier_printf(format, UNIT_NAME_MAX, table, info->root, info, ret);
110 }