1 /* SPDX-License-Identifier: LGPL-2.1+ */
7 #include "alloc-util.h"
9 #include "string-util.h"
11 #include "terminal-util.h"
12 #include "unit-name.h"
18 } arg_action
= ACTION_ESCAPE
;
19 static const char *arg_suffix
= NULL
;
20 static const char *arg_template
= NULL
;
21 static bool arg_path
= false;
22 static bool arg_instance
= false;
24 static int help(void) {
25 _cleanup_free_
char *link
= NULL
;
28 r
= terminal_urlify_man("systemd-escape", "1", &link
);
32 printf("%s [OPTIONS...] [NAME...]\n\n"
33 "Escape strings for usage in systemd unit names.\n\n"
34 " -h --help Show this help\n"
35 " --version Show package version\n"
36 " --suffix=SUFFIX Unit suffix to append to escaped strings\n"
37 " --template=TEMPLATE Insert strings as instance into template\n"
38 " --instance With --unescape, show just the instance part\n"
39 " -u --unescape Unescape strings\n"
40 " -m --mangle Mangle strings\n"
41 " -p --path When escaping/unescaping assume the string is a path\n"
42 "\nSee the %s for details.\n"
43 , program_invocation_short_name
50 static int parse_argv(int argc
, char *argv
[]) {
58 static const struct option options
[] = {
59 { "help", no_argument
, NULL
, 'h' },
60 { "version", no_argument
, NULL
, ARG_VERSION
},
61 { "suffix", required_argument
, NULL
, ARG_SUFFIX
},
62 { "template", required_argument
, NULL
, ARG_TEMPLATE
},
63 { "unescape", no_argument
, NULL
, 'u' },
64 { "mangle", no_argument
, NULL
, 'm' },
65 { "path", no_argument
, NULL
, 'p' },
66 { "instance", no_argument
, NULL
, 'i' },
75 while ((c
= getopt_long(argc
, argv
, "hump", options
, NULL
)) >= 0)
87 if (unit_type_from_string(optarg
) < 0) {
88 log_error("Invalid unit suffix type %s.", optarg
);
97 if (!unit_name_is_valid(optarg
, UNIT_NAME_TEMPLATE
)) {
98 log_error("Template name %s is not valid.", optarg
);
102 arg_template
= optarg
;
106 arg_action
= ACTION_UNESCAPE
;
110 arg_action
= ACTION_MANGLE
;
125 assert_not_reached("Unhandled option");
128 if (optind
>= argc
) {
129 log_error("Not enough arguments.");
133 if (arg_template
&& arg_suffix
) {
134 log_error("--suffix= and --template= may not be combined.");
138 if ((arg_template
|| arg_suffix
) && arg_action
== ACTION_MANGLE
) {
139 log_error("--suffix= and --template= are not compatible with --mangle.");
143 if (arg_suffix
&& arg_action
== ACTION_UNESCAPE
) {
144 log_error("--suffix is not compatible with --unescape.");
148 if (arg_path
&& !IN_SET(arg_action
, ACTION_ESCAPE
, ACTION_UNESCAPE
)) {
149 log_error("--path may not be combined with --mangle.");
153 if (arg_instance
&& arg_action
!= ACTION_UNESCAPE
) {
154 log_error("--instance must be used in conjunction with --unescape.");
158 if (arg_instance
&& arg_template
) {
159 log_error("--instance may not be combined with --template.");
166 int main(int argc
, char *argv
[]) {
170 log_parse_environment();
173 r
= parse_argv(argc
, argv
);
177 STRV_FOREACH(i
, argv
+ optind
) {
178 _cleanup_free_
char *e
= NULL
;
180 switch (arg_action
) {
184 r
= unit_name_path_escape(*i
, &e
);
186 log_error_errno(r
, "Failed to escape string: %m");
190 e
= unit_name_escape(*i
);
200 r
= unit_name_replace_instance(arg_template
, e
, &x
);
202 log_error_errno(r
, "Failed to replace instance: %m");
208 } else if (arg_suffix
) {
211 x
= strjoin(e
, ".", arg_suffix
);
223 case ACTION_UNESCAPE
: {
224 _cleanup_free_
char *name
= NULL
;
226 if (arg_template
|| arg_instance
) {
227 _cleanup_free_
char *template = NULL
;
229 r
= unit_name_to_instance(*i
, &name
);
231 log_error_errno(r
, "Failed to extract instance: %m");
235 log_error("Unit %s is missing the instance name.", *i
);
239 r
= unit_name_template(*i
, &template);
241 log_error_errno(r
, "Failed to extract template: %m");
244 if (arg_template
&& !streq(arg_template
, template)) {
245 log_error("Unit %s template %s does not match specified template %s.", *i
, template, arg_template
);
258 r
= unit_name_path_unescape(name
, &e
);
260 r
= unit_name_unescape(name
, &e
);
263 log_error_errno(r
, "Failed to unescape string: %m");
270 r
= unit_name_mangle(*i
, 0, &e
);
272 log_error_errno(r
, "Failed to mangle name: %m");
278 if (i
!= argv
+optind
)
287 return r
< 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;