Merge branch 'collectd-5.4'
[collectd.git] / src / curl_json.c
index 029c802..e99500a 100644 (file)
@@ -77,6 +77,7 @@ struct cj_s /* {{{ */
   char *cacert;
   struct curl_slist *headers;
   char *post_body;
+  cdtime_t interval;
 
   CURL *curl;
   char curl_errbuf[CURL_ERROR_SIZE];
@@ -233,9 +234,14 @@ static int cj_cb_number (void *ctx,
     if (key != NULL)
       NOTICE ("curl_json plugin: Found \"%s\", but the configuration expects"
               " a map.", buffer);
-    cj_cb_inc_array_index (ctx, /* update_key = */ 0);
-    return (CJ_CB_CONTINUE);
-  } else {
+    cj_cb_inc_array_index (ctx, /* update_key = */ 1);
+    key = db->state[db->depth].key;
+    if (key == NULL) {
+      return (CJ_CB_CONTINUE);
+    }
+  }
+  else
+  {
     cj_cb_inc_array_index (ctx, /* update_key = */ 1);
   }
 
@@ -275,10 +281,21 @@ static int cj_cb_map_key (void *ctx,
     memcpy (name, in_name, name_len);
     name[name_len] = 0;
 
-    if (c_avl_get (tree, name, (void *) &value) == 0)
-      db->state[db->depth].key = value;
+    if (c_avl_get (tree, name, (void *) &value) == 0) {
+      if (CJ_IS_KEY((cj_key_t*)value)) {
+        db->state[db->depth].key = value;
+      }
+      else {
+        db->state[db->depth].tree = (c_avl_tree_t*) value;
+      }
+    }
     else if (c_avl_get (tree, CJ_ANY, (void *) &value) == 0)
-      db->state[db->depth].key = value;
+      if (CJ_IS_KEY((cj_key_t*)value)) {
+        db->state[db->depth].key = value;
+      }
+      else {
+        db->state[db->depth].tree = (c_avl_tree_t*) value;
+      }
     else
       db->state[db->depth].key = NULL;
   }
@@ -594,6 +611,11 @@ static int cj_init_curl (cj_t *db) /* {{{ */
 
   if (db->user != NULL)
   {
+#ifdef HAVE_CURLOPT_USERNAME
+    curl_easy_setopt (db->curl, CURLOPT_USERNAME, db->user);
+    curl_easy_setopt (db->curl, CURLOPT_PASSWORD,
+        (db->pass == NULL) ? "" : db->pass);
+#else
     size_t credentials_size;
 
     credentials_size = strlen (db->user) + 2;
@@ -610,13 +632,10 @@ static int cj_init_curl (cj_t *db) /* {{{ */
     ssnprintf (db->credentials, credentials_size, "%s:%s",
                db->user, (db->pass == NULL) ? "" : db->pass);
     curl_easy_setopt (db->curl, CURLOPT_USERPWD, db->credentials);
-    
+#endif
+
     if (db->digest)
-    {
       curl_easy_setopt (db->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
-      curl_easy_setopt (db->curl, CURLOPT_USERNAME, db->user);
-      curl_easy_setopt (db->curl, CURLOPT_PASSWORD, db->pass);
-    }
   }
 
   curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYPEER, (long) db->verify_peer);
@@ -697,6 +716,8 @@ static int cj_config_add_url (oconfig_item_t *ci) /* {{{ */
       status = cf_util_get_string (child, &db->post_body);
     else if (strcasecmp ("Key", child->key) == 0)
       status = cj_config_add_key (db, child);
+    else if (strcasecmp ("Interval", child->key) == 0)
+      status = cf_util_get_cdtime(child, &db->interval);
     else
     {
       WARNING ("curl_json plugin: Option `%s' not allowed here.", child->key);
@@ -723,7 +744,10 @@ static int cj_config_add_url (oconfig_item_t *ci) /* {{{ */
   if (status == 0)
   {
     user_data_t ud;
-    char cb_name[DATA_MAX_NAME_LEN];
+    char *cb_name;
+    struct timespec interval = { 0, 0 };
+
+    CDTIME_T_TO_TIMESPEC (db->interval, &interval);
 
     if (db->instance == NULL)
       db->instance = strdup("default");
@@ -735,11 +759,13 @@ static int cj_config_add_url (oconfig_item_t *ci) /* {{{ */
     ud.data = (void *) db;
     ud.free_func = cj_free;
 
-    ssnprintf (cb_name, sizeof (cb_name), "curl_json-%s-%s",
+    cb_name = ssnprintf_alloc ("curl_json-%s-%s",
                db->instance, db->url ? db->url : db->sock);
 
     plugin_register_complex_read (/* group = */ NULL, cb_name, cj_read,
-                                  /* interval = */ NULL, &ud);
+                                  /* interval = */ (db->interval > 0) ? &interval : NULL,
+                                  &ud);
+    sfree (cb_name);
   }
   else
   {
@@ -822,6 +848,9 @@ static void cj_submit (cj_t *db, cj_key_t *key, value_t *value) /* {{{ */
   sstrncpy (vl.plugin_instance, db->instance, sizeof (vl.plugin_instance));
   sstrncpy (vl.type, key->type, sizeof (vl.type));
 
+  if (db->interval > 0)
+    vl.interval = db->interval;
+
   plugin_dispatch_values (&vl);
 } /* }}} int cj_submit */
 
@@ -965,9 +994,18 @@ static int cj_read (user_data_t *ud) /* {{{ */
   return cj_perform (db);
 } /* }}} int cj_read */
 
+static int cj_init (void) /* {{{ */
+{
+  /* Call this while collectd is still single-threaded to avoid
+   * initialization issues in libgcrypt. */
+  curl_global_init (CURL_GLOBAL_SSL);
+  return (0);
+} /* }}} int cj_init */
+
 void module_register (void)
 {
   plugin_register_complex_config ("curl_json", cj_config);
+  plugin_register_init ("curl_json", cj_init);
 } /* void module_register */
 
 /* vim: set sw=2 sts=2 et fdm=marker : */