X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fcommon%2Furi.c;h=6ca46474f06086666b68d22fa1871b51bebfdc9f;hb=51d7db73266e8bf7e3248981d722d3743c38d670;hp=3a58aedca53f95af2d8e9734eb53fd4fd5f5f4ba;hpb=3a5713dad195a7cfa3f4866ad2c75f3a83d73a2f;p=lttng-tools.git diff --git a/src/common/uri.c b/src/common/uri.c index 3a58aedca..6ca46474f 100644 --- a/src/common/uri.c +++ b/src/common/uri.c @@ -74,6 +74,39 @@ end: 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 */ + ERR("URI parse bad hostname %s for af %d", addr, af); + 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. * @@ -110,65 +143,47 @@ struct lttng_uri *uri_create(void) 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); if (ret < 1) { - printf("bad protocol\n"); + ERR("URI parse bad protocol %s", str_uri); goto error; } - DBG3("URI protocol : %s", str_uri); + DBG3("URI string: %s", str_uri); proto = validate_protocol(net); if (proto == NULL) { - printf("no protocol\n"); + ERR("URI parse unknown protocol %s", net); ret = -1; goto error; } @@ -178,12 +193,27 @@ ssize_t uri_parse(const char *str_uri, struct lttng_uri **uris) 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 */ @@ -199,9 +229,10 @@ ssize_t uri_parse(const char *str_uri, struct lttng_uri **uris) 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: