Code

Merge branch 'collectd-5.4' into collectd-5.5
authorFlorian Forster <octo@collectd.org>
Wed, 9 Dec 2015 08:49:55 +0000 (09:49 +0100)
committerFlorian Forster <octo@collectd.org>
Wed, 9 Dec 2015 08:49:55 +0000 (09:49 +0100)
1  2 
src/curl_json.c
src/curl_xml.c

diff --combined src/curl_json.c
index 3ba55603d329342e6a30fa86b6908531e3e36e73,5875feaef1c334b40aa56e2827c021713a0e5ac9..98ba0bb2ed9db58462fe465a6f8dbe902c17e6ae
@@@ -71,14 -71,11 +71,14 @@@ struct cj_s /* {{{ *
    char *user;
    char *pass;
    char *credentials;
 +  _Bool digest;
    _Bool verify_peer;
    _Bool verify_host;
    char *cacert;
    struct curl_slist *headers;
    char *post_body;
 +  cdtime_t interval;
 +  int timeout;
  
    CURL *curl;
    char curl_errbuf[CURL_ERROR_SIZE];
@@@ -232,7 -229,7 +232,7 @@@ static int cj_cb_number (void *ctx
    buffer[sizeof (buffer) - 1] = 0;
  
    if ((key == NULL) || !CJ_IS_KEY (key)) {
 -    if (key != NULL)
 +    if (key != NULL && !db->state[db->depth].in_array/*can be inhomogeneous*/)
        NOTICE ("curl_json plugin: Found \"%s\", but the configuration expects"
                " a map.", buffer);
      cj_cb_inc_array_index (ctx, /* update_key = */ 1);
@@@ -526,71 -523,68 +526,68 @@@ static int cj_config_add_key (cj_t *db
        break;
    } /* for (i = 0; i < ci->children_num; i++) */
  
-   while (status == 0)
+   if (status != 0)
    {
-     if (key->type == NULL)
-     {
-       WARNING ("curl_json plugin: `Type' missing in `Key' block.");
-       status = -1;
-     }
+     cj_key_free (key);
+     return (-1);
+   }
  
-     break;
-   } /* while (status == 0) */
+   if (key->type == NULL)
+   {
+     WARNING ("curl_json plugin: `Type' missing in `Key' block.");
+     cj_key_free (key);
+     return (-1);
+   }
  
    /* store path in a tree that will match the json map structure, example:
     * "httpd/requests/count",
     * "httpd/requests/current" ->
     * { "httpd": { "requests": { "count": $key, "current": $key } } }
     */
-   if (status == 0)
+   char *ptr;
+   char *name;
+   c_avl_tree_t *tree;
+   if (db->tree == NULL)
+     db->tree = cj_avl_create();
+   tree = db->tree;
+   ptr = key->path;
+   if (*ptr == '/')
+     ++ptr;
+   name = ptr;
+   while ((ptr = strchr (name, '/')) != NULL)
    {
-     char *ptr;
-     char *name;
      char ent[PATH_MAX];
-     c_avl_tree_t *tree;
+     c_avl_tree_t *value;
+     size_t len;
  
-     if (db->tree == NULL)
-       db->tree = cj_avl_create();
+     len = ptr - name;
+     if (len == 0)
+       break;
  
-     tree = db->tree;
-     ptr = key->path;
-     if (*ptr == '/')
-       ++ptr;
+     len = COUCH_MIN(len, sizeof (ent)-1);
+     sstrncpy (ent, name, len+1);
  
-     name = ptr;
-     while (*ptr)
-     {
-       if (*ptr == '/')
-       {
-         c_avl_tree_t *value;
-         int len;
-         len = ptr-name;
-         if (len == 0)
-           break;
-         len = COUCH_MIN(len, sizeof (ent)-1);
-         sstrncpy (ent, name, len+1);
-         if (c_avl_get (tree, ent, (void *) &value) != 0)
-         {
-           value = cj_avl_create ();
-           c_avl_insert (tree, strdup (ent), value);
-         }
-         tree = value;
-         name = ptr+1;
-       }
-       ++ptr;
-     }
-     if (*name)
-       c_avl_insert (tree, strdup(name), key);
-     else
+     if (c_avl_get (tree, ent, (void *) &value) != 0)
      {
-       ERROR ("curl_json plugin: invalid key: %s", key->path);
-       status = -1;
+       value = cj_avl_create ();
+       c_avl_insert (tree, strdup (ent), value);
      }
+     tree = value;
+     name = ptr + 1;
+   }
+   if (strlen (name) == 0)
+   {
+     ERROR ("curl_json plugin: invalid key: %s", key->path);
+     cj_key_free (key);
+     return (-1);
    }
  
