2004-02-24 Marcus Brinkmann <marcus@g10code.de>

* README.gpgconf: Revert last change.  Add new flags "default",
	"default desc" and "no arg desc".  Add new field ARGDEF.  Add new
	field FLAG to backend interface.
	* gpgconf-comp.c (struct gc_option): Make flags of type unsigned
	long.
	(gc_component_list_options): Adjust type for flags.
	Add default argument field.
	(retrieve_options_from_program): Use "1" as value for non-option
	arguments, not "Y".
	(gc_component_change_options): Read in flags from input.
This commit is contained in:
Marcus Brinkmann 2004-02-24 14:31:59 +00:00
parent 18a212f2c8
commit 54d5446797
3 changed files with 266 additions and 60 deletions

View File

@ -1,3 +1,16 @@
2004-02-24 Marcus Brinkmann <marcus@g10code.de>
* README.gpgconf: Revert last change. Add new flags "default",
"default desc" and "no arg desc". Add new field ARGDEF. Add new
field FLAG to backend interface.
* gpgconf-comp.c (struct gc_option): Make flags of type unsigned
long.
(gc_component_list_options): Adjust type for flags.
Add default argument field.
(retrieve_options_from_program): Use "1" as value for non-option
arguments, not "Y".
(gc_component_change_options): Read in flags from input.
2004-02-23 Marcus Brinkmann <marcus@g10code.de>
* README.gpgconf: Change meaning of type 0 options value if it is

View File

