From bc89445574c5bef2a905f213c3a615ea559bd4c8 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Wed, 24 Apr 2013 13:29:19 -0400 Subject: [PATCH] Move multiple URLs parsing fct from lttng-ctl to uri.c Just move some functions around so we can use the multiple URLs parsing to URIs function outside of liblttng-ctl. Signed-off-by: David Goulet --- src/common/uri.c | 172 ++++++++++++++++++++++++++++++++++ src/common/uri.h | 2 + src/lib/lttng-ctl/lttng-ctl.c | 172 +--------------------------------- 3 files changed, 177 insertions(+), 169 deletions(-) diff --git a/src/common/uri.c b/src/common/uri.c index 740a6d5c5..8d7cf9074 100644 --- a/src/common/uri.c +++ b/src/common/uri.c @@ -137,6 +137,47 @@ error: return -1; } +/* + * Set default URI attribute which is basically the given stream type and the + * default port if none is set in the URI. + */ +static void set_default_uri_attr(struct lttng_uri *uri, + enum lttng_stream_type stype) +{ + uri->stype = stype; + if (uri->dtype != LTTNG_DST_PATH && uri->port == 0) { + uri->port = (stype == LTTNG_STREAM_CONTROL) ? + DEFAULT_NETWORK_CONTROL_PORT : DEFAULT_NETWORK_DATA_PORT; + } +} + +/* + * Compare two URL destination. + * + * Return 0 is equal else is not equal. + */ +static int compare_destination(struct lttng_uri *ctrl, struct lttng_uri *data) +{ + int ret; + + assert(ctrl); + assert(data); + + switch (ctrl->dtype) { + case LTTNG_DST_IPV4: + ret = strncmp(ctrl->dst.ipv4, data->dst.ipv4, sizeof(ctrl->dst.ipv4)); + break; + case LTTNG_DST_IPV6: + ret = strncmp(ctrl->dst.ipv6, data->dst.ipv6, sizeof(ctrl->dst.ipv6)); + break; + default: + ret = -1; + break; + } + + return ret; +} + /* * Build a string URL from a lttng_uri object. */ @@ -474,3 +515,134 @@ free_error: error: return -1; } + +/* + * Parse a string URL and creates URI(s) returning the size of the populated + * array. + */ +LTTNG_HIDDEN +ssize_t uri_parse_str_urls(const char *ctrl_url, const char *data_url, + struct lttng_uri **uris) +{ + unsigned int equal = 1, idx = 0; + /* Add the "file://" size to the URL maximum size */ + char url[PATH_MAX + 7]; + ssize_t size_ctrl = 0, size_data = 0, size; + struct lttng_uri *ctrl_uris = NULL, *data_uris = NULL; + struct lttng_uri *tmp_uris = NULL; + + /* No URL(s) is allowed. This means that the consumer will be disabled. */ + if (ctrl_url == NULL && data_url == NULL) { + return 0; + } + + /* Check if URLs are equal and if so, only use the control URL */ + if ((ctrl_url && *ctrl_url != '\0') && (data_url && *data_url != '\0')) { + equal = !strcmp(ctrl_url, data_url); + } + + /* + * Since we allow the str_url to be a full local filesystem path, we are + * going to create a valid file:// URL if it's the case. + * + * Check if first character is a '/' or else reject the URL. + */ + if (ctrl_url && ctrl_url[0] == '/') { + int ret; + + ret = snprintf(url, sizeof(url), "file://%s", ctrl_url); + if (ret < 0) { + PERROR("snprintf file url"); + goto parse_error; + } + ctrl_url = url; + } + + /* Parse the control URL if there is one */ + if (ctrl_url && *ctrl_url != '\0') { + size_ctrl = uri_parse(ctrl_url, &ctrl_uris); + if (size_ctrl < 1) { + ERR("Unable to parse the URL %s", ctrl_url); + goto parse_error; + } + + /* At this point, we know there is at least one URI in the array */ + set_default_uri_attr(&ctrl_uris[0], LTTNG_STREAM_CONTROL); + + if (ctrl_uris[0].dtype == LTTNG_DST_PATH && + (data_url && *data_url != '\0')) { + ERR("Can not have a data URL when destination is file://"); + goto error; + } + + /* URL are not equal but the control URL uses a net:// protocol */ + if (size_ctrl == 2) { + if (!equal) { + ERR("Control URL uses the net:// protocol and the data URL is " + "different. Not allowed."); + goto error; + } else { + set_default_uri_attr(&ctrl_uris[1], LTTNG_STREAM_DATA); + /* + * The data_url and ctrl_url are equal and the ctrl_url + * contains a net:// protocol so we just skip the data part. + */ + data_url = NULL; + } + } + } + + if (data_url && *data_url != '\0') { + int ret; + + /* We have to parse the data URL in this case */ + size_data = uri_parse(data_url, &data_uris); + if (size_data < 1) { + ERR("Unable to parse the URL %s", data_url); + goto error; + } else if (size_data == 2) { + ERR("Data URL can not be set with the net[4|6]:// protocol"); + goto error; + } + + set_default_uri_attr(&data_uris[0], LTTNG_STREAM_DATA); + + ret = compare_destination(&ctrl_uris[0], &data_uris[0]); + if (ret != 0) { + ERR("Control and data destination mismatch"); + goto error; + } + } + + /* Compute total size */ + size = size_ctrl + size_data; + + tmp_uris = zmalloc(sizeof(struct lttng_uri) * size); + if (tmp_uris == NULL) { + PERROR("zmalloc uris"); + goto error; + } + + if (ctrl_uris) { + /* It's possible the control URIs array contains more than one URI */ + memcpy(tmp_uris, ctrl_uris, sizeof(struct lttng_uri) * size_ctrl); + ++idx; + free(ctrl_uris); + } + + if (data_uris) { + memcpy(&tmp_uris[idx], data_uris, sizeof(struct lttng_uri)); + free(data_uris); + } + + *uris = tmp_uris; + + return size; + +error: + free(ctrl_uris); + free(data_uris); + free(tmp_uris); +parse_error: + return -1; +} diff --git a/src/common/uri.h b/src/common/uri.h index 347b639b0..3ef6669e6 100644 --- a/src/common/uri.h +++ b/src/common/uri.h @@ -77,6 +77,8 @@ struct lttng_uri { int uri_compare(struct lttng_uri *uri1, struct lttng_uri *uri2); void uri_free(struct lttng_uri *uri); ssize_t uri_parse(const char *str_uri, struct lttng_uri **uris); +ssize_t uri_parse_str_urls(const char *ctrl_url, const char *data_url, + struct lttng_uri **uris); int uri_to_str_url(struct lttng_uri *uri, char *dst, size_t size); #endif /* _LTT_URI_H */ diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 5811d84df..afd55a1ab 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -75,172 +75,6 @@ static int connected; int lttng_opt_quiet; int lttng_opt_verbose; -/* - * Compare two URL destination. - * - * Return 0 is equal else is not equal. - */ -static int compare_destination(struct lttng_uri *ctrl, struct lttng_uri *data) -{ - int ret; - - assert(ctrl); - assert(data); - - switch (ctrl->dtype) { - case LTTNG_DST_IPV4: - ret = strncmp(ctrl->dst.ipv4, data->dst.ipv4, sizeof(ctrl->dst.ipv4)); - break; - case LTTNG_DST_IPV6: - ret = strncmp(ctrl->dst.ipv6, data->dst.ipv6, sizeof(ctrl->dst.ipv6)); - break; - default: - ret = -1; - break; - } - - return ret; -} - -static void set_default_url_attr(struct lttng_uri *uri, - enum lttng_stream_type stype) -{ - uri->stype = stype; - if (uri->dtype != LTTNG_DST_PATH && uri->port == 0) { - uri->port = (stype == LTTNG_STREAM_CONTROL) ? - DEFAULT_NETWORK_CONTROL_PORT : DEFAULT_NETWORK_DATA_PORT; - } -} - -/* - * Parse a string URL and creates URI(s) returning the size of the populated - * array. - */ -static ssize_t parse_str_urls_to_uri(const char *ctrl_url, const char *data_url, - struct lttng_uri **uris) -{ - unsigned int equal = 1, idx = 0; - /* Add the "file://" size to the URL maximum size */ - char url[PATH_MAX + 7]; - ssize_t size_ctrl = 0, size_data = 0, size; - struct lttng_uri *ctrl_uris = NULL, *data_uris = NULL; - struct lttng_uri *tmp_uris = NULL; - - /* No URL(s) is allowed. This means that the consumer will be disabled. */ - if (ctrl_url == NULL && data_url == NULL) { - return 0; - } - - /* Check if URLs are equal and if so, only use the control URL */ - if (ctrl_url && data_url) { - equal = !strcmp(ctrl_url, data_url); - } - - /* - * Since we allow the str_url to be a full local filesystem path, we are - * going to create a valid file:// URL if it's the case. - * - * Check if first character is a '/' or else reject the URL. - */ - if (ctrl_url && ctrl_url[0] == '/') { - int ret; - - ret = snprintf(url, sizeof(url), "file://%s", ctrl_url); - if (ret < 0) { - PERROR("snprintf file url"); - goto parse_error; - } - ctrl_url = url; - } - - /* Parse the control URL if there is one */ - if (ctrl_url) { - size_ctrl = uri_parse(ctrl_url, &ctrl_uris); - if (size_ctrl < 1) { - ERR("Unable to parse the URL %s", ctrl_url); - goto parse_error; - } - - /* At this point, we know there is at least one URI in the array */ - set_default_url_attr(&ctrl_uris[0], LTTNG_STREAM_CONTROL); - - if (ctrl_uris[0].dtype == LTTNG_DST_PATH && data_url) { - ERR("Can not have a data URL when destination is file://"); - goto error; - } - - /* URL are not equal but the control URL uses a net:// protocol */ - if (size_ctrl == 2) { - if (!equal) { - ERR("Control URL uses the net:// protocol and the data URL is " - "different. Not allowed."); - goto error; - } else { - set_default_url_attr(&ctrl_uris[1], LTTNG_STREAM_DATA); - /* - * The data_url and ctrl_url are equal and the ctrl_url - * contains a net:// protocol so we just skip the data part. - */ - data_url = NULL; - } - } - } - - if (data_url) { - int ret; - - /* We have to parse the data URL in this case */ - size_data = uri_parse(data_url, &data_uris); - if (size_data < 1) { - ERR("Unable to parse the URL %s", data_url); - goto error; - } else if (size_data == 2) { - ERR("Data URL can not be set with the net[4|6]:// protocol"); - goto error; - } - - set_default_url_attr(&data_uris[0], LTTNG_STREAM_DATA); - - ret = compare_destination(&ctrl_uris[0], &data_uris[0]); - if (ret != 0) { - ERR("Control and data destination mismatch"); - goto error; - } - } - - /* Compute total size */ - size = size_ctrl + size_data; - - tmp_uris = zmalloc(sizeof(struct lttng_uri) * size); - if (tmp_uris == NULL) { - PERROR("zmalloc uris"); - goto error; - } - - if (ctrl_uris) { - /* It's possible the control URIs array contains more than one URI */ - memcpy(tmp_uris, ctrl_uris, sizeof(struct lttng_uri) * size_ctrl); - ++idx; - free(ctrl_uris); - } - - if (data_uris) { - memcpy(&tmp_uris[idx], data_uris, sizeof(struct lttng_uri)); - free(data_uris); - } - - *uris = tmp_uris; - - return size; - -error: - free(ctrl_uris); - free(data_uris); - free(tmp_uris); -parse_error: - return -1; -} - /* * Copy string from src to dst and enforce null terminated byte. */ @@ -1183,7 +1017,7 @@ int lttng_create_session(const char *name, const char *url) lttng_ctl_copy_string(lsm.session.name, name, sizeof(lsm.session.name)); /* There should never be a data URL */ - size = parse_str_urls_to_uri(url, NULL, &uris); + size = uri_parse_str_urls(url, NULL, &uris); if (size < 0) { return -LTTNG_ERR_INVALID; } @@ -1478,7 +1312,7 @@ int lttng_set_consumer_url(struct lttng_handle *handle, sizeof(lsm.session.name)); lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain); - size = parse_str_urls_to_uri(control_url, data_url, &uris); + size = uri_parse_str_urls(control_url, data_url, &uris); if (size < 0) { return -LTTNG_ERR_INVALID; } @@ -1642,7 +1476,7 @@ int _lttng_create_session_ext(const char *name, const char *url, lttng_ctl_copy_string(lsm.session.name, name, sizeof(lsm.session.name)); /* There should never be a data URL */ - size = parse_str_urls_to_uri(url, NULL, &uris); + size = uri_parse_str_urls(url, NULL, &uris); if (size < 0) { ret = -LTTNG_ERR_INVALID; goto error; -- 2.34.1