]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/bus-internal.c
man: introduce new "Desktop" property for sessions
[thirdparty/systemd.git] / src / libsystemd / sd-bus / bus-internal.c
CommitLineData
de1c301e
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 Lennart Poettering
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 "bus-internal.h"
ac89bf1d
LP
23
24bool object_path_is_valid(const char *p) {
25 const char *q;
26 bool slash;
27
28 if (!p)
29 return false;
30
31 if (p[0] != '/')
32 return false;
33
34 if (p[1] == 0)
35 return true;
36
37 for (slash = true, q = p+1; *q; q++)
38 if (*q == '/') {
39 if (slash)
40 return false;
41
42 slash = true;
43 } else {
44 bool good;
45
46 good =
47 (*q >= 'a' && *q <= 'z') ||
48 (*q >= 'A' && *q <= 'Z') ||
49 (*q >= '0' && *q <= '9') ||
50 *q == '_';
51
52 if (!good)
53 return false;
54
55 slash = false;
56 }
57
58 if (slash)
59 return false;
60
61 return true;
62}
6693860f 63
29ddb38f
LP
64char* object_path_startswith(const char *a, const char *b) {
65 const char *p;
66
67 if (!object_path_is_valid(a) ||
68 !object_path_is_valid(b))
69 return NULL;
70
71 if (streq(b, "/"))
72 return (char*) a + 1;
73
74 p = startswith(a, b);
75 if (!p)
76 return NULL;
77
78 if (*p == 0)
79 return (char*) p;
80
81 if (*p == '/')
82 return (char*) p + 1;
83
84 return NULL;
85}
86
6693860f
LP
87bool interface_name_is_valid(const char *p) {
88 const char *q;
f5f6e41a 89 bool dot, found_dot = false;
6693860f
LP
90
91 if (isempty(p))
92 return false;
93
94 for (dot = true, q = p; *q; q++)
95 if (*q == '.') {
96 if (dot)
97 return false;
98
99 found_dot = dot = true;
100 } else {
101 bool good;
102
103 good =
104 (*q >= 'a' && *q <= 'z') ||
105 (*q >= 'A' && *q <= 'Z') ||
106 (!dot && *q >= '0' && *q <= '9') ||
107 *q == '_';
108
109 if (!good)
110 return false;
111
112 dot = false;
113 }
114
115 if (q - p > 255)
116 return false;
117
118 if (dot)
119 return false;
120
121 if (!found_dot)
122 return false;
123
124 return true;
125}
126
127bool service_name_is_valid(const char *p) {
128 const char *q;
f5f6e41a 129 bool dot, found_dot = false, unique;
6693860f
LP
130
131 if (isempty(p))
132 return false;
133
134 unique = p[0] == ':';
135
136 for (dot = true, q = unique ? p+1 : p; *q; q++)
137 if (*q == '.') {
138 if (dot)
139 return false;
140
141 found_dot = dot = true;
142 } else {
143 bool good;
144
145 good =
146 (*q >= 'a' && *q <= 'z') ||
147 (*q >= 'A' && *q <= 'Z') ||
148 ((!dot || unique) && *q >= '0' && *q <= '9') ||
149 *q == '_' || *q == '-';
150
151 if (!good)
152 return false;
153
154 dot = false;
155 }
156
157 if (q - p > 255)
158 return false;
159
160 if (dot)
161 return false;
162
163 if (!found_dot)
164 return false;
165
166 return true;
6693860f
LP
167}
168
169bool member_name_is_valid(const char *p) {
170 const char *q;
171
172 if (isempty(p))
173 return false;
174
175 for (q = p; *q; q++) {
176 bool good;
177
178 good =
179 (*q >= 'a' && *q <= 'z') ||
180 (*q >= 'A' && *q <= 'Z') ||
181 (*q >= '0' && *q <= '9') ||
182 *q == '_';
183
184 if (!good)
185 return false;
186 }
187
188 if (q - p > 255)
189 return false;
190
191 return true;
192}
392d5b37
LP
193
194static bool complex_pattern_check(char c, const char *a, const char *b) {
195 bool separator = false;
196
42c5aaf3
LP
197 if (!a && !b)
198 return true;
199
200 if (!a || !b)
201 return false;
202
392d5b37
LP
203 for (;;) {
204 if (*a != *b)
205 return (separator && (*a == 0 || *b == 0)) ||
206 (*a == 0 && *b == c && b[1] == 0) ||
207 (*b == 0 && *a == c && a[1] == 0);
208
209 if (*a == 0)
210 return true;
211
212 separator = *a == c;
213
214 a++, b++;
215 }
216}
217
218bool namespace_complex_pattern(const char *pattern, const char *value) {
219 return complex_pattern_check('.', pattern, value);
220}
221
222bool path_complex_pattern(const char *pattern, const char *value) {
223 return complex_pattern_check('/', pattern, value);
224}
225
226static bool simple_pattern_check(char c, const char *a, const char *b) {
42c5aaf3
LP
227
228 if (!a && !b)
229 return true;
230
231 if (!a || !b)
232 return false;
233
392d5b37
LP
234 for (;;) {
235 if (*a != *b)
236 return *a == 0 && *b == c;
237
238 if (*a == 0)
239 return true;
240
241 a++, b++;
242 }
243}
244
245bool namespace_simple_pattern(const char *pattern, const char *value) {
246 return simple_pattern_check('.', pattern, value);
247}
248
249bool path_simple_pattern(const char *pattern, const char *value) {
250 return simple_pattern_check('/', pattern, value);
251}
252
253int bus_message_type_from_string(const char *s, uint8_t *u) {
254 if (streq(s, "signal"))
40ca29a1 255 *u = SD_BUS_MESSAGE_SIGNAL;
392d5b37 256 else if (streq(s, "method_call"))
40ca29a1 257 *u = SD_BUS_MESSAGE_METHOD_CALL;
392d5b37 258 else if (streq(s, "error"))
40ca29a1 259 *u = SD_BUS_MESSAGE_METHOD_ERROR;
392d5b37 260 else if (streq(s, "method_return"))
40ca29a1 261 *u = SD_BUS_MESSAGE_METHOD_RETURN;
392d5b37
LP
262 else
263 return -EINVAL;
264
265 return 0;
266}
a56f19c4
LP
267
268const char *bus_message_type_to_string(uint8_t u) {
40ca29a1 269 if (u == SD_BUS_MESSAGE_SIGNAL)
a56f19c4 270 return "signal";
40ca29a1 271 else if (u == SD_BUS_MESSAGE_METHOD_CALL)
a56f19c4 272 return "method_call";
40ca29a1 273 else if (u == SD_BUS_MESSAGE_METHOD_ERROR)
a56f19c4 274 return "error";
40ca29a1 275 else if (u == SD_BUS_MESSAGE_METHOD_RETURN)
a56f19c4
LP
276 return "method_return";
277 else
278 return NULL;
279}
0f8bd8de
LP
280
281char *bus_address_escape(const char *v) {
282 const char *a;
283 char *r, *b;
284
285 r = new(char, strlen(v)*3+1);
286 if (!r)
287 return NULL;
288
289 for (a = v, b = r; *a; a++) {
290
291 if ((*a >= '0' && *a <= '9') ||
292 (*a >= 'a' && *a <= 'z') ||
293 (*a >= 'A' && *a <= 'Z') ||
294 strchr("_-/.", *a))
295 *(b++) = *a;
296 else {
297 *(b++) = '%';
298 *(b++) = hexchar(*a >> 4);
299 *(b++) = hexchar(*a & 0xF);
300 }
301 }
302
303 *b = 0;
304 return r;
305}