@ -82,9 +82,8 @@ argument depends on the type of the option and on some flags:
The simplest case is that the option does not take an argument at all
(TYPE is 0). Then the option argument is either empty if the option
is not set, or an unsigned number that specifies how often the option
occurs. If the LIST flag is not set, then the only valid numbers are
0 and 1. 0 often has a special meaning in this context as it actually
negates setting the option one or more times.
occurs. If the LIST flag is not set, then the only valid number is 1.
Options that don't take an argument never have the "default" flag set.
If the option takes a number argument (ALT-TYPE is 2 or 3), and it can
only occur once (LIST flag is not set), then the option argument is
@ -175,7 +174,7 @@ the next group and so on.
The format of each line is:
NAME:FLAGS:LEVEL:DESCRIPTION:TYPE:ALT-TYPE:ARGNAME:DEFAULT:VALUE
NAME:FLAGS:LEVEL:DESCRIPTION:TYPE:ALT-TYPE:ARGNAME:DEFAULT:ARGDEF:VALUE
NAME
@ -189,13 +188,19 @@ FLAGS
The flags field contains an unsigned number. Its value is the
OR-wise combination of the following flag values:
1 group If this flag is set, this is a line describing
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.
O 4 list If this flag is set, the option can be given
O 2 optional arg If this flag is set, the argument is optional.
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
O 8 runtime If this flag is set, the option can be changed
at runtime.
O 16 default If this flag is set, a default value is available.
O 32 default desc If this flag is set, a (runtime) default is available.
This and the 'default' flag are mutually exclusive.
O 64 no arg desc If this flag is set, and the 'optional arg' flag
is set, then the option has a special meaning if no
argument is given.
Flags marked with a 'O' are only defined for options (ie, if the GROUP
flag is not set).
@ -230,13 +235,16 @@ This field is only defined for options. It contains an unsigned
number that specifies the type of the option's argument, if any.
The following types are defined:
0 none No argument allowed.
1 string An unformatted string.
2 int32 A signed integer number.
3 uint32 An unsigned integer number.
4 pathname A string that describes the pathname of a file.
Basic types
0 none No argument allowed.
1 string An unformatted string.
2 int32 A signed integer number.
3 uint32 An unsigned integer number.
Complex types
32 pathname A string that describes the pathname of a file.
The file does not necessarily need to exist.
5 ldap server A string that describes an LDAP server in the format
33 ldap server A string that describes an LDAP server in the format
HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN.
More types will be added in the future. Please see the ALT-TYPE field
@ -244,12 +252,14 @@ for information on how to cope with unknown types.
ALT-TYPE
This field is identical to TYPE, except that only the types 0 to 3 are
allowed. The GUI is expected to present the user the option in the
format specified by TYPE. But if the argument type TYPE is not
This field is identical to TYPE, except that only the types 0 to 31
are allowed. The GUI is expected to present the user the option in
the format specified by TYPE. But if the argument type TYPE is not
supported by the GUI, it can still display the option in the more
generic basic type ALT-TYPE. The GUI must support the basic types 0
to 3 to be able to display all options.
generic basic type ALT-TYPE. The GUI must support all the defined
basic types to be able to display all options. More basic types may
be added in future versions. If the GUI encounters a basic type it
doesn't support, it should report an error and abort the operation.
ARGNAME
@ -267,6 +277,18 @@ value specifies the default value for this option. Note that this
field is also meaningful if the option itself does not take a real
argument.
ARGDEF
This field is defined only for options for which the "optional arg"
flag is set. If the "no arg desc" flag is not set, its format is that
of an option argument (see section Format Conventions for details).
If the default value is empty, then no default is known. Otherwise,
the value specifies the default value for this option. If the "no arg
desc" flag is set, the field is either empty or contains a description
of the effect of this option if no argument is given. Note that this
field is also meaningful if the option itself does not take a real
argument.
VALUE
This field is defined only for options. Its format is that of an
@ -283,18 +305,35 @@ CHANGING OPTIONS
To change the options for a component, you must provide them in the
following format:
NAME:NEW-VALUE
NAME:FLAGS:NEW-VALUE
NAME
This is the name of the option to change.
FLAGS
The flags field contains an unsigned number. Its value is the
OR-wise combination of the following flag values:
16 default If this flag is set, the option is deleted and the
default value is used instead (if applicable).
NEW-VALUE
The new value for the option. The format is that of an option
argument. If it is empty (or the field is omitted), the option will
be deleted, so that the default value is used. Otherwise, the option
will be set to the specified value.
The new value for the option. This field is only defined if the
"default" flag is not set. The format is that of an option argument.
If it is empty (or the field is omitted), the default argument is used
(only allowed if the argument is optional for this option).
Otherwise, the option will be set to the specified value.
Example:
To set the option force, which is of basic type 0 (none).
$ echo 'force:0:1' | gpgconf --change-options dirmngr
To delete the option force:
$ echo 'force:16:0' | gpgconf --change-options dirmngr
Option --runtime
----------------
@ -316,9 +355,62 @@ List the location of the configuration file, and all default values of
all options. The location of the configuration file must be an
absolute pathname.
The format of each line is:
NAME:FLAGS:DEFAULT:ARGDEF
NAME
This field contains a name tag for the group or option. The name tag
is used to specify the group or option in all communication with
GPGConf. The name tag is to be used verbatim. It is not in any
escaped format.
FLAGS
The flags field contains an unsigned number. Its value is the
OR-wise combination of the following flag values:
16 default If this flag is set, a default value is available.
32 default desc If this flag is set, a (runtime) default is available.
This and the "default" flag are mutually exclusive.
64 no arg desc If this flag is set, and the "optional arg" flag
is set, then the option has a special meaning if no
argument is given.
DEFAULT
This field is defined only for options. Its format is that of an
option argument (see section Format Conventions for details). If the
default value is empty, then no default is known. Otherwise, the
value specifies the default value for this option. Note that this
field is also meaningful if the option itself does not take a real
argument.
ARGDEF
This field is defined only for options for which the "optional arg"
flag is set. If the "no arg desc" flag is not set, its format is that
of an option argument (see section Format Conventions for details).
If the default value is empty, then no default is known. Otherwise,
the value specifies the default value for this option. If the "no arg
desc" flag is set, the field is either empty or contains a description
of the effect of this option if no argument is given. Note that this
field is also meaningful if the option itself does not take a real
argument.
Example:
$ dirmngr --gpgconf-list
gpgconf-config-file:/mnt/marcus/.gnupg/dirmngr.conf
ldapservers-file:/mnt/marcus/.gnupg/dirmngr_ldapservers.conf
add-servers:0
max-replies:10
TODO
----
* Extend the backend interface to include gettext domain and
description, if available, to avoid repeating this information in
gpgconf.

View File

