Merge branch 'collectd-5.8'
[collectd.git] / src / curl_json.c
index 181f18b..f0badc9 100644 (file)
@@ -74,7 +74,7 @@ typedef struct {
  * exists for this part of the JSON structure. */
 typedef struct {
   cj_tree_entry_t *entry;
-  _Bool in_array;
+  bool in_array;
   int index;
   char name[DATA_MAX_NAME_LEN];
 } cj_state_t;
@@ -82,6 +82,7 @@ typedef struct {
 struct cj_s /* {{{ */
 {
   char *instance;
+  char *plugin_name;
   char *host;
 
   char *sock;
@@ -90,9 +91,9 @@ struct cj_s /* {{{ */
   char *user;
   char *pass;
   char *credentials;
-  _Bool digest;
-  _Bool verify_peer;
-  _Bool verify_host;
+  bool digest;
+  bool verify_peer;
+  bool verify_host;
   char *cacert;
   struct curl_slist *headers;
   char *post_body;
@@ -132,18 +133,18 @@ static size_t cj_curl_callback(void *buf, /* {{{ */
   len = size * nmemb;
 
   if (len == 0)
-    return (len);
+    return len;
 
   db = user_data;
   if (db == NULL)
-    return (0);
+    return 0;
 
   status = yajl_parse(db->yajl, (unsigned char *)buf, len);
   if (status == yajl_status_ok)
-    return (len);
+    return len;
 #if !HAVE_YAJL_V2
   else if (status == yajl_status_insufficient_data)
-    return (len);
+    return len;
 #endif
 
   unsigned char *msg =
@@ -151,7 +152,7 @@ static size_t cj_curl_callback(void *buf, /* {{{ */
                      /* jsonText = */ (unsigned char *)buf, (unsigned int)len);
   ERROR("curl_json plugin: yajl_parse failed: %s", msg);
   yajl_free_error(db->yajl, msg);
-  return (0); /* abort write callback */
+  return 0; /* abort write callback */
 } /* }}} size_t cj_curl_callback */
 
 static int cj_get_type(cj_key_t *key) {
@@ -217,7 +218,7 @@ static void cj_advance_array(cj_t *db) {
   db->state[db->depth].index++;
 
   char name[DATA_MAX_NAME_LEN];
-  ssnprintf(name, sizeof(name), "%d", db->state[db->depth].index);
+  snprintf(name, sizeof(name), "%d", db->state[db->depth].index);
   cj_load_key(db, name);
 }
 
@@ -225,14 +226,9 @@ static void cj_advance_array(cj_t *db) {
 #define CJ_CB_ABORT 0
 #define CJ_CB_CONTINUE 1
 
-static int cj_cb_boolean(void *ctx, int boolVal) {
-  cj_advance_array(ctx);
-  return (CJ_CB_CONTINUE);
-}
-
 static int cj_cb_null(void *ctx) {
   cj_advance_array(ctx);
-  return (CJ_CB_CONTINUE);
+  return CJ_CB_CONTINUE;
 }
 
 static int cj_cb_number(void *ctx, const char *number, yajl_len_t number_len) {
@@ -262,12 +258,12 @@ static int cj_cb_number(void *ctx, const char *number, yajl_len_t number_len) {
   if (status != 0) {
     NOTICE("curl_json plugin: Unable to parse number: \"%s\"", buffer);
     cj_advance_array(ctx);
-    return (CJ_CB_CONTINUE);
+    return CJ_CB_CONTINUE;
   }
 
   cj_submit(db, key, &vt);
   cj_advance_array(ctx);
-  return (CJ_CB_CONTINUE);
+  return CJ_CB_CONTINUE;
 } /* int cj_cb_number */
 
 /* Queries the key-tree of the parent context for "in_name" and, if found,
@@ -288,15 +284,22 @@ static int cj_cb_map_key(void *ctx, unsigned char const *in_name,
 
 static int cj_cb_string(void *ctx, const unsigned char *val, yajl_len_t len) {
   /* Handle the string as if it was a number. */
-  return (cj_cb_number(ctx, (const char *)val, len));
+  return cj_cb_number(ctx, (const char *)val, len);
 } /* int cj_cb_string */
 
+static int cj_cb_boolean(void *ctx, int boolVal) {
+  if (boolVal)
+    return cj_cb_number(ctx, "1", 1);
+  else
+    return cj_cb_number(ctx, "0", 1);
+} /* int cj_cb_boolean */
+
 static int cj_cb_end(void *ctx) {
   cj_t *db = (cj_t *)ctx;
   memset(&db->state[db->depth], 0, sizeof(db->state[db->depth]));
   db->depth--;
   cj_advance_array(ctx);
-  return (CJ_CB_CONTINUE);
+  return CJ_CB_CONTINUE;
 }
 
 static int cj_cb_start_map(void *ctx) {
@@ -305,10 +308,10 @@ static int cj_cb_start_map(void *ctx) {
   if ((db->depth + 1) >= YAJL_MAX_DEPTH) {
     ERROR("curl_json plugin: %s depth exceeds max, aborting.",
           db->url ? db->url : db->sock);
-    return (CJ_CB_ABORT);
+    return CJ_CB_ABORT;
   }
   db->depth++;
-  return (CJ_CB_CONTINUE);
+  return CJ_CB_CONTINUE;
 }
 
 static int cj_cb_end_map(void *ctx) { return cj_cb_end(ctx); }
@@ -322,7 +325,7 @@ static int cj_cb_start_array(void *ctx) {
     return CJ_CB_ABORT;
   }
   db->depth++;
-  db->state[db->depth].in_array = 1;
+  db->state[db->depth].in_array = true;
   db->state[db->depth].index = 0;
 
   cj_load_key(db, "0");
@@ -332,7 +335,7 @@ static int cj_cb_start_array(void *ctx) {
 
 static int cj_cb_end_array(void *ctx) {
   cj_t *db = (cj_t *)ctx;
-  db->state[db->depth].in_array = 0;
+  db->state[db->depth].in_array = false;
   return cj_cb_end(ctx);
 }
 
@@ -396,6 +399,7 @@ static void cj_free(void *arg) /* {{{ */
   db->tree = NULL;
 
   sfree(db->instance);
+  sfree(db->plugin_name);
   sfree(db->host);
 
   sfree(db->sock);
@@ -424,16 +428,16 @@ static int cj_config_append_string(const char *name,
   struct curl_slist *temp = NULL;
   if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
     WARNING("curl_json plugin: `%s' needs exactly one string argument.", name);
-    return (-1);
+    return -1;
   }
 
   temp = curl_slist_append(*dest, ci->values[0].value.string);
   if (temp == NULL)
-    return (-1);
+    return -1;
 
   *dest = temp;
 
-  return (0);
+  return 0;
 } /* }}} int cj_config_append_string */
 
 /* cj_append_key adds key to the configuration stored in db.
@@ -505,27 +509,27 @@ static int cj_config_add_key(cj_t *db, /* {{{ */
   if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
     WARNING("curl_json plugin: The `Key' block "
             "needs exactly one string argument.");
-    return (-1);
+    return -1;
   }
 
   key = calloc(1, sizeof(*key));
   if (key == NULL) {
     ERROR("curl_json plugin: calloc failed.");
-    return (-1);
+    return -1;
   }
 
   if (strcasecmp("Key", ci->key) == 0) {
     status = cf_util_get_string(ci, &key->path);
     if (status != 0) {
       sfree(key);
-      return (status);
+      return status;
     }
   } else {
     ERROR("curl_json plugin: cj_config: "
           "Invalid key: %s",
           ci->key);
     cj_key_free(key);
-    return (-1);
+    return -1;
   }
 
   status = 0;
@@ -547,13 +551,13 @@ static int cj_config_add_key(cj_t *db, /* {{{ */
 
   if (status != 0) {
     cj_key_free(key);
-    return (-1);
+    return -1;
   }
 
   if (key->type == NULL) {
     WARNING("curl_json plugin: `Type' missing in `Key' block.");
     cj_key_free(key);
-    return (-1);
+    return -1;
   }
 
   status = cj_append_key(db, key);
@@ -570,7 +574,7 @@ static int cj_init_curl(cj_t *db) /* {{{ */
   db->curl = curl_easy_init();
   if (db->curl == NULL) {
     ERROR("curl_json plugin: curl_easy_init failed.");
-    return (-1);
+    return -1;
   }
 
   curl_easy_setopt(db->curl, CURLOPT_NOSIGNAL, 1L);
@@ -578,7 +582,6 @@ static int cj_init_curl(cj_t *db) /* {{{ */
   curl_easy_setopt(db->curl, CURLOPT_WRITEDATA, db);
   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);
 
@@ -597,11 +600,11 @@ static int cj_init_curl(cj_t *db) /* {{{ */
     db->credentials = malloc(credentials_size);
     if (db->credentials == NULL) {
       ERROR("curl_json plugin: malloc failed.");
-      return (-1);
+      return -1;
     }
 
-    ssnprintf(db->credentials, credentials_size, "%s:%s", db->user,
-              (db->pass == NULL) ? "" : db->pass);
+    snprintf(db->credentials, credentials_size, "%s:%s", db->user,
+             (db->pass == NULL) ? "" : db->pass);
     curl_easy_setopt(db->curl, CURLOPT_USERPWD, db->credentials);
 #endif
 
@@ -629,7 +632,7 @@ static int cj_init_curl(cj_t *db) /* {{{ */
                      (long)CDTIME_T_TO_MS(plugin_get_interval()));
 #endif
 
-  return (0);
+  return 0;
 } /* }}} int cj_init_curl */
 
 static int cj_config_add_url(oconfig_item_t *ci) /* {{{ */
@@ -640,13 +643,13 @@ static int cj_config_add_url(oconfig_item_t *ci) /* {{{ */
   if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
     WARNING("curl_json plugin: The `URL' block "
             "needs exactly one string argument.");
-    return (-1);
+    return -1;
   }
 
   db = calloc(1, sizeof(*db));
   if (db == NULL) {
     ERROR("curl_json plugin: calloc failed.");
-    return (-1);
+    return -1;
   }
 
   db->timeout = -1;
@@ -660,11 +663,11 @@ static int cj_config_add_url(oconfig_item_t *ci) /* {{{ */
           "Invalid key: %s",
           ci->key);
     cj_free(db);
-    return (-1);
+    return -1;
   }
   if (status != 0) {
     sfree(db);
-    return (status);
+    return status;
   }
 
   /* Fill the `cj_t' structure.. */
