aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/ChangeLog10
-rw-r--r--tools/README.gpgconf1
-rw-r--r--tools/gpgconf-comp.c143
3 files changed, 141 insertions, 13 deletions
diff --git a/tools/ChangeLog b/tools/ChangeLog
index fab5cafec..69af2eb99 100644
--- a/tools/ChangeLog
+++ b/tools/ChangeLog
@@ -1,3 +1,13 @@
+2004-02-26 Marcus Brinkmann <[email protected]>
+
+ * README.gpgconf (NAME): Add info about optional arg and arg type 0.
+ * gpgconf-comp.c (gc_component_change_options): Parse list of
+ arg type 0 options.
+ (option_check_validity): Add new argument NEW_VALUE_NR. Perform
+ rigorous validity checks.
+ (change_options_program): Disable an option also if we have a new
+ value for it.
+
2004-02-25 Marcus Brinkmann <[email protected]>
* gpgconf-comp.c (gc_component_list_options): Correct output for
diff --git a/tools/README.gpgconf b/tools/README.gpgconf
index 84fed518b..2f6a2e073 100644
--- a/tools/README.gpgconf
+++ b/tools/README.gpgconf
@@ -191,6 +191,7 @@ OR-wise combination of the following flag values:
1 group If this flag is set, this is a line describing
a group and not an option.
O 2 optional arg If this flag is set, the argument is optional.
+ This is never set for arg type 0 (none) options.
O 4 list If this flag is set, the option can be given
multiple times.
O 8 runtime If this flag is set, the option can be changed
diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
index ee980c5da..dc8de903c 100644
--- a/tools/gpgconf-comp.c
+++ b/tools/gpgconf-comp.c
@@ -289,7 +289,7 @@ static struct
flag set. */
#define GC_OPT_FLAG_GROUP (1UL << 0)
/* The ARG_OPT flag for an option indicates that the argument is
- optional. */
+ optional. This is never set for GC_ARG_TYPE_NONE options. */
#define GC_OPT_FLAG_ARG_OPT (1UL << 1)
/* The LIST flag for an option indicates that the option can occur
several times. A comma separated list of arguments is used as the
@@ -1216,23 +1216,116 @@ gc_component_retrieve_options (int component)
}
-/* Perform a simple validity check based on the type. */
+/* Perform a simple validity check based on the type. Return in
+ NEW_VALUE_NR the value of the number in NEW_VALUE if OPTION is of
+ type GC_ARG_TYPE_NONE. */
static void
option_check_validity (gc_option_t *option, unsigned long flags,
- const char *new_value)
+ char *new_value, unsigned long *new_value_nr)
{
if (option->new_flags || option->new_value)
gc_error (1, 0, "option %s already changed", option->name);
- if ((flags & GC_OPT_FLAG_DEFAULT) && *new_value)
- gc_error (1, 0, "value %s provided for deleted option %s",
- new_value, option->name);
+ if (flags & GC_OPT_FLAG_DEFAULT)
+ {
+ if (*new_value)
+ gc_error (1, 0, "argument %s provided for deleted option %s",
+ new_value, option->name);
+ }
+ else
+ {
+ /* This is even correct for GC_ARG_TYPE_NONE options, for which
+ GC_OPT_FLAG_ARG_OPT is never set. */
+ if (!(option->flags & GC_OPT_FLAG_ARG_OPT) && (*new_value == '\0'))
+ gc_error (1, 0, "no argument for option %s", option->name);
+
+ if (*new_value)
+ {
+ if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
+ {
+ char *tail;
+
+ errno = 0;
+ *new_value_nr = strtoul (new_value, &tail, 0);
+
+ if (errno)
+ gc_error (1, errno, "invalid argument for option %s",
+ option->name);
+ if (*tail)
+ gc_error (1, 0, "garbage after argument for option %s",
+ option->name);
+
+ if (!(option->flags & GC_OPT_FLAG_LIST))
+ {
+ if (*new_value_nr != 1)
+ gc_error (1, 0, "argument for non-list option %s of type 0 "
+ "(none) must be 1", option->name);
+ }
+ else
+ {
+ if (*new_value_nr == 0)
+ gc_error (1, 0, "argument for option %s of type 0 (none) "
+ "must be positive", option->name);
+ }
+ }
+ else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING)
+ {
+ if (*new_value != '"')
+ gc_error (1, 0, "string argument for option %s must begin "
+ "with a quote (\") character", option->name);
+ }
+ else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
+ {
+ char *tail = new_value;
+
+ while (*tail)
+ {
+ errno = 0;
+ (void) strtol (new_value, &tail, 0);
- if (!*new_value)
- return;
+ if (errno)
+ gc_error (1, errno, "invalid argument for option %s",
+ option->name);
+ if (*tail == ',')
+ {
+ if (!(option->flags & GC_OPT_FLAG_LIST))
+ gc_error (1, 0, "list found for non-list option %s",
+ option->name);
+ tail++;
+ }
+ else if (*tail)
+ gc_error (1, 0, "garbage after argument for option %s",
+ option->name);
+ }
+ }
+ else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_UINT32)
+ {
+ char *tail = new_value;
- /* FIXME. Verify that lists are lists, numbers are numbers, strings
- are strings, etc. */
+ while (*tail)
+ {
+ errno = 0;
+ (void) strtoul (new_value, &tail, 0);
+
+ if (errno)
+ gc_error (1, errno, "invalid argument for option %s",
+ option->name);
+ if (*tail == ',')
+ {
+ if (!(option->flags & GC_OPT_FLAG_LIST))
+ gc_error (1, 0, "list found for non-list option %s",
+ option->name);
+ tail++;
+ }
+ else if (*tail)
+ gc_error (1, 0, "garbage after argument for option %s",
+ option->name);
+ }
+ }
+ else
+ assert (!"Unexpected argument type");
+ }
+ }
}
@@ -1342,7 +1435,8 @@ change_options_program (gc_component_t component, gc_backend_t backend,
option = find_option (component, start, backend);
*end = saved_end;
- if (option && (option->new_flags & GC_OPT_FLAG_DEFAULT))
+ if (option && ((option->new_flags & GC_OPT_FLAG_DEFAULT)
+ || option->new_value))
disable = 1;
}
if (disable)
@@ -1472,6 +1566,7 @@ change_options_program (gc_component_t component, gc_backend_t backend,
return -1;
}
+
/* Read the modifications from IN and apply them. */
void
gc_component_change_options (int component, FILE *in)
@@ -1498,6 +1593,7 @@ gc_component_change_options (int component, FILE *in)
char *linep;
unsigned long flags = 0;
char *new_value = "";
+ unsigned long new_value_nr;
/* Strip newline and carriage return, if present. */
while (length > 0
@@ -1547,11 +1643,32 @@ gc_component_change_options (int component, FILE *in)
if (!option)
gc_error (1, 0, "unknown option %s", line);
- option_check_validity (option, flags, new_value);
+ option_check_validity (option, flags, new_value, &new_value_nr);
option->new_flags = flags;
if (!(flags & GC_OPT_FLAG_DEFAULT))
- option->new_value = xstrdup (new_value);
+ {
+ if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
+ && (option->flags & GC_OPT_FLAG_LIST))
+ {
+ char *str;
+
+ /* We convert the number to a list of 1's for
+ convenient list handling. */
+ assert (new_value_nr > 0);
+ option->new_value = xmalloc ((2 * (new_value_nr - 1) + 1) + 1);
+ str = option->new_value;
+ *(str++) = '1';
+ while (--new_value_nr > 0)
+ {
+ *(str++) = ',';
+ *(str++) = '1';
+ }
+ *(str++) = '\0';
+ }
+ else
+ option->new_value = xstrdup (new_value);
+ }
}
/* Now that we have collected and locally verified the changes,