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