Declare loop variable in the loop expression.
[collectd.git] / src / utils_cmd_putval.c
index 36419c6..691f1f8 100644 (file)
@@ -68,9 +68,12 @@ static int set_option (value_list_t *vl, const char *key, const char *value)
  * public API
  */
 
-cmd_status_t cmd_parse_putval (char *buffer,
-               cmd_putval_t *ret_putval, cmd_error_handler_t *err)
+cmd_status_t cmd_parse_putval (size_t argc, char **argv,
+               cmd_putval_t *ret_putval, const cmd_options_t *opts,
+               cmd_error_handler_t *err)
 {
+       cmd_status_t result;
+
        char *identifier;
        char *hostname;
        char *plugin;
@@ -83,30 +86,37 @@ cmd_status_t cmd_parse_putval (char *buffer,
 
        const data_set_t *ds;
        value_list_t vl = VALUE_LIST_INIT;
-       vl.values = NULL;
 
-       identifier = NULL;
-       status = parse_string (&buffer, &identifier);
-       if (status != 0)
+       if ((ret_putval == NULL) || (opts == NULL))
        {
-               cmd_error (CMD_PARSE_ERROR, err, "Cannot parse identifier.");
+               errno = EINVAL;
+               cmd_error (CMD_ERROR, err, "Invalid arguments to cmd_parse_putval.");
+               return (CMD_ERROR);
+       }
+
+       if (argc < 2)
+       {
+               cmd_error (CMD_PARSE_ERROR, err,
+                               "Missing identifier and/or value-list.");
                return (CMD_PARSE_ERROR);
        }
-       assert (identifier != NULL);
 
-       /* parse_identifier() modifies its first argument,
-        * returning pointers into it */
+       identifier = argv[0];
+
+       /* parse_identifier() modifies its first argument, returning pointers into
+        * it; retain the old value for later. */
        identifier_copy = sstrdup (identifier);
 
-       status = parse_identifier (identifier_copy, &hostname,
+       status = parse_identifier (identifier, &hostname,
                        &plugin, &plugin_instance,
-                       &type, &type_instance);
+                       &type, &type_instance,
+                       opts->identifier_default_host);
        if (status != 0)
        {
                DEBUG ("cmd_handle_putval: Cannot parse identifier `%s'.",
-                               identifier);
+                               identifier_copy);
                cmd_error (CMD_PARSE_ERROR, err, "Cannot parse identifier `%s'.",
-                               identifier);
+                               identifier_copy);
                sfree (identifier_copy);
                return (CMD_PARSE_ERROR);
        }
@@ -139,70 +149,61 @@ cmd_status_t cmd_parse_putval (char *buffer,
                return (CMD_PARSE_ERROR);
        }
 
-       /* Free identifier_copy */
        hostname = NULL;
        plugin = NULL; plugin_instance = NULL;
        type = NULL;   type_instance = NULL;
-       sfree (identifier_copy);
 
        vl.values_len = ds->ds_num;
        vl.values = malloc (vl.values_len * sizeof (*vl.values));
        if (vl.values == NULL)
        {
                cmd_error (CMD_ERROR, err, "malloc failed.");
+               sfree (identifier_copy);
                return (CMD_ERROR);
        }
 
-       ret_putval->identifier = strdup (identifier);
-       if (ret_putval->identifier == NULL)
+       ret_putval->raw_identifier = identifier_copy;
+       if (ret_putval->raw_identifier == NULL)
        {
                cmd_error (CMD_ERROR, err, "malloc failed.");
                cmd_destroy_putval (ret_putval);
+               sfree (vl.values);
                return (CMD_ERROR);
        }
 
