Fix: return size from location deserialization function
[lttng-tools.git] / src / common / location.c
CommitLineData
434131e4
JG
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
22static
23struct 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;
34end:
35 return location;
36}
37
38LTTNG_HIDDEN
39void 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
61LTTNG_HIDDEN
62struct 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
82end:
83 return location;
84error:
85 lttng_trace_archive_location_destroy(location);
86 return NULL;
87}
88
89LTTNG_HIDDEN
90struct 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;
120end:
121 return location;
122error:
123 lttng_trace_archive_location_destroy(location);
124 return NULL;
125}
126
1e9f1cf8
JG
127LTTNG_HIDDEN
128ssize_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
e4b6e50f 202 return offset;
1e9f1cf8
JG
203error:
204 return -1;
205}
206
207LTTNG_HIDDEN
208ssize_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;
273error:
274 return -1;
275}
276
434131e4
JG
277enum 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;
288end:
289 return type;
290}
291
292enum lttng_trace_archive_location_status
293lttng_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;
307end:
308 return status;
309}
310
311enum lttng_trace_archive_location_status
312lttng_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;
326end:
327 return status;
328}
329
330enum lttng_trace_archive_location_status
331lttng_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;
345end:
346 return status;
347}
348
349enum lttng_trace_archive_location_status
350lttng_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;
364end:
365 return status;
366}
367
368enum lttng_trace_archive_location_status
369lttng_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;
383end:
384 return status;
385}
386
387enum lttng_trace_archive_location_status
388lttng_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;
402end:
403 return status;
404}
This page took 0.038933 seconds and 5 git commands to generate.