Line data Source code
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 2 : static int specifier_prefix_and_instance(char specifier, const void *data, const void *userdata, char **ret) {
18 2 : const UnitFileInstallInfo *i = userdata;
19 2 : _cleanup_free_ char *prefix = NULL;
20 : int r;
21 :
22 2 : assert(i);
23 :
24 2 : r = unit_name_to_prefix_and_instance(i->name, &prefix);
25 2 : if (r < 0)
26 0 : return r;
27 :
28 2 : if (endswith(prefix, "@") && i->default_instance) {
29 : char *ans;
30 :
31 0 : ans = strjoin(prefix, i->default_instance);
32 0 : if (!ans)
33 0 : return -ENOMEM;
34 0 : *ret = ans;
35 : } else
36 2 : *ret = TAKE_PTR(prefix);
37 :
38 2 : return 0;
39 : }
40 :
41 2 : static int specifier_name(char specifier, const void *data, const void *userdata, char **ret) {
42 2 : const UnitFileInstallInfo *i = userdata;
43 : char *ans;
44 :
45 2 : assert(i);
46 :
47 2 : if (unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE) && i->default_instance)
48 0 : return unit_name_replace_instance(i->name, i->default_instance, ret);
49 :
50 2 : ans = strdup(i->name);
51 2 : if (!ans)
52 0 : return -ENOMEM;
53 2 : *ret = ans;
54 2 : return 0;
55 : }
56 :
57 3 : static int specifier_prefix(char specifier, const void *data, const void *userdata, char **ret) {
58 3 : const UnitFileInstallInfo *i = userdata;
59 :
60 3 : assert(i);
61 :
62 3 : return unit_name_to_prefix(i->name, ret);
63 : }
64 :
65 1 : static int specifier_instance(char specifier, const void *data, const void *userdata, char **ret) {
66 1 : const UnitFileInstallInfo *i = userdata;
67 : char *instance;
68 : int r;
69 :
70 1 : assert(i);
71 :
72 1 : r = unit_name_to_instance(i->name, &instance);
73 1 : if (r < 0)
74 0 : return r;
75 :
76 1 : if (isempty(instance)) {
77 1 : r = free_and_strdup(&instance, strempty(i->default_instance));
78 1 : if (r < 0)
79 0 : return r;
80 : }
81 :
82 1 : *ret = instance;
83 1 : return 0;
84 : }
85 :
86 1 : static int specifier_last_component(char specifier, const void *data, const void *userdata, char **ret) {
87 1 : _cleanup_free_ char *prefix = NULL;
88 : char *dash;
89 : int r;
90 :
91 1 : r = specifier_prefix(specifier, data, userdata, &prefix);
92 1 : if (r < 0)
93 0 : return r;
94 :
95 1 : dash = strrchr(prefix, '-');
96 1 : if (dash) {
97 0 : dash = strdup(dash + 1);
98 0 : if (!dash)
99 0 : return -ENOMEM;
100 0 : *ret = dash;
101 : } else
102 1 : *ret = TAKE_PTR(prefix);
103 :
104 1 : return 0;
105 : }
106 :
107 137 : 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 137 : 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 137 : assert(i);
144 137 : assert(format);
145 137 : assert(ret);
146 :
147 137 : return specifier_printf(format, table, i, ret);
148 : }
|