-       /* All the remaining fields are part of the optionlist. */
-       while (*buffer != 0)
+       /* All the remaining fields are part of the option list. */
+       result = CMD_OK;
+       for (size_t i = 1; i < argc; ++i)
        {
                value_list_t *tmp;
 
-               char *string = NULL;
-               char *value  = NULL;
+               char *key   = NULL;
+               char *value = NULL;
 
-               status = parse_option (&buffer, &string, &value);
-               if (status < 0)
-               {
-                       /* parse_option failed, buffer has been modified.
-                        * => we need to abort */
-                       cmd_error (CMD_PARSE_ERROR, err, "Misformatted option.");
-                       cmd_destroy_putval (ret_putval);
-                       return (CMD_PARSE_ERROR);
-               }
-               else if (status == 0)
+               status = cmd_parse_option (argv[i], &key, &value, err);
+               if (status == CMD_OK)
                {
-                       assert (string != NULL);
+                       assert (key != NULL);
                        assert (value != NULL);
-                       set_option (&vl, string, value);
+                       set_option (&vl, key, value);
                        continue;
                }
-               /* else: parse_option but buffer has not been modified. This is
-                * the default if no `=' is found.. */
-
-               status = parse_string (&buffer, &string);
-               if (status != 0)
+               else if (status != CMD_NO_OPTION)
                {
-                       cmd_error (CMD_PARSE_ERROR, err, "Misformatted value.");
-                       cmd_destroy_putval (ret_putval);
-                       return (CMD_PARSE_ERROR);
+                       /* parse_option failed, buffer has been modified.
+                        * => we need to abort */
+                       result = status;
+                       break;
                }
-               assert (string != NULL);
+               /* else: cmd_parse_option did not find an option; treat this as a
+                * value list. */
 
-               status = parse_values (string, &vl, ds);
+               status = parse_values (argv[i], &vl, ds);
                if (status != 0)
                {
                        cmd_error (CMD_PARSE_ERROR, err, "Parsing the values string failed.");
-                       cmd_destroy_putval (ret_putval);
-                       return (CMD_PARSE_ERROR);
+                       result = CMD_PARSE_ERROR;
+                       break;
                }
 
                tmp = (value_list_t *) realloc (ret_putval->vl,
@@ -211,7 +212,8 @@ cmd_status_t cmd_parse_putval (char *buffer,
                {
                        cmd_error (CMD_ERROR, err, "realloc failed.");
                        cmd_destroy_putval (ret_putval);
-                       return (CMD_ERROR);
+                       result = CMD_ERROR;
+                       break;
                }
 
                ret_putval->vl = tmp;
@@ -220,21 +222,27 @@ cmd_status_t cmd_parse_putval (char *buffer,
        } /* while (*buffer != 0) */
        /* Done parsing the options. */
 
-       return (CMD_OK);
+       if (result != CMD_OK)
+       {
+               if (ret_putval->vl_num == 0)
+                       sfree (vl.values);
+               cmd_destroy_putval (ret_putval);
+       }
+
+       return (result);
 } /* cmd_status_t cmd_parse_putval */
 
 void cmd_destroy_putval (cmd_putval_t *putval)
 {
-       size_t i;
-
        if (putval == NULL)
                return;
 
-       sfree (putval->identifier);
+       sfree (putval->raw_identifier);
 
-       for (i = 0; i < putval->vl_num; ++i)
+       for (size_t i = 0; i < putval->vl_num; ++i)
        {
-               sfree (putval->vl[i].values);
+               if (i == 0) /* values is shared between all entries */
+                       sfree (putval->vl[i].values);
                meta_data_destroy (putval->vl[i].meta);
                putval->vl[i].meta = NULL;
        }
@@ -247,14 +255,13 @@ cmd_status_t cmd_handle_putval (FILE *fh, char *buffer)
 {
        cmd_error_handler_t err = { cmd_error_fh, fh };
        cmd_t cmd;
-       size_t i;
 
        int status;
 
        DEBUG ("utils_cmd_putval: cmd_handle_putval (fh = %p, buffer = %s);",
                        (void *) fh, buffer);
 
-       if ((status = cmd_parse (buffer, &cmd, &err)) != CMD_OK)
+       if ((status = cmd_parse (buffer, &cmd, NULL, &err)) != CMD_OK)
                return (status);
        if (cmd.type != CMD_PUTVAL)
        {
@@ -264,7 +271,7 @@ cmd_status_t cmd_handle_putval (FILE *fh, char *buffer)
                return (CMD_UNKNOWN_COMMAND);
        }
 
-       for (i = 0; i < cmd.cmd.putval.vl_num; ++i)
+       for (size_t i = 0; i < cmd.cmd.putval.vl_num; ++i)
                plugin_dispatch_values (&cmd.cmd.putval.vl[i]);
 
        if (fh != stdout)