return supported;
}
+/*
+ * Set network address from string into dst. Supports both IP string and
+ * hostname.
+ */
+static int set_ip_address(const char *addr, int af, char *dst, size_t size)
+{
+ int ret;
+ unsigned char buf[sizeof(struct in6_addr)];
+ struct hostent *record;
+
+ /* Network protocol */
+ ret = inet_pton(af, addr, buf);
+ if (ret < 1) {
+ /* We consider the dst to be an hostname or an invalid IP char */
+ record = gethostbyname2(addr, af);
+ if (record == NULL) {
+ /* At this point, the IP or the hostname is bad */
+ printf("bad hostname\n");
+ goto error;
+ }
+
+ /* Translate IP to string */
+ (void) inet_ntop(af, record->h_addr_list[0], dst, size);
+ } else {
+ memcpy(dst, addr, size);
+ }
+
+ return 0;
+
+error:
+ return -1;
+}
+
/*
* Compare two URIs.
*
return uri;
}
-static int set_ip_address(const char *addr, int af, char *dst, size_t size)
-{
- int ret;
- unsigned char buf[sizeof(struct in6_addr)];
- struct hostent *record;
-
- /* Network protocol */
- ret = inet_pton(af, addr, buf);
- if (ret < 1) {
- /* We consider the dst to be an hostname or an invalid IP char */
- record = gethostbyname2(addr, af);
- if (record == NULL) {
- /* At this point, the IP or the hostname is bad */
- printf("bad hostname\n");
- goto error;
- }
-
- /* Translate IP to string */
- (void) inet_ntop(af, record->h_addr_list[0], dst, size);
- } else {
- memcpy(dst, addr, size);
- }
-
- return 0;
-
-error:
- return -1;
-}
-
+/*
+ * Parses a string URI to a lttng_uri. This function can potentially return
+ * more than one URI in uris so the size of the array is returned and uris is
+ * allocated and populated. Caller must free(3) the array.
+ *
+ * This function can not detect the stream type of the URI so the caller has to
+ * make sure the correct type (stype) is set on the return URI(s). The default
+ * port must also be set by the caller if the returned URI has its port set to
+ * zero.
+ */
ssize_t uri_parse(const char *str_uri, struct lttng_uri **uris)
{
int ret;
+ size_t str_offset = 0;
/* Size of the uris array. Default is 1 */
ssize_t size = 1;
- char net[6], dst[LTTNG_MAX_DNNAME + 1];
- unsigned int ctrl_port = DEFAULT_NETWORK_CONTROL_PORT;
- unsigned int data_port = DEFAULT_NETWORK_DATA_PORT;
+ char net[6], dst[LTTNG_MAX_DNNAME + 1], subdir[PATH_MAX];
+ unsigned int ctrl_port = 0;
+ unsigned int data_port = 0;
struct lttng_uri *uri;
const struct uri_proto *proto;
/*
* The first part is the protocol portion of a maximum of 5 bytes for now.
- * (tcp, tcp6, udp, udp6, file, net). The second part is the hostname or IP
- * address. The 255 bytes size is the limit found in the RFC 1035 for the
- * total length of a domain name (https://www.ietf.org/rfc/rfc1035.txt).
- * Finally, with the net:// protocol, two ports can be specified.
+ * The second part is the hostname or IP address. The 255 bytes size is the
+ * limit found in the RFC 1035 for the total length of a domain name
+ * (https://www.ietf.org/rfc/rfc1035.txt). Finally, for the net://
+ * protocol, two ports CAN be specified.
*/
ret = sscanf(str_uri, "%5[^:]://", net);
goto error;
}
- DBG3("URI protocol : %s", str_uri);
+ DBG3("URI string: %s", str_uri);
proto = validate_protocol(net);
if (proto == NULL) {
size = 2;
}
+ memset(subdir, 0, sizeof(subdir));
+ str_offset += strlen(net);
+
/* Parse the rest of the URI */
- ret = sscanf(str_uri + strlen(net), "://%255[^:]:%u:%u", dst,
- &ctrl_port, &data_port);
- if (ret < 0) {
- printf("bad URI\n");
- goto error;
+ if (sscanf(str_uri + str_offset, "://%255[^:]:%u:%u/%s", dst, &ctrl_port,
+ &data_port, subdir) == 4) {
+ /* All set */
+ } else if (sscanf(str_uri + str_offset, "://%255[^:]:%u:%u", dst,
+ &ctrl_port, &data_port) == 3) {
+ } else if (sscanf(str_uri + str_offset, "://%255[^:]:%u/%s", dst,
+ &ctrl_port, subdir) == 3) {
+ } else if (sscanf(str_uri + str_offset, "://%255[^:]:%u", dst,
+ &ctrl_port) == 2) {
+ } else if (sscanf(str_uri + str_offset, "://%255[^/]/%s", dst,
+ subdir) == 2) {
+ } else {
+ ret = sscanf(str_uri + str_offset, "://%255[^:]", dst);
+ if (ret < 0) {
+ ERR("Bad URI");
+ goto error;
+ }
}
/* We have enough valid information to create URI(s) object */
uri[0].dtype = proto->dtype;
uri[0].proto = proto->type;
uri[0].port = ctrl_port;
+ strncpy(uri[0].subdir, subdir, sizeof(uri[0].subdir));
- DBG3("URI dtype: %d, proto: %d, port: %d", proto->dtype, proto->type,
- ctrl_port);
+ DBG3("URI dtype: %d, proto: %d, host: %s, subdir: %s, ctrl: %d, data: %d",
+ proto->dtype, proto->type, dst, subdir, ctrl_port, data_port);
switch (proto->code) {
case P_FILE: