src/librrdc.c: Sending to the daemon has been added.
[rrdd.git] / src / librrdc.c
1 /**
2  * collectd - src/rrdc.c
3  * Copyright (C) 2008 Florian octo Forster
4  *
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.
8  *
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.
13  *
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
17  *
18  * Authors:
19  *   Florian octo Forster <octo at verplant.org>
20  **/
21
22 #include "rrdd.h"
23 #include "rrdc.h"
24
25 #define SOCK_TEMPLATE "/tmp/rrdc.sock.XXXXXX"
26
27 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
28 static int sd;
29 static FILE *sh;
30
31 static int buffer_add_string (const char *str,
32     char **buffer_ret, size_t *buffer_size_ret)
33 {
34   size_t str_size;
35
36   str_size = strlen (str) + 1;
37
38   if (*buffer_size_ret < str_size)
39     return (-1);
40
41   memcpy (*buffer_ret, str, str_size);
42   *buffer_ret += str_size;
43   *buffer_size_ret -= str_size;
44
45   return (0);
46 } /* int buffer_add_string */
47
48 static int buffer_add_value (const char *value,
49     char **buffer_ret, size_t *buffer_size_ret)
50 {
51   char temp[4096];
52
53   if (strncmp (value, "N:", 2) == 0)
54     snprintf (temp, sizeof (temp), "%lu:%s",
55         (unsigned long) time (NULL), value + 2);
56   else
57     strncpy (temp, value, sizeof (temp));
58   temp[sizeof (temp) - 1] = 0;
59
60   return (buffer_add_string (temp, buffer_ret, buffer_size_ret));
61 } /* int buffer_add_value */
62
63 int rrdd_connect (const char *path)
64 {
65   struct sockaddr_un sa;
66   int status;
67
68   pthread_mutex_lock (&lock);
69
70   if (sh != NULL)
71   {
72     pthread_mutex_unlock (&lock);
73     return (0);
74   }
75
76   sd = socket (PF_UNIX, SOCK_STREAM, /* protocol = */ 0);
77   if (sd < 0)
78   {
79     status = errno;
80     pthread_mutex_unlock (&lock);
81     return (status);
82   }
83
84   memset (&sa, 0, sizeof (sa));
85   sa.sun_family = AF_UNIX;
86   strncpy (sa.sun_path, path, sizeof (sa.sun_path) - 1);
87
88   status = connect (sd, (struct sockaddr *) &sa, sizeof (sa));
89   if (status != 0)
90   {
91     status = errno;
92     pthread_mutex_unlock (&lock);
93     return (status);
94   }
95
96   sh = fdopen (sd, "w+");
97   if (sh == NULL)
98   {
99     status = errno;
100     close (sd);
101     sd = -1;
102     pthread_mutex_unlock (&lock);
103     return (status);
104   }
105
106   pthread_mutex_unlock (&lock);
107
108   return (0);
109 } /* int rrdd_connect */
110
111 int rrdd_disconnect (void)
112 {
113   int status;
114
115   pthread_mutex_lock (&lock);
116
117   if (sh == NULL)
118   {
119     pthread_mutex_unlock (&lock);
120     return (-1);
121   }
122
123   status = fclose (sh);
124   if (status != 0)
125     status = errno;
126
127   sh = NULL;
128   sd = -1;
129
130   pthread_mutex_unlock (&lock);
131
132   return (status);
133 } /* int rrdd_disconnect */
134
135 int rrdd_update (const char *filename, int values_num,
136                 const char * const *values)
137 {
138   char buffer[4096];
139   char *buffer_ptr;
140   size_t buffer_size;
141   int status;
142   int i;
143
144   memset (buffer, 0, sizeof (buffer));
145   buffer_ptr = &buffer[0];
146   buffer_size = sizeof (buffer) - 1;
147
148   buffer_add_string (filename, &buffer_ptr, &buffer_size);
149   for (i = 0; i < values_num; i++)
150     buffer_add_value (values[i], &buffer_ptr, &buffer_size);
151
152   pthread_mutex_lock (&lock);
153
154   if (sh == NULL)
155   {
156     pthread_mutex_unlock (&lock);
157     return (-1);
158   }
159
160   status = write (sd, buffer, sizeof (buffer) - buffer_size);
161
162   pthread_mutex_unlock (&lock);
163
164   return (0);
165 } /* int rrd_update_daemon */
166
167 /*
168  * vim: set sw=2 sts=2 ts=8 et fdm=marker :
169  */