/src/systemd/src/shared/install-printf.c
Line | Count | Source (jump to first uncovered line) |
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 | 0 | static int specifier_prefix_and_instance(char specifier, const void *data, const void *userdata, char **ret) { |
18 | 0 | const UnitFileInstallInfo *i = userdata; |
19 | 0 | _cleanup_free_ char *prefix = NULL; |
20 | 0 | int r; |
21 | 0 |
|
22 | 0 | assert(i); |
23 | 0 |
|
24 | 0 | r = unit_name_to_prefix_and_instance(i->name, &prefix); |
25 | 0 | if (r < 0) |
26 | 0 | return r; |
27 | 0 | |
28 | 0 | if (endswith(prefix, "@") && i->default_instance) { |
29 | 0 | char *ans; |
30 | 0 |
|
31 | 0 | ans = strjoin(prefix, i->default_instance); |
32 | 0 | if (!ans) |
33 | 0 | return -ENOMEM; |
34 | 0 | *ret = ans; |
35 | 0 | } else |
36 | 0 | *ret = TAKE_PTR(prefix); |
37 | 0 |
|
38 | 0 | return 0; |
39 | 0 | } |
40 | | |
41 | 0 | static int specifier_name(char specifier, const void *data, const void *userdata, char **ret) { |
42 | 0 | const UnitFileInstallInfo *i = userdata; |
43 | 0 | char *ans; |
44 | 0 |
|
45 | 0 | assert(i); |
46 | 0 |
|
47 | 0 | 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 | 0 | |
50 | 0 | ans = strdup(i->name); |
51 | 0 | if (!ans) |
52 | 0 | return -ENOMEM; |
53 | 0 | *ret = ans; |
54 | 0 | return 0; |
55 | 0 | } |
56 | | |
57 | 0 | static int specifier_prefix(char specifier, const void *data, const void *userdata, char **ret) { |
58 | 0 | const UnitFileInstallInfo *i = userdata; |
59 | 0 |
|
60 | 0 | assert(i); |
61 | 0 |
|
62 | 0 | return unit_name_to_prefix(i->name, ret); |
63 | 0 | } |
64 | | |
65 | 0 | static int specifier_instance(char specifier, const void *data, const void *userdata, char **ret) { |
66 | 0 | const UnitFileInstallInfo *i = userdata; |
67 | 0 | char *instance; |
68 | 0 | int r; |
69 | 0 |
|
70 | 0 | assert(i); |
71 | 0 |
|
72 | 0 | r = unit_name_to_instance(i->name, &instance); |
73 | 0 | if (r < 0) |
74 | 0 | return r; |
75 | 0 | |
76 | 0 | if (isempty(instance)) { |
77 | 0 | r = free_and_strdup(&instance, strempty(i->default_instance)); |
78 | 0 | if (r < 0) |
79 | 0 | return r; |
80 | 0 | } |
81 | 0 | |
82 | 0 | *ret = instance; |
83 | 0 | return 0; |
84 | 0 | } |
85 | | |
86 | 0 | static int specifier_last_component(char specifier, const void *data, const void *userdata, char **ret) { |
87 | 0 | _cleanup_free_ char *prefix = NULL; |
88 | 0 | char *dash; |
89 | 0 | int r; |
90 | 0 |
|
91 | 0 | r = specifier_prefix(specifier, data, userdata, &prefix); |
92 | 0 | if (r < 0) |
93 | 0 | return r; |
94 | 0 | |
95 | 0 | dash = strrchr(prefix, '-'); |
96 | 0 | if (dash) { |
97 | 0 | dash = strdup(dash + 1); |
98 | 0 | if (!dash) |
99 | 0 | return -ENOMEM; |
100 | 0 | *ret = dash; |
101 | 0 | } else |
102 | 0 | *ret = TAKE_PTR(prefix); |
103 | 0 |
|
104 | 0 | return 0; |
105 | 0 | } |
106 | | |
107 | 0 | int install_full_printf(const UnitFileInstallInfo *i, const char *format, char **ret) { |
108 | 0 | /* This is similar to unit_full_printf() but does not support |
109 | 0 | * anything path-related. |
110 | 0 | * |
111 | 0 | * %n: the full id of the unit (foo@bar.waldo) |
112 | 0 | * %N: the id of the unit without the suffix (foo@bar) |
113 | 0 | * %p: the prefix (foo) |
114 | 0 | * %i: the instance (bar) |
115 | 0 |
|
116 | 0 | * %U the UID of the running user |
117 | 0 | * %u the username of running user |
118 | 0 | * %m the machine ID of the running system |
119 | 0 | * %H the host name of the running system |
120 | 0 | * %b the boot ID of the running system |
121 | 0 | * %v `uname -r` of the running system |
122 | 0 | */ |
123 | 0 |
|
124 | 0 | const Specifier table[] = { |
125 | 0 | { 'n', specifier_name, NULL }, |
126 | 0 | { 'N', specifier_prefix_and_instance, NULL }, |
127 | 0 | { 'p', specifier_prefix, NULL }, |
128 | 0 | { 'i', specifier_instance, NULL }, |
129 | 0 | { 'j', specifier_last_component, NULL }, |
130 | 0 |
|
131 | 0 | { 'g', specifier_group_name, NULL }, |
132 | 0 | { 'G', specifier_group_id, NULL }, |
133 | 0 | { 'U', specifier_user_id, NULL }, |
134 | 0 | { 'u', specifier_user_name, NULL }, |
135 | 0 |
|
136 | 0 | { 'm', specifier_machine_id, NULL }, |
137 | 0 | { 'H', specifier_host_name, NULL }, |
138 | 0 | { 'b', specifier_boot_id, NULL }, |
139 | 0 | { 'v', specifier_kernel_release, NULL }, |
140 | 0 | {} |
141 | 0 | }; |
142 | 0 |
|
143 | 0 | assert(i); |
144 | 0 | assert(format); |
145 | 0 | assert(ret); |
146 | 0 |
|
147 | 0 | return specifier_printf(format, table, i, ret); |
148 | 0 | } |