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