+static
+struct lttng_session_descriptor *create_session_descriptor(void)
+{
+ int ret;
+ ssize_t uri_count;
+ enum output_type output_type;
+ struct lttng_uri *uris = NULL;
+ struct lttng_session_descriptor *descriptor = NULL;
+ const char *uri_str1 = NULL, *uri_str2 = NULL;
+ char local_output_path[LTTNG_PATH_MAX] = {};
+
+ if (opt_no_output) {
+ output_type = OUTPUT_NONE;
+ } else if (opt_output_path) {
+ char *expanded_output_path;
+
+ output_type = OUTPUT_LOCAL;
+ expanded_output_path = utils_expand_path(opt_output_path);
+ if (!expanded_output_path) {
+ ERR("Failed to expand output path.");
+ goto end;
+ }
+ ret = lttng_strncpy(local_output_path, expanded_output_path,
+ sizeof(local_output_path));
+ free(expanded_output_path);
+ if (ret) {
+ ERR("Output path exceeds the maximal supported length (%zu bytes)",
+ sizeof(local_output_path));
+ goto end;
+ }
+ } else if (opt_url || opt_ctrl_url) {
+ uri_str1 = opt_ctrl_url ? opt_ctrl_url : opt_url;
+ uri_str2 = opt_data_url;
+
+ uri_count = uri_parse_str_urls(uri_str1, uri_str2, &uris);
+ if (uri_count != 1 && uri_count != 2) {
+ ERR("Unrecognized URL format.");
+ goto end;
+ }
+
+ switch (uri_count) {
+ case 1:
+ output_type = OUTPUT_LOCAL;
+ if (uris[0].dtype != LTTNG_DST_PATH) {
+ ERR("Unrecognized URL format.");
+ goto end;
+ }
+ ret = lttng_strncpy(local_output_path, uris[0].dst.path,
+ sizeof(local_output_path));
+ if (ret) {
+ ERR("Output path exceeds the maximal supported length (%zu bytes)",
+ sizeof(local_output_path));
+ }
+ break;
+ case 2:
+ output_type = OUTPUT_NETWORK;
+ break;
+ default:
+ /* Already checked. */
+ abort();
+ }
+ } else {
+ output_type = OUTPUT_UNSPECIFIED;
+ }
+
+ if (opt_snapshot) {
+ /* Snapshot session. */
+ switch (output_type) {
+ case OUTPUT_UNSPECIFIED:
+ case OUTPUT_LOCAL:
+ descriptor = lttng_session_descriptor_snapshot_local_create(
+ opt_session_name,
+ output_type == OUTPUT_LOCAL ?
+ local_output_path : NULL);
+ break;
+ case OUTPUT_NONE:
+ descriptor = lttng_session_descriptor_snapshot_create(
+ opt_session_name);
+ break;
+ case OUTPUT_NETWORK:
+ descriptor = lttng_session_descriptor_snapshot_network_create(
+ opt_session_name, uri_str1, uri_str2);
+ break;
+ default:
+ abort();
+ }
+ } else if (opt_live_timer) {
+ /* Live session. */
+ if (output_type != OUTPUT_UNSPECIFIED &&
+ output_type != OUTPUT_NETWORK) {
+ ERR("Unsupported output type specified for live session.");
+ goto end;
+ }
+ descriptor = lttng_session_descriptor_live_network_create(
+ opt_session_name, uri_str1, uri_str2,
+ opt_live_timer);
+ } else {
+ /* Regular session. */
+ switch (output_type) {
+ case OUTPUT_UNSPECIFIED:
+ case OUTPUT_LOCAL:
+ descriptor = lttng_session_descriptor_local_create(
+ opt_session_name,
+ output_type == OUTPUT_LOCAL ?
+ local_output_path : NULL);
+ break;
+ case OUTPUT_NONE:
+ descriptor = lttng_session_descriptor_create(
+ opt_session_name);
+ break;
+ case OUTPUT_NETWORK:
+ descriptor = lttng_session_descriptor_network_create(
+ opt_session_name, uri_str1, uri_str2);
+ break;
+ default:
+ abort();
+ }
+ }
+ if (!descriptor) {
+ ERR("Failed to initialize session creation command.");
+ } else {
+ /*
+ * Auto-launch the relay daemon when a live session
+ * is created using default URLs.
+ */
+ if (!opt_url && !opt_ctrl_url && !opt_data_url &&
+ opt_live_timer && !check_relayd()) {
+ int ret;
+ const char *pathname = opt_relayd_path ? :
+ INSTALL_BIN_PATH "/lttng-relayd";
+
+ ret = spawn_relayd(pathname, 0);
+ if (ret < 0) {
+ lttng_session_descriptor_destroy(descriptor);
+ descriptor = NULL;
+ }
+ }
+ }
+end:
+ free(uris);
+ return descriptor;
+}
+