2 * RRDTool - src/rrd_client.c
3 * Copyright (C) 2008 Florian octo Forster
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; only version 2 of the License is applicable.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 * Florian octo Forster <octo at verplant.org>
23 #include "rrd_client.h"
30 #include <sys/types.h>
31 #include <sys/socket.h>
35 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
39 static int buffer_add_string (const char *str, /* {{{ */
40 char **buffer_ret, size_t *buffer_size_ret)
44 str_size = strlen (str) + 1;
46 if (*buffer_size_ret < str_size)
49 memcpy (*buffer_ret, str, str_size);
50 *buffer_ret += str_size;
51 *buffer_size_ret -= str_size;
54 } /* }}} int buffer_add_string */
56 static int buffer_add_value (const char *value, /* {{{ */
57 char **buffer_ret, size_t *buffer_size_ret)
61 if (strncmp (value, "N:", 2) == 0)
62 snprintf (temp, sizeof (temp), "%lu:%s",
63 (unsigned long) time (NULL), value + 2);
65 strncpy (temp, value, sizeof (temp));
66 temp[sizeof (temp) - 1] = 0;
68 return (buffer_add_string (temp, buffer_ret, buffer_size_ret));
69 } /* }}} int buffer_add_value */
71 static int rrdc_connect_unix (const char *path) /* {{{ */
73 struct sockaddr_un sa;
77 path = RRDD_SOCK_PATH;
79 pthread_mutex_lock (&lock);
83 pthread_mutex_unlock (&lock);
87 sd = socket (PF_UNIX, SOCK_STREAM, /* protocol = */ 0);
91 pthread_mutex_unlock (&lock);
95 memset (&sa, 0, sizeof (sa));
96 sa.sun_family = AF_UNIX;
97 strncpy (sa.sun_path, path, sizeof (sa.sun_path) - 1);
99 status = connect (sd, (struct sockaddr *) &sa, sizeof (sa));
103 pthread_mutex_unlock (&lock);
107 sh = fdopen (sd, "w+");
113 pthread_mutex_unlock (&lock);
117 pthread_mutex_unlock (&lock);
120 } /* }}} int rrdc_connect_unix */
122 int rrdc_connect (const char *addr) /* {{{ */
124 struct addrinfo ai_hints;
125 struct addrinfo *ai_res;
126 struct addrinfo *ai_ptr;
130 addr = RRDD_SOCK_PATH;
132 if (strncmp ("unix:", addr, strlen ("unix:")) == 0)
133 return (rrdc_connect_unix (addr + strlen ("unix:")));
134 else if (addr[0] == '/')
135 return (rrdc_connect_unix (addr));
137 pthread_mutex_lock (&lock);
141 pthread_mutex_unlock (&lock);
145 memset (&ai_hints, 0, sizeof (ai_hints));
146 ai_hints.ai_flags = 0;
148 ai_hints.ai_flags |= AI_ADDRCONFIG;
150 ai_hints.ai_family = AF_UNSPEC;
151 ai_hints.ai_socktype = SOCK_STREAM;
154 status = getaddrinfo (addr, DEFAULT_PORT, &ai_hints, &ai_res);
157 pthread_mutex_unlock (&lock);
161 for (ai_ptr = ai_res; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
163 sd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol);
171 status = connect (sd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
180 sh = fdopen (sd, "w+");
189 assert (status == 0);
192 pthread_mutex_unlock (&lock);
195 } /* }}} int rrdc_connect */
197 int rrdc_disconnect (void) /* {{{ */
201 pthread_mutex_lock (&lock);
205 pthread_mutex_unlock (&lock);
209 status = fclose (sh);
216 pthread_mutex_unlock (&lock);
219 } /* }}} int rrdc_disconnect */
221 int rrdc_update (const char *filename, int values_num, /* {{{ */
222 const char * const *values)
230 memset (buffer, 0, sizeof (buffer));
231 buffer_ptr = &buffer[0];
232 buffer_size = sizeof (buffer) - 1;
234 buffer_add_string ("update", &buffer_ptr, &buffer_size);
235 buffer_add_string (filename, &buffer_ptr, &buffer_size);
236 for (i = 0; i < values_num; i++)
237 buffer_add_value (values[i], &buffer_ptr, &buffer_size);
239 pthread_mutex_lock (&lock);
243 pthread_mutex_unlock (&lock);
247 status = write (sd, buffer, sizeof (buffer) - buffer_size);
249 status = read (sd, buffer, sizeof (buffer));
253 pthread_mutex_unlock (&lock);
256 else if (status == 0)
258 pthread_mutex_unlock (&lock);
262 status = atoi (buffer);
264 pthread_mutex_unlock (&lock);
267 } /* }}} int rrd_update_daemon */
270 * vim: set sw=2 sts=2 ts=8 et fdm=marker :