X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Flibrrdc.c;h=0e2281d9d0d104caa34e88664ce47c4850c4029f;hb=c8d9d4d92ba1e86253efa711a81097ddeb8dc9d5;hp=c0ede89239e9b1e0a0c61ab0da41a861d6920391;hpb=d1bb7d8bba2159935609fcbf2cbc9b2ed33b5bb5;p=rrdd.git diff --git a/src/librrdc.c b/src/librrdc.c index c0ede89..0e2281d 100644 --- a/src/librrdc.c +++ b/src/librrdc.c @@ -22,17 +22,50 @@ #include "rrdd.h" #include "rrdc.h" -#define SOCK_TEMPLATE "/tmp/rrdc.sock.XXXXXX" - static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; static int sd; static FILE *sh; -int rrdd_connect (const char *path) +static int buffer_add_string (const char *str, + char **buffer_ret, size_t *buffer_size_ret) +{ + size_t str_size; + + str_size = strlen (str) + 1; + + if (*buffer_size_ret < str_size) + return (-1); + + memcpy (*buffer_ret, str, str_size); + *buffer_ret += str_size; + *buffer_size_ret -= str_size; + + return (0); +} /* int buffer_add_string */ + +static int buffer_add_value (const char *value, + char **buffer_ret, size_t *buffer_size_ret) +{ + char temp[4096]; + + if (strncmp (value, "N:", 2) == 0) + snprintf (temp, sizeof (temp), "%lu:%s", + (unsigned long) time (NULL), value + 2); + else + strncpy (temp, value, sizeof (temp)); + temp[sizeof (temp) - 1] = 0; + + return (buffer_add_string (temp, buffer_ret, buffer_size_ret)); +} /* int buffer_add_value */ + +static int rrdd_connect_unix (const char *path) { struct sockaddr_un sa; int status; + if (path == NULL) + path = RRDD_SOCK_PATH; + pthread_mutex_lock (&lock); if (sh != NULL) @@ -74,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) @@ -103,17 +211,49 @@ int rrdd_disconnect (void) int rrdd_update (const char *filename, int values_num, const char * const *values) { + char buffer[4096]; + char *buffer_ptr; + size_t buffer_size; + int status; + int i; + + memset (buffer, 0, sizeof (buffer)); + buffer_ptr = &buffer[0]; + buffer_size = sizeof (buffer) - 1; + + buffer_add_string ("update", &buffer_ptr, &buffer_size); + buffer_add_string (filename, &buffer_ptr, &buffer_size); + for (i = 0; i < values_num; i++) + buffer_add_value (values[i], &buffer_ptr, &buffer_size); + pthread_mutex_lock (&lock); if (sh == NULL) { pthread_mutex_unlock (&lock); - return (-1); + return (ENOTCONN); } + status = write (sd, buffer, sizeof (buffer) - buffer_size); + + status = read (sd, buffer, sizeof (buffer)); + if (status < 0) + { + status = errno; + pthread_mutex_unlock (&lock); + return (status); + } + else if (status == 0) + { + pthread_mutex_unlock (&lock); + return (ENODATA); + } + + status = atoi (buffer); + pthread_mutex_unlock (&lock); - return (0); + return (status); } /* int rrd_update_daemon */ /*