+   c_avl_insert (tree, strdup (name), key);
    return (status);
  } /* }}} int cj_config_add_key */
  
@@@ -606,19 -600,13 +603,19 @@@ static int cj_init_curl (cj_t *db) /* {
    curl_easy_setopt (db->curl, CURLOPT_NOSIGNAL, 1L);
    curl_easy_setopt (db->curl, CURLOPT_WRITEFUNCTION, cj_curl_callback);
    curl_easy_setopt (db->curl, CURLOPT_WRITEDATA, db);
 -  curl_easy_setopt (db->curl, CURLOPT_USERAGENT,
 -                    PACKAGE_NAME"/"PACKAGE_VERSION);
 +  curl_easy_setopt (db->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT);
    curl_easy_setopt (db->curl, CURLOPT_ERRORBUFFER, db->curl_errbuf);
    curl_easy_setopt (db->curl, CURLOPT_URL, db->url);
 +  curl_easy_setopt (db->curl, CURLOPT_FOLLOWLOCATION, 1L);
 +  curl_easy_setopt (db->curl, CURLOPT_MAXREDIRS, 50L);
  
    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;
      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_SSL_VERIFYPEER, (long) db->verify_peer);
    if (db->post_body != NULL)
      curl_easy_setopt (db->curl, CURLOPT_POSTFIELDS, db->post_body);
  
 +#ifdef HAVE_CURLOPT_TIMEOUT_MS
 +  if (db->timeout >= 0)
 +    curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) db->timeout);
 +  else if (db->interval > 0)
 +    curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS,
 +        CDTIME_T_TO_MS(db->timeout));
 +  else
 +    curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS,
 +        CDTIME_T_TO_MS(plugin_get_interval()));
 +#endif
 +
    return (0);
  } /* }}} int cj_init_curl */
  
