src/plugin.c: Move the error-checking code up.
[collectd.git] / src / curl_json.c
index 3ad80a2..5549f0a 100644 (file)
@@ -32,7 +32,7 @@
 
 #define CJ_DEFAULT_HOST "localhost"
 #define CJ_KEY_MAGIC 0x43484b59UL /* CHKY */
-#define CJ_IS_KEY(key) (key)->magic == CJ_KEY_MAGIC
+#define CJ_IS_KEY(key) ((key)->magic == CJ_KEY_MAGIC)
 #define CJ_ANY "*"
 #define COUCH_MIN(x,y) ((x) < (y) ? (x) : (y))
 
@@ -136,39 +136,21 @@ static int cj_cb_number (void *ctx,
 
   cj_t *db = (cj_t *)ctx;
   cj_key_t *key = db->state[db->depth].key;
-  char *endptr;
   value_t vt;
   int type;
+  int status;
 
-  if (key == NULL)
+  if ((key == NULL) || !CJ_IS_KEY (key))
     return (CJ_CB_CONTINUE);
 
   memcpy (buffer, number, number_len);
   buffer[sizeof (buffer) - 1] = 0;
 
   type = cj_get_type (key);
-
-  endptr = NULL;
-  errno = 0;
-
-  if (type == DS_TYPE_COUNTER)
-    vt.counter = (counter_t) strtoull (buffer, &endptr, /* base = */ 0);
-  else if (type == DS_TYPE_GAUGE)
-    vt.gauge = (gauge_t) strtod (buffer, &endptr);
-  else if (type == DS_TYPE_DERIVE)
-    vt.derive = (derive_t) strtoll (buffer, &endptr, /* base = */ 0);
-  else if (type == DS_TYPE_ABSOLUTE)
-    vt.absolute = (absolute_t) strtoull (buffer, &endptr, /* base = */ 0);
-  else
-  {
-    ERROR ("curl_json plugin: Unknown data source type: \"%s\"", key->type);
-    return (CJ_CB_ABORT);
-  }
-
-  if ((endptr == &buffer[0]) || (errno != 0))
+  status = parse_value (buffer, &vt, type);
+  if (status != 0)
   {
-    NOTICE ("curl_json plugin: Overflow while parsing number. "
-        "Ignoring this value.");
+    NOTICE ("curl_json plugin: Unable to parse number: \"%s\"", buffer);
     return (CJ_CB_CONTINUE);
   }
 
@@ -208,34 +190,26 @@ static int cj_cb_string (void *ctx, const unsigned char *val,
                            unsigned int len)
 {
   cj_t *db = (cj_t *)ctx;
-  c_avl_tree_t *tree;
-  char *ptr;
-
-  if (db->depth != 1) /* e.g. _all_dbs */
-    return (CJ_CB_CONTINUE);
+  char str[len + 1];
 
-  cj_cb_map_key (ctx, val, len); /* same logic */
+  /* Create a null-terminated version of the string. */
+  memcpy (str, val, len);
+  str[len] = 0;
 
-  tree = db->state[db->depth].tree;
+  /* No configuration for this string -> simply return. */
+  if (db->state[db->depth].key == NULL)
+    return (CJ_CB_CONTINUE);
 
-  if ((tree != NULL) && (ptr = rindex (db->url, '/')))
+  if (!CJ_IS_KEY (db->state[db->depth].key))
   {
-    char url[PATH_MAX];
-    CURL *curl;
-
-    /* url =~ s,[^/]+$,$name, */
-    len = (ptr - db->url) + 1;
-    ptr = url;
-    sstrncpy (ptr, db->url, sizeof (url));
-    sstrncpy (ptr + len, db->state[db->depth].name, sizeof (url) - len);
-
-    curl = curl_easy_duphandle (db->curl);
-    curl_easy_setopt (curl, CURLOPT_URL, url);
-    cj_curl_perform (db, curl);
-    curl_easy_cleanup (curl);
+    NOTICE ("curl_json plugin: Found string \"%s\", but the configuration "
+        "expects a map here.", str);
+    return (CJ_CB_CONTINUE);
   }
-  return (CJ_CB_CONTINUE);
-}
+
+  /* Handle the string as if it was a number. */
+  return (cj_cb_number (ctx, (const char *) val, len));
+} /* int cj_cb_string */
 
 static int cj_cb_start (void *ctx)
 {
@@ -273,7 +247,7 @@ static int cj_cb_start_array (void * ctx)
 
 static int cj_cb_end_array (void * ctx)
 {
-  return cj_cb_start (ctx);
+  return cj_cb_end (ctx);
 }
 
 static yajl_callbacks ycallbacks = {
@@ -731,17 +705,19 @@ static int cj_curl_perform (cj_t *db, CURL *curl) /* {{{ */
     return (-1);
   }
 
+  url = NULL;
+  curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url);
+
   status = curl_easy_perform (curl);
   if (status != 0)
   {
     ERROR ("curl_json plugin: curl_easy_perform failed with status %i: %s (%s)",
-           status, db->curl_errbuf, url);
+           status, db->curl_errbuf, (url != NULL) ? url : "<null>");
     yajl_free (db->yajl);
     db->yajl = yprev;
     return (-1);
   }
 
-  curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url);
   curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &rc);
 
   /* The response code is zero if a non-HTTP transport was used. */