From: Florian Forster Date: Sun, 22 Jun 2008 12:20:32 +0000 (+0200) Subject: src/librrdc.c: rrdd_connect: Allow connecting to arbitrary addresses. X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=c8d9d4d92ba1e86253efa711a81097ddeb8dc9d5;p=rrdd.git src/librrdc.c: rrdd_connect: Allow connecting to arbitrary addresses. UNIX domain sockets are handled specially, because getaddrinfo(3) doesn't now how to handle them. --- diff --git a/src/librrdc.c b/src/librrdc.c index 93d9420..0e2281d 100644 --- a/src/librrdc.c +++ b/src/librrdc.c @@ -58,7 +58,7 @@ static int buffer_add_value (const char *value, return (buffer_add_string (temp, buffer_ret, buffer_size_ret)); } /* int buffer_add_value */ -int rrdd_connect (const char *path) +static int rrdd_connect_unix (const char *path) { struct sockaddr_un sa; int status; @@ -107,6 +107,81 @@ int rrdd_connect (const char *path) pthread_mutex_unlock (&lock); return (0); +} /* int rrdd_connect_unix */ + +int rrdd_connect (const char *addr) +{ + struct addrinfo ai_hints; + struct addrinfo *ai_res; + struct addrinfo *ai_ptr; + int status; + + if (addr == NULL) + addr = RRDD_SOCK_PATH; + + if (strncmp ("unix:", addr, strlen ("unix:")) == 0) + return (rrdd_connect_unix (addr + strlen ("unix:"))); + else if (addr[0] == '/') + return (rrdd_connect_unix (addr)); + + pthread_mutex_lock (&lock); + + if (sh != NULL) + { + pthread_mutex_unlock (&lock); + return (0); + } + + memset (&ai_hints, 0, sizeof (ai_hints)); + ai_hints.ai_flags = 0; +#ifdef AI_ADDRCONFIG + ai_hints.ai_flags |= AI_ADDRCONFIG; +#endif + ai_hints.ai_family = AF_UNSPEC; + ai_hints.ai_socktype = SOCK_STREAM; + + ai_res = NULL; + status = getaddrinfo (addr, DEFAULT_PORT, &ai_hints, &ai_res); + if (status != 0) + { + pthread_mutex_unlock (&lock); + return (status); + } + + for (ai_ptr = ai_res; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) + { + sd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); + if (sd < 0) + { + status = errno; + sd = -1; + continue; + } + + status = connect (sd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); + if (status != 0) + { + status = errno; + close (sd); + sd = -1; + continue; + } + + sh = fdopen (sd, "w+"); + if (sh == NULL) + { + status = errno; + close (sd); + sd = -1; + continue; + } + + assert (status == 0); + break; + } /* for (ai_ptr) */ + pthread_mutex_unlock (&lock); + + return (status); } /* int rrdd_connect */ int rrdd_disconnect (void)