Fix: return size from location deserialization function
[lttng-tools.git] / src / common / location.c
1 /*
2 * Copyright (C) 2018 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License, version 2.1 only,
6 * as published by the Free Software Foundation.
7 *
8 * This library is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18 #include <lttng/location-internal.h>
19 #include <common/macros.h>
20 #include <stdlib.h>
21
22 static
23 struct lttng_trace_archive_location *lttng_trace_archive_location_create(
24 enum lttng_trace_archive_location_type type)
25 {
26 struct lttng_trace_archive_location *location;
27
28 location = zmalloc(sizeof(*location));
29 if (!location) {
30 goto end;
31 }
32
33 location->type = type;
34 end:
35 return location;
36 }
37
38 LTTNG_HIDDEN
39 void lttng_trace_archive_location_destroy(
40 struct lttng_trace_archive_location *location)
41 {
42 if (!location) {
43 return;
44 }
45
46 switch (location->type) {
47 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
48 free(location->types.local.absolute_path);
49 break;
50 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
51 free(location->types.relay.host);
52 free(location->types.relay.relative_path);
53 break;
54 default:
55 abort();
56 }
57
58 free(location);
59 }
60
61 LTTNG_HIDDEN
62 struct lttng_trace_archive_location *lttng_trace_archive_location_local_create(
63 const char *absolute_path)
64 {
65 struct lttng_trace_archive_location *location = NULL;
66
67 if (!absolute_path) {
68 goto end;
69 }
70
71 location = lttng_trace_archive_location_create(
72 LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL);
73 if (!location) {
74 goto end;
75 }
76
77 location->types.local.absolute_path = strdup(absolute_path);
78 if (!location->types.local.absolute_path) {
79 goto error;
80 }
81
82 end:
83 return location;
84 error:
85 lttng_trace_archive_location_destroy(location);
86 return NULL;
87 }
88
89 LTTNG_HIDDEN
90 struct lttng_trace_archive_location *lttng_trace_archive_location_relay_create(
91 const char *host,
92 enum lttng_trace_archive_location_relay_protocol_type protocol,
93 uint16_t control_port, uint16_t data_port,
94 const char *relative_path)
95 {
96 struct lttng_trace_archive_location *location = NULL;
97
98 if (!host || !relative_path) {
99 goto end;
100 }
101
102 location = lttng_trace_archive_location_create(
103 LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY);
104 if (!location) {
105 goto end;
106 }
107
108 location->types.relay.host = strdup(host);
109 if (!location->types.relay.host) {
110 goto error;
111 }
112 location->types.relay.relative_path = strdup(relative_path);
113 if (!location->types.relay.relative_path) {
114 goto error;
115 }
116
117 location->types.relay.protocol = protocol;
118 location->types.relay.ports.control = control_port;
119 location->types.relay.ports.data = data_port;
120 end:
121 return location;
122 error:
123 lttng_trace_archive_location_destroy(location);
124 return NULL;
125 }
126
127 LTTNG_HIDDEN
128 ssize_t lttng_trace_archive_location_create_from_buffer(
129 const struct lttng_buffer_view *view,
130 struct lttng_trace_archive_location **location)
131 {
132 size_t offset = 0;
133 const struct lttng_trace_archive_location_comm *location_comm;
134 struct lttng_buffer_view location_comm_view;
135
136 location_comm_view = lttng_buffer_view_from_view(view, 0,
137 sizeof(*location_comm));
138 if (!location_comm_view.data) {
139 goto error;
140 }
141 offset += location_comm_view.size;
142 location_comm = (const struct lttng_trace_archive_location_comm *) view->data;
143
144 switch ((enum lttng_trace_archive_location_type) location_comm->type) {
145 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
146 {
147 const struct lttng_buffer_view absolute_path_view =
148 lttng_buffer_view_from_view(view, offset,
149 location_comm->types.local.absolute_path_len);
150
151 if (!absolute_path_view.data) {
152 goto error;
153 }
154 if (absolute_path_view.data[absolute_path_view.size - 1] != '\0') {
155 goto error;
156 }
157 offset += absolute_path_view.size;
158
159 *location = lttng_trace_archive_location_local_create(
160 absolute_path_view.data);
161 if (!*location) {
162 goto error;
163 }
164 break;
165 }
166 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
167 {
168 const struct lttng_buffer_view hostname_view =
169 lttng_buffer_view_from_view(view, offset,
170 location_comm->types.relay.hostname_len);
171 const struct lttng_buffer_view relative_path_view =
172 lttng_buffer_view_from_view(view,
173 offset + hostname_view.size,
174 location_comm->types.relay.relative_path_len);
175
176 if (!hostname_view.data || !relative_path_view.data) {
177 goto error;
178 }
179 if (hostname_view.data[hostname_view.size - 1] != '\0') {
180 goto error;
181 }
182 if (relative_path_view.data[relative_path_view.size - 1] != '\0') {
183 goto error;
184 }
185 offset += hostname_view.size + relative_path_view.size;
186
187 *location = lttng_trace_archive_location_relay_create(
188 hostname_view.data,
189 (enum lttng_trace_archive_location_relay_protocol_type) location_comm->types.relay.protocol,
190 location_comm->types.relay.ports.control,
191 location_comm->types.relay.ports.data,
192 relative_path_view.data);
193 if (!*location) {
194 goto error;
195 }
196 break;
197 }
198 default:
199 goto error;
200 }
201
202 return offset;
203 error:
204 return -1;
205 }
206
207 LTTNG_HIDDEN
208 ssize_t lttng_trace_archive_location_serialize(
209 const struct lttng_trace_archive_location *location,
210 struct lttng_dynamic_buffer *buffer)
211 {
212 int ret;
213 struct lttng_trace_archive_location_comm location_comm;
214 const size_t original_buffer_size = buffer->size;
215
216 location_comm.type = (int8_t) location->type;
217
218 switch (location->type) {
219 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
220 location_comm.types.local.absolute_path_len =
221 strlen(location->types.local.absolute_path) + 1;
222 break;
223 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
224 location_comm.types.relay.hostname_len =
225 strlen(location->types.relay.host) + 1;
226 location_comm.types.relay.protocol =
227 (int8_t) location->types.relay.protocol;
228 location_comm.types.relay.ports.control =
229 location->types.relay.ports.control;
230 location_comm.types.relay.ports.data =
231 location->types.relay.ports.data;
232 location_comm.types.relay.relative_path_len =
233 strlen(location->types.relay.relative_path) + 1;
234 break;
235 default:
236 abort();
237 }
238
239 ret = lttng_dynamic_buffer_append(buffer, &location_comm,
240 sizeof(location_comm));
241 if (ret) {
242 goto error;
243 }
244
245 switch (location->type) {
246 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
247 ret = lttng_dynamic_buffer_append(buffer,
248 location->types.local.absolute_path,
249 location_comm.types.local.absolute_path_len);
250 if (ret) {
251 goto error;
252 }
253 break;
254 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
255 ret = lttng_dynamic_buffer_append(buffer,
256 location->types.relay.host,
257 location_comm.types.relay.hostname_len);
258 if (ret) {
259 goto error;
260 }
261 ret = lttng_dynamic_buffer_append(buffer,
262 location->types.relay.relative_path,
263 location_comm.types.relay.relative_path_len);
264 if (ret) {
265 goto error;
266 }
267 break;
268 default:
269 abort();
270 }
271
272 return buffer->size - original_buffer_size;
273 error:
274 return -1;
275 }
276
277 enum lttng_trace_archive_location_type lttng_trace_archive_location_get_type(
278 const struct lttng_trace_archive_location *location)
279 {
280 enum lttng_trace_archive_location_type type;
281
282 if (!location) {
283 type = LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_UNKNOWN;
284 goto end;
285 }
286
287 type = location->type;
288 end:
289 return type;
290 }
291
292 enum lttng_trace_archive_location_status
293 lttng_trace_archive_location_local_get_absolute_path(
294 const struct lttng_trace_archive_location *location,
295 const char **absolute_path)
296 {
297 enum lttng_trace_archive_location_status status =
298 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
299
300 if (!location || !absolute_path ||
301 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL) {
302 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
303 goto end;
304 }
305
306 *absolute_path = location->types.local.absolute_path;
307 end:
308 return status;
309 }
310
311 enum lttng_trace_archive_location_status
312 lttng_trace_archive_location_relay_get_host(
313 const struct lttng_trace_archive_location *location,
314 const char **relay_host)
315 {
316 enum lttng_trace_archive_location_status status =
317 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
318
319 if (!location || !relay_host ||
320 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
321 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
322 goto end;
323 }
324
325 *relay_host = location->types.relay.host;
326 end:
327 return status;
328 }
329
330 enum lttng_trace_archive_location_status
331 lttng_trace_archive_location_relay_get_relative_path(
332 const struct lttng_trace_archive_location *location,
333 const char **relative_path)
334 {
335 enum lttng_trace_archive_location_status status =
336 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
337
338 if (!location || !relative_path ||
339 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
340 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
341 goto end;
342 }
343
344 *relative_path = location->types.relay.relative_path;
345 end:
346 return status;
347 }
348
349 enum lttng_trace_archive_location_status
350 lttng_trace_archive_location_relay_get_control_port(
351 const struct lttng_trace_archive_location *location,
352 uint16_t *control_port)
353 {
354 enum lttng_trace_archive_location_status status =
355 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
356
357 if (!location || !control_port ||
358 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
359 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
360 goto end;
361 }
362
363 *control_port = location->types.relay.ports.control;
364 end:
365 return status;
366 }
367
368 enum lttng_trace_archive_location_status
369 lttng_trace_archive_location_relay_get_data_port(
370 const struct lttng_trace_archive_location *location,
371 uint16_t *data_port)
372 {
373 enum lttng_trace_archive_location_status status =
374 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
375
376 if (!location || !data_port ||
377 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
378 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
379 goto end;
380 }
381
382 *data_port = location->types.relay.ports.data;
383 end:
384 return status;
385 }
386
387 enum lttng_trace_archive_location_status
388 lttng_trace_archive_location_relay_get_protocol_type(
389 const struct lttng_trace_archive_location *location,
390 enum lttng_trace_archive_location_relay_protocol_type *protocol)
391 {
392 enum lttng_trace_archive_location_status status =
393 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
394
395 if (!location || !protocol ||
396 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
397 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
398 goto end;
399 }
400
401 *protocol = location->types.relay.protocol;
402 end:
403 return status;
404 }
This page took 0.037344 seconds and 5 git commands to generate.