@ -176,20 +176,21 @@ typedef enum
/* An unsigned integer argument. */
GC_ARG_TYPE_UINT32 = 3,
/* ADD NEW BASIC TYPE ENTRIES HERE. */
/* Complex argument types. */
/* A complete pathname. */
GC_ARG_TYPE_PATHNAME = 4,
GC_ARG_TYPE_PATHNAME = 32,
/* An LDAP server in the format
HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN. */
GC_ARG_TYPE_LDAP_SERVER = 5,
GC_ARG_TYPE_LDAP_SERVER = 33,
/* A 40 character fingerprint. */
GC_ARG_TYPE_KEY_FPR = 6,
GC_ARG_TYPE_KEY_FPR = 34,
/* ADD NEW ENTRIES HERE. */
/* ADD NEW COMPLEX TYPE ENTRIES HERE. */
/* The number of the above entries. */
GC_ARG_TYPE_NR
@ -214,6 +215,22 @@ static struct
{ GC_ARG_TYPE_INT32, "int32" },
{ GC_ARG_TYPE_UINT32, "uint32" },
/* Reserved basic type entries for future extension. */
{ GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
{ GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
{ GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
{ GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
{ GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
{ GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
{ GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
{ GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
{ GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
{ GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
{ GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
{ GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
{ GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
{ GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
/* The complex argument types have a basic type as fallback. */
{ GC_ARG_TYPE_STRING, "pathname" },
{ GC_ARG_TYPE_STRING, "ldap server" },
@ -266,21 +283,32 @@ static struct
/* Option flags. YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING
FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE. */
#define GC_OPT_FLAG_NONE 0
#define GC_OPT_FLAG_NONE 0UL
/* Some entries in the option list are not options, but mark the
beginning of a new group of options. These entries have the GROUP
flag set. */
#define GC_OPT_FLAG_GROUP (1 << 0)
#define GC_OPT_FLAG_GROUP (1UL << 0)
/* The ARG_OPT flag for an option indicates that the argument is
optional. */
#define GC_OPT_FLAG_ARG_OPT (1 << 1)
#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
argument value. */
#define GC_OPT_FLAG_LIST (1 << 2)
#define GC_OPT_FLAG_LIST (1UL << 2)
/* The RUNTIME flag for an option indicates that the option can be
changed at runtime. */
#define GC_OPT_FLAG_RUNTIME (1 << 3)
#define GC_OPT_FLAG_RUNTIME (1UL << 3)
/* The following flags are incorporated from the backend. */
/* The DEFAULT flag for an option indicates that the option has a
default value. */
#define GC_OPT_FLAG_DEFAULT (1UL << 4)
/* The DEF_DESC flag for an option indicates that the option has a
default, which is described by the value of the default field. */
#define GC_OPT_FLAG_DEF_DESC (1UL << 5)
/* The NO_ARG_DESC flag for an option indicates that the argument has
a default, which is described by the value of the ARGDEF field. */
#define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6)
/* A human-readable description for each flag. */
static struct
@ -311,7 +339,7 @@ struct gc_option
group marker, not an option, and only the fields LEVEL,
DESC_DOMAIN and DESC are valid. In all other cases, this entry
describes a new option and all fields are valid. */
unsigned int flags;
unsigned long flags;
/* The expert level. This field is valid for options and groups. A
group has the expert level of the lowest-level option in the
@ -350,6 +378,11 @@ struct gc_option
available, and otherwise a quoted string. */
char *default_value;
/* The default argument is only valid if the "optional arg" flag is
set, and specifies the default argument (value) that is used if
the argument is omitted. */
char *default_arg;
/* The current value of this option. */
char *value;
@ -744,7 +777,7 @@ gc_component_list_options (int component, FILE *out)
fprintf (out, "%s", option->name);
/* The flags field. */
fprintf (out, ":%u", option->flags);
fprintf (out, ":%lu", option->flags);
if (opt.verbose)
{
putc (' ', out);
@ -753,9 +786,9 @@ gc_component_list_options (int component, FILE *out)
fprintf (out, "none");
else
{
unsigned int flags = option->flags;
unsigned int flag = 0;
unsigned int first = 1;
unsigned long flags = option->flags;
unsigned long flag = 0;
unsigned long first = 1;
while (flags)
{
@ -800,6 +833,9 @@ gc_component_list_options (int component, FILE *out)
/* The default value field. */
fprintf (out, ":%s", option->default_value ? option->default_value : "");
/* The default argument field. */
fprintf (out, ":%s", option->default_arg ? option->default_arg : "");
/* The value field. */
fprintf (out, ":%s", option->value ? option->value : "");
@ -884,26 +920,53 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
while ((length = getline (&line, &line_len, config)) > 0)
{
gc_option_t *option;
char *value;
char *linep;
unsigned long flags = 0;
char *default_value = NULL;
/* Strip newline and carriage return, if present. */
while (length > 0
&& (line[length - 1] == '\n' || line[length - 1] == '\r'))
line[--length] = '\0';
linep = strchr (line, ':');
if (linep)
*(linep++) = '\0';
/* Extract additional flags. Default to none. */
if (linep)
{
char *end;
char *tail;
end = strchr (linep, ':');
if (end)
*(end++) = '\0';
errno = 0;
flags = strtoul (linep, &tail, 0);
if (errno)
gc_error (1, errno, "malformed flags in option %s from %s", line, cmd_line);
if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
gc_error (1, 0, "garbage after flags in option %s from %s", line, cmd_line);
linep = end;
}
/* Extract default value, if present. Default to empty if
not. */
value = strchr (line, ':');
if (!value)
value = "";
else
if (linep)
{
char *end;
*(value++) = '\0';
end = strchr (value, ':');
end = strchr (linep, ':');
if (end)
*end = '\0';
*(end++) = '\0';
if (flags & GC_OPT_FLAG_DEFAULT)
default_value = linep;
linep = end;
}
/* Look up the option in the component and install the
@ -915,8 +978,10 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
gc_error (1, errno, "option %s returned twice from %s",
line, cmd_line);
option->active = 1;
if (*value)
option->default_value = xstrdup (value);
option->flags |= flags;
if (default_value && *default_value)
option->default_value = xstrdup (default_value);
}
}
if (ferror (config))
@ -981,7 +1046,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
gc_error (0, 0,
"warning: ignoring argument %s for option %s",
value, name);
opt_value = xstrdup ("Y");
opt_value = xstrdup ("1");
}
else if (gc_arg_type[option->arg_type].fallback
== GC_ARG_TYPE_STRING)
@ -1011,6 +1076,8 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
== GC_ARG_TYPE_STRING)
opt_val++;
/* FIXME. For type none arguments, this is
wrong. */
option->value = xasprintf ("%s,%s", option->value,
opt_val);
xfree (opt_value);
@ -1411,32 +1478,66 @@ gc_component_change_options (int component, FILE *in)
while ((length = getline (&line, &line_len, in)) > 0)
{
char *value;
char *linep;
unsigned long flags = 0;
char *new_value = NULL;
/* Strip newline and carriage return, if present. */
while (length > 0
&& (line[length - 1] == '\n' || line[length - 1] == '\r'))
line[--length] = '\0';
value = strchr (line, ':');
if (!value)
value = "";
else
linep = strchr (line, ':');
if (linep)
*(linep++) = '\0';
/* Extract additional flags. Default to none. */
if (linep)
{
char *end;
char *tail;
end = strchr (linep, ':');
if (end)
*(end++) = '\0';
errno = 0;
flags = strtoul (linep, &tail, 0);
if (errno)
gc_error (1, errno, "malformed flags in option %s", line);
if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
gc_error (1, 0, "garbage after flags in option %s", line);
linep = end;
}
/* Extract default value, if present. Default to empty if
not. */
if (linep)
{
char *end;
*(value++) = '\0';
end = strchr (value, ':');
end = strchr (linep, ':');
if (end)
*end = '\0';
*(end++) = '\0';
if (!(flags & GC_OPT_FLAG_DEFAULT))
new_value = linep;
linep = end;
}
option = find_option (component, line, GC_BACKEND_ANY);
if (!option)
gc_error (1, 0, "unknown option %s", line);
option_check_validity (option, value);
option->new_value = xstrdup (value);
/* FIXME: This is not correct, as it ignores the optional arg
case. */
if (flags & GC_OPT_FLAG_DEFAULT)
new_value = "";
option_check_validity (option, new_value);
option->new_value = xstrdup (new_value);
}
/* Now that we have collected and locally verified the changes,