2 * collectd - src/utils_cms_putval.c
3 * Copyright (C) 2007-2009 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>
26 #include "utils_parse_option.h"
28 #define print_to_socket(fh, ...) \
29 if (fprintf (fh, __VA_ARGS__) < 0) { \
31 WARNING ("handle_putval: failed to write to socket #%i: %s", \
32 fileno (fh), sstrerror (errno, errbuf, sizeof (errbuf))); \
36 static int dispatch_values (const data_set_t *ds, value_list_t *vl,
37 FILE *fh, char *buffer)
41 status = parse_values (buffer, vl, ds);
44 print_to_socket (fh, "-1 Parsing the values string failed.\n");
48 plugin_dispatch_values (vl);
50 } /* int dispatch_values */
52 static int set_option (value_list_t *vl, const char *key, const char *value)
54 if ((vl == NULL) || (key == NULL) || (value == NULL))
57 if (strcasecmp ("interval", key) == 0)
64 tmp = strtol (value, &endptr, 0);
66 if ((errno == 0) && (endptr != NULL)
67 && (endptr != value) && (tmp > 0))
74 } /* int parse_option */
76 int handle_putval (FILE *fh, char *buffer)
82 char *plugin_instance;
88 char *identifier_copy;
91 value_list_t vl = VALUE_LIST_INIT;
93 DEBUG ("utils_cmd_putval: handle_putval (fh = %p, buffer = %s);",
97 status = parse_string (&buffer, &command);
100 print_to_socket (fh, "-1 Cannot parse command.\n");
103 assert (command != NULL);
105 if (strcasecmp ("PUTVAL", command) != 0)
107 print_to_socket (fh, "-1 Unexpected command: `%s'.\n", command);
112 status = parse_string (&buffer, &identifier);
115 print_to_socket (fh, "-1 Cannot parse identifier.\n");
118 assert (identifier != NULL);
120 /* parse_identifier() modifies its first argument,
121 * returning pointers into it */
122 identifier_copy = sstrdup (identifier);
124 status = parse_identifier (identifier_copy, &hostname,
125 &plugin, &plugin_instance,
126 &type, &type_instance);
129 DEBUG ("handle_putval: Cannot parse identifier `%s'.",
131 print_to_socket (fh, "-1 Cannot parse identifier `%s'.\n",
133 sfree (identifier_copy);
137 if ((strlen (hostname) >= sizeof (vl.host))
138 || (strlen (plugin) >= sizeof (vl.plugin))
139 || ((plugin_instance != NULL)
140 && (strlen (plugin_instance) >= sizeof (vl.plugin_instance)))
141 || ((type_instance != NULL)
142 && (strlen (type_instance) >= sizeof (vl.type_instance))))
144 print_to_socket (fh, "-1 Identifier too long.\n");
145 sfree (identifier_copy);
149 sstrncpy (vl.host, hostname, sizeof (vl.host));
150 sstrncpy (vl.plugin, plugin, sizeof (vl.plugin));
151 sstrncpy (vl.type, type, sizeof (vl.type));
152 if (plugin_instance != NULL)
153 sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
154 if (type_instance != NULL)
155 sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
157 ds = plugin_get_ds (type);
159 print_to_socket (fh, "-1 Type `%s' isn't defined.\n", type);
160 sfree (identifier_copy);
164 /* Free identifier_copy */
166 plugin = NULL; plugin_instance = NULL;
167 type = NULL; type_instance = NULL;
168 sfree (identifier_copy);
170 vl.values_len = ds->ds_num;
171 vl.values = (value_t *) malloc (vl.values_len * sizeof (value_t));
172 if (vl.values == NULL)
174 print_to_socket (fh, "-1 malloc failed.\n");
178 /* All the remaining fields are part of the optionlist. */
179 values_submitted = 0;
185 status = parse_option (&buffer, &string, &value);
188 /* parse_option failed, buffer has been modified.
189 * => we need to abort */
190 print_to_socket (fh, "-1 Misformatted option.\n");
193 else if (status == 0)
195 assert (string != NULL);
196 assert (value != NULL);
197 set_option (&vl, string, value);
200 /* else: parse_option but buffer has not been modified. This is
201 * the default if no `=' is found.. */
203 status = parse_string (&buffer, &string);
206 print_to_socket (fh, "-1 Misformatted value.\n");
209 assert (string != NULL);
211 status = dispatch_values (ds, &vl, fh, string);
214 /* An error has already been printed. */
218 } /* while (*buffer != 0) */
219 /* Done parsing the options. */
221 print_to_socket (fh, "0 Success: %i %s been dispatched.\n",
223 (values_submitted == 1) ? "value has" : "values have");
228 } /* int handle_putval */
230 int create_putval (char *ret, size_t ret_len, /* {{{ */
231 const data_set_t *ds, const value_list_t *vl)
233 char buffer_ident[6 * DATA_MAX_NAME_LEN];
234 char buffer_values[1024];
237 status = FORMAT_VL (buffer_ident, sizeof (buffer_ident), vl);
240 escape_string (buffer_ident, sizeof (buffer_ident));
242 status = format_values (buffer_values, sizeof (buffer_values),
243 ds, vl, /* store rates = */ 0);
246 escape_string (buffer_values, sizeof (buffer_values));
248 ssnprintf (ret, ret_len,
249 "PUTVAL %s interval=%i %s",
251 (vl->interval > 0) ? vl->interval : interval_g,
255 } /* }}} int create_putval */