common: compile libcommon as C++
[lttng-tools.git] / src / common / location.cpp
diff --git a/src/common/location.cpp b/src/common/location.cpp
new file mode 100644 (file)
index 0000000..80c4b4d
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ * Copyright (C) 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#include <lttng/location-internal.h>
+#include <common/macros.h>
+#include <stdlib.h>
+#include <common/error.h>
+
+static
+struct lttng_trace_archive_location *lttng_trace_archive_location_create(
+               enum lttng_trace_archive_location_type type)
+{
+       struct lttng_trace_archive_location *location;
+
+       location = (lttng_trace_archive_location *) zmalloc(sizeof(*location));
+       if (!location) {
+               goto end;
+       }
+
+       urcu_ref_init(&location->ref);
+       location->type = type;
+end:
+       return location;
+}
+
+static
+void trace_archive_location_destroy_ref(struct urcu_ref *ref)
+{
+       struct lttng_trace_archive_location *location =
+                       container_of(ref, struct lttng_trace_archive_location, ref);
+
+       switch (location->type) {
+       case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
+               free(location->types.local.absolute_path);
+               break;
+       case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
+               free(location->types.relay.host);
+               free(location->types.relay.relative_path);
+               break;
+       default:
+               abort();
+       }
+
+       free(location);
+}
+
+void lttng_trace_archive_location_get(struct lttng_trace_archive_location *location)
+{
+       urcu_ref_get(&location->ref);
+}
+
+void lttng_trace_archive_location_put(struct lttng_trace_archive_location *location)
+{
+       if (!location) {
+               return;
+       }
+
+       urcu_ref_put(&location->ref, trace_archive_location_destroy_ref);
+}
+
+struct lttng_trace_archive_location *lttng_trace_archive_location_local_create(
+               const char *absolute_path)
+{
+       struct lttng_trace_archive_location *location = NULL;
+
+       if (!absolute_path) {
+               goto end;
+       }
+
+       location = lttng_trace_archive_location_create(
+                       LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL);
+       if (!location) {
+               goto end;
+       }
+
+       location->types.local.absolute_path = strdup(absolute_path);
+       if (!location->types.local.absolute_path) {
+               goto error;
+       }
+
+end:
+       return location;
+error:
+       lttng_trace_archive_location_put(location);
+       return NULL;
+}
+
+struct lttng_trace_archive_location *lttng_trace_archive_location_relay_create(
+               const char *host,
+               enum lttng_trace_archive_location_relay_protocol_type protocol,
+               uint16_t control_port, uint16_t data_port,
+               const char *relative_path)
+{
+       struct lttng_trace_archive_location *location = NULL;
+
+       if (!host || !relative_path) {
+               goto end;
+       }
+
+       location = lttng_trace_archive_location_create(
+                       LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY);
+       if (!location) {
+               goto end;
+       }
+
+       location->types.relay.host = strdup(host);
+       if (!location->types.relay.host) {
+               goto error;
+       }
+       location->types.relay.relative_path = strdup(relative_path);
+       if (!location->types.relay.relative_path) {
+               goto error;
+       }
+
+       location->types.relay.protocol = protocol;
+       location->types.relay.ports.control = control_port;
+       location->types.relay.ports.data = data_port;
+end:
+       return location;
+error:
+       lttng_trace_archive_location_put(location);
+       return NULL;
+}
+
+ssize_t lttng_trace_archive_location_create_from_buffer(
+               const struct lttng_buffer_view *view,
+               struct lttng_trace_archive_location **location)
+{
+       size_t offset = 0;
+       const struct lttng_trace_archive_location_comm *location_comm;
+       struct lttng_buffer_view location_comm_view;
+
+       location_comm_view = lttng_buffer_view_from_view(view, 0,
+                       sizeof(*location_comm));
+       if (!lttng_buffer_view_is_valid(&location_comm_view)) {
+               goto error;
+       }
+
+       offset += location_comm_view.size;
+       location_comm = (const struct lttng_trace_archive_location_comm *) location_comm_view.data;
+
+       switch ((enum lttng_trace_archive_location_type) location_comm->type) {
+       case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
+       {
+               const struct lttng_buffer_view absolute_path_view =
+                               lttng_buffer_view_from_view(view, offset,
+                               location_comm->types.local.absolute_path_len);
+
+               if (!lttng_buffer_view_is_valid(&absolute_path_view)) {
+                       goto error;
+               }
+
+               if (absolute_path_view.data[absolute_path_view.size - 1] != '\0') {
+                       goto error;
+               }
+               offset += absolute_path_view.size;
+
+               *location = lttng_trace_archive_location_local_create(
+                               absolute_path_view.data);
+               if (!*location) {
+                       goto error;
+               }
+               break;
+       }
+       case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
+       {
+               const struct lttng_buffer_view hostname_view =
+                               lttng_buffer_view_from_view(view, offset,
+                               location_comm->types.relay.hostname_len);
+               const struct lttng_buffer_view relative_path_view =
+                               lttng_buffer_view_from_view(view,
+                               offset + hostname_view.size,
+                               location_comm->types.relay.relative_path_len);
+
+               if (!lttng_buffer_view_is_valid(&hostname_view) ||
+                               !lttng_buffer_view_is_valid(
+                                               &relative_path_view)) {
+                       goto error;
+               }
+
+               if (hostname_view.data[hostname_view.size - 1] != '\0') {
+                       goto error;
+               }
+               if (relative_path_view.data[relative_path_view.size - 1] != '\0') {
+                       goto error;
+               }
+               offset += hostname_view.size + relative_path_view.size;
+
+               *location = lttng_trace_archive_location_relay_create(
+                               hostname_view.data,
+                               (enum lttng_trace_archive_location_relay_protocol_type) location_comm->types.relay.protocol,
+                               location_comm->types.relay.ports.control,
+                               location_comm->types.relay.ports.data,
+                               relative_path_view.data);
+               if (!*location) {
+                       goto error;
+               }
+               break;
+       }
+       default:
+               goto error;
+       }
+
+       return offset;
+error:
+       return -1;
+}
+
+ssize_t lttng_trace_archive_location_serialize(
+               const struct lttng_trace_archive_location *location,
+               struct lttng_dynamic_buffer *buffer)
+{
+       int ret;
+       struct lttng_trace_archive_location_comm location_comm;
+
+       location_comm.type = (int8_t) location->type;
+
+       switch (location->type) {
+       case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
+               location_comm.types.local.absolute_path_len =
+                               strlen(location->types.local.absolute_path) + 1;
+               break;
+       case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
+               location_comm.types.relay.hostname_len =
+                               strlen(location->types.relay.host) + 1;
+               location_comm.types.relay.protocol =
+                               (int8_t) location->types.relay.protocol;
+               location_comm.types.relay.ports.control =
+                               location->types.relay.ports.control;
+               location_comm.types.relay.ports.data =
+                               location->types.relay.ports.data;
+               location_comm.types.relay.relative_path_len =
+                               strlen(location->types.relay.relative_path) + 1;
+               break;
+       default:
+               abort();
+       }
+
+       ret = lttng_dynamic_buffer_append(buffer, &location_comm,
+                       sizeof(location_comm));
+       if (ret) {
+               goto error;
+       }
+
+       switch (location->type) {
+       case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
+               ret = lttng_dynamic_buffer_append(buffer,
+                               location->types.local.absolute_path,
+                               location_comm.types.local.absolute_path_len);
+               if (ret) {
+                       goto error;
+               }
+               break;
+       case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
+               ret = lttng_dynamic_buffer_append(buffer,
+                               location->types.relay.host,
+                               location_comm.types.relay.hostname_len);
+               if (ret) {
+                       goto error;
+               }
+               ret = lttng_dynamic_buffer_append(buffer,
+                               location->types.relay.relative_path,
+                               location_comm.types.relay.relative_path_len);
+               if (ret) {
+                       goto error;
+               }
+               break;
+       default:
+               abort();
+       }
+
+       return 0;
+error:
+       return -1;
+}
+
+enum lttng_trace_archive_location_type lttng_trace_archive_location_get_type(
+               const struct lttng_trace_archive_location *location)
+{
+       enum lttng_trace_archive_location_type type;
+
+       if (!location) {
+               type = LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_UNKNOWN;
+               goto end;
+       }
+
+       type = location->type;
+end:
+       return type;
+}
+
+enum lttng_trace_archive_location_status
+lttng_trace_archive_location_local_get_absolute_path(
+               const struct lttng_trace_archive_location *location,
+               const char **absolute_path)
+{
+       enum lttng_trace_archive_location_status status =
+                       LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
+
+       if (!location || !absolute_path ||
+                       location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL) {
+               status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
+               goto end;
+       }
+
+       *absolute_path = location->types.local.absolute_path;
+end:
+       return status;
+}
+
+enum lttng_trace_archive_location_status
+lttng_trace_archive_location_relay_get_host(
+               const struct lttng_trace_archive_location *location,
+               const char **relay_host)
+{
+       enum lttng_trace_archive_location_status status =
+                       LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
+
+       if (!location || !relay_host ||
+                       location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
+               status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
+               goto end;
+       }
+
+       *relay_host = location->types.relay.host;
+end:
+       return status;
+}
+
+enum lttng_trace_archive_location_status
+lttng_trace_archive_location_relay_get_relative_path(
+               const struct lttng_trace_archive_location *location,
+               const char **relative_path)
+{
+       enum lttng_trace_archive_location_status status =
+                       LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
+
+       if (!location || !relative_path ||
+                       location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
+               status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
+               goto end;
+       }
+
+       *relative_path = location->types.relay.relative_path;
+end:
+       return status;
+}
+
+enum lttng_trace_archive_location_status
+lttng_trace_archive_location_relay_get_control_port(
+               const struct lttng_trace_archive_location *location,
+               uint16_t *control_port)
+{
+       enum lttng_trace_archive_location_status status =
+                       LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
+
+       if (!location || !control_port ||
+                       location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
+               status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
+               goto end;
+       }
+
+       *control_port = location->types.relay.ports.control;
+end:
+       return status;
+}
+
+enum lttng_trace_archive_location_status
+lttng_trace_archive_location_relay_get_data_port(
+               const struct lttng_trace_archive_location *location,
+               uint16_t *data_port)
+{
+       enum lttng_trace_archive_location_status status =
+                       LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
+
+       if (!location || !data_port ||
+                       location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
+               status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
+               goto end;
+       }
+
+       *data_port = location->types.relay.ports.data;
+end:
+       return status;
+}
+
+enum lttng_trace_archive_location_status
+lttng_trace_archive_location_relay_get_protocol_type(
+               const struct lttng_trace_archive_location *location,
+               enum lttng_trace_archive_location_relay_protocol_type *protocol)
+{
+       enum lttng_trace_archive_location_status status =
+                       LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
+
+       if (!location || !protocol ||
+                       location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
+               status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
+               goto end;
+       }
+
+       *protocol = location->types.relay.protocol;
+end:
+       return status;
+}
This page took 0.026456 seconds and 4 git commands to generate.