@@ -673,6 +676,8 @@ static int cj_config_add_url(oconfig_item_t *ci) /* {{{ */
 
     if (strcasecmp("Instance", child->key) == 0)
       status = cf_util_get_string(child, &db->instance);
+    else if (strcasecmp("Plugin", child->key) == 0)
+      status = cf_util_get_string(child, &db->plugin_name);
     else if (strcasecmp("Host", child->key) == 0)
       status = cf_util_get_string(child, &db->host);
     else if (db->url && strcasecmp("User", child->key) == 0)
@@ -740,10 +745,10 @@ static int cj_config_add_url(oconfig_item_t *ci) /* {{{ */
     sfree(cb_name);
   } else {
     cj_free(db);
-    return (-1);
+    return -1;
   }
 
-  return (0);
+  return 0;
 }
 /* }}} int cj_config_add_database */
 
@@ -774,10 +779,10 @@ static int cj_config(oconfig_item_t *ci) /* {{{ */
 
   if ((success == 0) && (errors > 0)) {
     ERROR("curl_json plugin: All statements failed.");
-    return (-1);
+    return -1;
   }
 
-  return (0);
+  return 0;
 } /* }}} int cj_config */
 
 /* }}} End of configuration handling functions */
@@ -800,13 +805,14 @@ static void cj_submit_impl(cj_t *db, cj_key_t *key, value_t *value) /* {{{ */
   if (key->instance == NULL) {
     int len = 0;
     for (int 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);
+      len += snprintf(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.host, cj_host(db), sizeof(vl.host));
-  sstrncpy(vl.plugin, "curl_json", sizeof(vl.plugin));
+  sstrncpy(vl.plugin, (db->plugin_name != NULL) ? db->plugin_name : "curl_json",
+           sizeof(vl.plugin));
   sstrncpy(vl.plugin_instance, db->instance, sizeof(vl.plugin_instance));
   sstrncpy(vl.type, key->type, sizeof(vl.type));
 
@@ -818,7 +824,6 @@ static void cj_submit_impl(cj_t *db, cj_key_t *key, value_t *value) /* {{{ */
 
 static int cj_sock_perform(cj_t *db) /* {{{ */
 {
-  char errbuf[1024];
   struct sockaddr_un sa_unix = {
       .sun_family = AF_UNIX,
   };
@@ -826,13 +831,12 @@ static int cj_sock_perform(cj_t *db) /* {{{ */
 
   int fd = socket(AF_UNIX, SOCK_STREAM, 0);
   if (fd < 0)
-    return (-1);
+    return -1;
   if (connect(fd, (struct sockaddr *)&sa_unix, sizeof(sa_unix)) < 0) {
     ERROR("curl_json plugin: connect(%s) failed: %s",
-          (db->sock != NULL) ? db->sock : "<null>",
-          sstrerror(errno, errbuf, sizeof(errbuf)));
+          (db->sock != NULL) ? db->sock : "<null>", STRERRNO);
     close(fd);
-    return (-1);
+    return -1;
   }
 
   ssize_t red;
@@ -841,16 +845,15 @@ static int cj_sock_perform(cj_t *db) /* {{{ */
     red = read(fd, buffer, sizeof(buffer));
     if (red < 0) {
       ERROR("curl_json plugin: read(%s) failed: %s",
-            (db->sock != NULL) ? db->sock : "<null>",
-            sstrerror(errno, errbuf, sizeof(errbuf)));
+            (db->sock != NULL) ? db->sock : "<null>", STRERRNO);
       close(fd);
-      return (-1);
+      return -1;
     }
     if (!cj_curl_callback(buffer, red, 1, db))
       break;
   } while (red > 0);
   close(fd);
