hddtemp: Lift 32-device limit
[collectd.git] / src / hddtemp.c
index 4428b75..4840e14 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (C) 2005,2006  Vincent StehlĂ©
  * Copyright (C) 2006-2010  Florian octo Forster
  * Copyright (C) 2008       Sebastian Harl
+ * Copyright (C) 2014       Carnegie Mellon University
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -20,8 +21,9 @@
  *
  * Authors:
  *   Vincent StehlĂ© <vincent.stehle at free.fr>
- *   Florian octo Forster <octo at verplant.org>
+ *   Florian octo Forster <octo at collectd.org>
  *   Sebastian Harl <sh at tokkee.org>
+ *   Benjamin Gilbert <bgilbert at cs.cmu.edu>
  *
  * TODO:
  *   Do a pass, some day, and spare some memory. We consume too much for now
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 # include <netdb.h>
-# include <sys/socket.h>
 # include <netinet/in.h>
 # include <netinet/tcp.h>
 # include <libgen.h> /* for basename */
@@ -89,19 +90,9 @@ static int hddtemp_query_daemon (char *buffer, int buffer_size)
        const char *host;
        const char *port;
 
-       struct addrinfo  ai_hints;
-       struct addrinfo *ai_list, *ai_ptr;
+       struct addrinfo *ai_list;
        int              ai_return;
 
-       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   = PF_UNSPEC;
-       ai_hints.ai_socktype = SOCK_STREAM;
-       ai_hints.ai_protocol = IPPROTO_TCP;
-
        host = hddtemp_host;
        if (host == NULL)
                host = HDDTEMP_DEF_HOST;
@@ -110,6 +101,13 @@ static int hddtemp_query_daemon (char *buffer, int buffer_size)
        if (strlen (port) == 0)
                port = HDDTEMP_DEF_PORT;
 
+       struct addrinfo ai_hints = {
+               .ai_flags = AI_ADDRCONFIG,
+               .ai_family = AF_UNSPEC,
+               .ai_protocol = IPPROTO_TCP,
+               .ai_socktype = SOCK_STREAM
+       };
+
        if ((ai_return = getaddrinfo (host, port, &ai_hints, &ai_list)) != 0)
        {
                char errbuf[1024];
@@ -122,7 +120,7 @@ static int hddtemp_query_daemon (char *buffer, int buffer_size)
        }
 
        fd = -1;
-       for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+       for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
        {
                /* create our socket descriptor */
                fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype,
@@ -230,12 +228,9 @@ static int hddtemp_config (const char *key, const char *value)
 
 static void hddtemp_submit (char *type_instance, double value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "hddtemp", sizeof (vl.plugin));
@@ -248,52 +243,41 @@ static void hddtemp_submit (char *type_instance, double value)
 static int hddtemp_read (void)
 {
        char buf[1024];
-       char *fields[128];
        char *ptr;
        char *saveptr;
-       int num_fields;
-       int num_disks;
-       int i;
+       char *name;
+       char *model;
+       char *temperature;
+       char *mode;
 
        /* get data from daemon */
        if (hddtemp_query_daemon (buf, sizeof (buf)) < 0)
                return (-1);
 
        /* NB: strtok_r will eat up "||" and leading "|"'s */
-       num_fields = 0;
        ptr = buf;
        saveptr = NULL;
-       while ((fields[num_fields] = strtok_r (ptr, "|", &saveptr)) != NULL)
+       while ((name = strtok_r (ptr, "|", &saveptr)) != NULL &&
+              (model = strtok_r (NULL, "|", &saveptr)) != NULL &&
+              (temperature = strtok_r (NULL, "|", &saveptr)) != NULL &&
+              (mode = strtok_r (NULL, "|", &saveptr)) != NULL)
        {
-               ptr = NULL;
-               num_fields++;
+               double temperature_value;
 
-               if (num_fields >= 128)
-                       break;
-       }
-
-       num_disks = num_fields / 4;
-
-       for (i = 0; i < num_disks; i++)
-       {
-               char *name;
-               double temperature;
-               char *mode;
-
-               mode = fields[4*i + 3];
-               name = basename (fields[4*i + 0]);
+               ptr = NULL;
 
                /* Skip non-temperature information */
                if (mode[0] != 'C' && mode[0] != 'F')
                        continue;
 
-               temperature = atof (fields[4*i + 2]);
+               name = basename (name);
+               temperature_value = atof (temperature);
 
                /* Convert farenheit to celsius */
                if (mode[0] == 'F')
-                       temperature = (temperature - 32.0) * 5.0 / 9.0;
+                       temperature_value = (temperature_value - 32.0) * 5.0 / 9.0;
 
-               hddtemp_submit (name, temperature);
+               hddtemp_submit (name, temperature_value);
        }
        
        return (0);