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