2008-02-01 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / tools / gpgconf-comp.c
1 /* gpgconf-comp.c - Configuration utility for GnuPG.
2  * Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GnuPG; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #if HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <sys/types.h>
29 #include <assert.h>
30 #include <errno.h>
31 #include <time.h>
32 #include <stdarg.h>
33 #include <signal.h>
34 #include <ctype.h>
35 #ifdef HAVE_W32_SYSTEM
36 # define WIN32_LEAN_AND_MEAN 1
37 # include <windows.h>
38 #else
39 # include <pwd.h>
40 # include <grp.h>
41 #endif
42
43 /* For log_logv(), asctimestamp(), gnupg_get_time ().  */
44 #define JNLIB_NEED_LOG_LOGV
45 #include "util.h"
46 #include "i18n.h"
47 #include "exechelp.h"
48
49 #include "gc-opt-flags.h"
50 #include "gpgconf.h"
51
52
53 /* There is a problem with gpg 1.4 under Windows: --gpgconf-list
54    returns a plain filename without escaping.  As long as we have not
55    fixed that we need to use gpg2 - it might actually be better to use
56    gpg2 in any case.  */
57 #ifdef HAVE_W32_SYSTEM
58 #define GPGNAME "gpg2"
59 #else
60 #define GPGNAME "gpg"
61 #endif
62
63 \f
64 /* TODO:
65    Components: Add more components and their options.
66    Robustness: Do more validation.  Call programs to do validation for us.
67    Add options to change backend binary path.
68    Extract binary path for some backends from gpgsm/gpg config.
69 */
70
71 \f
72 #if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ))
73 void gc_error (int status, int errnum, const char *fmt, ...) \
74   __attribute__ ((format (printf, 3, 4)));
75 #endif
76
77 /* Output a diagnostic message.  If ERRNUM is not 0, then the output
78    is followed by a colon, a white space, and the error string for the
79    error number ERRNUM.  In any case the output is finished by a
80    newline.  The message is prepended by the program name, a colon,
81    and a whitespace.  The output may be further formatted or
82    redirected by the jnlib logging facility.  */
83 void
84 gc_error (int status, int errnum, const char *fmt, ...)
85 {
86   va_list arg_ptr;
87
88   va_start (arg_ptr, fmt);
89   log_logv (JNLIB_LOG_ERROR, fmt, arg_ptr);
90   va_end (arg_ptr);
91
92   if (errnum)
93     log_printf (": %s\n", strerror (errnum));
94   else
95     log_printf ("\n");
96
97   if (status)
98     {
99       log_printf (NULL);
100       log_printf ("fatal error (exit status %i)\n", status);
101       exit (status);
102     }
103 }
104
105 \f
106 /* Forward declaration.  */
107 void gpg_agent_runtime_change (void);
108
109 /* Backend configuration.  Backends are used to decide how the default
110    and current value of an option can be determined, and how the
111    option can be changed.  To every option in every component belongs
112    exactly one backend that controls and determines the option.  Some
113    backends are programs from the GPG system.  Others might be
114    implemented by GPGConf itself.  If you change this enum, don't
115    forget to update GC_BACKEND below.  */
116 typedef enum
117   {
118     /* Any backend, used for find_option ().  */
119     GC_BACKEND_ANY,
120
121     /* The Gnu Privacy Guard.  */
122     GC_BACKEND_GPG,
123
124     /* The Gnu Privacy Guard for S/MIME.  */
125     GC_BACKEND_GPGSM,
126
127     /* The GPG Agent.  */
128     GC_BACKEND_GPG_AGENT,
129
130     /* The GnuPG SCDaemon.  */
131     GC_BACKEND_SCDAEMON,
132
133     /* The Aegypten directory manager.  */
134     GC_BACKEND_DIRMNGR,
135
136     /* The LDAP server list file for the Aegypten director manager.  */
137     GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST,
138
139     /* The number of the above entries.  */
140     GC_BACKEND_NR
141   } gc_backend_t;
142
143
144 /* To be able to implement generic algorithms for the various
145    backends, we collect all information about them in this struct.  */
146 static struct
147 {
148   /* The name of the backend.  */
149   const char *name;
150
151   /* The name of the program that acts as the backend.  Some backends
152      don't have an associated program, but are implemented directly by
153      GPGConf.  In this case, PROGRAM is NULL.  */
154   char *program;
155
156   /* The module name (GNUPG_MODULE_NAME_foo) as defined by
157      ../common/util.h.  This value is used to get the actual installed
158      path of the program.  0 is used if no backedn program is
159      available. */
160   char module_name;
161
162   /* The runtime change callback.  */
163   void (*runtime_change) (void);
164
165   /* The option name for the configuration filename of this backend.
166      This must be an absolute pathname.  It can be an option from a
167      different backend (but then ordering of the options might
168      matter).  */
169   const char *option_config_filename;
170
171   /* If this is a file backend rather than a program backend, then
172      this is the name of the option associated with the file.  */
173   const char *option_name;
174 } gc_backend[GC_BACKEND_NR] =
175   {
176     { NULL },           /* GC_BACKEND_ANY dummy entry.  */
177     { "GnuPG", GPGNAME, GNUPG_MODULE_NAME_GPG,
178       NULL, "gpgconf-gpg.conf" },
179     { "GPGSM", "gpgsm", GNUPG_MODULE_NAME_GPGSM,
180       NULL, "gpgconf-gpgsm.conf" },
181     { "GPG Agent", "gpg-agent", GNUPG_MODULE_NAME_AGENT, 
182       gpg_agent_runtime_change, "gpgconf-gpg-agent.conf" },
183     { "SCDaemon", "scdaemon", GNUPG_MODULE_NAME_SCDAEMON,
184       NULL, "gpgconf-scdaemon.conf" },
185     { "DirMngr", "dirmngr", GNUPG_MODULE_NAME_DIRMNGR,
186       NULL, "gpgconf-dirmngr.conf" },
187     { "DirMngr LDAP Server List", NULL, 0, 
188       NULL, "ldapserverlist-file", "LDAP Server" },
189   };
190
191 \f
192 /* Option configuration.  */
193
194 /* An option might take an argument, or not.  Argument types can be
195    basic or complex.  Basic types are generic and easy to validate.
196    Complex types provide more specific information about the intended
197    use, but can be difficult to validate.  If you add to this enum,
198    don't forget to update GC_ARG_TYPE below.  YOU MUST NOT CHANGE THE
199    NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE EXTERNAL
200    INTERFACE.  */
201 typedef enum
202   {
203     /* Basic argument types.  */
204
205     /* No argument.  */
206     GC_ARG_TYPE_NONE = 0,
207
208     /* A String argument.  */
209     GC_ARG_TYPE_STRING = 1,
210
211     /* A signed integer argument.  */
212     GC_ARG_TYPE_INT32 = 2,
213
214     /* An unsigned integer argument.  */
215     GC_ARG_TYPE_UINT32 = 3,
216
217     /* ADD NEW BASIC TYPE ENTRIES HERE.  */
218
219     /* Complex argument types.  */
220
221     /* A complete pathname.  */
222     GC_ARG_TYPE_PATHNAME = 32,
223
224     /* An LDAP server in the format
225        HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN.  */
226     GC_ARG_TYPE_LDAP_SERVER = 33,
227
228     /* A 40 character fingerprint.  */
229     GC_ARG_TYPE_KEY_FPR = 34,
230
231     /* ADD NEW COMPLEX TYPE ENTRIES HERE.  */
232
233     /* The number of the above entries.  */
234     GC_ARG_TYPE_NR
235   } gc_arg_type_t;
236
237
238 /* For every argument, we record some information about it in the
239    following struct.  */
240 static struct
241 {
242   /* For every argument type exists a basic argument type that can be
243      used as a fallback for input and validation purposes.  */
244   gc_arg_type_t fallback;
245
246   /* Human-readable name of the type.  */
247   const char *name;
248 } gc_arg_type[GC_ARG_TYPE_NR] =
249   {
250     /* The basic argument types have their own types as fallback.  */
251     { GC_ARG_TYPE_NONE, "none" },
252     { GC_ARG_TYPE_STRING, "string" },
253     { GC_ARG_TYPE_INT32, "int32" },
254     { GC_ARG_TYPE_UINT32, "uint32" },
255
256     /* Reserved basic type entries for future extension.  */
257     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
258     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
259     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
260     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
261     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
262     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
263     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
264     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
265     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
266     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
267     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
268     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
269     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
270     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
271
272     /* The complex argument types have a basic type as fallback.  */
273     { GC_ARG_TYPE_STRING, "pathname" },
274     { GC_ARG_TYPE_STRING, "ldap server" },
275     { GC_ARG_TYPE_STRING, "key fpr" },
276   };
277
278
279 /* Every option has an associated expert level, than can be used to
280    hide advanced and expert options from beginners.  If you add to
281    this list, don't forget to update GC_LEVEL below.  YOU MUST NOT
282    CHANGE THE NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE
283    EXTERNAL INTERFACE.  */
284 typedef enum
285   {
286     /* The basic options should always be displayed.  */
287     GC_LEVEL_BASIC,
288
289     /* The advanced options may be hidden from beginners.  */
290     GC_LEVEL_ADVANCED,
291
292     /* The expert options should only be displayed to experts.  */
293     GC_LEVEL_EXPERT,
294
295     /* The invisible options should normally never be displayed.  */
296     GC_LEVEL_INVISIBLE,
297
298     /* The internal options are never exported, they mark options that
299        are recorded for internal use only.  */
300     GC_LEVEL_INTERNAL,
301
302     /* ADD NEW ENTRIES HERE.  */
303
304     /* The number of the above entries.  */
305     GC_LEVEL_NR
306   } gc_expert_level_t;
307
308 /* A description for each expert level.  */
309 static struct
310 {
311   const char *name;
312 } gc_level[] =
313   {
314     { "basic" },
315     { "advanced" },
316     { "expert" },
317     { "invisible" },
318     { "internal" }
319   };
320
321
322 /* Option flags.  The flags which are used by the backends are defined
323    by gc-opt-flags.h, included above.
324
325    YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING FLAGS, AS THEY ARE
326    PART OF THE EXTERNAL INTERFACE.  */
327
328 /* Some entries in the option list are not options, but mark the
329    beginning of a new group of options.  These entries have the GROUP
330    flag set.  */
331 #define GC_OPT_FLAG_GROUP       (1UL << 0)
332 /* The ARG_OPT flag for an option indicates that the argument is
333    optional.  This is never set for GC_ARG_TYPE_NONE options.  */
334 #define GC_OPT_FLAG_ARG_OPT     (1UL << 1)
335 /* The LIST flag for an option indicates that the option can occur
336    several times.  A comma separated list of arguments is used as the
337    argument value.  */
338 #define GC_OPT_FLAG_LIST        (1UL << 2)
339 /* The NO_CHANGE flag for an option indicates that the user should not
340    be allowed to change this option using the standard gpgconf method.
341    Frontends using gpgconf should grey out such options, so that only
342    the current value is displayed.  */
343 #define GC_OPT_FLAG_NO_CHANGE   (1UL <<7)
344
345
346 /* A human-readable description for each flag.  */
347 static struct
348 {
349   const char *name;
350 } gc_flag[] =
351   {
352     { "group" },
353     { "optional arg" },
354     { "list" },
355     { "runtime" },
356     { "default" },
357     { "default desc" },
358     { "no arg desc" },
359     { "no change" }
360   };
361
362
363 /* To each option, or group marker, the information in the GC_OPTION
364    struct is provided.  If you change this, don't forget to update the
365    option list of each component.  */
366 struct gc_option
367 {
368   /* If this is NULL, then this is a terminator in an array of unknown
369      length.  Otherwise, if this entry is a group marker (see FLAGS),
370      then this is the name of the group described by this entry.
371      Otherwise it is the name of the option described by this
372      entry.  The name must not contain a colon.  */
373   const char *name;
374
375   /* The option flags.  If the GROUP flag is set, then this entry is a
376      group marker, not an option, and only the fields LEVEL,
377      DESC_DOMAIN and DESC are valid.  In all other cases, this entry
378      describes a new option and all fields are valid.  */
379   unsigned long flags;
380
381   /* The expert level.  This field is valid for options and groups.  A
382      group has the expert level of the lowest-level option in the
383      group.  */
384   gc_expert_level_t level;
385
386   /* A gettext domain in which the following description can be found.
387      If this is NULL, then DESC is not translated.  Valid for groups
388      and options.
389      
390      Note that we try to keep the description of groups within the
391      gnupg domain. 
392      
393      IMPORTANT: If you add a new domain please make sure to add a code
394      set switching call to the function my_dgettext further below.  */
395   const char *desc_domain;
396
397   /* A gettext description for this group or option.  If it starts
398      with a '|', then the string up to the next '|' describes the
399      argument, and the description follows the second '|'. 
400
401      In general enclosing these description in N_() is not required
402      because the description should be identical to the one in the
403      help menu of the respective program. */
404   const char *desc;
405
406   /* The following fields are only valid for options.  */
407
408   /* The type of the option argument.  */
409   gc_arg_type_t arg_type;
410
411   /* The backend that implements this option.  */
412   gc_backend_t backend;
413
414   /* The following fields are set to NULL at startup (because all
415      option's are declared as static variables).  They are at the end
416      of the list so that they can be omitted from the option
417      declarations.  */
418
419   /* This is true if the option is supported by this version of the
420      backend.  */
421   int active;
422
423   /* The default value for this option.  This is NULL if the option is
424      not present in the backend, the empty string if no default is
425      available, and otherwise a quoted string.  */
426   char *default_value;
427
428   /* The default argument is only valid if the "optional arg" flag is
429      set, and specifies the default argument (value) that is used if
430      the argument is omitted.  */
431   char *default_arg;
432
433   /* The current value of this option.  */
434   char *value;
435
436   /* The new flags for this option.  The only defined flag is actually
437      GC_OPT_FLAG_DEFAULT, and it means that the option should be
438      deleted.  In this case, NEW_VALUE is NULL.  */
439   unsigned long new_flags;
440
441   /* The new value of this option.  */
442   char *new_value;
443 };
444 typedef struct gc_option gc_option_t;
445
446 /* Use this macro to terminate an option list.  */
447 #define GC_OPTION_NULL { NULL }
448
449 \f
450 /* The options of the GC_COMPONENT_GPG_AGENT component.  */
451 static gc_option_t gc_options_gpg_agent[] =
452  {
453    /* The configuration file to which we write the changes.  */
454    { "gpgconf-gpg-agent.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
455      NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT },
456
457    { "Monitor",
458      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
459      "gnupg", N_("Options controlling the diagnostic output") },
460    { "verbose", GC_OPT_FLAG_LIST|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
461      "gnupg", "verbose",
462      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
463    { "quiet", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
464      "gnupg", "be somewhat more quiet",
465      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
466    { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
467      NULL, NULL,
468      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
469
470    { "Configuration",
471      GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
472      "gnupg", N_("Options controlling the configuration") },
473    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
474      "gnupg", "|FILE|read options from FILE",
475      GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT },
476    { "disable-scdaemon", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
477      "gnupg", "do not use the SCdaemon",
478      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
479
480    { "Debug",
481      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
482      "gnupg", N_("Options useful for debugging") },
483    { "debug-level", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
484      "gnupg", "|LEVEL|set the debugging level to LEVEL",
485      GC_ARG_TYPE_STRING, GC_BACKEND_GPG_AGENT },
486    { "log-file", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
487      "gnupg", N_("|FILE|write server mode logs to FILE"),
488      GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT },
489    { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
490      NULL, NULL,
491      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
492
493    { "Security",
494      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
495      "gnupg", N_("Options controlling the security") },
496    { "default-cache-ttl", GC_OPT_FLAG_RUNTIME,
497      GC_LEVEL_BASIC, "gnupg", 
498      "|N|expire cached PINs after N seconds",
499      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
500    { "default-cache-ttl-ssh", GC_OPT_FLAG_RUNTIME,
501      GC_LEVEL_ADVANCED, "gnupg",
502      N_("|N|expire SSH keys after N seconds"),
503      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
504    { "max-cache-ttl", GC_OPT_FLAG_RUNTIME,
505      GC_LEVEL_EXPERT, "gnupg",
506      N_("|N|set maximum PIN cache lifetime to N seconds"),
507      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
508    { "max-cache-ttl-ssh", GC_OPT_FLAG_RUNTIME,
509      GC_LEVEL_EXPERT, "gnupg", 
510      N_("|N|set maximum SSH key lifetime to N seconds"),
511      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
512    { "ignore-cache-for-signing", GC_OPT_FLAG_RUNTIME,
513      GC_LEVEL_BASIC, "gnupg", "do not use the PIN cache when signing",
514      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
515    { "allow-mark-trusted", GC_OPT_FLAG_RUNTIME,
516      GC_LEVEL_ADVANCED, "gnupg", "allow clients to mark keys as \"trusted\"",
517      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
518    { "no-grab", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT,
519      "gnupg", "do not grab keyboard and mouse",
520      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
521
522    { "Passphrase policy",
523      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
524      "gnupg", N_("Options enforcing a passphrase policy") },
525    { "enforce-passphrase-constraints", GC_OPT_FLAG_RUNTIME, 
526      GC_LEVEL_EXPERT, "gnupg", 
527      N_("do not allow to bypass the passphrase policy"),
528      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
529    { "min-passphrase-len", GC_OPT_FLAG_RUNTIME,
530      GC_LEVEL_ADVANCED, "gnupg", 
531      N_("|N|set minimal required length for new passphrases to N"),
532      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
533    { "min-passphrase-nonalpha", GC_OPT_FLAG_RUNTIME,
534      GC_LEVEL_EXPERT, "gnupg", 
535      N_("|N|require at least N non-alpha characters for a new passphrase"),
536      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
537    { "check-passphrase-pattern", GC_OPT_FLAG_RUNTIME,
538      GC_LEVEL_EXPERT,
539      "gnupg", N_("|FILE|check new passphrases against pattern in FILE"),
540      GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT },
541    { "max-passphrase-days", GC_OPT_FLAG_RUNTIME,
542      GC_LEVEL_EXPERT, "gnupg", 
543      N_("|N|expire the passphrase after N days"),
544      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
545    { "enable-passphrase-history", GC_OPT_FLAG_RUNTIME, 
546      GC_LEVEL_EXPERT, "gnupg", 
547      N_("do not allow the reuse of old passphrases"),
548      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
549
550    GC_OPTION_NULL
551  };
552
553
554 /* The options of the GC_COMPONENT_SCDAEMON component.  */
555 static gc_option_t gc_options_scdaemon[] =
556  {
557    /* The configuration file to which we write the changes.  */
558    { "gpgconf-scdaemon.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
559      NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON },
560
561    { "Monitor",
562      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
563      "gnupg", N_("Options controlling the diagnostic output") },
564    { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
565      "gnupg", "verbose",
566      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
567    { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
568      "gnupg", "be somewhat more quiet",
569      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
570    { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
571      NULL, NULL,
572      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
573
574    { "Configuration",
575      GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
576      "gnupg", N_("Options controlling the configuration") },
577    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
578      "gnupg", "|FILE|read options from FILE",
579      GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON },
580    { "reader-port", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
581      "gnupg", "|N|connect to reader at port N",
582      GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
583    { "ctapi-driver", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
584      "gnupg", "|NAME|use NAME as ct-API driver",
585      GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
586    { "pcsc-driver", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
587      "gnupg", "|NAME|use NAME as PC/SC driver",
588      GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
589    { "disable-opensc", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
590      "gnupg", "do not use the OpenSC layer",
591      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
592    { "disable-ccid", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
593      "gnupg", "do not use the internal CCID driver",
594      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
595    { "disable-keypad", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
596      "gnupg", "do not use a reader's keypad",
597      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
598
599    { "Debug",
600      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
601      "gnupg", N_("Options useful for debugging") },
602    { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
603      "gnupg", "|LEVEL|set the debugging level to LEVEL",
604      GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
605    { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
606      "gnupg", N_("|FILE|write server mode logs to FILE"),
607      GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON },
608
609    { "Security",
610      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
611      "gnupg", N_("Options controlling the security") },
612    { "allow-admin", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
613      "gnupg", "allow the use of admin card commands",
614      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
615
616
617    GC_OPTION_NULL
618  };
619
620
621 /* The options of the GC_COMPONENT_GPG component.  */
622 static gc_option_t gc_options_gpg[] =
623  {
624    /* The configuration file to which we write the changes.  */
625    { "gpgconf-gpg.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
626      NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG },
627
628    { "Monitor",
629      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
630      "gnupg", N_("Options controlling the diagnostic output") },
631    { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
632      "gnupg", "verbose",
633      GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
634    { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
635      "gnupg", "be somewhat more quiet",
636      GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
637    { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
638      NULL, NULL,
639      GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
640
641    { "Configuration",
642      GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
643      "gnupg", N_("Options controlling the configuration") },
644    { "default-key", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
645      "gnupg", N_("|NAME|use NAME as default secret key"),
646      GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
647    { "encrypt-to", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
648      "gnupg", N_("|NAME|encrypt to user ID NAME as well"),
649      GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
650    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
651      "gnupg", "|FILE|read options from FILE",
652      GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG },
653
654    { "Debug",
655      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
656      "gnupg", N_("Options useful for debugging") },
657    { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
658      "gnupg", "|LEVEL|set the debugging level to LEVEL",
659      GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
660    { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
661      "gnupg", N_("|FILE|write server mode logs to FILE"),
662      GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG },
663 /*    { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, */
664 /*      NULL, NULL, */
665 /*      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG }, */
666
667    { "Keyserver",
668      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
669      "gnupg", N_("Configuration for Keyservers") },
670    { "keyserver", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
671      "gnupg", N_("|URL|use keyserver at URL"),
672      GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
673    { "allow-pka-lookup", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
674      "gnupg", N_("allow PKA lookups (DNS requests)"),
675      GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
676
677
678    GC_OPTION_NULL
679  };
680
681
682
683 /* The options of the GC_COMPONENT_GPGSM component.  */
684 static gc_option_t gc_options_gpgsm[] =
685  {
686    /* The configuration file to which we write the changes.  */
687    { "gpgconf-gpgsm.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
688      NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM },
689
690    { "Monitor",
691      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
692      "gnupg", N_("Options controlling the diagnostic output") },
693    { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
694      "gnupg", "verbose",
695      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
696    { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
697      "gnupg", "be somewhat more quiet",
698      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
699    { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
700      NULL, NULL,
701      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
702
703    { "Configuration",
704      GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
705      "gnupg", N_("Options controlling the configuration") },
706    { "default-key", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
707      "gnupg", N_("|NAME|use NAME as default secret key"),
708      GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
709    { "encrypt-to", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
710      "gnupg", N_("|NAME|encrypt to user ID NAME as well"),
711      GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
712    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
713      "gnupg", "|FILE|read options from FILE",
714      GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM },
715    { "prefer-system-dirmngr", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
716      "gnupg", "use system's dirmngr if available",
717      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
718    { "p12-charset", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
719      "gnupg", N_("|NAME|use encoding NAME for PKCS#12 passphrases"),
720      GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
721
722    { "Debug",
723      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
724      "gnupg", N_("Options useful for debugging") },
725    { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
726      "gnupg", "|LEVEL|set the debugging level to LEVEL",
727      GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
728    { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
729      "gnupg", N_("|FILE|write server mode logs to FILE"),
730      GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM },
731    { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
732      NULL, NULL,
733      GC_ARG_TYPE_UINT32, GC_BACKEND_GPGSM },
734
735    { "Security",
736      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
737      "gnupg", N_("Options controlling the security") },
738    { "disable-crl-checks", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
739      "gnupg", "never consult a CRL",
740      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
741    { "disable-trusted-cert-crl-check", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
742      "gnupg", N_("do not check CRLs for root certificates"),
743      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
744    { "enable-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
745      "gnupg", "check validity using OCSP",
746      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
747    { "include-certs", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
748      "gnupg", "|N|number of certificates to include",
749      GC_ARG_TYPE_INT32, GC_BACKEND_GPGSM },
750    { "disable-policy-checks", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
751      "gnupg", "do not check certificate policies",
752      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
753    { "auto-issuer-key-retrieve", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
754      "gnupg", "fetch missing issuer certificates",
755      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
756    { "cipher-algo", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
757      "gnupg", "|NAME|use cipher algorithm NAME",
758      GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
759
760    GC_OPTION_NULL
761  };
762
763
764 /* The options of the GC_COMPONENT_DIRMNGR component.  */
765 static gc_option_t gc_options_dirmngr[] =
766  {
767    /* The configuration file to which we write the changes.  */
768    { "gpgconf-dirmngr.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
769      NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
770
771    { "Monitor",
772      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
773      "gnupg", N_("Options controlling the diagnostic output") },
774    { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
775      "dirmngr", "verbose",
776      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
777    { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
778      "dirmngr", "be somewhat more quiet",
779      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
780    { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
781      NULL, NULL,
782      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
783
784    { "Format",
785      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
786      "gnupg", N_("Options controlling the format of the output") },
787    { "sh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
788      "dirmngr", "sh-style command output",
789      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
790    { "csh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
791      "dirmngr", "csh-style command output",
792      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
793    
794    { "Configuration",
795      GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
796      "gnupg", N_("Options controlling the configuration") },
797    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
798      "dirmngr", "|FILE|read options from FILE",
799      GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
800
801    { "Debug",
802      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
803      "gnupg", N_("Options useful for debugging") },
804    { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
805      "dirmngr", "|LEVEL|set the debugging level to LEVEL",
806      GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
807    { "no-detach", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
808      "dirmngr", "do not detach from the console",
809      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
810    { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
811      "dirmngr", N_("|FILE|write server mode logs to FILE"),
812      GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
813    { "debug-wait", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
814      NULL, NULL,
815      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
816    { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
817      NULL, NULL,
818      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
819
820    { "Enforcement",
821      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
822      "gnupg", N_("Options controlling the interactivity and enforcement") },
823    { "batch", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
824      "dirmngr", "run without asking a user",
825      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
826    { "force", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
827      "dirmngr", "force loading of outdated CRLs",
828      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
829
830    { "HTTP",
831      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
832      "gnupg", N_("Configuration for HTTP servers") },
833    { "disable-http", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
834      "dirmngr", "inhibit the use of HTTP",
835       GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
836    { "ignore-http-dp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
837      "dirmngr", "ignore HTTP CRL distribution points",
838       GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
839    { "http-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
840      "dirmngr", "|URL|redirect all HTTP requests to URL",
841      GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
842    { "honor-http-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
843      "gnupg", N_("use system's HTTP proxy setting"),
844      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
845
846    { "LDAP",
847      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
848      "gnupg", N_("Configuration of LDAP servers to use") },
849    { "disable-ldap", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
850      "dirmngr", "inhibit the use of LDAP",
851       GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
852    { "ignore-ldap-dp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
853      "dirmngr", "ignore LDAP CRL distribution points",
854       GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
855    { "ldap-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
856      "dirmngr", "|HOST|use HOST for LDAP queries",
857      GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
858    { "only-ldap-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
859      "dirmngr", "do not use fallback hosts with --ldap-proxy",
860       GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
861    { "add-servers", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
862      "dirmngr", "add new servers discovered in CRL distribution points"
863      " to serverlist", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
864    { "ldaptimeout", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
865      "dirmngr", "|N|set LDAP timeout to N seconds",
866      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
867    /* The following entry must not be removed, as it is required for
868       the GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST.  */
869    { "ldapserverlist-file",
870      GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
871      "dirmngr", "|FILE|read LDAP server list from FILE",
872      GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
873    /* This entry must come after at least one entry for
874       GC_BACKEND_DIRMNGR in this component, so that the entry for
875       "ldapserverlist-file will be initialized before this one.  */
876    { "LDAP Server", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
877      "gnupg", N_("LDAP server list"),
878      GC_ARG_TYPE_LDAP_SERVER, GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST },
879    { "max-replies", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
880      "dirmngr", "|N|do not return more than N items in one query",
881      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
882
883    { "OCSP",
884      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
885      "gnupg", N_("Configuration for OCSP") },
886    { "allow-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
887      "dirmngr", "allow sending OCSP requests",
888      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
889    { "ignore-ocsp-service-url", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
890      "dirmngr", "ignore certificate contained OCSP service URLs",
891       GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
892    { "ocsp-responder", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
893      "dirmngr", "|URL|use OCSP responder at URL",
894      GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
895    { "ocsp-signer", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
896      "dirmngr", "|FPR|OCSP response signed by FPR",
897      GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
898
899
900    GC_OPTION_NULL
901  };
902
903 \f
904 /* Component system.  Each component is a set of options that can be
905    configured at the same time.  If you change this, don't forget to
906    update GC_COMPONENT below.  */
907 typedef enum
908   {
909     /* The classic GPG for OpenPGP.  */
910     GC_COMPONENT_GPG,
911
912     /* The GPG Agent.  */
913     GC_COMPONENT_GPG_AGENT,
914
915     /* The Smardcard Daemon.  */
916     GC_COMPONENT_SCDAEMON,
917
918     /* GPG for S/MIME.  */
919     GC_COMPONENT_GPGSM,
920
921     /* The LDAP Directory Manager for CRLs.  */
922     GC_COMPONENT_DIRMNGR,
923
924     /* The number of components.  */
925     GC_COMPONENT_NR
926   } gc_component_t;
927
928
929 /* The information associated with each component.  */
930 static struct
931 {
932   /* The name of this component.  Must not contain a colon (':')
933      character.  */
934   const char *name;
935
936   /* The gettext domain for the description DESC.  If this is NULL,
937      then the description is not translated.  */
938   const char *desc_domain;
939
940   /* The description for this domain.  */
941   const char *desc;
942
943   /* The list of options for this component, terminated by
944      GC_OPTION_NULL.  */
945   gc_option_t *options;
946 } gc_component[] =
947   {
948     { "gpg", NULL,   "GPG for OpenPGP", gc_options_gpg },
949     { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent },
950     { "scdaemon", NULL, "Smartcard Daemon", gc_options_scdaemon },
951     { "gpgsm", NULL, "GPG for S/MIME", gc_options_gpgsm },
952     { "dirmngr", NULL, "Directory Manager", gc_options_dirmngr }
953   };
954
955
956
957 /* Structure used to collect error output of the backend programs.  */
958 struct error_line_s;
959 typedef struct error_line_s *error_line_t;
960 struct error_line_s
961 {
962   error_line_t next;   /* Link to next item.  */
963   const char *fname;   /* Name of the config file (points into BUFFER).  */
964   unsigned int lineno; /* Line number of the config file.  */
965   const char *errtext; /* Text of the error message (points into BUFFER).  */
966   char buffer[1];  /* Helper buffer.  */
967 };
968
969
970 \f
971 /* Engine specific support.  */
972 void
973 gpg_agent_runtime_change (void)
974 {
975 #ifndef HAVE_W32_SYSTEM
976   char *agent = getenv ("GPG_AGENT_INFO");
977   char *pid_str;
978   unsigned long pid_long;
979   char *tail;
980   pid_t pid;
981
982   if (!agent)
983     return;
984
985   pid_str = strchr (agent, ':');
986   if (!pid_str)
987     return;
988
989   pid_str++;
990   errno = 0;
991   pid_long = strtoul (pid_str, &tail, 0);
992   if (errno || (*tail != ':' && *tail != '\0'))
993     return;
994
995   pid = (pid_t) pid_long;
996
997   /* Check for overflow.  */
998   if (pid_long != (unsigned long) pid)
999     return;
1000
1001   /* Ignore any errors here.  */
1002   kill (pid, SIGHUP);
1003 #endif /*!HAVE_W32_SYSTEM*/
1004 }
1005
1006 \f
1007 /* More or less Robust version of dgettext.  It has the side effect of
1008    switching the codeset to utf-8 because this is what we want to
1009    output.  In theory it is posible to keep the orginal code set and
1010    switch back for regular disgnostic output (redefine "_(" for that)
1011    but given the natur of this tool, being something invoked from
1012    other pograms, it does not make much sense.  */
1013 static const char *
1014 my_dgettext (const char *domain, const char *msgid)
1015 {
1016 #ifdef ENABLE_NLS
1017   if (domain)
1018     {
1019       static int switched_codeset;
1020       char *text;
1021       
1022       if (!switched_codeset)
1023         {
1024           switched_codeset = 1;
1025           bind_textdomain_codeset (PACKAGE_GT, "utf-8");
1026
1027           bindtextdomain ("dirmngr", LOCALEDIR);
1028           bind_textdomain_codeset ("dirmngr", "utf-8");
1029    
1030         }
1031
1032       /* Note: This is a hack to actually use the gnupg2 domain as
1033          long we are in a transition phase where gnupg 1.x and 1.9 may
1034          coexist. */
1035       if (!strcmp (domain, "gnupg"))
1036         domain = PACKAGE_GT;
1037
1038       text = dgettext (domain, msgid);
1039       return text ? text : msgid;
1040     }
1041   else
1042 #endif
1043     return msgid;
1044 }
1045
1046
1047 /* Percent-Escape special characters.  The string is valid until the
1048    next invocation of the function.  */
1049 static char *
1050 my_percent_escape (const char *src)
1051 {
1052   static char *esc_str;
1053   static int esc_str_len;
1054   int new_len = 3 * strlen (src) + 1;
1055   char *dst;
1056
1057   if (esc_str_len < new_len)
1058     {
1059       char *new_esc_str = realloc (esc_str, new_len);
1060       if (!new_esc_str)
1061         gc_error (1, errno, "can not escape string");
1062       esc_str = new_esc_str;
1063       esc_str_len = new_len;
1064     }
1065
1066   dst = esc_str;
1067   while (*src)
1068     {
1069       if (*src == '%')
1070         {
1071           *(dst++) = '%';
1072           *(dst++) = '2';
1073           *(dst++) = '5';
1074         }         
1075       else if (*src == ':')
1076         {
1077           /* The colon is used as field separator.  */
1078           *(dst++) = '%';
1079           *(dst++) = '3';
1080           *(dst++) = 'a';
1081         }
1082       else if (*src == ',')
1083         {
1084           /* The comma is used as list separator.  */
1085           *(dst++) = '%';
1086           *(dst++) = '2';
1087           *(dst++) = 'c';
1088         }
1089       else
1090         *(dst++) = *(src);
1091       src++;
1092     }
1093   *dst = '\0';
1094   return esc_str;
1095 }
1096
1097
1098
1099 /* Percent-Deescape special characters.  The string is valid until the
1100    next invocation of the function.  */
1101 static char *
1102 percent_deescape (const char *src)
1103 {
1104   static char *str;
1105   static int str_len;
1106   int new_len = 3 * strlen (src) + 1;
1107   char *dst;
1108
1109   if (str_len < new_len)
1110     {
1111       char *new_str = realloc (str, new_len);
1112       if (!new_str)
1113         gc_error (1, errno, "can not deescape string");
1114       str = new_str;
1115       str_len = new_len;
1116     }
1117
1118   dst = str;
1119   while (*src)
1120     {
1121       if (*src == '%')
1122         {
1123           int val = hextobyte (src + 1);
1124
1125           if (val < 0)
1126             gc_error (1, 0, "malformed end of string %s", src);
1127
1128           *(dst++) = (char) val;
1129           src += 3;
1130         }         
1131       else
1132         *(dst++) = *(src++);
1133     }
1134   *dst = '\0';
1135   return str;
1136 }
1137
1138 \f
1139 /* List all components that are available.  */
1140 void
1141 gc_component_list_components (FILE *out)
1142 {
1143   gc_component_t component;
1144   gc_option_t *option;
1145   gc_backend_t backend;
1146   int backend_seen[GC_BACKEND_NR];
1147   const char *desc;
1148   const char *pgmname;
1149
1150   for (component = 0; component < GC_COMPONENT_NR; component++)
1151     {
1152       option = gc_component[component].options;
1153       if (option)
1154         {
1155           for (backend = 0; backend < GC_BACKEND_NR; backend++)
1156             backend_seen[backend] = 0;
1157
1158           pgmname = "";
1159           for (; option && option->name; option++)
1160             {
1161               if ((option->flags & GC_OPT_FLAG_GROUP))
1162                 continue;
1163               backend = option->backend;
1164               if (backend_seen[backend])
1165                 continue;
1166               backend_seen[backend] = 1;
1167               assert (backend != GC_BACKEND_ANY);
1168               if (gc_backend[backend].program
1169                   && !gc_backend[backend].module_name)
1170                 continue;
1171               pgmname = gnupg_module_name (gc_backend[backend].module_name);
1172               break;
1173             }
1174
1175           desc = gc_component[component].desc;
1176           desc = my_dgettext (gc_component[component].desc_domain, desc);
1177           fprintf (out, "%s:%s:",
1178                    gc_component[component].name,  my_percent_escape (desc));
1179           fprintf (out, "%s\n",  my_percent_escape (pgmname));
1180         }
1181     }
1182 }
1183
1184
1185 \f
1186 static int
1187 all_digits_p (const char *p, size_t len)
1188 {
1189   if (!len)
1190     return 0; /* No. */
1191   for (; len; len--, p++)
1192     if (!isascii (*p) || !isdigit (*p))
1193       return 0; /* No.  */
1194   return 1; /* Yes.  */
1195 }
1196
1197
1198 /* Collect all error lines from file descriptor FD. Only lines
1199    prefixed with TAG are considered.  Close that file descriptor
1200    then.  Returns a list of error line items (which may be empty).
1201    There is no error return.  */
1202 static error_line_t
1203 collect_error_output (int fd, const char *tag)
1204 {
1205   FILE *fp;
1206   char buffer[1024];
1207   char *p, *p2, *p3;
1208   int c, cont_line;
1209   unsigned int pos;
1210   error_line_t eitem, errlines, *errlines_tail;
1211   size_t taglen = strlen (tag);
1212
1213   fp = fdopen (fd, "r");
1214   if (!fp)
1215     gc_error (1, errno, "can't fdopen pipe for reading");
1216
1217   errlines = NULL;
1218   errlines_tail = &errlines;
1219   pos = 0;
1220   cont_line = 0;
1221   while ((c=getc (fp)) != EOF)
1222     {
1223       buffer[pos++] = c;
1224       if (pos >= sizeof buffer - 5 || c == '\n')
1225         {
1226           buffer[pos - (c == '\n')] = 0;
1227           if (cont_line)
1228             ; /*Ignore continuations of previous line. */
1229           else if (!strncmp (buffer, tag, taglen) && buffer[taglen] == ':') 
1230             {
1231               /* "gpgsm: foo:4: bla" */
1232               /* Yep, we are interested in this line.  */
1233               p = buffer + taglen + 1;
1234               while (*p == ' ' || *p == '\t')
1235                 p++;
1236               if (!*p)
1237                 ; /* Empty lines are ignored.  */
1238               else if ( (p2 = strchr (p, ':')) && (p3 = strchr (p2+1, ':'))
1239                         && all_digits_p (p2+1, p3 - (p2+1)))
1240                 {
1241                   /* Line in standard compiler format.  */
1242                   p3++;
1243                   while (*p3 == ' ' || *p3 == '\t')
1244                     p3++;
1245                   eitem = xmalloc (sizeof *eitem + strlen (p));
1246                   eitem->next = NULL;
1247                   strcpy (eitem->buffer, p);
1248                   eitem->fname = eitem->buffer;
1249                   eitem->buffer[p2-p] = 0;
1250                   eitem->errtext = eitem->buffer + (p3 - p);
1251                   /* (we already checked that there are only ascii
1252                      digits followed by a colon) */
1253                   eitem->lineno = 0;
1254                   for (p2++; isdigit (*p2); p2++)
1255                     eitem->lineno = eitem->lineno*10 + (*p2 - '0');
1256                   *errlines_tail = eitem;
1257                   errlines_tail = &eitem->next;
1258                 }
1259               else
1260                 {
1261                   /* Other error output.  */
1262                   eitem = xmalloc (sizeof *eitem + strlen (p));
1263                   eitem->next = NULL;
1264                   strcpy (eitem->buffer, p);
1265                   eitem->fname = NULL;
1266                   eitem->errtext = eitem->buffer;
1267                   eitem->lineno = 0;
1268                   *errlines_tail = eitem;
1269                   errlines_tail = &eitem->next;
1270                 }
1271             }
1272           pos = 0;
1273           /* If this was not a complete line mark that we are in a
1274              continuation.  */
1275           cont_line = (c != '\n');
1276         }
1277     }
1278   
1279   /* We ignore error lines not terminated by a LF.  */
1280
1281   fclose (fp);
1282   return errlines;
1283 }
1284
1285
1286
1287 /* Check all components that are available.  */
1288 void
1289 gc_component_check_programs (FILE *out)
1290 {
1291   gpg_error_t err;
1292   gc_component_t component;
1293   unsigned int result;
1294   int backend_seen[GC_BACKEND_NR];
1295   gc_backend_t backend;
1296   gc_option_t *option;
1297   const char *desc;
1298   const char *pgmname;
1299   const char *argv[2];
1300   pid_t pid;
1301   int exitcode;
1302   int filedes[2];
1303   error_line_t errlines, errptr;
1304
1305   /* We use a temporary file to collect the error output.  It would be
1306      better to use a pipe here but as of now we have no suitable
1307      fucntion to create a portable pipe outside of exechelp.  Thus it
1308      is easier to use the tempfile approach.  */
1309   for (component = 0; component < GC_COMPONENT_NR; component++)
1310     {
1311       if (!gc_component[component].options)
1312         continue;
1313
1314       for (backend = 0; backend < GC_BACKEND_NR; backend++)
1315         backend_seen[backend] = 0;
1316
1317       option = gc_component[component].options;
1318       for (; option && option->name; option++)
1319         {
1320           if ((option->flags & GC_OPT_FLAG_GROUP))
1321             continue;
1322           backend = option->backend;
1323           if (backend_seen[backend])
1324             continue;
1325           backend_seen[backend] = 1;
1326           assert (backend != GC_BACKEND_ANY);
1327           if (!gc_backend[backend].program)
1328             continue;
1329           if (!gc_backend[backend].module_name)
1330             continue;
1331
1332           pgmname = gnupg_module_name (gc_backend[backend].module_name);
1333           argv[0] = "--gpgconf-test";
1334           argv[1] = NULL;
1335
1336           err = gnupg_create_inbound_pipe (filedes);
1337           if (err)
1338             gc_error (1, 0, _("error creating a pipe: %s\n"), 
1339                       gpg_strerror (err));
1340
1341           result = 0;
1342           errlines = NULL;
1343           if (gnupg_spawn_process_fd (pgmname, argv, -1, -1, filedes[1], &pid))
1344             {
1345               close (filedes[0]);
1346               close (filedes[1]);
1347               result |= 1; /* Program could not be run.  */
1348             }
1349           else 
1350             {
1351               close (filedes[1]);
1352               errlines = collect_error_output (filedes[0], 
1353                                                gc_component[component].name);
1354               if (gnupg_wait_process (pgmname, pid, &exitcode))
1355                 {
1356                   if (exitcode == -1)
1357                     result |= 1; /* Program could not be run or it
1358                                     terminated abnormally.  */
1359                   result |= 2; /* Program returned an error.  */
1360                 }
1361             }
1362           
1363           /* If the program could not be run, we can't tell whether
1364              the config file is good.  */
1365           if ((result&1))
1366             result |= 2;  
1367           
1368           desc = gc_component[component].desc;
1369           desc = my_dgettext (gc_component[component].desc_domain, desc);
1370           fprintf (out, "%s:%s:",
1371                    gc_component[component].name, my_percent_escape (desc));
1372           fputs (my_percent_escape (pgmname), out);
1373           fprintf (out, ":%d:%d:", !(result & 1), !(result & 2));
1374           for (errptr = errlines; errptr; errptr = errptr->next)
1375             {
1376               if (errptr != errlines)
1377                 fputs ("\n:::::", out); /* Continuation line.  */
1378               if (errptr->fname)
1379                 fputs (my_percent_escape (errptr->fname), out);
1380               putc (':', out);
1381               if (errptr->fname)
1382                 fprintf (out, "%u", errptr->lineno);
1383               putc (':', out);
1384               fputs (my_percent_escape (errptr->errtext), out);
1385               putc (':', out);
1386             }
1387           putc ('\n', out);
1388           
1389           while (errlines)
1390             {
1391               error_line_t tmp = errlines->next;
1392               xfree (errlines);
1393               errlines = tmp;
1394             }
1395           break; /* Loop over options of this component  */
1396         }
1397     } 
1398 }
1399
1400
1401 \f
1402 /* Find the component with the name NAME.  Returns -1 if not
1403    found.  */
1404 int
1405 gc_component_find (const char *name)
1406 {
1407   gc_component_t idx;
1408
1409   for (idx = 0; idx < GC_COMPONENT_NR; idx++)
1410     {
1411       if (gc_component[idx].options
1412           && !strcmp (name, gc_component[idx].name))
1413         return idx;
1414     }
1415   return -1;
1416 }
1417
1418 \f
1419 /* List the option OPTION.  */
1420 static void
1421 list_one_option (const gc_option_t *option, FILE *out)
1422 {
1423   const char *desc = NULL;
1424   char *arg_name = NULL;
1425
1426   if (option->desc)
1427     {
1428       desc = my_dgettext (option->desc_domain, option->desc);
1429
1430       if (*desc == '|')
1431         {
1432           const char *arg_tail = strchr (&desc[1], '|');
1433
1434           if (arg_tail)
1435             {
1436               int arg_len = arg_tail - &desc[1];
1437               arg_name = xmalloc (arg_len + 1);
1438               memcpy (arg_name, &desc[1], arg_len);
1439               arg_name[arg_len] = '\0';
1440               desc = arg_tail + 1;
1441             }
1442         }
1443     }
1444
1445
1446   /* YOU MUST NOT REORDER THE FIELDS IN THIS OUTPUT, AS THEIR ORDER IS
1447      PART OF THE EXTERNAL INTERFACE.  YOU MUST NOT REMOVE ANY
1448      FIELDS.  */
1449
1450   /* The name field.  */
1451   fprintf (out, "%s", option->name);
1452
1453   /* The flags field.  */
1454   fprintf (out, ":%lu", option->flags);
1455   if (opt.verbose)
1456     {
1457       putc (' ', out);
1458           
1459       if (!option->flags)
1460         fprintf (out, "none");
1461       else
1462         {
1463           unsigned long flags = option->flags;
1464           unsigned long flag = 0;
1465           unsigned long first = 1;
1466
1467           while (flags)
1468             {
1469               if (flags & 1)
1470                 {
1471                   if (first)
1472                     first = 0;
1473                   else
1474                     putc (',', out);
1475                   fprintf (out, "%s", gc_flag[flag].name);
1476                 }
1477               flags >>= 1;
1478               flag++;
1479             }
1480         }
1481     }
1482
1483   /* The level field.  */
1484   fprintf (out, ":%u", option->level);
1485   if (opt.verbose)
1486     fprintf (out, " %s", gc_level[option->level].name);
1487
1488   /* The description field.  */
1489   fprintf (out, ":%s", desc ? my_percent_escape (desc) : "");
1490   
1491   /* The type field.  */
1492   fprintf (out, ":%u", option->arg_type);
1493   if (opt.verbose)
1494     fprintf (out, " %s", gc_arg_type[option->arg_type].name);
1495
1496   /* The alternate type field.  */
1497   fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback);
1498   if (opt.verbose)
1499     fprintf (out, " %s",
1500              gc_arg_type[gc_arg_type[option->arg_type].fallback].name);
1501
1502   /* The argument name field.  */
1503   fprintf (out, ":%s", arg_name ? my_percent_escape (arg_name) : "");
1504   if (arg_name)
1505     xfree (arg_name);
1506
1507   /* The default value field.  */
1508   fprintf (out, ":%s", option->default_value ? option->default_value : "");
1509
1510   /* The default argument field.  */
1511   fprintf (out, ":%s", option->default_arg ? option->default_arg : "");
1512
1513   /* The value field.  */
1514   if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
1515       && (option->flags & GC_OPT_FLAG_LIST)
1516       && option->value)
1517     /* The special format "1,1,1,1,...,1" is converted to a number
1518        here.  */
1519     fprintf (out, ":%u", (unsigned int)((strlen (option->value) + 1) / 2));
1520   else
1521     fprintf (out, ":%s", option->value ? option->value : "");
1522
1523   /* ADD NEW FIELDS HERE.  */
1524
1525   putc ('\n', out);
1526 }
1527
1528
1529 /* List all options of the component COMPONENT.  */
1530 void
1531 gc_component_list_options (int component, FILE *out)
1532 {  
1533   const gc_option_t *option = gc_component[component].options;
1534
1535   while (option && option->name)
1536     {
1537       /* Do not output unknown or internal options.  */
1538       if (!(option->flags & GC_OPT_FLAG_GROUP)
1539           && (!option->active || option->level == GC_LEVEL_INTERNAL))
1540         {
1541           option++;
1542           continue;
1543         }
1544
1545       if (option->flags & GC_OPT_FLAG_GROUP)
1546         {
1547           const gc_option_t *group_option = option + 1;
1548           gc_expert_level_t level = GC_LEVEL_NR;
1549
1550           /* The manual states that the group level is always the
1551              minimum of the levels of all contained options.  Due to
1552              different active options, and because it is hard to
1553              maintain manually, we calculate it here.  The value in
1554              the global static table is ignored.  */
1555           
1556           while (group_option->name)
1557             {
1558               if (group_option->flags & GC_OPT_FLAG_GROUP)
1559                 break;
1560               if (group_option->level < level)
1561                 level = group_option->level;
1562               group_option++;
1563             }
1564
1565           /* Check if group is empty.  */
1566           if (level != GC_LEVEL_NR)
1567             {
1568               gc_option_t opt_copy;
1569
1570               /* Fix up the group level.  */
1571               memcpy (&opt_copy, option, sizeof (opt_copy));
1572               opt_copy.level = level;
1573               list_one_option (&opt_copy, out);
1574             }
1575         }
1576       else
1577         list_one_option (option, out);
1578
1579       option++;
1580     }
1581 }
1582
1583
1584 /* Find the option NAME in component COMPONENT, for the backend
1585    BACKEND.  If BACKEND is GC_BACKEND_ANY, any backend will match.  */
1586 static gc_option_t *
1587 find_option (gc_component_t component, const char *name,
1588              gc_backend_t backend)
1589 {
1590   gc_option_t *option = gc_component[component].options;
1591   while (option->name)
1592     {
1593       if (!(option->flags & GC_OPT_FLAG_GROUP)
1594           && !strcmp (option->name, name)
1595           && (backend == GC_BACKEND_ANY || option->backend == backend))
1596         break;
1597       option++;
1598     }
1599   return option->name ? option : NULL;
1600 }
1601
1602 \f
1603 /* Determine the configuration pathname for the component COMPONENT
1604    and backend BACKEND.  */
1605 static char *
1606 get_config_pathname (gc_component_t component, gc_backend_t backend)
1607 {
1608   char *pathname = NULL;
1609   gc_option_t *option = find_option
1610     (component, gc_backend[backend].option_config_filename, GC_BACKEND_ANY);
1611   assert (option);
1612   assert (option->arg_type == GC_ARG_TYPE_PATHNAME);
1613   assert (!(option->flags & GC_OPT_FLAG_LIST));
1614
1615   if (!option->active || !option->default_value)
1616     gc_error (1, 0, "Option %s, needed by backend %s, was not initialized",
1617               gc_backend[backend].option_config_filename,
1618               gc_backend[backend].name);
1619
1620   if (option->value && *option->value)
1621     pathname = percent_deescape (&option->value[1]);
1622   else if (option->default_value && *option->default_value)
1623     pathname = percent_deescape (&option->default_value[1]);
1624   else
1625     pathname = "";
1626
1627 #ifdef HAVE_DOSISH_SYSTEM
1628   if (!(pathname[0] 
1629         && pathname[1] == ':'
1630         && (pathname[2] == '/' || pathname[2] == '\\')))
1631 #else
1632   if (pathname[0] != '/')
1633 #endif
1634     gc_error (1, 0, "Option %s, needed by backend %s, is not absolute",
1635               gc_backend[backend].option_config_filename,
1636               gc_backend[backend].name);
1637
1638   return pathname;
1639 }
1640
1641 \f
1642 /* Retrieve the options for the component COMPONENT from backend
1643    BACKEND, which we already know is a program-type backend.  */
1644 static void
1645 retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
1646 {
1647   gpg_error_t err;
1648   int filedes[2];
1649   const char *pgmname;
1650   const char *argv[2];
1651   int exitcode;
1652   pid_t pid;
1653   char *line = NULL;
1654   size_t line_len = 0;
1655   ssize_t length;
1656   FILE *config;
1657   char *config_pathname;
1658
1659   err = gnupg_create_inbound_pipe (filedes);
1660   if (err)
1661     gc_error (1, 0, _("error creating a pipe: %s\n"), gpg_strerror (err));
1662
1663   pgmname = (gc_backend[backend].module_name 
1664              ? gnupg_module_name (gc_backend[backend].module_name) 
1665              : gc_backend[backend].program );
1666   argv[0] = "--gpgconf-list";
1667   argv[1] = NULL;
1668
1669   err = gnupg_spawn_process_fd (pgmname, argv, -1, filedes[1], -1, &pid);
1670   if (err)
1671     {
1672       close (filedes[0]);
1673       close (filedes[1]);
1674       gc_error (1, 0, "could not gather active options from `%s': %s",
1675                 pgmname, gpg_strerror (err));
1676     }
1677   close (filedes[1]);
1678   config = fdopen (filedes[0], "r");
1679   if (!config)
1680     gc_error (1, errno, "can't fdopen pipe for reading");
1681
1682   while ((length = read_line (config, &line, &line_len, NULL)) > 0)
1683     {
1684       gc_option_t *option;
1685       char *linep;
1686       unsigned long flags = 0;
1687       char *default_value = NULL;
1688       
1689       /* Strip newline and carriage return, if present.  */
1690       while (length > 0
1691              && (line[length - 1] == '\n' || line[length - 1] == '\r'))
1692         line[--length] = '\0';
1693
1694       linep = strchr (line, ':');
1695       if (linep)
1696         *(linep++) = '\0';
1697       
1698       /* Extract additional flags.  Default to none.  */
1699       if (linep)
1700         {
1701           char *end;
1702           char *tail;
1703
1704           end = strchr (linep, ':');
1705           if (end)
1706             *(end++) = '\0';
1707
1708           errno = 0;
1709           flags = strtoul (linep, &tail, 0);
1710           if (errno)
1711             gc_error (1, errno, "malformed flags in option %s from %s",
1712                       line, pgmname);
1713           if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
1714             gc_error (1, 0, "garbage after flags in option %s from %s",
1715                       line, pgmname);
1716
1717           linep = end;
1718         }
1719
1720       /* Extract default value, if present.  Default to empty if
1721          not.  */
1722       if (linep)
1723         {
1724           char *end;
1725
1726           end = strchr (linep, ':');
1727           if (end)
1728             *(end++) = '\0';
1729
1730           if (flags & GC_OPT_FLAG_DEFAULT)
1731             default_value = linep;
1732
1733           linep = end;
1734         }
1735
1736       /* Look up the option in the component and install the
1737          configuration data.  */
1738       option = find_option (component, line, backend);
1739       if (option)
1740         {
1741           if (option->active)
1742             gc_error (1, errno, "option %s returned twice from %s",
1743                       line, pgmname);
1744           option->active = 1;
1745
1746           option->flags |= flags;
1747           if (default_value && *default_value)
1748             option->default_value = xstrdup (default_value);
1749         }
1750     }
1751   if (length < 0 || ferror (config))
1752     gc_error (1, errno, "error reading from %s",pgmname);
1753   if (fclose (config) && ferror (config))
1754     gc_error (1, errno, "error closing %s", pgmname);
1755
1756   err = gnupg_wait_process (pgmname, pid, &exitcode);
1757   if (err)
1758     gc_error (1, 0, "running %s failed (exitcode=%d): %s",
1759               pgmname, exitcode, gpg_strerror (err));
1760
1761
1762   /* At this point, we can parse the configuration file.  */
1763   config_pathname = get_config_pathname (component, backend);
1764
1765   config = fopen (config_pathname, "r");
1766   if (!config)
1767     gc_error (0, errno, "warning: can not open config file %s",
1768               config_pathname);
1769   else
1770     {
1771       while ((length = read_line (config, &line, &line_len, NULL)) > 0)
1772         {
1773           char *name;
1774           char *value;
1775           gc_option_t *option;
1776           
1777           name = line;
1778           while (*name == ' ' || *name == '\t')
1779             name++;
1780           if (!*name || *name == '#' || *name == '\r' || *name == '\n')
1781             continue;
1782
1783           value = name;
1784           while (*value && *value != ' ' && *value != '\t'
1785                  && *value != '#' && *value != '\r' && *value != '\n')
1786             value++;
1787           if (*value == ' ' || *value == '\t')
1788             {
1789               char *end;
1790
1791               *(value++) = '\0';
1792               while (*value == ' ' || *value == '\t')
1793                 value++;
1794
1795               end = value;
1796               while (*end && *end != '#' && *end != '\r' && *end != '\n')
1797                 end++;
1798               while (end > value && (end[-1] == ' ' || end[-1] == '\t'))
1799                 end--;
1800               *end = '\0';
1801             }
1802           else
1803             *value = '\0';
1804
1805           /* Look up the option in the component and install the
1806              configuration data.  */
1807           option = find_option (component, line, backend);
1808           if (option)
1809             {
1810               char *opt_value;
1811
1812               if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
1813                 {
1814                   if (*value)
1815                     gc_error (0, 0,
1816                               "warning: ignoring argument %s for option %s",
1817                               value, name);
1818                   opt_value = xstrdup ("1");
1819                 }
1820               else if (gc_arg_type[option->arg_type].fallback
1821                        == GC_ARG_TYPE_STRING)
1822                 opt_value = xasprintf ("\"%s", my_percent_escape (value));
1823               else
1824                 {
1825                   /* FIXME: Verify that the number is sane.  */
1826                   opt_value = xstrdup (value);
1827                 }
1828
1829               /* Now enter the option into the table.  */
1830               if (!(option->flags & GC_OPT_FLAG_LIST))
1831                 {
1832                   if (option->value)
1833                     free (option->value);
1834                   option->value = opt_value;
1835                 }
1836               else
1837                 {
1838                   if (!option->value)
1839                     option->value = opt_value;
1840                   else
1841                     {
1842                       char *opt_val = opt_value;
1843
1844                       option->value = xasprintf ("%s,%s", option->value,
1845                                                  opt_val);
1846                       xfree (opt_value);
1847                     }
1848                 }
1849             }
1850         }
1851
1852       if (length < 0 || ferror (config))
1853         gc_error (1, errno, "error reading from %s", config_pathname);
1854       if (fclose (config) && ferror (config))
1855         gc_error (1, errno, "error closing %s", config_pathname);
1856     }
1857
1858   xfree (line);
1859 }
1860
1861
1862 /* Retrieve the options for the component COMPONENT from backend
1863    BACKEND, which we already know is of type file list.  */ 
1864 static void
1865 retrieve_options_from_file (gc_component_t component, gc_backend_t backend)
1866 {
1867   gc_option_t *list_option;
1868   char *list_pathname;
1869   FILE *list_file;
1870   char *line = NULL;
1871   size_t line_len = 0;
1872   ssize_t length;
1873   char *list = NULL;
1874
1875   list_option = find_option (component,
1876                              gc_backend[backend].option_name, GC_BACKEND_ANY);
1877   assert (list_option);
1878   assert (!list_option->active);
1879
1880   list_pathname = get_config_pathname (component, backend);
1881   list_file = fopen (list_pathname, "r");
1882   if (!list_file)
1883     gc_error (0, errno, "warning: can not open list file %s", list_pathname);
1884   else
1885     {
1886
1887       while ((length = read_line (list_file, &line, &line_len, NULL)) > 0)
1888         {
1889           char *start;
1890           char *end;
1891           char *new_list;
1892
1893           start = line;
1894           while (*start == ' ' || *start == '\t')
1895             start++;
1896           if (!*start || *start == '#' || *start == '\r' || *start == '\n')
1897             continue;
1898
1899           end = start;
1900           while (*end && *end != '#' && *end != '\r' && *end != '\n')
1901             end++;
1902           /* Walk back to skip trailing white spaces.  Looks evil, but
1903              works because of the conditions on START and END imposed
1904              at this point (END is at least START + 1, and START is
1905              not a whitespace character).  */
1906           while (*(end - 1) == ' ' || *(end - 1) == '\t')
1907             end--;
1908           *end = '\0';
1909           /* FIXME: Oh, no!  This is so lame!  Should use realloc and
1910              really append.  */
1911           if (list)
1912             {
1913               new_list = xasprintf ("%s,\"%s", list, my_percent_escape (start));
1914               xfree (list);
1915               list = new_list;
1916             }
1917           else
1918             list = xasprintf ("\"%s", my_percent_escape (start));
1919         }
1920       if (length < 0 || ferror (list_file))
1921         gc_error (1, errno, "can not read list file %s", list_pathname);
1922     }
1923
1924   list_option->active = 1;
1925   list_option->value = list;
1926
1927   if (list_file && fclose (list_file) && ferror (list_file))
1928     gc_error (1, errno, "error closing %s", list_pathname);
1929   xfree (line);
1930 }
1931
1932
1933 /* Retrieve the currently active options and their defaults from all
1934    involved backends for this component.  Using -1 for component will
1935    retrieve all options from all components. */
1936 void
1937 gc_component_retrieve_options (int component)
1938 {
1939   int process_all = 0;
1940   int backend_seen[GC_BACKEND_NR];
1941   gc_backend_t backend;
1942   gc_option_t *option;
1943
1944   for (backend = 0; backend < GC_BACKEND_NR; backend++)
1945     backend_seen[backend] = 0;
1946
1947   if (component == -1)
1948     {
1949       process_all = 1;
1950       component = 0;
1951       assert (component < GC_COMPONENT_NR);
1952     }
1953       
1954   do
1955     {
1956       option = gc_component[component].options;
1957
1958       while (option && option->name)
1959         {
1960           if (!(option->flags & GC_OPT_FLAG_GROUP))
1961             {
1962               backend = option->backend;
1963               
1964               if (backend_seen[backend])
1965                 {
1966                   option++;
1967                   continue;
1968                 }
1969               backend_seen[backend] = 1;
1970               
1971               assert (backend != GC_BACKEND_ANY);
1972               
1973               if (gc_backend[backend].program)
1974                 retrieve_options_from_program (component, backend);
1975               else
1976                 retrieve_options_from_file (component, backend);
1977             }
1978           option++;
1979         }
1980     }
1981   while (process_all && ++component < GC_COMPONENT_NR);
1982
1983 }
1984
1985
1986 \f
1987 /* Perform a simple validity check based on the type.  Return in
1988    NEW_VALUE_NR the value of the number in NEW_VALUE if OPTION is of
1989    type GC_ARG_TYPE_NONE.  */
1990 static void
1991 option_check_validity (gc_option_t *option, unsigned long flags,
1992                        char *new_value, unsigned long *new_value_nr)
1993 {
1994   char *arg;
1995
1996   if (!option->active)
1997     gc_error (1, 0, "option %s not supported by backend %s",
1998               option->name, gc_backend[option->backend].name);
1999       
2000   if (option->new_flags || option->new_value)
2001     gc_error (1, 0, "option %s already changed", option->name);
2002
2003   if (flags & GC_OPT_FLAG_DEFAULT)
2004     {
2005       if (*new_value)
2006         gc_error (1, 0, "argument %s provided for deleted option %s",
2007                   new_value, option->name);
2008
2009       return;
2010     }
2011
2012   /* GC_ARG_TYPE_NONE options have special list treatment.  */
2013   if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
2014     {
2015       char *tail;
2016
2017       errno = 0;
2018       *new_value_nr = strtoul (new_value, &tail, 0);
2019
2020       if (errno)
2021         gc_error (1, errno, "invalid argument for option %s",
2022                   option->name);
2023       if (*tail)
2024         gc_error (1, 0, "garbage after argument for option %s",
2025                       option->name);
2026
2027       if (!(option->flags & GC_OPT_FLAG_LIST))
2028         {
2029           if (*new_value_nr != 1)
2030             gc_error (1, 0, "argument for non-list option %s of type 0 "
2031                       "(none) must be 1", option->name);
2032         }
2033       else
2034         {
2035           if (*new_value_nr == 0)
2036             gc_error (1, 0, "argument for option %s of type 0 (none) "
2037                       "must be positive", option->name);
2038         }
2039
2040       return;
2041     }
2042
2043   arg = new_value;
2044   do
2045     {
2046       if (*arg == '\0' || *arg == ',')
2047         {
2048           if (!(option->flags & GC_OPT_FLAG_ARG_OPT))
2049             gc_error (1, 0, "argument required for option %s", option->name);
2050
2051           if (*arg == ',' && !(option->flags & GC_OPT_FLAG_LIST))
2052             gc_error (1, 0, "list found for non-list option %s", option->name);
2053         }
2054       else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING)
2055         {
2056           if (*arg != '"')
2057             gc_error (1, 0, "string argument for option %s must begin "
2058                       "with a quote (\") character", option->name);
2059         }
2060       else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
2061         {
2062           errno = 0;
2063           (void) strtol (arg, &arg, 0);
2064
2065           if (errno)
2066             gc_error (1, errno, "invalid argument for option %s",
2067                       option->name);
2068
2069           if (*arg != '\0' && *arg != ',')
2070             gc_error (1, 0, "garbage after argument for option %s",
2071                       option->name);
2072         }
2073       else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
2074         {
2075           errno = 0;
2076           (void) strtoul (arg, &arg, 0);
2077
2078           if (errno)
2079             gc_error (1, errno, "invalid argument for option %s",
2080                       option->name);
2081
2082           if (*arg != '\0' && *arg != ',')
2083             gc_error (1, 0, "garbage after argument for option %s",
2084                       option->name);
2085         }
2086       arg = strchr (arg, ',');
2087       if (arg)
2088         arg++;
2089     }
2090   while (arg && *arg);
2091 }
2092
2093 #ifdef HAVE_W32_SYSTEM
2094 int
2095 copy_file (const char *src_name, const char *dst_name)
2096 {
2097 #define BUF_LEN 4096
2098   char buffer[BUF_LEN];
2099   int len;
2100   FILE *src;
2101   FILE *dst;
2102
2103   src = fopen (src_name, "r");
2104   if (src == NULL)
2105     return -1;
2106
2107   dst = fopen (dst_name, "w");
2108   if (dst == NULL)
2109     {
2110       int saved_err = errno;
2111       fclose (src);
2112       errno = saved_err;
2113       return -1;
2114     }
2115
2116   do
2117     {
2118       int written;
2119
2120       len = fread (buffer, 1, BUF_LEN, src);
2121       if (len == 0)
2122         break;
2123       written = fwrite (buffer, 1, len, dst);
2124       if (written != len)
2125         break;
2126     }
2127   while (!feof (src) && !ferror (src) && !ferror (dst));
2128
2129   if (ferror (src) || ferror (dst) || !feof (src))
2130     {
2131       int saved_errno = errno;
2132       fclose (src);
2133       fclose (dst);
2134       unlink (dst_name);
2135       errno = saved_errno;
2136       return -1;
2137     }
2138
2139   if (fclose (dst) && ferror (dst))
2140     gc_error (1, errno, "error closing %s", dst_name);
2141   if (fclose (src) && ferror (src))
2142     gc_error (1, errno, "error closing %s", src_name);
2143
2144   return 0;
2145 }
2146 #endif /* HAVE_W32_SYSTEM */
2147
2148
2149 /* Create and verify the new configuration file for the specified
2150    backend and component.  Returns 0 on success and -1 on error.  */
2151 static int
2152 change_options_file (gc_component_t component, gc_backend_t backend,
2153                      char **src_filenamep, char **dest_filenamep,
2154                      char **orig_filenamep)
2155 {
2156   static const char marker[] = "###+++--- GPGConf ---+++###";
2157   /* True if we are within the marker in the config file.  */
2158   int in_marker = 0;
2159   gc_option_t *option;
2160   char *line = NULL;
2161   size_t line_len;
2162   ssize_t length;
2163   int res;
2164   int fd;
2165   FILE *src_file = NULL;
2166   FILE *dest_file = NULL;
2167   char *src_filename;
2168   char *dest_filename;
2169   char *orig_filename;
2170   char *arg;
2171   char *cur_arg = NULL;
2172
2173   option = find_option (component,
2174                         gc_backend[backend].option_name, GC_BACKEND_ANY);
2175   assert (option);
2176   assert (option->active);
2177   assert (gc_arg_type[option->arg_type].fallback != GC_ARG_TYPE_NONE);
2178
2179   /* FIXME.  Throughout the function, do better error reporting.  */
2180   /* Note that get_config_pathname() calls percent_deescape(), so we
2181      call this before processing the arguments.  */
2182   dest_filename = xstrdup (get_config_pathname (component, backend));
2183   src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ());
2184   orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ());
2185
2186   arg = option->new_value;
2187   if (arg && arg[0] == '\0')
2188     arg = NULL;
2189   else if (arg)
2190     {
2191       char *end;
2192
2193       arg++;
2194       end = strchr (arg, ',');
2195       if (end)
2196         *end = '\0';
2197
2198       cur_arg = percent_deescape (arg);
2199       if (end)
2200         {
2201           *end = ',';
2202           arg = end + 1;
2203         }
2204       else
2205         arg = NULL;
2206     }
2207
2208 #ifdef HAVE_W32_SYSTEM
2209   res = copy_file (dest_filename, orig_filename);
2210 #else
2211   res = link (dest_filename, orig_filename);
2212 #endif
2213   if (res < 0 && errno != ENOENT)
2214     return -1;
2215   if (res < 0)
2216     {
2217       xfree (orig_filename);
2218       orig_filename = NULL;
2219     }
2220
2221   /* We now initialize the return strings, so the caller can do the
2222      cleanup for us.  */
2223   *src_filenamep = src_filename;
2224   *dest_filenamep = dest_filename;
2225   *orig_filenamep = orig_filename;
2226
2227   /* Use open() so that we can use O_EXCL.  */
2228   fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
2229   if (fd < 0)
2230     return -1;
2231   src_file = fdopen (fd, "w");
2232   res = errno;
2233   if (!src_file)
2234     {
2235       errno = res;
2236       return -1;
2237     }
2238
2239   /* Only if ORIG_FILENAME is not NULL did the configuration file
2240      exist already.  In this case, we will copy its content into the
2241      new configuration file, changing it to our liking in the
2242      process.  */
2243   if (orig_filename)
2244     {
2245       dest_file = fopen (dest_filename, "r");
2246       if (!dest_file)
2247         goto change_file_one_err;
2248
2249       while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
2250         {
2251           int disable = 0;
2252           char *start;
2253
2254           if (!strncmp (marker, line, sizeof (marker) - 1))
2255             {
2256               if (!in_marker)
2257                 in_marker = 1;
2258               else
2259                 break;
2260             }
2261
2262           start = line;
2263           while (*start == ' ' || *start == '\t')
2264             start++;
2265           if (*start && *start != '\r' && *start != '\n' && *start != '#')
2266             {
2267               char *end;
2268               char *endp;
2269               char saved_end;
2270
2271               endp = start;
2272               end = endp;
2273
2274               /* Search for the end of the line.  */
2275               while (*endp && *endp != '#' && *endp != '\r' && *endp != '\n')
2276                 {
2277                   endp++;
2278                   if (*endp && *endp != ' ' && *endp != '\t'
2279                       && *endp != '\r' && *endp != '\n' && *endp != '#')
2280                     end = endp + 1;
2281                 }
2282               saved_end = *end;
2283               *end = '\0';
2284
2285               if ((option->new_flags & GC_OPT_FLAG_DEFAULT)
2286                   || !cur_arg || strcmp (start, cur_arg))
2287                 disable = 1;
2288               else
2289                 {
2290                   /* Find next argument.  */
2291                   if (arg)
2292                     {
2293                       char *arg_end;
2294
2295                       arg++;
2296                       arg_end = strchr (arg, ',');
2297                       if (arg_end)
2298                         *arg_end = '\0';
2299
2300                       cur_arg = percent_deescape (arg);
2301                       if (arg_end)
2302                         {
2303                           *arg_end = ',';
2304                           arg = arg_end + 1;
2305                         }
2306                       else
2307                         arg = NULL;
2308                     }
2309                   else
2310                     cur_arg = NULL;
2311                 }
2312
2313               *end = saved_end;
2314             }
2315
2316           if (disable)
2317             {
2318               if (!in_marker)
2319                 {
2320                   fprintf (src_file,
2321                            "# GPGConf disabled this option here at %s\n",
2322                            asctimestamp (gnupg_get_time ()));
2323                   if (ferror (src_file))
2324                     goto change_file_one_err;
2325                   fprintf (src_file, "# %s", line);
2326                   if (ferror (src_file))
2327                     goto change_file_one_err;
2328                 }
2329             }
2330           else
2331             {
2332               fprintf (src_file, "%s", line);
2333               if (ferror (src_file))
2334                 goto change_file_one_err;
2335             }
2336         }
2337       if (length < 0 || ferror (dest_file))
2338         goto change_file_one_err;
2339     }
2340
2341   if (!in_marker)
2342     {
2343       /* There was no marker.  This is the first time we edit the
2344          file.  We add our own marker at the end of the file and
2345          proceed.  Note that we first write a newline, this guards us
2346          against files which lack the newline at the end of the last
2347          line, while it doesn't hurt us in all other cases.  */
2348       fprintf (src_file, "\n%s\n", marker);
2349       if (ferror (src_file))
2350         goto change_file_one_err;
2351     }
2352
2353   /* At this point, we have copied everything up to the end marker
2354      into the new file, except for the arguments we are going to add.
2355      Now, dump the new arguments and write the end marker, possibly
2356      followed by the rest of the original file.  */
2357   while (cur_arg)
2358     {
2359       fprintf (src_file, "%s\n", cur_arg);
2360
2361       /* Find next argument.  */
2362       if (arg)
2363         {
2364           char *end;
2365
2366           arg++;
2367           end = strchr (arg, ',');
2368           if (end)
2369             *end = '\0';
2370
2371           cur_arg = percent_deescape (arg);
2372           if (end)
2373             {
2374               *end = ',';
2375               arg = end + 1;
2376             }
2377           else
2378             arg = NULL;
2379         }
2380       else
2381         cur_arg = NULL;
2382     }
2383
2384   fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
2385   if (ferror (src_file))
2386     goto change_file_one_err;
2387
2388   if (!in_marker)
2389     {
2390       fprintf (src_file, "# GPGConf edited this configuration file.\n");
2391       if (ferror (src_file))
2392         goto change_file_one_err;
2393       fprintf (src_file, "# It will disable options before this marked "
2394                "block, but it will\n");
2395       if (ferror (src_file))
2396         goto change_file_one_err;
2397       fprintf (src_file, "# never change anything below these lines.\n");
2398       if (ferror (src_file))
2399         goto change_file_one_err;
2400     }
2401   if (dest_file)
2402     {
2403       while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
2404         {
2405           fprintf (src_file, "%s", line);
2406           if (ferror (src_file))
2407             goto change_file_one_err;
2408         }
2409       if (length < 0 || ferror (dest_file))
2410         goto change_file_one_err;
2411     }
2412   xfree (line);
2413   line = NULL;
2414
2415   res = fclose (src_file);
2416   if (res)
2417     {
2418       res = errno;
2419       close (fd);
2420       if (dest_file)
2421         fclose (dest_file);
2422       errno = res;
2423       return -1;
2424     }
2425   close (fd);
2426   if (dest_file)
2427     {
2428       res = fclose (dest_file);
2429       if (res)
2430         return -1;
2431     }
2432   return 0;
2433
2434  change_file_one_err:
2435   xfree (line);
2436   res = errno;
2437   if (src_file)
2438     {
2439       fclose (src_file);
2440       close (fd);
2441     }
2442   if (dest_file)
2443     fclose (dest_file);
2444   errno = res;
2445   return -1;
2446 }
2447
2448
2449 /* Create and verify the new configuration file for the specified
2450    backend and component.  Returns 0 on success and -1 on error.  */
2451 static int
2452 change_options_program (gc_component_t component, gc_backend_t backend,
2453                         char **src_filenamep, char **dest_filenamep,
2454                         char **orig_filenamep)
2455 {
2456   static const char marker[] = "###+++--- GPGConf ---+++###";
2457   /* True if we are within the marker in the config file.  */
2458   int in_marker = 0;
2459   gc_option_t *option;
2460   char *line = NULL;
2461   size_t line_len;
2462   ssize_t length;
2463   int res;
2464   int fd;
2465   FILE *src_file = NULL;
2466   FILE *dest_file = NULL;
2467   char *src_filename;
2468   char *dest_filename;
2469   char *orig_filename;
2470   /* Special hack for gpg, see below.  */
2471   int utf8strings_seen = 0;
2472
2473   /* FIXME.  Throughout the function, do better error reporting.  */
2474   dest_filename = xstrdup (get_config_pathname (component, backend));
2475   src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ());
2476   orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ());
2477
2478 #ifdef HAVE_W32_SYSTEM
2479   res = copy_file (dest_filename, orig_filename);
2480 #else
2481   res = link (dest_filename, orig_filename);
2482 #endif
2483   if (res < 0 && errno != ENOENT)
2484     return -1;
2485   if (res < 0)
2486     {
2487       xfree (orig_filename);
2488       orig_filename = NULL;
2489     }
2490
2491   /* We now initialize the return strings, so the caller can do the
2492      cleanup for us.  */
2493   *src_filenamep = src_filename;
2494   *dest_filenamep = dest_filename;
2495   *orig_filenamep = orig_filename;
2496
2497   /* Use open() so that we can use O_EXCL.  */
2498   fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
2499   if (fd < 0)
2500     return -1;
2501   src_file = fdopen (fd, "w");
2502   res = errno;
2503   if (!src_file)
2504     {
2505       errno = res;
2506       return -1;
2507     }
2508
2509   /* Only if ORIG_FILENAME is not NULL did the configuration file
2510      exist already.  In this case, we will copy its content into the
2511      new configuration file, changing it to our liking in the
2512      process.  */
2513   if (orig_filename)
2514     {
2515       dest_file = fopen (dest_filename, "r");
2516       if (!dest_file)
2517         goto change_one_err;
2518
2519       while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
2520         {
2521           int disable = 0;
2522           char *start;
2523
2524           if (!strncmp (marker, line, sizeof (marker) - 1))
2525             {
2526               if (!in_marker)
2527                 in_marker = 1;
2528               else
2529                 break;
2530             }
2531           else if (backend == GC_BACKEND_GPG && in_marker
2532                    && ! strcmp ("utf8-strings\n", line))
2533             {
2534               /* Strip duplicated entries.  */
2535               if (utf8strings_seen)
2536                 disable = 1;
2537               else
2538                 utf8strings_seen = 1;
2539             }
2540
2541           start = line;
2542           while (*start == ' ' || *start == '\t')
2543             start++;
2544           if (*start && *start != '\r' && *start != '\n' && *start != '#')
2545             {
2546               char *end;
2547               char saved_end;
2548
2549               end = start;
2550               while (*end && *end != ' ' && *end != '\t'
2551                      && *end != '\r' && *end != '\n' && *end != '#')
2552                 end++;
2553               saved_end = *end;
2554               *end = '\0';
2555
2556               option = find_option (component, start, backend);
2557               *end = saved_end;
2558               if (option && ((option->new_flags & GC_OPT_FLAG_DEFAULT)
2559                              || option->new_value))
2560                 disable = 1;
2561             }
2562           if (disable)
2563             {
2564               if (!in_marker)
2565                 {
2566                   fprintf (src_file,
2567                            "# GPGConf disabled this option here at %s\n",
2568                            asctimestamp (gnupg_get_time ()));
2569                   if (ferror (src_file))
2570                     goto change_one_err;
2571                   fprintf (src_file, "# %s", line);
2572                   if (ferror (src_file))
2573                     goto change_one_err;
2574                 }
2575             }
2576           else
2577             {
2578               fprintf (src_file, "%s", line);
2579               if (ferror (src_file))
2580                 goto change_one_err;
2581             }
2582         }
2583       if (length < 0 || ferror (dest_file))
2584         goto change_one_err;
2585     }
2586
2587   if (!in_marker)
2588     {
2589       /* There was no marker.  This is the first time we edit the
2590          file.  We add our own marker at the end of the file and
2591          proceed.  Note that we first write a newline, this guards us
2592          against files which lack the newline at the end of the last
2593          line, while it doesn't hurt us in all other cases.  */
2594       fprintf (src_file, "\n%s\n", marker);
2595       if (ferror (src_file))
2596         goto change_one_err;
2597     }
2598   /* At this point, we have copied everything up to the end marker
2599      into the new file, except for the options we are going to change.
2600      Now, dump the changed options (except for those we are going to
2601      revert to their default), and write the end marker, possibly
2602      followed by the rest of the original file.  */
2603
2604   /* We have to turn on UTF8 strings for GnuPG.  */
2605   if (backend == GC_BACKEND_GPG && ! utf8strings_seen)
2606     fprintf (src_file, "utf8-strings\n");
2607
2608   option = gc_component[component].options;
2609   while (option->name)
2610     {
2611       if (!(option->flags & GC_OPT_FLAG_GROUP)
2612           && option->backend == backend
2613           && option->new_value)
2614         {
2615           char *arg = option->new_value;
2616
2617           do
2618             {
2619               if (*arg == '\0' || *arg == ',')
2620                 {
2621                   fprintf (src_file, "%s\n", option->name);
2622                   if (ferror (src_file))
2623                     goto change_one_err;
2624                 }
2625               else if (gc_arg_type[option->arg_type].fallback
2626                        == GC_ARG_TYPE_NONE)
2627                 {
2628                   assert (*arg == '1');
2629                   fprintf (src_file, "%s\n", option->name);
2630                   if (ferror (src_file))
2631                     goto change_one_err;
2632
2633                   arg++;
2634                 }
2635               else if (gc_arg_type[option->arg_type].fallback
2636                        == GC_ARG_TYPE_STRING)
2637                 {
2638                   char *end;
2639                   
2640                   assert (*arg == '"');
2641                   arg++;
2642                   
2643                   end = strchr (arg, ',');
2644                   if (end)
2645                     *end = '\0';
2646
2647                   fprintf (src_file, "%s %s\n", option->name,
2648                            percent_deescape (arg));
2649                   if (ferror (src_file))
2650                     goto change_one_err;
2651
2652                   if (end)
2653                     *end = ',';
2654                   arg = end;
2655                 }
2656               else
2657                 {
2658                   char *end;
2659
2660                   end = strchr (arg, ',');
2661                   if (end)
2662                     *end = '\0';
2663
2664                   fprintf (src_file, "%s %s\n", option->name, arg);
2665                   if (ferror (src_file))
2666                     goto change_one_err;
2667
2668                   if (end)
2669                     *end = ',';
2670                   arg = end;
2671                 }
2672
2673               assert (arg == NULL || *arg == '\0' || *arg == ',');
2674               if (arg && *arg == ',')
2675                 arg++;
2676             }
2677           while (arg && *arg);
2678         }
2679       option++;
2680     }
2681
2682   fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
2683   if (ferror (src_file))
2684     goto change_one_err;
2685
2686   if (!in_marker)
2687     {
2688       fprintf (src_file, "# GPGConf edited this configuration file.\n");
2689       if (ferror (src_file))
2690         goto change_one_err;
2691       fprintf (src_file, "# It will disable options before this marked "
2692                "block, but it will\n");
2693       if (ferror (src_file))
2694         goto change_one_err;
2695       fprintf (src_file, "# never change anything below these lines.\n");
2696       if (ferror (src_file))
2697         goto change_one_err;
2698     }
2699   if (dest_file)
2700     {
2701       while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
2702         {
2703           fprintf (src_file, "%s", line);
2704           if (ferror (src_file))
2705             goto change_one_err;
2706         }
2707       if (length < 0 || ferror (dest_file))
2708         goto change_one_err;
2709     }
2710   xfree (line);
2711   line = NULL;
2712
2713   res = fclose (src_file);
2714   if (res)
2715     {
2716       res = errno;
2717       close (fd);
2718       if (dest_file)
2719         fclose (dest_file);
2720       errno = res;
2721       return -1;
2722     }
2723   close (fd);
2724   if (dest_file)
2725     {
2726       res = fclose (dest_file);
2727       if (res)
2728         return -1;
2729     }
2730   return 0;
2731
2732  change_one_err:
2733   xfree (line);
2734   res = errno;
2735   if (src_file)
2736     {
2737       fclose (src_file);
2738       close (fd);
2739     }
2740   if (dest_file)
2741     fclose (dest_file);
2742   errno = res;
2743   return -1;
2744 }
2745
2746
2747 /* Common code for gc_component_change_options and
2748    gc_process_gpgconf_conf.  */
2749 static void
2750 change_one_value (gc_option_t *option, int *runtime,
2751                   unsigned long flags, char *new_value)
2752 {
2753   unsigned long new_value_nr = 0;
2754
2755   option_check_validity (option, flags, new_value, &new_value_nr);
2756
2757   if (option->flags & GC_OPT_FLAG_RUNTIME)
2758     runtime[option->backend] = 1;
2759
2760   option->new_flags = flags;
2761   if (!(flags & GC_OPT_FLAG_DEFAULT))
2762     {
2763       if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
2764           && (option->flags & GC_OPT_FLAG_LIST))
2765         {
2766           char *str;
2767
2768           /* We convert the number to a list of 1's for convenient
2769              list handling.  */
2770           assert (new_value_nr > 0);
2771           option->new_value = xmalloc ((2 * (new_value_nr - 1) + 1) + 1);
2772           str = option->new_value;
2773           *(str++) = '1';
2774           while (--new_value_nr > 0)
2775             {
2776               *(str++) = ',';
2777               *(str++) = '1';
2778             }
2779           *(str++) = '\0';
2780         }
2781       else
2782         option->new_value = xstrdup (new_value);
2783     }
2784 }
2785
2786
2787 /* Read the modifications from IN and apply them.  If IN is NULL the
2788    modifications are expected to already have been set to the global
2789    table. */
2790 void
2791 gc_component_change_options (int component, FILE *in)
2792 {
2793   int err = 0;
2794   int runtime[GC_BACKEND_NR];
2795   char *src_pathname[GC_BACKEND_NR];
2796   char *dest_pathname[GC_BACKEND_NR];
2797   char *orig_pathname[GC_BACKEND_NR];
2798   gc_backend_t backend;
2799   gc_option_t *option;
2800   char *line = NULL;
2801   size_t line_len = 0;
2802   ssize_t length;
2803
2804   for (backend = 0; backend < GC_BACKEND_NR; backend++)
2805     {
2806       runtime[backend] = 0;
2807       src_pathname[backend] = NULL;
2808       dest_pathname[backend] = NULL;
2809       orig_pathname[backend] = NULL;
2810     }
2811
2812   if (in)
2813     {
2814       /* Read options from the file IN.  */
2815       while ((length = read_line (in, &line, &line_len, NULL)) > 0)
2816         {
2817           char *linep;
2818           unsigned long flags = 0;
2819           char *new_value = "";
2820           
2821           /* Strip newline and carriage return, if present.  */
2822           while (length > 0
2823                  && (line[length - 1] == '\n' || line[length - 1] == '\r'))
2824             line[--length] = '\0';
2825           
2826           linep = strchr (line, ':');
2827           if (linep)
2828             *(linep++) = '\0';
2829           
2830           /* Extract additional flags.  Default to none.  */
2831           if (linep)
2832             {
2833               char *end;
2834               char *tail;
2835
2836               end = strchr (linep, ':');
2837               if (end)
2838                 *(end++) = '\0';
2839               
2840               errno = 0;
2841               flags = strtoul (linep, &tail, 0);
2842               if (errno)
2843                 gc_error (1, errno, "malformed flags in option %s", line);
2844               if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
2845                 gc_error (1, 0, "garbage after flags in option %s", line);
2846               
2847               linep = end;
2848             }
2849
2850           /* Don't allow setting of the no change flag.  */
2851           flags &= ~GC_OPT_FLAG_NO_CHANGE;
2852           
2853           /* Extract default value, if present.  Default to empty if not.  */
2854           if (linep)
2855             {
2856               char *end;
2857               end = strchr (linep, ':');
2858               if (end)
2859                 *(end++) = '\0';
2860               new_value = linep;
2861               linep = end;
2862             }
2863           
2864           option = find_option (component, line, GC_BACKEND_ANY);
2865           if (!option)
2866             gc_error (1, 0, "unknown option %s", line);
2867           
2868           if ((option->flags & GC_OPT_FLAG_NO_CHANGE))
2869             {
2870               gc_error (0, 0, "ignoring new value for option %s",
2871                         option->name);
2872               continue;
2873             }
2874           
2875           change_one_value (option, runtime, flags, new_value);
2876         }
2877     }
2878
2879   /* Now that we have collected and locally verified the changes,
2880      write them out to new configuration files, verify them
2881      externally, and then commit them.  */
2882   option = gc_component[component].options;
2883   while (option && option->name)
2884     {
2885       /* Go on if we have already seen this backend, or if there is
2886          nothing to do.  */
2887       if (src_pathname[option->backend]
2888           || !(option->new_flags || option->new_value))
2889         {
2890           option++;
2891           continue;
2892         }
2893
2894       if (gc_backend[option->backend].program)
2895         err = change_options_program (component, option->backend,
2896                                       &src_pathname[option->backend],
2897                                       &dest_pathname[option->backend],
2898                                       &orig_pathname[option->backend]);
2899       else
2900         err = change_options_file (component, option->backend,
2901                                    &src_pathname[option->backend],
2902                                    &dest_pathname[option->backend],
2903                                    &orig_pathname[option->backend]);
2904         
2905       if (err)
2906         break;
2907           
2908       option++;
2909     }
2910
2911   if (!err)
2912     {
2913       int i;
2914
2915       for (i = 0; i < GC_BACKEND_NR; i++)
2916         {
2917           if (src_pathname[i])
2918             {
2919               /* FIXME: Make a verification here.  */
2920
2921               assert (dest_pathname[i]);
2922
2923               if (orig_pathname[i])
2924                 {
2925 #ifdef HAVE_W32_SYSTEM
2926                   /* There is no atomic update on W32.  */
2927                   err = unlink (dest_pathname[i]);
2928 #endif /* HAVE_W32_SYSTEM */
2929                   if (!err)
2930                     err = rename (src_pathname[i], dest_pathname[i]);
2931                 }
2932               else
2933                 {
2934 #ifdef HAVE_W32_SYSTEM
2935                   /* We skip the unlink if we expect the file not to
2936                      be there.  */
2937                   err = rename (src_pathname[i], dest_pathname[i]);
2938 #else /* HAVE_W32_SYSTEM */
2939                   /* This is a bit safer than rename() because we
2940                      expect DEST_PATHNAME not to be there.  If it
2941                      happens to be there, this will fail.  */
2942                   err = link (src_pathname[i], dest_pathname[i]);
2943                   if (!err)
2944                     err = unlink (src_pathname[i]);
2945 #endif /* !HAVE_W32_SYSTEM */
2946                 }
2947               if (err)
2948                 break;
2949               src_pathname[i] = NULL;
2950             }
2951         }
2952     }
2953
2954   if (err)
2955     {
2956       int i;
2957       int saved_errno = errno;
2958
2959       /* An error occured.  */
2960       for (i = 0; i < GC_BACKEND_NR; i++)
2961         {
2962           if (src_pathname[i])
2963             {
2964               /* The change was not yet committed.  */
2965               unlink (src_pathname[i]);
2966               if (orig_pathname[i])
2967                 unlink (orig_pathname[i]);
2968             }
2969           else
2970             {
2971               /* The changes were already committed.  FIXME: This is a
2972                  tad dangerous, as we don't know if we don't overwrite
2973                  a version of the file that is even newer than the one
2974                  we just installed.  */
2975               if (orig_pathname[i])
2976                 {
2977 #ifdef HAVE_W32_SYSTEM
2978                   /* There is no atomic update on W32.  */
2979                   unlink (dest_pathname[i]);
2980 #endif /* HAVE_W32_SYSTEM */
2981                   rename (orig_pathname[i], dest_pathname[i]);
2982                 }
2983               else
2984                 unlink (dest_pathname[i]);
2985             }
2986         }
2987       gc_error (1, saved_errno, "could not commit changes");
2988     }
2989
2990   /* If it all worked, notify the daemons of the changes.  */
2991   if (opt.runtime)
2992     for (backend = 0; backend < GC_BACKEND_NR; backend++)  
2993       {
2994         if (runtime[backend] && gc_backend[backend].runtime_change)
2995           (*gc_backend[backend].runtime_change) ();
2996       }
2997
2998   /* Move the per-process backup file into its place.  */
2999   for (backend = 0; backend < GC_BACKEND_NR; backend++)  
3000     if (orig_pathname[backend])
3001       {
3002         char *backup_pathname;
3003
3004         assert (dest_pathname[backend]);
3005
3006         backup_pathname = xasprintf ("%s.gpgconf.bak", dest_pathname[backend]);
3007
3008 #ifdef HAVE_W32_SYSTEM
3009         /* There is no atomic update on W32.  */
3010         unlink (backup_pathname);
3011 #endif /* HAVE_W32_SYSTEM */
3012         rename (orig_pathname[backend], backup_pathname);
3013       }
3014
3015   xfree (line);
3016 }
3017
3018
3019 /* Check whether USER matches the current user of one of its group.
3020    This function may change USER.  Returns true is there is a
3021    match.  */
3022 static int
3023 key_matches_user_or_group (char *user)
3024 {
3025   char *group;
3026
3027   if (*user == '*' && user[1] == 0)
3028     return 1; /* A single asterisk matches all users.  */
3029
3030   group = strchr (user, ':');
3031   if (group)
3032     *group++ = 0;
3033
3034 #ifdef HAVE_W32_SYSTEM
3035   /* Under Windows we don't support groups. */   
3036   if (group && *group)
3037     gc_error (0, 0, _("Note that group specifications are ignored\n"));
3038   if (*user)
3039     {
3040       static char *my_name;
3041
3042       if (!my_name)
3043         {
3044           char tmp[1];
3045           DWORD size = 1;
3046
3047           GetUserNameA (tmp, &size);
3048           my_name = xmalloc (size);
3049           if (!GetUserNameA (my_name, &size))
3050             gc_error (1,0, "error getting current user name: %s",
3051                       w32_strerror (-1));
3052         }
3053
3054       if (!strcmp (user, my_name))
3055         return 1; /* Found.  */
3056     }
3057 #else /*!HAVE_W32_SYSTEM*/
3058   /* First check whether the user matches.  */
3059   if (*user)
3060     {
3061       static char *my_name;
3062
3063       if (!my_name)
3064         {
3065           struct passwd *pw = getpwuid ( getuid () );
3066           if (!pw)
3067             gc_error (1, errno, "getpwuid failed for current user");
3068           my_name = xstrdup (pw->pw_name);
3069         }
3070       if (!strcmp (user, my_name))
3071         return 1; /* Found.  */
3072     }
3073
3074   /* If that failed, check whether a group matches.  */
3075   if (group && *group)
3076     {
3077       static char *my_group;
3078       static char **my_supgroups;
3079       int n;
3080
3081       if (!my_group)
3082         {
3083           struct group *gr = getgrgid ( getgid () );
3084           if (!gr)
3085             gc_error (1, errno, "getgrgid failed for current user");
3086           my_group = xstrdup (gr->gr_name);
3087         }
3088       if (!strcmp (group, my_group))
3089         return 1; /* Found.  */
3090
3091       if (!my_supgroups)
3092         {
3093           int ngids;
3094           gid_t *gids;
3095
3096           ngids = getgroups (0, NULL);
3097           gids  = xcalloc (ngids+1, sizeof *gids);
3098           ngids = getgroups (ngids, gids);
3099           if (ngids < 0)
3100             gc_error (1, errno, "getgroups failed for current user");
3101           my_supgroups = xcalloc (ngids+1, sizeof *my_supgroups);
3102           for (n=0; n < ngids; n++)
3103             {
3104               struct group *gr = getgrgid ( gids[n] );
3105               if (!gr)
3106                 gc_error (1, errno, "getgrgid failed for supplementary group");
3107               my_supgroups[n] = xstrdup (gr->gr_name);
3108             }
3109           xfree (gids);
3110         }
3111
3112       for (n=0; my_supgroups[n]; n++)
3113         if (!strcmp (group, my_supgroups[n]))
3114           return 1; /* Found.  */
3115     }
3116 #endif /*!HAVE_W32_SYSTEM*/
3117   return 0; /* No match.  */
3118 }
3119
3120
3121
3122 /* Read and process the global configuration file for gpgconf.  This
3123    optional file is used to update our internal tables at runtime and
3124    may also be used to set new default values.  If FNAME is NULL the
3125    default name will be used.  With UPDATE set to true the internal
3126    tables are actually updated; if not set, only a syntax check is
3127    done.  If DEFAULTS is true the global options are written to the
3128    configuration files.  If LISTFP is set, no changes are done but the
3129    configuration file is printed to LISTFP in a colon separated format.
3130
3131    Returns 0 on success or if the config file is not present; -1 is
3132    returned on error. */
3133 int
3134 gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
3135                          FILE *listfp)
3136 {
3137   int result = 0;
3138   char *line = NULL;
3139   size_t line_len = 0;
3140   ssize_t length;
3141   FILE *config;
3142   int lineno = 0;
3143   int in_rule = 0;
3144   int got_match = 0;
3145   int runtime[GC_BACKEND_NR];
3146   int used_components[GC_COMPONENT_NR];
3147   int backend_id, component_id;
3148   char *fname;
3149
3150   if (fname_arg)
3151     fname = xstrdup (fname_arg);
3152   else
3153     fname = make_filename (gnupg_sysconfdir (), "gpgconf.conf", NULL);
3154
3155   for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
3156     runtime[backend_id] = 0;
3157   for (component_id = 0; component_id < GC_COMPONENT_NR; component_id++)
3158     used_components[component_id] = 0;
3159
3160   config = fopen (fname, "r");
3161   if (!config)
3162     {
3163       /* Do not print an error if the file is not available, except
3164          when running in syntax check mode.  */
3165       if (errno != ENOENT || !update)
3166         {
3167           gc_error (0, errno, "can not open global config file `%s'", fname);
3168           result = -1;
3169         }
3170       xfree (fname);
3171       return result;
3172     }
3173
3174   while ((length = read_line (config, &line, &line_len, NULL)) > 0)
3175     {
3176       char *key, *component, *option, *flags, *value;
3177       char *empty;
3178       gc_option_t *option_info = NULL;
3179       char *p;
3180       int is_continuation;
3181       
3182       lineno++;
3183       key = line;
3184       while (*key == ' ' || *key == '\t')
3185         key++;
3186       if (!*key || *key == '#' || *key == '\r' || *key == '\n')
3187         continue;
3188
3189       is_continuation = (key != line);
3190
3191       /* Parse the key field.  */
3192       if (!is_continuation && got_match)
3193         break;  /* Finish after the first match.  */
3194       else if (!is_continuation)
3195         {
3196           in_rule = 0;
3197           for (p=key+1; *p && !strchr (" \t\r\n", *p); p++)
3198             ;
3199           if (!*p)
3200             {
3201               gc_error (0, 0, "missing rule at `%s', line %d", fname, lineno);
3202               result = -1;
3203               continue;
3204             }
3205           *p++ = 0;
3206           component = p;
3207         }
3208       else if (!in_rule)
3209         {
3210           gc_error (0, 0, "continuation but no rule at `%s', line %d",
3211                     fname, lineno);
3212           result = -1;
3213           continue;
3214         }
3215       else
3216         {
3217           component = key;
3218           key = NULL;
3219         }
3220
3221       in_rule = 1;
3222
3223       /* Parse the component.  */
3224       while (*component == ' ' || *component == '\t')
3225         component++;
3226       for (p=component; *p && !strchr (" \t\r\n", *p); p++)
3227         ;
3228       if (p == component)
3229         {
3230           gc_error (0, 0, "missing component at `%s', line %d",
3231                     fname, lineno);
3232           result = -1;
3233           continue;
3234         }
3235       empty = p;
3236       *p++ = 0;
3237       option = p;
3238       component_id = gc_component_find (component);
3239       if (component_id < 0)
3240         {
3241           gc_error (0, 0, "unknown component at `%s', line %d",
3242                     fname, lineno);
3243           result = -1;
3244         }
3245
3246       /* Parse the option name.  */
3247       while (*option == ' ' || *option == '\t')
3248         option++;
3249       for (p=option; *p && !strchr (" \t\r\n", *p); p++)
3250         ;
3251       if (p == option)
3252         {
3253           gc_error (0, 0, "missing option at `%s', line %d",
3254                     fname, lineno);
3255           result = -1;
3256           continue;
3257         }
3258       *p++ = 0;
3259       flags = p;
3260       if ( component_id != -1)
3261         {
3262           option_info = find_option (component_id, option, GC_BACKEND_ANY);
3263           if (!option_info)
3264             {
3265               gc_error (0, 0, "unknown option at `%s', line %d",
3266                         fname, lineno);
3267               result = -1;
3268             }
3269         }
3270
3271
3272       /* Parse the optional flags.  */
3273       while (*flags == ' ' || *flags == '\t')
3274         flags++;
3275       if (*flags == '[')
3276         {
3277           flags++;
3278           p = strchr (flags, ']');
3279           if (!p)
3280             {
3281               gc_error (0, 0, "syntax error in rule at `%s', line %d",
3282                         fname, lineno);
3283               result = -1;
3284               continue;
3285             }
3286           *p++ = 0;
3287           value = p;
3288         }
3289       else  /* No flags given.  */
3290         {
3291           value = flags;
3292           flags = NULL;
3293         }
3294
3295       /* Parse the optional value.  */
3296       while (*value == ' ' || *value == '\t')
3297        value++;
3298       for (p=value; *p && !strchr ("\r\n", *p); p++)
3299         ;
3300       if (p == value)
3301         value = empty; /* No value given; let it point to an empty string.  */
3302       else
3303         {
3304           /* Strip trailing white space.  */
3305           *p = 0;
3306           for (p--; p > value && (*p == ' ' || *p == '\t'); p--)
3307             *p = 0;
3308         }
3309
3310       /* Check flag combinations.  */
3311       if (!flags)
3312         ;
3313       else if (!strcmp (flags, "default"))
3314         {
3315           if (*value)
3316             {
3317               gc_error (0, 0, "flag \"default\" may not be combined "
3318                         "with a value at `%s', line %d",
3319                         fname, lineno);
3320               result = -1;
3321             }
3322         }
3323       else if (!strcmp (flags, "change"))
3324         ;
3325       else if (!strcmp (flags, "no-change"))
3326         ;
3327       else
3328         {
3329           gc_error (0, 0, "unknown flag at `%s', line %d",
3330                     fname, lineno);
3331           result = -1;
3332         }
3333
3334       /* In list mode we print out all records.  */
3335       if (listfp && !result)
3336         {
3337           /* If this is a new ruleset, print a key record.  */
3338           if (!is_continuation)
3339             {
3340               char *group = strchr (key, ':');
3341               if (group)
3342                 {
3343                   *group++ = 0;
3344                   if ((p = strchr (group, ':')))
3345                     *p = 0; /* We better strip any extra stuff. */
3346                 }                    
3347               
3348               fprintf (listfp, "k:%s:", my_percent_escape (key));
3349               fprintf (listfp, "%s\n", group? my_percent_escape (group):"");
3350             }
3351
3352           /* All other lines are rule records.  */
3353           fprintf (listfp, "r:::%s:%s:%s:",
3354                    gc_component[component_id].name,                     
3355                    option_info->name? option_info->name : "",
3356                    flags? flags : "");
3357           if (value != empty)
3358             fprintf (listfp, "\"%s", my_percent_escape (value));
3359           
3360           putc ('\n', listfp);
3361         }
3362
3363       /* Check whether the key matches but do this only if we are not
3364          running in syntax check mode. */
3365       if ( update 
3366            && !result && !listfp
3367            && (got_match || (key && key_matches_user_or_group (key))) )
3368         {
3369           int newflags = 0;
3370
3371           got_match = 1;
3372
3373           /* Apply the flags from gpgconf.conf.  */
3374           if (!flags)
3375             ;
3376           else if (!strcmp (flags, "default"))
3377             newflags |= GC_OPT_FLAG_DEFAULT;
3378           else if (!strcmp (flags, "no-change"))
3379             option_info->flags |= GC_OPT_FLAG_NO_CHANGE;
3380           else if (!strcmp (flags, "change"))
3381             option_info->flags &= ~GC_OPT_FLAG_NO_CHANGE;
3382
3383           if (defaults)
3384             {
3385               assert (component_id >= 0 && component_id < GC_COMPONENT_NR);
3386               used_components[component_id] = 1;
3387
3388               /* Here we explicitly allow to update the value again.  */
3389               if (newflags)
3390                 {
3391                   option_info->new_flags = 0;
3392                 }
3393               if (*value)
3394                 {
3395                   xfree (option_info->new_value);
3396                   option_info->new_value = NULL;
3397                 }
3398               change_one_value (option_info, runtime, newflags, value);
3399             }
3400         }
3401     }
3402
3403   if (length < 0 || ferror (config))
3404     {
3405       gc_error (0, errno, "error reading from `%s'", fname);
3406       result = -1;
3407     }
3408   if (fclose (config) && ferror (config))
3409     gc_error (0, errno, "error closing `%s'", fname);
3410
3411   xfree (line);
3412
3413   /* If it all worked, process the options. */
3414   if (!result && update && defaults && !listfp)
3415     {
3416       /* We need to switch off the runtime update, so that we can do
3417          it later all at once. */
3418       int save_opt_runtime = opt.runtime;
3419       opt.runtime = 0;
3420
3421       for (component_id = 0; component_id < GC_COMPONENT_NR; component_id++)
3422         {
3423           gc_component_change_options (component_id, NULL);
3424         }
3425       opt.runtime = save_opt_runtime;
3426
3427       if (opt.runtime)
3428         {
3429           for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)  
3430             if (runtime[backend_id] && gc_backend[backend_id].runtime_change)
3431               (*gc_backend[backend_id].runtime_change) ();
3432         }
3433     }
3434
3435   xfree (fname);
3436   return result;
3437 }