]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/escape/escape.c
dhcp6-option: Add helper function for uncompressed domain names
[thirdparty/systemd.git] / src / escape / escape.c
CommitLineData
b1a5a998
MB
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2014 Michael Biebl
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <stdio.h>
23#include <stdlib.h>
a1948c7b 24#include <getopt.h>
b1a5a998
MB
25
26#include "log.h"
27#include "unit-name.h"
a1948c7b
LP
28#include "build.h"
29#include "strv.h"
b1a5a998 30
a1948c7b
LP
31static enum {
32 ACTION_ESCAPE,
33 ACTION_UNESCAPE,
34 ACTION_MANGLE
35} arg_action = ACTION_ESCAPE;
36static const char *arg_suffix = NULL;
37static const char *arg_template = NULL;
38static bool arg_path = false;
39
601185b4 40static void help(void) {
a1948c7b
LP
41 printf("%s [OPTIONS...] [NAME...]\n\n"
42 "Show system and user paths.\n\n"
43 " -h --help Show this help\n"
44 " --version Show package version\n"
45 " --suffix=SUFFIX Unit suffix to append to escaped strings\n"
46 " --template=TEMPLATE Insert strings as instance into template\n"
47 " -u --unescape Unescape strings\n"
48 " -m --mangle Mangle strings\n"
601185b4
ZJS
49 " -p --path When escaping/unescaping assume the string is a path\n"
50 , program_invocation_short_name);
a1948c7b
LP
51}
52
53static int parse_argv(int argc, char *argv[]) {
54
55 enum {
56 ARG_VERSION = 0x100,
57 ARG_SUFFIX,
58 ARG_TEMPLATE
59 };
60
61 static const struct option options[] = {
62 { "help", no_argument, NULL, 'h' },
63 { "version", no_argument, NULL, ARG_VERSION },
64 { "suffix", required_argument, NULL, ARG_SUFFIX },
65 { "template", required_argument, NULL, ARG_TEMPLATE },
66 { "unescape", no_argument, NULL, 'u' },
67 { "mangle", no_argument, NULL, 'm' },
68 { "path", no_argument, NULL, 'p' },
69 {}
70 };
71
72 int c;
73
74 assert(argc >= 0);
75 assert(argv);
76
601185b4 77 while ((c = getopt_long(argc, argv, "hump", options, NULL)) >= 0)
a1948c7b
LP
78
79 switch (c) {
80
81 case 'h':
601185b4
ZJS
82 help();
83 return 0;
a1948c7b
LP
84
85 case ARG_VERSION:
86 puts(PACKAGE_STRING);
87 puts(SYSTEMD_FEATURES);
88 return 0;
89
90 case ARG_SUFFIX:
91
92 if (unit_type_from_string(optarg) < 0) {
93 log_error("Invalid unit suffix type %s.", optarg);
94 return -EINVAL;
95 }
96
97 arg_suffix = optarg;
98 break;
99
100 case ARG_TEMPLATE:
101
7410616c 102 if (!unit_name_is_valid(optarg, UNIT_NAME_TEMPLATE)) {
a1948c7b
LP
103 log_error("Template name %s is not valid.", optarg);
104 return -EINVAL;
105 }
106
107 arg_template = optarg;
108 break;
109
110 case 'u':
111 arg_action = ACTION_UNESCAPE;
112 break;
113
114 case 'm':
115 arg_action = ACTION_MANGLE;
116 break;
117
118 case 'p':
119 arg_path = true;
120 break;
121
122 case '?':
123 return -EINVAL;
124
125 default:
126 assert_not_reached("Unhandled option");
127 }
b1a5a998 128
a1948c7b
LP
129 if (optind >= argc) {
130 log_error("Not enough arguments.");
131 return -EINVAL;
b1a5a998
MB
132 }
133
a1948c7b
LP
134 if (arg_template && arg_suffix) {
135 log_error("--suffix= and --template= may not be combined.");
136 return -EINVAL;
137 }
138
139 if ((arg_template || arg_suffix) && arg_action != ACTION_ESCAPE) {
140 log_error("--suffix= and --template= are not compatible with --unescape or --mangle.");
141 return -EINVAL;
142 }
143
144 if (arg_path && !IN_SET(arg_action, ACTION_ESCAPE, ACTION_UNESCAPE)) {
145 log_error("--path may not be combined with --mangle.");
146 return -EINVAL;
147 }
148
149 return 1;
150}
151
152int main(int argc, char *argv[]) {
153 char **i;
154 int r;
155
156 log_parse_environment();
157 log_open();
158
159 r = parse_argv(argc, argv);
160 if (r <= 0)
161 goto finish;
162
163 STRV_FOREACH(i, argv + optind) {
164 _cleanup_free_ char *e = NULL;
165
166 switch (arg_action) {
167
168 case ACTION_ESCAPE:
7410616c
LP
169 if (arg_path) {
170 r = unit_name_path_escape(*i, &e);
171 if (r < 0) {
172 log_error_errno(r, "Failed to escape string: %m");
173 goto finish;
174 }
175 } else {
a1948c7b 176 e = unit_name_escape(*i);
7410616c
LP
177 if (!e) {
178 r = log_oom();
179 goto finish;
180 }
a1948c7b
LP
181 }
182
183 if (arg_template) {
184 char *x;
185
7410616c
LP
186 r = unit_name_replace_instance(arg_template, e, &x);
187 if (r < 0) {
188 log_error_errno(r, "Failed to replace instance: %m");
a1948c7b
LP
189 goto finish;
190 }
191
192 free(e);
193 e = x;
194 } else if (arg_suffix) {
195 char *x;
196
197 x = strjoin(e, ".", arg_suffix, NULL);
198 if (!x) {
199 r = log_oom();
200 goto finish;
201 }
202
203 free(e);
204 e = x;
205 }
206
207 break;
208
209 case ACTION_UNESCAPE:
210 if (arg_path)
7410616c 211 r = unit_name_path_unescape(*i, &e);
a1948c7b 212 else
7410616c 213 r = unit_name_unescape(*i, &e);
a1948c7b 214
7410616c
LP
215 if (r < 0) {
216 log_error_errno(r, "Failed to unescape string: %m");
a1948c7b
LP
217 goto finish;
218 }
219 break;
220
221 case ACTION_MANGLE:
7410616c
LP
222 r = unit_name_mangle(*i, UNIT_NAME_NOGLOB, &e);
223 if (r < 0) {
224 log_error_errno(r, "Failed to mangle name: %m");
a1948c7b
LP
225 goto finish;
226 }
227 break;
228 }
229
230 if (i != argv+optind)
231 fputc(' ', stdout);
b1a5a998 232
a1948c7b 233 fputs(e, stdout);
b1a5a998
MB
234 }
235
a1948c7b 236 fputc('\n', stdout);
b1a5a998 237
a1948c7b 238finish:
ff9c82cc 239 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
b1a5a998 240}