@@@ -687,8 -660,6 +684,8 @@@ static int cj_config_add_url (oconfig_i
    }
    memset (db, 0, sizeof (*db));
  
 +  db->timeout = -1;
 +
    if (strcasecmp ("URL", ci->key) == 0)
      status = cf_util_get_string (ci, &db->url);
    else if (strcasecmp ("Sock", ci->key) == 0)
        status = cf_util_get_string (child, &db->user);
      else if (db->url && strcasecmp ("Password", child->key) == 0)
        status = cf_util_get_string (child, &db->pass);
 +    else if (strcasecmp ("Digest", child->key) == 0)
 +      status = cf_util_get_boolean (child, &db->digest);
      else if (db->url && strcasecmp ("VerifyPeer", child->key) == 0)
        status = cf_util_get_boolean (child, &db->verify_peer);
      else if (db->url && strcasecmp ("VerifyHost", child->key) == 0)
        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 if (strcasecmp ("Timeout", child->key) == 0)
 +      status = cf_util_get_int (child, &db->timeout);
      else
      {
        WARNING ("curl_json plugin: Option `%s' not allowed here.", child->key);
    {
      user_data_t ud;
      char *cb_name;
 +    struct timespec interval = { 0, 0 };
 +
 +    CDTIME_T_TO_TIMESPEC (db->interval, &interval);
  
      if (db->instance == NULL)
        db->instance = strdup("default");
      cb_name = ssnprintf_alloc ("curl_json-%s-%s",
                 db->instance, db->url ? db->url : db->sock);
  
 -    plugin_register_complex_read (/* group = */ "curl_json", cb_name, cj_read,
 -                                  /* interval = */ NULL, &ud);
 +    plugin_register_complex_read (/* group = */ NULL, cb_name, cj_read,
 +                                  /* interval = */ (db->interval > 0) ? &interval : NULL,
 +                                  &ud);
      sfree (cb_name);
    }
    else
@@@ -854,10 -815,11 +851,10 @@@ static void cj_submit (cj_t *db, cj_key
  
    if (key->instance == NULL)
    {
 -    if ((db->depth == 0) || (strcmp ("", db->state[db->depth-1].name) == 0))
 -      sstrncpy (vl.type_instance, db->state[db->depth].name, sizeof (vl.type_instance));
 -    else
 -      ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%s-%s",
 -          db->state[db->depth-1].name, db->state[db->depth].name);
 +    int i, len = 0;
 +    for (i = 0; i < db->depth; i++)
 +      len += ssnprintf(vl.type_instance+len, sizeof(vl.type_instance)-len,
 +                       i ? "-%s" : "%s", db->state[i+1].name);
    }
    else
      sstrncpy (vl.type_instance, key->instance, sizeof (vl.type_instance));
    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 */
  
diff --combined src/curl_xml.c
index efaf290e7af80f77b7cf89687f67ca061e947c2c,d34b69efee25a4af6c050470117c03535399bf90..3ffb71c559c77d3f00d5f8027880646be0f7c2be
@@@ -76,12 -76,10 +76,12 @@@ struct cx_s /* {{{ *
    char *user;
    char *pass;
    char *credentials;
 +  _Bool digest;
    _Bool verify_peer;
    _Bool verify_host;
    char *cacert;
    char *post_body;
 +  int timeout;
    struct curl_slist *headers;
  
    cx_namespace_t *namespaces;
@@@ -701,14 -699,15 +701,15 @@@ static int cx_config_add_values (const 
    return (0);
  } /* }}} cx_config_add_values */
  
- static int cx_config_add_xpath (cx_t *db, /* {{{ */
-                                    oconfig_item_t *ci)
+ static int cx_config_add_xpath (cx_t *db, oconfig_item_t *ci) /* {{{ */
  {
    cx_xpath_t *xpath;
+   char *name;
+   llentry_t *le;
    int status;
    int i;
  
-   xpath = (cx_xpath_t *) malloc (sizeof (*xpath));
+   xpath = malloc (sizeof (*xpath));
    if (xpath == NULL)
    {
      ERROR ("curl_xml plugin: malloc failed.");
    status = cf_util_get_string (ci, &xpath->path);
    if (status != 0)
    {
-     sfree (xpath);
+     cx_xpath_free (xpath);
      return (status);
    }
  
    /* error out if xpath->path is an empty string */
-   if (*xpath->path == 0)
+   if (strlen (xpath->path) == 0)
    {
      ERROR ("curl_xml plugin: invalid xpath. "
             "xpath value can't be an empty string");
-     sfree (xpath);
+     cx_xpath_free (xpath);
      return (-1);
    }
  
        break;
    } /* for (i = 0; i < ci->children_num; i++) */
  
-   if (status == 0 && xpath->type == NULL)
+   if (status != 0)
    {
-     WARNING ("curl_xml plugin: `Type' missing in `xpath' block.");
-     status = -1;
+     cx_xpath_free (xpath);
+     return status;
    }
  
-   if (status == 0)
+   if (xpath->type == NULL)
    {
-     char *name;
-     llentry_t *le;
+     WARNING ("curl_xml plugin: `Type' missing in `xpath' block.");
+     cx_xpath_free (xpath);
+     return -1;
+   }
  
+   if (db->list == NULL)
+   {
+     db->list = llist_create();
      if (db->list == NULL)
      {
-       db->list = llist_create();
-       if (db->list == NULL)
-       {
-         ERROR ("curl_xml plugin: list creation failed.");
-         sfree (xpath->path);
-         sfree (xpath);
-         return (-1);
-       }
-     }
-     name = strdup(xpath->path);
-     if (name == NULL)
-     {
-         ERROR ("curl_xml plugin: strdup failed.");
-         sfree (xpath->path);
-         sfree (xpath);
-         return (-1);
-     }
-     le = llentry_create (name, xpath);
-     if (le == NULL)
-     {
-       ERROR ("curl_xml plugin: llentry_create failed.");
-       sfree (xpath->path);
-       sfree (xpath);
+       ERROR ("curl_xml plugin: list creation failed.");
+       cx_xpath_free (xpath);
        return (-1);
      }
+   }
+   name = strdup (xpath->path);
+   if (name == NULL)
+   {
+     ERROR ("curl_xml plugin: strdup failed.");
+     cx_xpath_free (xpath);
+     return (-1);
+   }
  
-     llist_append (db->list, le);
+   le = llentry_create (name, xpath);
+   if (le == NULL)
+   {
+     ERROR ("curl_xml plugin: llentry_create failed.");
+     cx_xpath_free (xpath);
+     sfree (name);
+     return (-1);
    }
  
-   return (status);
+   llist_append (db->list, le);
+   return (0);
  } /* }}} int cx_config_add_xpath */
  
  static int cx_config_add_namespace (cx_t *db, /* {{{ */
@@@ -855,19 -852,13 +854,19 @@@ static int cx_init_curl (cx_t *db) /* {
    curl_easy_setopt (db->curl, CURLOPT_NOSIGNAL, 1L);
    curl_easy_setopt (db->curl, CURLOPT_WRITEFUNCTION, cx_curl_callback);
    curl_easy_setopt (db->curl, CURLOPT_WRITEDATA, db);
 -  curl_easy_setopt (db->curl, CURLOPT_USERAGENT,
 -                    PACKAGE_NAME"/"PACKAGE_VERSION);
 +  curl_easy_setopt (db->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT);
    curl_easy_setopt (db->curl, CURLOPT_ERRORBUFFER, db->curl_errbuf);
    curl_easy_setopt (db->curl, CURLOPT_URL, db->url);
 +  curl_easy_setopt (db->curl, CURLOPT_FOLLOWLOCATION, 1L);
 +  curl_easy_setopt (db->curl, CURLOPT_MAXREDIRS, 50L);
  
    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;
      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_SSL_VERIFYPEER, db->verify_peer ? 1L : 0L);
    if (db->post_body != NULL)
      curl_easy_setopt (db->curl, CURLOPT_POSTFIELDS, db->post_body);
  
 +#ifdef HAVE_CURLOPT_TIMEOUT_MS
 +  if (db->timeout >= 0)
 +    curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) db->timeout);
 +  else
 +    curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS,
 +       CDTIME_T_TO_MS(plugin_get_interval()));
 +#endif
 +
    return (0);
  } /* }}} int cx_init_curl */
  
@@@ -933,8 -912,6 +932,8 @@@ static int cx_config_add_url (oconfig_i
    }
    memset (db, 0, sizeof (*db));
  
 +  db->timeout = -1;
 +
    if (strcasecmp ("URL", ci->key) == 0)
    {
      status = cf_util_get_string (ci, &db->url);
        status = cf_util_get_string (child, &db->user);
      else if (strcasecmp ("Password", child->key) == 0)
        status = cf_util_get_string (child, &db->pass);
 +    else if (strcasecmp ("Digest", child->key) == 0)
 +      status = cf_util_get_boolean (child, &db->digest);
      else if (strcasecmp ("VerifyPeer", child->key) == 0)
        status = cf_util_get_boolean (child, &db->verify_peer);
      else if (strcasecmp ("VerifyHost", child->key) == 0)
        status = cf_util_get_string (child, &db->post_body);
      else if (strcasecmp ("Namespace", child->key) == 0)
        status = cx_config_add_namespace (db, child);
 +    else if (strcasecmp ("Timeout", child->key) == 0)
 +      status = cf_util_get_int (child, &db->timeout);
      else
      {
        WARNING ("curl_xml plugin: Option `%s' not allowed here.", child->key);