index 06e9f2801e2ba582f856a757ff7abfe6672d926f..2168cd1af3d624801146905b853adb0c92db3d7b 100644 (file)
--- a/src/utils_parse_option.c
+++ b/src/utils_parse_option.c
#include "plugin.h"
#include "utils_parse_option.h"
-/*
- * parse_option
- * ------------
- * Parses an ``option'' as used with the unixsock and exec commands. An
- * option is of the form:
- * name0="value"
- * name1="value with \"quotes\""
- * name2="value \\ backslash"
- * However, if the value does *not* contain a space character, you can skip
- * the quotes.
- */
-int parse_option (char **ret_buffer, char **ret_key, char **ret_value)
+int parse_string (char **ret_buffer, char **ret_string)
{
char *buffer;
- char *key;
- char *value;
+ char *string;
buffer = *ret_buffer;
- /* Eat up leading spaces */
- key = buffer;
- while (isspace ((int) *key))
- key++;
- if (*key == 0)
- return (1);
-
- /* Look for the equal sign */
- value = key;
- while (isalnum ((int) *value))
- value++;
- if ((*value != '=') || (value == key))
+ /* Eat up leading spaces. */
+ string = buffer;
+ while (isspace ((int) *string))
+ string++;
+ if (*string == 0)
return (1);
- *value = 0;
- value++;
- /* Empty values must be written as "" */
- if (isspace ((int) *value) || (*value == 0))
- return (-1);
- /* A quoted value */
- if (*value == '"')
+ /* A quoted string */
+ if (*string == '"')
{
char *dst;
- value++;
- if (*value == 0)
- return (-1);
+ string++;
+ if (*string == 0)
+ return (1);
- dst = value;
- buffer = value;
+ dst = string;
+ buffer = string;
while ((*buffer != '"') && (*buffer != 0))
{
/* Un-escape backslashes */
/* No quote sign has been found */
if (*buffer == 0)
return (-1);
+
+ *dst = 0;
+ dst++;
*buffer = 0;
buffer++;
if ((*buffer != 0) && !isspace ((int) *buffer))
return (-1);
}
- else /* an unquoted value */
+ else /* an unquoted string */
{
- buffer = value;
- while (!isspace ((int) *buffer))
+ buffer = string;
+ while ((*buffer != 0) && !isspace ((int) *buffer))
buffer++;
if (*buffer != 0)
{
buffer++;
}
}
-
+
/* Eat up trailing spaces */
while (isspace ((int) *buffer))
buffer++;
+ *ret_buffer = buffer;
+ *ret_string = string;
+
+ return (0);
+} /* int parse_string */
+
+/*
+ * parse_option
+ * ------------
+ * Parses an ``option'' as used with the unixsock and exec commands. An
+ * option is of the form:
+ * name0="value"
+ * name1="value with \"quotes\""
+ * name2="value \\ backslash"
+ * However, if the value does *not* contain a space character, you can skip
+ * the quotes.
+ */
+int parse_option (char **ret_buffer, char **ret_key, char **ret_value)
+{
+ char *buffer;
+ char *key;
+ char *value;
+ int status;
+
+ buffer = *ret_buffer;
+
+ /* Eat up leading spaces */
+ key = buffer;
+ while (isspace ((int) *key))
+ key++;
+ if (*key == 0)
+ return (1);
+
+ /* Look for the equal sign */
+ buffer = key;
+ while (isalnum ((int) *buffer))
+ buffer++;
+ if ((*buffer != '=') || (buffer == key))
+ return (1);
+ *buffer = 0;
+ buffer++;
+ /* Empty values must be written as "" */
+ if (isspace ((int) *buffer) || (*buffer == 0))
+ return (-1);
+
+ status = parse_string (&buffer, &value);
+ if (status != 0)
+ return (-1);
+
+ /* NB: parse_string will have eaten up all trailing spaces. */
+
*ret_buffer = buffer;
*ret_key = key;
*ret_value = value;
return (0);
} /* int parse_option */
+int escape_string (char *buffer, size_t buffer_size)
+{
+ char *temp;
+ size_t i;
+ size_t j;
+
+ /* Check if we need to escape at all first */
+ temp = strpbrk (buffer, " \t\"\\");
+ if (temp == NULL)
+ return (0);
+
+ temp = (char *) malloc (buffer_size);
+ if (temp == NULL)
+ return (-1);
+ memset (temp, 0, buffer_size);
+
+ temp[0] = '"';
+ j = 1;
+
+ for (i = 0; i < buffer_size; i++)
+ {
+ if (buffer[i] == 0)
+ {
+ break;
+ }
+ else if ((buffer[i] == '"') || (buffer[i] == '\\'))
+ {
+ if (j > (buffer_size - 4))
+ break;
+ temp[j] = '\\';
+ temp[j + 1] = buffer[i];
+ j += 2;
+ }
+ else
+ {
+ if (j > (buffer_size - 3))
+ break;
+ temp[j] = buffer[i];
+ j++;
+ }
+ }
+
+ assert ((j + 1) < buffer_size);
+ temp[j] = '"';
+ temp[j + 1] = 0;
+
+ sstrncpy (buffer, temp, buffer_size);
+ sfree (temp);
+ return (0);
+} /* int escape_string */
+
/* vim: set sw=2 ts=8 tw=78 et : */