Merge branch 'master' of git://git.verplant.org/collectd
[collectd.git] / src / snmp.c
index 0dad67c..3ba93fe 100644 (file)
@@ -22,6 +22,7 @@
 #include "collectd.h"
 #include "common.h"
 #include "plugin.h"
+#include "utils_complain.h"
 
 #include <pthread.h>
 
@@ -67,6 +68,7 @@ struct host_definition_s
   char *community;
   int version;
   void *sess_handle;
+  c_complain_t complaint;
   uint32_t interval;
   time_t next_update;
   data_definition_t **data_list;
@@ -116,6 +118,7 @@ static pthread_cond_t  host_cond = PTHREAD_COND_INITIALIZER;
 /*
  * Private functions
  */
+/* Many functions to handle the configuration. {{{ */
 /* First there are many functions which do configuration stuff. It's a big
  * bloated and messy, I'm afraid. */
 
@@ -551,6 +554,7 @@ static int csnmp_config_add_host (oconfig_item_t *ci)
     return (-1);
   memset (hd, '\0', sizeof (host_definition_t));
   hd->version = 2;
+  C_COMPLAIN_INIT (&hd->complaint);
 
   hd->name = strdup (ci->values[0].value.string);
   if (hd->name == NULL)
@@ -653,7 +657,7 @@ static int csnmp_config (oconfig_item_t *ci)
   return (0);
 } /* int csnmp_config */
 
-/* End of the config stuff. Now the interesting part begins */
+/* }}} End of the config stuff. Now the interesting part begins */
 
 static void csnmp_host_close_session (host_definition_t *host)
 {
@@ -729,22 +733,41 @@ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type,
 
   if (vl->type == ASN_OCTET_STR)
   {
-    char *string;
     char *endptr;
 
-    string = (char *) vl->val.string;
     endptr = NULL;
-
-    if (string != NULL)
+    if (vl->val.string != NULL)
     {
+      char string[64];
+      size_t string_length;
+
+      string_length = sizeof (string) - 1;
+      if (vl->val_len < string_length)
+       string_length = vl->val_len;
+
+      /* The strings we get from the Net-SNMP library may not be null
+       * terminated. That is why we're using `membpy' here and not `strcpy'.
+       * `string_length' is set to `vl->val_len' which holds the length of the
+       * string.  -octo */
+      memcpy (string, vl->val.string, string_length);
+      string[string_length] = 0;
+
       if (type == DS_TYPE_COUNTER)
+      {
        ret.counter = (counter_t) strtoll (string, &endptr, /* base = */ 0);
+       DEBUG ("snmp plugin: csnmp_value_list_to_value: String to counter: %s -> %llu",
+           string, (unsigned long long) ret.counter);
+      }
       else if (type == DS_TYPE_GAUGE)
+      {
        ret.gauge = (gauge_t) strtod (string, &endptr);
+       DEBUG ("snmp plugin: csnmp_value_list_to_value: String to gauge: %s -> %g",
+           string, (double) ret.gauge);
+      }
     }
 
     /* Check if an error occurred */
-    if ((string == NULL) || (endptr == string))
+    if ((vl->val.string == NULL) || (endptr == (char *) vl->val.string))
     {
       if (type == DS_TYPE_COUNTER)
        ret.counter = 0;
@@ -859,22 +882,15 @@ static int csnmp_instance_list_add (csnmp_list_instances_t **head,
     char *ptr;
     size_t instance_len;
 
+    memset (il->instance, 0, sizeof (il->instance));
     instance_len = sizeof (il->instance) - 1;
     if (instance_len > vb->val_len)
       instance_len = vb->val_len;
 
-    if (instance_len < 1)
-    {
-      ERROR ("snmp plugin: csnmp_instance_list_add: instance_len = %zu, "
-         "which is less than one.", instance_len);
-      sfree (il);
-      return (-1);
-    }
-
     sstrncpy (il->instance, (char *) ((vb->type == ASN_OCTET_STR)
          ? vb->val.string
          : vb->val.bitstring),
-       instance_len);
+       instance_len + 1);
 
     for (ptr = il->instance; *ptr != '\0'; ptr++)
     {
@@ -1134,7 +1150,9 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data)
       char *errstr = NULL;
 
       snmp_sess_error (host->sess_handle, NULL, NULL, &errstr);
-      ERROR ("snmp plugin: host %s: snmp_sess_synch_response failed: %s",
+
+      c_complain (LOG_ERR, &host->complaint,
+         "snmp plugin: host %s: snmp_sess_synch_response failed: %s",
          host->name, (errstr == NULL) ? "Unknown problem" : errstr);
 
       if (res != NULL)
@@ -1149,6 +1167,9 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data)
     }
     status = 0;
     assert (res != NULL);
+    c_release (LOG_INFO, &host->complaint,
+       "snmp plugin: host %s: snmp_sess_synch_response successful.",
+       host->name);
 
     vb = res->variables;
     if (vb == NULL)
@@ -1614,5 +1635,5 @@ void module_register (void)
 } /* void module_register */
 
 /*
- * vim: shiftwidth=2 softtabstop=2 tabstop=8
+ * vim: shiftwidth=2 softtabstop=2 tabstop=8 fdm=marker
  */