-  return (0);
+  return 0;
 } /* }}} int cj_sock_perform */
 
 static int cj_curl_perform(cj_t *db) /* {{{ */
@@ -858,13 +861,14 @@ static int cj_curl_perform(cj_t *db) /* {{{ */
   int status;
   long rc;
   char *url;
-  url = db->url;
+
+  curl_easy_setopt(db->curl, CURLOPT_URL, db->url);
 
   status = curl_easy_perform(db->curl);
   if (status != CURLE_OK) {
     ERROR("curl_json plugin: curl_easy_perform failed with status %i: %s (%s)",
-          status, db->curl_errbuf, url);
-    return (-1);
+          status, db->curl_errbuf, db->url);
+    return -1;
   }
   if (db->stats != NULL)
     curl_stats_dispatch(db->stats, db->curl, cj_host(db), "curl_json",
@@ -878,9 +882,9 @@ static int cj_curl_perform(cj_t *db) /* {{{ */
     ERROR("curl_json plugin: curl_easy_perform failed with "
           "response code %ld (%s)",
           rc, url);
-    return (-1);
+    return -1;
   }
-  return (0);
+  return 0;
 } /* }}} int cj_curl_perform */
 
 static int cj_perform(cj_t *db) /* {{{ */
@@ -898,7 +902,7 @@ static int cj_perform(cj_t *db) /* {{{ */
   if (db->yajl == NULL) {
     ERROR("curl_json plugin: yajl_alloc failed.");
     db->yajl = yprev;
-    return (-1);
+    return -1;
   }
 
   if (db->url)
@@ -908,7 +912,7 @@ static int cj_perform(cj_t *db) /* {{{ */
   if (status < 0) {
     yajl_free(db->yajl);
     db->yajl = yprev;
-    return (-1);
+    return -1;
   }
 
 #if HAVE_YAJL_V2
@@ -925,12 +929,12 @@ static int cj_perform(cj_t *db) /* {{{ */
     yajl_free_error(db->yajl, errmsg);
     yajl_free(db->yajl);
     db->yajl = yprev;
-    return (-1);
+    return -1;
   }
 
   yajl_free(db->yajl);
   db->yajl = yprev;
-  return (0);
+  return 0;
 } /* }}} int cj_perform */
 
 static int cj_read(user_data_t *ud) /* {{{ */
@@ -939,7 +943,7 @@ static int cj_read(user_data_t *ud) /* {{{ */
 
   if ((ud == NULL) || (ud->data == NULL)) {
     ERROR("curl_json plugin: cj_read: Invalid user data.");
-    return (-1);
+    return -1;
   }
 
   db = (cj_t *)ud->data;
@@ -966,7 +970,7 @@ 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);
+  return 0;
 } /* }}} int cj_init */
 
 void module_register(void) {