X-Git-Url: https://git.octo.it/?p=rrdtool.git;a=blobdiff_plain;f=src%2Frrd_client.c;h=5583bfeb59fe5e159b787f2cdb087feb7303a019;hp=c573dad308dd75892951ced112d63f0daa4324bb;hb=837a4b7874724d57e7721e23f65ef57c998d9dff;hpb=f3816cb9cea7ce0b5390afe5508b5f209ec7a52a diff --git a/src/rrd_client.c b/src/rrd_client.c index c573dad..5583bfe 100644 --- a/src/rrd_client.c +++ b/src/rrd_client.c @@ -212,6 +212,8 @@ static int response_read (rrdc_response_t **ret_response) /* {{{ */ if (ret->status <= 0) { + if (ret->status < 0) + rrd_set_error("rrdcached: %s", ret->message); *ret_response = ret; return (0); } @@ -266,6 +268,8 @@ static int request (const char *buffer, size_t buffer_size, /* {{{ */ { close_connection (); pthread_mutex_unlock (&lock); + rrd_set_error("request: socket error (%d) while talking to rrdcached", + status); return (-1); } fflush (sh); @@ -276,7 +280,11 @@ static int request (const char *buffer, size_t buffer_size, /* {{{ */ pthread_mutex_unlock (&lock); if (status != 0) + { + if (status < 0) + rrd_set_error("request: internal error while talking to rrdcached"); return (status); + } *ret_response = res; return (0); @@ -347,16 +355,22 @@ static int rrdc_connect_unix (const char *path) /* {{{ */ return (0); } /* }}} int rrdc_connect_unix */ -static int rrdc_connect_network (const char *addr) /* {{{ */ +static int rrdc_connect_network (const char *addr_orig) /* {{{ */ { struct addrinfo ai_hints; struct addrinfo *ai_res; struct addrinfo *ai_ptr; + char addr_copy[NI_MAXHOST]; + char *addr; char *port; - assert (addr != NULL); + assert (addr_orig != NULL); assert (sd == -1); + strncpy(addr_copy, addr_orig, sizeof(addr_copy)); + addr_copy[sizeof(addr_copy) - 1] = '\0'; + addr = addr_copy; + int status; memset (&ai_hints, 0, sizeof (ai_hints)); ai_hints.ai_flags = 0; @@ -366,9 +380,40 @@ static int rrdc_connect_network (const char *addr) /* {{{ */ ai_hints.ai_family = AF_UNSPEC; ai_hints.ai_socktype = SOCK_STREAM; - port = rindex(addr, ':'); - if (port != NULL) - *port++ = '\0'; + port = NULL; + if (*addr == '[') /* IPv6+port format */ + { + /* `addr' is something like "[2001:780:104:2:211:24ff:feab:26f8]:12345" */ + addr++; + + port = strchr (addr, ']'); + if (port == NULL) + { + rrd_set_error("malformed address: %s", addr_orig); + return (-1); + } + *port = 0; + port++; + + if (*port == ':') + port++; + else if (*port == 0) + port = NULL; + else + { + rrd_set_error("garbage after address: %s", port); + return (-1); + } + } /* if (*addr = ']') */ + else if (strchr (addr, '.') != NULL) /* Hostname or IPv4 */ + { + port = rindex(addr, ':'); + if (port != NULL) + { + *port = 0; + port++; + } + } ai_res = NULL; status = getaddrinfo (addr, @@ -473,6 +518,7 @@ int rrdc_update (const char *filename, int values_num, /* {{{ */ rrdc_response_t *res; int status; int i; + char file_path[PATH_MAX]; memset (buffer, 0, sizeof (buffer)); buffer_ptr = &buffer[0]; @@ -482,6 +528,10 @@ int rrdc_update (const char *filename, int values_num, /* {{{ */ if (status != 0) return (ENOBUFS); + /* change to absolute path for rrdcached */ + if (*filename != '/' && realpath(filename, file_path) != NULL) + filename = file_path; + status = buffer_add_string (filename, &buffer_ptr, &buffer_free); if (status != 0) return (ENOBUFS); @@ -517,6 +567,7 @@ int rrdc_flush (const char *filename) /* {{{ */ size_t buffer_size; rrdc_response_t *res; int status; + char file_path[PATH_MAX]; if (filename == NULL) return (-1); @@ -529,6 +580,10 @@ int rrdc_flush (const char *filename) /* {{{ */ if (status != 0) return (ENOBUFS); + /* change to absolute path for rrdcached */ + if (*filename != '/' && realpath(filename, file_path) != NULL) + filename = file_path; + status = buffer_add_string (filename, &buffer_ptr, &buffer_free); if (status != 0) return (ENOBUFS); @@ -567,7 +622,7 @@ int rrdc_flush_if_daemon (const char *opt_daemon, const char *filename) /* {{{ * rrd_set_error ("rrdc_flush (%s) failed with status %i.", filename, status); } - } /* if (daemon_addr) */ + } /* if (rrdc_is_connected(..)) */ return status; } /* }}} int rrdc_flush_if_daemon */ @@ -696,7 +751,7 @@ void rrdc_stats_free (rrdc_stats_t *ret_stats) /* {{{ */ if (this->name != NULL) { - free (this->name); + free ((char *)this->name); this->name = NULL; } free (this);