src/collectd-nagios.c: Improve handling of lines returned from `GETVAL'.
authorFlorian Forster <octo@huhu.verplant.org>
Mon, 6 Oct 2008 09:46:59 +0000 (11:46 +0200)
committerFlorian Forster <octo@huhu.verplant.org>
Mon, 6 Oct 2008 09:46:59 +0000 (11:46 +0200)
Then selecting only certain data sources with the `-d' option, the program
would try to read more lines from the server than the server reports, resulting
in the communication never finishing.

This patch resolves that problem and introduces a couple other error handling
blocks.

Thanks to Fabian Linzberger for pointing this out.

src/collectd-nagios.c

index 1bf5b3f..ca72a68 100644 (file)
@@ -150,6 +150,7 @@ static int get_values (int *ret_values_num, double **ret_values,
        char **values_names;
 
        int i;
+       int j;
 
        fd = socket (PF_UNIX, SOCK_STREAM, 0);
        if (fd < 0)
@@ -229,31 +230,58 @@ static int get_values (int *ret_values_num, double **ret_values,
                free (values);
                return (-1);
        }
+       memset (values_names, 0, values_num * sizeof (char *));
 
-       i = 0;
+       i = 0; /* index of the values returned by the server */
+       j = 0; /* number of values in `values_names' and `values' */
        while (fgets (buffer, sizeof (buffer), fh_in) != NULL)
        {
-               char *key;
-               char *value;
+               do /* while (0) */
+               {
+                       char *key;
+                       char *value;
+                       char *endptr;
+
+                       key = buffer;
 
-               key = buffer;
+                       value = strchr (key, '=');
+                       if (value == NULL)
+                       {
+                               fprintf (stderr, "Cannot parse line: %s\n", buffer);
+                               break;
+                       }
+                       *value = 0;
+                       value++;
 
-               value = strchr (key, '=');
-               if (value == NULL)
-                       continue;
-               *value = '\0'; value++;
+                       if (ignore_ds (key) != 0)
+                               break;
 
-               if (ignore_ds (key) != 0)
-                       continue;
+                       endptr = NULL;
+                       errno = 0;
+                       values[j] = strtod (value, &endptr);
+                       if ((endptr == value) || (errno != 0))
+                       {
+                               fprintf (stderr, "Could not parse buffer "
+                                               "as number: %s\n", value);
+                               break;
+                       }
 
-               values_names[i] = strdup (key);
-               values[i] = atof (value);
+                       values_names[j] = strdup (key);
+                       if (values_names[j] == NULL)
+                       {
+                               fprintf (stderr, "strdup failed.\n");
+                               break;
+                       }
+                       j++;
+               } while (0);
 
                i++;
                if (i >= values_num)
                        break;
        }
-       values_num = i;
+       /* Set `values_num' to the number of values actually stored in the
+        * array. */
+       values_num = j;
 
        fclose (fh_in); fh_in = NULL; fd = -1;
        fclose (fh_out); fh_out = NULL;