]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/bus-label.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / basic / bus-label.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
f01de965
KS
2/***
3 This file is part of systemd.
4
5 Copyright 2013 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
f01de965 21#include <stdlib.h>
f01de965 22
b5efdb8a 23#include "alloc-util.h"
f01de965 24#include "bus-label.h"
e4e73a63 25#include "hexdecoct.h"
b5efdb8a 26#include "macro.h"
f01de965
KS
27
28char *bus_label_escape(const char *s) {
29 char *r, *t;
30 const char *f;
31
32 assert_return(s, NULL);
33
34 /* Escapes all chars that D-Bus' object path cannot deal
35 * with. Can be reversed with bus_path_unescape(). We special
36 * case the empty string. */
37
38 if (*s == 0)
39 return strdup("_");
40
41 r = new(char, strlen(s)*3 + 1);
42 if (!r)
43 return NULL;
44
45 for (f = s, t = r; *f; f++) {
46
47 /* Escape everything that is not a-zA-Z0-9. We also
48 * escape 0-9 if it's the first character */
49
50 if (!(*f >= 'A' && *f <= 'Z') &&
51 !(*f >= 'a' && *f <= 'z') &&
52 !(f > s && *f >= '0' && *f <= '9')) {
53 *(t++) = '_';
54 *(t++) = hexchar(*f >> 4);
55 *(t++) = hexchar(*f);
56 } else
57 *(t++) = *f;
58 }
59
60 *t = 0;
61
62 return r;
63}
64
ad922737 65char *bus_label_unescape_n(const char *f, size_t l) {
f01de965 66 char *r, *t;
ad922737 67 size_t i;
f01de965
KS
68
69 assert_return(f, NULL);
70
71 /* Special case for the empty string */
ad922737 72 if (l == 1 && *f == '_')
f01de965
KS
73 return strdup("");
74
ad922737 75 r = new(char, l + 1);
f01de965
KS
76 if (!r)
77 return NULL;
78
ad922737
DH
79 for (i = 0, t = r; i < l; ++i) {
80 if (f[i] == '_') {
f01de965
KS
81 int a, b;
82
ad922737
DH
83 if (l - i < 3 ||
84 (a = unhexchar(f[i + 1])) < 0 ||
85 (b = unhexchar(f[i + 2])) < 0) {
f01de965
KS
86 /* Invalid escape code, let's take it literal then */
87 *(t++) = '_';
88 } else {
89 *(t++) = (char) ((a << 4) | b);
ad922737 90 i += 2;
f01de965
KS
91 }
92 } else
ad922737 93 *(t++) = f[i];
f01de965
KS
94 }
95
96 *t = 0;
97
98 return r;
99}