2004-03-23 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / tools / gpgconf-comp.c
1 /* gpgconf-comp.c - Configuration utility for GnuPG.
2    Copyright (C) 2004 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 2 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, write to the Free Software Foundation,
18    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
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 /* FIXME use gettext.h */
27 #include <libintl.h>
28 #include <fcntl.h>
29 #include <unistd.h>
30 #include <sys/types.h>
31 #include <assert.h>
32 #include <errno.h>
33 #include <time.h>
34 #include <stdarg.h>
35 #include <signal.h>
36
37 /* For log_logv(), asctimestamp(), gnupg_get_time ().  */
38 #define JNLIB_NEED_LOG_LOGV
39 #include "util.h"
40
41 #include "gpgconf.h"
42
43 \f
44 /* TODO:
45    Portability - Add gnulib replacements for getline, etc.
46  
47 XXX Marcus: Please use the read_line code from dirmngr/src/http.c - it
48 has been in use for may years and provides the ability to limit the
49 length of the line and thus thwart DoS (not a issue here but at many
50 other places).
51
52    Components: Add more components and their options.
53    Robustness: Do more validation.  Call programs to do validation for us.
54    Don't use popen, as this will not tell us if the program had a
55    non-zero exit code.
56    Add options to change backend binary path.
57    Extract binary path for some backends from gpgsm/gpg config.
58 */
59
60 \f
61 #if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ))
62 void gc_error (int status, int errnum, const char *fmt, ...) \
63   __attribute__ ((format (printf, 3, 4)));
64 #endif
65
66 /* Output a diagnostic message.  If ERRNUM is not 0, then the output
67    is followed by a colon, a white space, and the error string for the
68    error number ERRNUM.  In any case the output is finished by a
69    newline.  The message is prepended by the program name, a colon,
70    and a whitespace.  The output may be further formatted or
71    redirected by the jnlib logging facility.  */
72 void
73 gc_error (int status, int errnum, const char *fmt, ...)
74 {
75   va_list arg_ptr;
76
77   va_start (arg_ptr, fmt);
78   log_logv (JNLIB_LOG_ERROR, fmt, arg_ptr);
79   va_end (arg_ptr);
80
81   if (errnum)
82     log_printf (": %s\n", strerror (errnum));
83   else
84     log_printf ("\n");
85
86   if (status)
87     {
88       log_printf (NULL);
89       log_printf ("fatal error (exit status %i)\n", status);
90       exit (status);
91     }
92 }
93
94 \f
95 /* Forward declaration.  */
96 void gpg_agent_runtime_change (void);
97
98 /* Backend configuration.  Backends are used to decide how the default
99    and current value of an option can be determined, and how the
100    option can be changed.  To every option in every component belongs
101    exactly one backend that controls and determines the option.  Some
102    backends are programs from the GPG system.  Others might be
103    implemented by GPGConf itself.  If you change this enum, don't
104    forget to update GC_BACKEND below.  */
105 typedef enum
106   {
107     /* Any backend, used for find_option ().  */
108     GC_BACKEND_ANY,
109
110     /* The Gnu Privacy Guard.  */
111     GC_BACKEND_GPG,
112
113     /* The Gnu Privacy Guard for S/MIME.  */
114     GC_BACKEND_GPGSM,
115
116     /* The GPG Agent.  */
117     GC_BACKEND_GPG_AGENT,
118
119     /* The GnuPG SCDaemon.  */
120     GC_BACKEND_SCDAEMON,
121
122     /* The Aegypten directory manager.  */
123     GC_BACKEND_DIRMNGR,
124
125     /* The LDAP server list file for the Aegypten director manager.  */
126     GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST,
127
128     /* The number of the above entries.  */
129     GC_BACKEND_NR
130   } gc_backend_t;
131
132
133 /* To be able to implement generic algorithms for the various
134    backends, we collect all information about them in this struct.  */
135 static struct
136 {
137   /* The name of the backend.  */
138   const char *name;
139
140   /* The name of the program that acts as the backend.  Some backends
141      don't have an associated program, but are implemented directly by
142      GPGConf.  In this case, PROGRAM is NULL.  */
143   char *program;
144
145   /* The runtime change callback.  */
146   void (*runtime_change) (void);
147
148   /* The option name for the configuration filename of this backend.
149      This must be an absolute pathname.  It can be an option from a
150      different backend (but then ordering of the options might
151      matter).  */
152   const char *option_config_filename;
153
154   /* If this is a file backend rather than a program backend, then
155      this is the name of the option associated with the file.  */
156   const char *option_name;
157 } gc_backend[GC_BACKEND_NR] =
158   {
159     { NULL },           /* GC_BACKEND_ANY dummy entry.  */
160     { "GnuPG", "gpg", NULL, "gpgconf-gpg.conf" },
161     { "GPGSM", "gpgsm", NULL, "gpgconf-gpgsm.conf" },
162     { "GPG Agent", "gpg-agent", gpg_agent_runtime_change,
163       "gpgconf-gpg-agent.conf" },
164     { "SCDaemon", "scdaemon", NULL, "gpgconf-scdaemon.conf" },
165     { "DirMngr", "dirmngr", NULL, "gpgconf-dirmngr.conf" },
166     { "DirMngr LDAP Server List", NULL, NULL, "ldapserverlist-file",
167       "LDAP Server" },
168   };
169
170 \f
171 /* Option configuration.  */
172
173 /* An option might take an argument, or not.  Argument types can be
174    basic or complex.  Basic types are generic and easy to validate.
175    Complex types provide more specific information about the intended
176    use, but can be difficult to validate.  If you add to this enum,
177    don't forget to update GC_ARG_TYPE below.  YOU MUST NOT CHANGE THE
178    NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE EXTERNAL
179    INTERFACE.  */
180 typedef enum
181   {
182     /* Basic argument types.  */
183
184     /* No argument.  */
185     GC_ARG_TYPE_NONE = 0,
186
187     /* A String argument.  */
188     GC_ARG_TYPE_STRING = 1,
189
190     /* A signed integer argument.  */
191     GC_ARG_TYPE_INT32 = 2,
192
193     /* An unsigned integer argument.  */
194     GC_ARG_TYPE_UINT32 = 3,
195
196     /* ADD NEW BASIC TYPE ENTRIES HERE.  */
197
198     /* Complex argument types.  */
199
200     /* A complete pathname.  */
201     GC_ARG_TYPE_PATHNAME = 32,
202
203     /* An LDAP server in the format
204        HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN.  */
205     GC_ARG_TYPE_LDAP_SERVER = 33,
206
207     /* A 40 character fingerprint.  */
208     GC_ARG_TYPE_KEY_FPR = 34,
209
210     /* ADD NEW COMPLEX TYPE ENTRIES HERE.  */
211
212     /* The number of the above entries.  */
213     GC_ARG_TYPE_NR
214   } gc_arg_type_t;
215
216
217 /* For every argument, we record some information about it in the
218    following struct.  */
219 static struct
220 {
221   /* For every argument type exists a basic argument type that can be
222      used as a fallback for input and validation purposes.  */
223   gc_arg_type_t fallback;
224
225   /* Human-readable name of the type.  */
226   const char *name;
227 } gc_arg_type[GC_ARG_TYPE_NR] =
228   {
229     /* The basic argument types have their own types as fallback.  */
230     { GC_ARG_TYPE_NONE, "none" },
231     { GC_ARG_TYPE_STRING, "string" },
232     { GC_ARG_TYPE_INT32, "int32" },
233     { GC_ARG_TYPE_UINT32, "uint32" },
234
235     /* Reserved basic type entries for future extension.  */
236     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
237     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
238     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
239     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
240     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
241     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
242     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
243     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
244     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
245     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
246     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
247     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
248     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
249     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
250
251     /* The complex argument types have a basic type as fallback.  */
252     { GC_ARG_TYPE_STRING, "pathname" },
253     { GC_ARG_TYPE_STRING, "ldap server" },
254     { GC_ARG_TYPE_STRING, "key fpr" },
255   };
256
257
258 /* Every option has an associated expert level, than can be used to
259    hide advanced and expert options from beginners.  If you add to
260    this list, don't forget to update GC_LEVEL below.  YOU MUST NOT
261    CHANGE THE NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE
262    EXTERNAL INTERFACE.  */
263 typedef enum
264   {
265     /* The basic options should always be displayed.  */
266     GC_LEVEL_BASIC,
267
268     /* The advanced options may be hidden from beginners.  */
269     GC_LEVEL_ADVANCED,
270
271     /* The expert options should only be displayed to experts.  */
272     GC_LEVEL_EXPERT,
273
274     /* The invisible options should normally never be displayed.  */
275     GC_LEVEL_INVISIBLE,
276
277     /* The internal options are never exported, they mark options that
278        are recorded for internal use only.  */
279     GC_LEVEL_INTERNAL,
280
281     /* ADD NEW ENTRIES HERE.  */
282
283     /* The number of the above entries.  */
284     GC_LEVEL_NR
285   } gc_expert_level_t;
286
287 /* A description for each expert level.  */
288 static struct
289 {
290   const char *name;
291 } gc_level[] =
292   {
293     { "basic" },
294     { "advanced" },
295     { "expert" },
296     { "invisible" },
297     { "internal" }
298   };
299
300
301 /* Option flags.  YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING
302    FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE.  */
303 #define GC_OPT_FLAG_NONE        0UL
304 /* Some entries in the option list are not options, but mark the
305    beginning of a new group of options.  These entries have the GROUP
306    flag set.  */
307 #define GC_OPT_FLAG_GROUP       (1UL << 0)
308 /* The ARG_OPT flag for an option indicates that the argument is
309    optional.  This is never set for GC_ARG_TYPE_NONE options.  */
310 #define GC_OPT_FLAG_ARG_OPT     (1UL << 1)
311 /* The LIST flag for an option indicates that the option can occur
312    several times.  A comma separated list of arguments is used as the
313    argument value.  */
314 #define GC_OPT_FLAG_LIST        (1UL << 2)
315 /* The RUNTIME flag for an option indicates that the option can be
316    changed at runtime.  */
317 #define GC_OPT_FLAG_RUNTIME     (1UL << 3)
318
319 /* The following flags are incorporated from the backend.  */
320 /* The DEFAULT flag for an option indicates that the option has a
321    default value.  */
322 #define GC_OPT_FLAG_DEFAULT     (1UL << 4)
323 /* The DEF_DESC flag for an option indicates that the option has a
324    default, which is described by the value of the default field.  */
325 #define GC_OPT_FLAG_DEF_DESC    (1UL << 5)
326 /* The NO_ARG_DESC flag for an option indicates that the argument has
327    a default, which is described by the value of the ARGDEF field.  */
328 #define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6)
329
330 /* A human-readable description for each flag.  */
331 static struct
332 {
333   const char *name;
334 } gc_flag[] =
335   {
336     { "group" },
337     { "optional arg" },
338     { "list" },
339     { "runtime" }
340   };
341
342
343 /* To each option, or group marker, the information in the GC_OPTION
344    struct is provided.  If you change this, don't forget to update the
345    option list of each component.  */
346 struct gc_option
347 {
348   /* If this is NULL, then this is a terminator in an array of unknown
349      length.  Otherwise, if this entry is a group marker (see FLAGS),
350      then this is the name of the group described by this entry.
351      Otherwise it is the name of the option described by this
352      entry.  The name must not contain a colon.  */
353   const char *name;
354
355   /* The option flags.  If the GROUP flag is set, then this entry is a
356      group marker, not an option, and only the fields LEVEL,
357      DESC_DOMAIN and DESC are valid.  In all other cases, this entry
358      describes a new option and all fields are valid.  */
359   unsigned long flags;
360
361   /* The expert level.  This field is valid for options and groups.  A
362      group has the expert level of the lowest-level option in the
363      group.  */
364   gc_expert_level_t level;
365
366   /* A gettext domain in which the following description can be found.
367      If this is NULL, then DESC is not translated.  Valid for groups
368      and options.  */
369   const char *desc_domain;
370
371   /* A gettext description for this group or option.  If it starts
372      with a '|', then the string up to the next '|' describes the
373      argument, and the description follows the second '|'.  */
374   const char *desc;
375
376   /* The following fields are only valid for options.  */
377
378   /* The type of the option argument.  */
379   gc_arg_type_t arg_type;
380
381   /* The backend that implements this option.  */
382   gc_backend_t backend;
383
384   /* The following fields are set to NULL at startup (because all
385      option's are declared as static variables).  They are at the end
386      of the list so that they can be omitted from the option
387      declarations.  */
388
389   /* This is true if the option is supported by this version of the
390      backend.  */
391   int active;
392
393   /* The default value for this option.  This is NULL if the option is
394      not present in the backend, the empty string if no default is
395      available, and otherwise a quoted string.  */
396   char *default_value;
397
398   /* The default argument is only valid if the "optional arg" flag is
399      set, and specifies the default argument (value) that is used if
400      the argument is omitted.  */
401   char *default_arg;
402
403   /* The current value of this option.  */
404   char *value;
405
406   /* The new flags for this option.  The only defined flag is actually
407      GC_OPT_FLAG_DEFAULT, and it means that the option should be
408      deleted.  In this case, NEW_VALUE is NULL.  */
409   unsigned long new_flags;
410
411   /* The new value of this option.  */
412   char *new_value;
413 };
414 typedef struct gc_option gc_option_t;
415
416 /* Use this macro to terminate an option list.  */
417 #define GC_OPTION_NULL { NULL }
418
419 \f
420 /* The options of the GC_COMPONENT_GPG_AGENT component.  */
421 static gc_option_t gc_options_gpg_agent[] =
422  {
423    /* The configuration file to which we write the changes.  */
424    { "gpgconf-gpg-agent.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
425      NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT },
426
427    { "Monitor",
428      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
429      NULL, "Options controlling the diagnostic output" },
430    { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
431      "gnupg", "verbose",
432      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
433    { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
434      "gnupg", "be somewhat more quiet",
435      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
436    { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
437      NULL, NULL,
438      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
439
440    { "Configuration",
441      GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
442      NULL, "Options controlling the configuration" },
443    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
444      "gnupg", "|FILE|read options from FILE",
445      GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT },
446
447    { "Debug",
448      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
449      "gnupg", "Options useful for debugging" },
450    { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
451      "gnupg", "|LEVEL|set the debugging level to LEVEL",
452      GC_ARG_TYPE_STRING, GC_BACKEND_GPG_AGENT },
453    { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
454      "gnupg", "|FILE|write logs to FILE",
455      GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT },
456    { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
457      NULL, NULL,
458      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
459
460    { "Security",
461      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
462      NULL, "Options controlling the security" },
463    { "default-cache-ttl", GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
464      "gnupg", "|N|expire cached PINs after N seconds",
465      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
466    { "ignore-cache-for-signing", GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
467      "gnupg", "do not use the PIN cache when signing",
468      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
469    { "no-grab", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
470      "gnupg", "do not grab keybourd and mouse",
471      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
472
473
474    GC_OPTION_NULL
475  };
476
477
478 /* The options of the GC_COMPONENT_SCDAEMON component.  */
479 static gc_option_t gc_options_scdaemon[] =
480  {
481    /* The configuration file to which we write the changes.  */
482    { "gpgconf-scdaemon.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
483      NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON },
484
485    { "Monitor",
486      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
487      NULL, "Options controlling the diagnostic output" },
488    { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
489      "gnupg", "verbose",
490      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
491    { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
492      "gnupg", "be somewhat more quiet",
493      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
494    { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
495      NULL, NULL,
496      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
497
498    { "Configuration",
499      GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
500      NULL, "Options controlling the configuration" },
501    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
502      "gnupg", "|FILE|read options from FILE",
503      GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON },
504    { "reader-port", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
505      "gnupg", "|N|connect to reader at port N",
506      GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
507    { "ctapi-driver", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
508      "gnupg", "|NAME|use NAME as ct-API driver",
509      GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
510    { "pcsc-driver", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
511      "gnupg", "|NAME|use NAME as PC/SC driver",
512      GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
513    { "disable-opensc", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
514      "gnupg", "do not use the OpenSC layer",
515      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
516    { "disable-ccid", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
517      "gnupg", "do not use the internal CCID driver",
518      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
519
520
521    { "Debug",
522      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
523      "gnupg", "Options useful for debugging" },
524    { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
525      "gnupg", "|LEVEL|set the debugging level to LEVEL",
526      GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
527    { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
528      "gnupg", "|FILE|write logs to FILE",
529      GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON },
530
531    { "Security",
532      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
533      NULL, "Options controlling the security" },
534    { "allow-admin", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
535      "gnupg", "allow the use of admin card commands",
536      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
537
538
539    GC_OPTION_NULL
540  };
541
542
543 /* The options of the GC_COMPONENT_GPGSM component.  */
544 static gc_option_t gc_options_gpgsm[] =
545  {
546    /* The configuration file to which we write the changes.  */
547    { "gpgconf-gpgsm.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
548      NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM },
549
550    { "Monitor",
551      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
552      NULL, "Options controlling the diagnostic output" },
553    { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
554      "gnupg", "verbose",
555      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
556    { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
557      "gnupg", "be somewhat more quiet",
558      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
559    { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
560      NULL, NULL,
561      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
562
563    { "Configuration",
564      GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
565      NULL, "Options controlling the configuration" },
566    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
567      "gnupg", "|FILE|read options from FILE",
568      GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM },
569
570    { "Debug",
571      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
572      "gnupg", "Options useful for debugging" },
573    { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
574      "gnupg", "|LEVEL|set the debugging level to LEVEL",
575      GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
576    { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
577      "gnupg", "|FILE|write logs to FILE",
578      GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM },
579    { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
580      NULL, NULL,
581      GC_ARG_TYPE_UINT32, GC_BACKEND_GPGSM },
582
583    { "Security",
584      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
585      NULL, "Options controlling the security" },
586    { "disable-crl-checks", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
587      "gnupg", "never consult a CRL",
588      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
589    { "enable-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
590      "gnupg", "check validity using OCSP",
591      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
592    { "include-certs", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
593      "gnupg", "|N|number of certificates to include",
594      GC_ARG_TYPE_INT32, GC_BACKEND_GPGSM },
595    { "disable-policy-checks", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
596      "gnupg", "do not check certificate policies",
597      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
598    { "auto-issuer-key-retrieve", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
599      "gnupg", "fetch missing issuer certificates",
600      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
601
602    GC_OPTION_NULL
603  };
604
605
606 /* The options of the GC_COMPONENT_DIRMNGR component.  */
607 static gc_option_t gc_options_dirmngr[] =
608  {
609    /* The configuration file to which we write the changes.  */
610    { "gpgconf-dirmngr.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
611      NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
612
613    { "Monitor",
614      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
615      NULL, "Options controlling the diagnostic output" },
616    { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
617      "dirmngr", "verbose",
618      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
619    { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
620      "dirmngr", "be somewhat more quiet",
621      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
622    { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
623      NULL, NULL,
624      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
625
626    { "Format",
627      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
628      NULL, "Options controlling the format of the output" },
629    { "sh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
630      "dirmngr", "sh-style command output",
631      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
632    { "csh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
633      "dirmngr", "csh-style command output",
634      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
635    
636    { "Configuration",
637      GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
638      NULL, "Options controlling the configuration" },
639    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
640      "dirmngr", "|FILE|read options from FILE",
641      GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
642
643    { "Debug",
644      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
645      "dirmngr", "Options useful for debugging" },
646    { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
647      "dirmngr", "|LEVEL|set the debugging level to LEVEL",
648      GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
649    { "no-detach", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
650      "dirmngr", "do not detach from the console",
651      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
652    { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
653      "dirmngr", "|FILE|write logs to FILE",
654      GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
655    { "debug-wait", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
656      NULL, NULL,
657      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
658    { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
659      NULL, NULL,
660      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
661
662    { "Enforcement",
663      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
664      NULL, "Options controlling the interactivity and enforcement" },
665    { "batch", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
666      "dirmngr", "run without asking a user",
667      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
668    { "force", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
669      "dirmngr", "force loading of outdated CRLs",
670      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
671
672    { "LDAP",
673      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
674      NULL, "Configuration of LDAP servers to use" },
675    { "add-servers", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
676      "dirmngr", "add new servers discovered in CRL distribution points"
677      " to serverlist", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
678    { "ldaptimeout", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
679      "dirmngr", "|N|set LDAP timeout to N seconds",
680      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
681    /* The following entry must not be removed, as it is required for
682       the GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST.  */
683    { "ldapserverlist-file",
684      GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
685      "dirmngr", "|FILE|read LDAP server list from FILE",
686      GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
687    /* This entry must come after at least one entry for
688       GC_BACKEND_DIRMNGR in this component, so that the entry for
689       "ldapserverlist-file will be initialized before this one.  */
690    { "LDAP Server", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
691      NULL, "LDAP server list",
692      GC_ARG_TYPE_LDAP_SERVER, GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST },
693
694    { "CRL",
695      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
696      NULL, "Configuration of the CRL" },
697    { "max-replies", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
698      "dirmngr", "|N|do not return more than N items in one query",
699      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
700
701    { "OCSP",
702      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
703      NULL, "Configuration for OCSP" },
704    { "ocsp-responder", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
705      "dirmngr", "|URL|use OCSP responder URL",
706      GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
707
708
709    GC_OPTION_NULL
710  };
711
712 \f
713 /* Component system.  Each component is a set of options that can be
714    configured at the same time.  If you change this, don't forget to
715    update GC_COMPONENT below.  */
716 typedef enum
717   {
718     /* The GPG Agent.  */
719     GC_COMPONENT_GPG_AGENT,
720
721     /* The Smardcard Daemon.  */
722     GC_COMPONENT_SCDAEMON,
723
724     /* GPG for S/MIME.  */
725     GC_COMPONENT_GPGSM,
726
727     /* The LDAP Directory Manager for CRLs.  */
728     GC_COMPONENT_DIRMNGR,
729
730     /* The number of components.  */
731     GC_COMPONENT_NR
732   } gc_component_t;
733
734
735 /* The information associated with each component.  */
736 static struct
737 {
738   /* The name of this component.  Must not contain a colon (':')
739      character.  */
740   const char *name;
741
742   /* The gettext domain for the description DESC.  If this is NULL,
743      then the description is not translated.  */
744   const char *desc_domain;
745
746   /* The description for this domain.  */
747   const char *desc;
748
749   /* The list of options for this component, terminated by
750      GC_OPTION_NULL.  */
751   gc_option_t *options;
752 } gc_component[] =
753   {
754     { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent },
755     { "scdaemon", NULL, "Smartcard Daemon", gc_options_scdaemon },
756     { "gpgsm", NULL, "GPG for S/MIME", gc_options_gpgsm },
757     { "dirmngr", NULL, "CRL Manager", gc_options_dirmngr }
758   };
759
760 \f
761 /* Engine specific support.  */
762 void
763 gpg_agent_runtime_change (void)
764 {
765   char *agent = getenv ("GPG_AGENT_INFO");
766   char *pid_str;
767   unsigned long pid_long;
768   char *tail;
769   pid_t pid;
770
771   if (!agent)
772     return;
773
774   pid_str = strchr (agent, ':');
775   if (!pid_str)
776     return;
777
778   pid_str++;
779   errno = 0;
780   pid_long = strtoul (pid_str, &tail, 0);
781   if (errno || (*tail != ':' && *tail != '\0'))
782     return;
783
784   pid = (pid_t) pid_long;
785
786   /* Check for overflow.  */
787   if (pid_long != (unsigned long) pid)
788     return;
789
790   /* Ignore any errors here.  */
791   kill (pid, SIGHUP);
792 }
793
794 \f
795 /* Robust version of dgettext.  */
796 static const char *
797 my_dgettext (const char *domain, const char *msgid)
798 {
799   if (domain)
800     {
801       char *text = dgettext (domain, msgid);
802       return text ? text : msgid;
803     }
804   else
805     return msgid;
806 }
807
808
809 /* Percent-Escape special characters.  The string is valid until the
810    next invocation of the function.  */
811 static char *
812 percent_escape (const char *src)
813 {
814   static char *esc_str;
815   static int esc_str_len;
816   int new_len = 3 * strlen (src) + 1;
817   char *dst;
818
819   if (esc_str_len < new_len)
820     {
821       char *new_esc_str = realloc (esc_str, new_len);
822       if (!new_esc_str)
823         gc_error (1, errno, "can not escape string");
824       esc_str = new_esc_str;
825       esc_str_len = new_len;
826     }
827
828   dst = esc_str;
829   while (*src)
830     {
831       if (*src == '%')
832         {
833           *(dst++) = '%';
834           *(dst++) = '2';
835           *(dst++) = '5';
836         }         
837       else if (*src == ':')
838         {
839           /* The colon is used as field separator.  */
840           *(dst++) = '%';
841           *(dst++) = '3';
842           *(dst++) = 'a';
843         }
844       else if (*src == ',')
845         {
846           /* The comma is used as list separator.  */
847           *(dst++) = '%';
848           *(dst++) = '2';
849           *(dst++) = 'c';
850         }
851       else
852         *(dst++) = *(src);
853       src++;
854     }
855   *dst = '\0';
856   return esc_str;
857 }
858
859
860 /* Convert two hexadecimal digits from STR to the value they
861    represent.  Returns -1 if one of the characters is not a
862    hexadecimal digit.  */
863 static int
864 hextobyte (const char *str)
865 {
866   int val = 0;
867   int i;
868
869 #define NROFHEXDIGITS 2
870   for (i = 0; i < NROFHEXDIGITS; i++)
871     {
872       if (*str >= '0' && *str <= '9')
873         val += *str - '0';
874       else if (*str >= 'A' && *str <= 'F')
875         val += 10 + *str - 'A';
876       else if (*str >= 'a' && *str <= 'f')
877         val += 10 + *str - 'a';
878       else
879         return -1;
880       if (i < NROFHEXDIGITS - 1)
881         val *= 16;
882       str++;
883     }
884   return val;
885 }
886
887
888
889 /* Percent-Deescape special characters.  The string is valid until the
890    next invocation of the function.  */
891 static char *
892 percent_deescape (const char *src)
893 {
894   static char *str;
895   static int str_len;
896   int new_len = 3 * strlen (src) + 1;
897   char *dst;
898
899   if (str_len < new_len)
900     {
901       char *new_str = realloc (str, new_len);
902       if (!new_str)
903         gc_error (1, errno, "can not deescape string");
904       str = new_str;
905       str_len = new_len;
906     }
907
908   dst = str;
909   while (*src)
910     {
911       if (*src == '%')
912         {
913           int val = hextobyte (src + 1);
914
915           if (val < 0)
916             gc_error (1, 0, "malformed end of string %s", src);
917
918           *(dst++) = (char) val;
919           src += 3;
920         }         
921       else
922         *(dst++) = *(src++);
923     }
924   *dst = '\0';
925   return str;
926 }
927
928 \f
929 /* List all components that are available.  */
930 void
931 gc_component_list_components (FILE *out)
932 {
933   gc_component_t idx;
934
935   for (idx = 0; idx < GC_COMPONENT_NR; idx++)
936     {
937       const char *desc = gc_component[idx].desc;
938       desc = my_dgettext (gc_component[idx].desc_domain, desc);
939       fprintf (out, "%s:%s\n", gc_component[idx].name, percent_escape (desc));
940     }
941 }
942
943 \f
944 /* Find the component with the name NAME.  Returns -1 if not
945    found.  */
946 int
947 gc_component_find (const char *name)
948 {
949   gc_component_t idx;
950
951   for (idx = 0; idx < GC_COMPONENT_NR; idx++)
952     {
953       if (!strcmp (name, gc_component[idx].name))
954         return idx;
955     }
956   return -1;
957 }
958
959 \f
960 /* List the option OPTION.  */
961 static void
962 list_one_option (const gc_option_t *option, FILE *out)
963 {
964   const char *desc = NULL;
965   char *arg_name = NULL;
966
967   if (option->desc)
968     {
969       desc = my_dgettext (option->desc_domain, option->desc);
970
971       if (*desc == '|')
972         {
973           const char *arg_tail = strchr (&desc[1], '|');
974
975           if (arg_tail)
976             {
977               int arg_len = arg_tail - &desc[1];
978               arg_name = xmalloc (arg_len + 1);
979               memcpy (arg_name, &desc[1], arg_len);
980               arg_name[arg_len] = '\0';
981               desc = arg_tail + 1;
982             }
983         }
984     }
985
986
987   /* YOU MUST NOT REORDER THE FIELDS IN THIS OUTPUT, AS THEIR ORDER IS
988      PART OF THE EXTERNAL INTERFACE.  YOU MUST NOT REMOVE ANY
989      FIELDS.  */
990
991   /* The name field.  */
992   fprintf (out, "%s", option->name);
993
994   /* The flags field.  */
995   fprintf (out, ":%lu", option->flags);
996   if (opt.verbose)
997     {
998       putc (' ', out);
999           
1000       if (!option->flags)
1001         fprintf (out, "none");
1002       else
1003         {
1004           unsigned long flags = option->flags;
1005           unsigned long flag = 0;
1006           unsigned long first = 1;
1007
1008           while (flags)
1009             {
1010               if (flags & 1)
1011                 {
1012                   if (first)
1013                     first = 0;
1014                   else
1015                     putc (',', out);
1016                   fprintf (out, "%s", gc_flag[flag].name);
1017                 }
1018               flags >>= 1;
1019               flag++;
1020             }
1021         }
1022     }
1023
1024   /* The level field.  */
1025   fprintf (out, ":%u", option->level);
1026   if (opt.verbose)
1027     fprintf (out, " %s", gc_level[option->level].name);
1028
1029   /* The description field.  */
1030   fprintf (out, ":%s", desc ? percent_escape (desc) : "");
1031   
1032   /* The type field.  */
1033   fprintf (out, ":%u", option->arg_type);
1034   if (opt.verbose)
1035     fprintf (out, " %s", gc_arg_type[option->arg_type].name);
1036
1037   /* The alternate type field.  */
1038   fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback);
1039   if (opt.verbose)
1040     fprintf (out, " %s",
1041              gc_arg_type[gc_arg_type[option->arg_type].fallback].name);
1042
1043   /* The argument name field.  */
1044   fprintf (out, ":%s", arg_name ? percent_escape (arg_name) : "");
1045   if (arg_name)
1046     xfree (arg_name);
1047
1048   /* The default value field.  */
1049   fprintf (out, ":%s", option->default_value ? option->default_value : "");
1050
1051   /* The default argument field.  */
1052   fprintf (out, ":%s", option->default_arg ? option->default_arg : "");
1053
1054   /* The value field.  */
1055   if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
1056       && (option->flags & GC_OPT_FLAG_LIST)
1057       && option->value)
1058     /* The special format "1,1,1,1,...,1" is converted to a number
1059        here.  */
1060     fprintf (out, ":%u", (strlen (option->value) + 1) / 2);
1061   else
1062     fprintf (out, ":%s", option->value ? option->value : "");
1063
1064   /* ADD NEW FIELDS HERE.  */
1065
1066   putc ('\n', out);
1067 }
1068
1069
1070 /* List all options of the component COMPONENT.  */
1071 void
1072 gc_component_list_options (int component, FILE *out)
1073 {  
1074   const gc_option_t *option = gc_component[component].options;
1075   const gc_option_t *group_option = NULL;
1076
1077   while (option->name)
1078     {
1079       /* Do not output unknown or internal options.  */
1080       if (!(option->flags & GC_OPT_FLAG_GROUP)
1081           && (!option->active || option->level == GC_LEVEL_INTERNAL))
1082         {
1083           option++;
1084           continue;
1085         }
1086
1087       if (option->flags & GC_OPT_FLAG_GROUP)
1088         group_option = option;
1089       else
1090         {
1091           if (group_option)
1092             {
1093               list_one_option (group_option, out);
1094               group_option = NULL;
1095             }
1096
1097           list_one_option (option, out);
1098         }
1099
1100       option++;
1101     }
1102 }
1103
1104
1105 /* Find the option NAME in component COMPONENT, for the backend
1106    BACKEND.  If BACKEND is GC_BACKEND_ANY, any backend will match.  */
1107 static gc_option_t *
1108 find_option (gc_component_t component, const char *name,
1109              gc_backend_t backend)
1110 {
1111   gc_option_t *option = gc_component[component].options;
1112   while (option->name)
1113     {
1114       if (!(option->flags & GC_OPT_FLAG_GROUP)
1115           && !strcmp (option->name, name)
1116           && (backend == GC_BACKEND_ANY || option->backend == backend))
1117         break;
1118       option++;
1119     }
1120   return option->name ? option : NULL;
1121 }
1122
1123 \f
1124 /* Determine the configuration pathname for the component COMPONENT
1125    and backend BACKEND.  */
1126 static char *
1127 get_config_pathname (gc_component_t component, gc_backend_t backend)
1128 {
1129   char *pathname = NULL;
1130   gc_option_t *option = find_option
1131     (component, gc_backend[backend].option_config_filename, GC_BACKEND_ANY);
1132   assert (option);
1133   assert (option->arg_type == GC_ARG_TYPE_PATHNAME);
1134   assert (!(option->flags & GC_OPT_FLAG_LIST));
1135
1136   if (!option->active || !option->default_value)
1137     gc_error (1, 0, "Option %s, needed by backend %s, was not initialized",
1138               gc_backend[backend].option_config_filename,
1139               gc_backend[backend].name);
1140
1141   if (option->value && *option->value)
1142     pathname = percent_deescape (&option->value[1]);
1143   else if (option->default_value && *option->default_value)
1144     pathname = percent_deescape (&option->default_value[1]);
1145   else
1146     pathname = "";
1147
1148   if (pathname[0] != '/')
1149     gc_error (1, 0, "Option %s, needed by backend %s, is not absolute",
1150               gc_backend[backend].option_config_filename,
1151               gc_backend[backend].name);
1152
1153   return pathname;
1154 }
1155
1156 \f
1157 /* Retrieve the options for the component COMPONENT from backend
1158    BACKEND, which we already know is a program-type backend.  */
1159 static void
1160 retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
1161 {
1162   char *cmd_line;
1163   char *line = NULL;
1164   size_t line_len = 0;
1165   ssize_t length;
1166   FILE *config;
1167   char *config_pathname;
1168
1169   cmd_line = xasprintf ("%s --gpgconf-list", gc_backend[backend].program);
1170
1171   config = popen (cmd_line, "r");
1172   if (!config)
1173     gc_error (1, errno, "could not gather active options from %s", cmd_line);
1174
1175   while ((length = getline (&line, &line_len, config)) > 0)
1176     {
1177       gc_option_t *option;
1178       char *linep;
1179       unsigned long flags = 0;
1180       char *default_value = NULL;
1181       
1182       /* Strip newline and carriage return, if present.  */
1183       while (length > 0
1184              && (line[length - 1] == '\n' || line[length - 1] == '\r'))
1185         line[--length] = '\0';
1186
1187       linep = strchr (line, ':');
1188       if (linep)
1189         *(linep++) = '\0';
1190       
1191       /* Extract additional flags.  Default to none.  */
1192       if (linep)
1193         {
1194           char *end;
1195           char *tail;
1196
1197           end = strchr (linep, ':');
1198           if (end)
1199             *(end++) = '\0';
1200
1201           errno = 0;
1202           flags = strtoul (linep, &tail, 0);
1203           if (errno)
1204             gc_error (1, errno, "malformed flags in option %s from %s", line, cmd_line);
1205           if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
1206             gc_error (1, 0, "garbage after flags in option %s from %s", line, cmd_line);
1207
1208           linep = end;
1209         }
1210
1211       /* Extract default value, if present.  Default to empty if
1212          not.  */
1213       if (linep)
1214         {
1215           char *end;
1216
1217           end = strchr (linep, ':');
1218           if (end)
1219             *(end++) = '\0';
1220
1221           if (flags & GC_OPT_FLAG_DEFAULT)
1222             default_value = linep;
1223
1224           linep = end;
1225         }
1226
1227       /* Look up the option in the component and install the
1228          configuration data.  */
1229       option = find_option (component, line, backend);
1230       if (option)
1231         {
1232           if (option->active)
1233             gc_error (1, errno, "option %s returned twice from %s",
1234                       line, cmd_line);
1235           option->active = 1;
1236
1237           option->flags |= flags;
1238           if (default_value && *default_value)
1239             option->default_value = xstrdup (default_value);
1240         }
1241     }
1242   if (ferror (config))
1243     gc_error (1, errno, "error reading from %s", cmd_line);
1244   if (fclose (config) && ferror (config))
1245     gc_error (1, errno, "error closing %s", cmd_line);
1246   xfree (cmd_line);
1247
1248   /* At this point, we can parse the configuration file.  */
1249   config_pathname = get_config_pathname (component, backend);
1250
1251   config = fopen (config_pathname, "r");
1252   if (!config)
1253     gc_error (0, errno, "warning: can not open config file %s",
1254               config_pathname);
1255   else
1256     {
1257       while ((length = getline (&line, &line_len, config)) > 0)
1258         {
1259           char *name;
1260           char *value;
1261           gc_option_t *option;
1262           
1263           name = line;
1264           while (*name == ' ' || *name == '\t')
1265             name++;
1266           if (!*name || *name == '#' || *name == '\r' || *name == '\n')
1267             continue;
1268
1269           value = name;
1270           while (*value && *value != ' ' && *value != '\t'
1271                  && *value != '#' && *value != '\r' && *value != '\n')
1272             value++;
1273           if (*value == ' ' || *value == '\t')
1274             {
1275               char *end;
1276
1277               *(value++) = '\0';
1278               while (*value == ' ' || *value == '\t')
1279                 value++;
1280
1281               end = value;
1282               while (*end && *end != '#' && *end != '\r' && *end != '\n')
1283                 end++;
1284               while (end > value && (end[-1] == ' ' || end[-1] == '\t'))
1285                 end--;
1286               *end = '\0';
1287             }
1288           else
1289             *value = '\0';
1290
1291           /* Look up the option in the component and install the
1292              configuration data.  */
1293           option = find_option (component, line, backend);
1294           if (option)
1295             {
1296               char *opt_value;
1297
1298               if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
1299                 {
1300                   if (*value)
1301                     gc_error (0, 0,
1302                               "warning: ignoring argument %s for option %s",
1303                               value, name);
1304                   opt_value = xstrdup ("1");
1305                 }
1306               else if (gc_arg_type[option->arg_type].fallback
1307                        == GC_ARG_TYPE_STRING)
1308                 opt_value = xasprintf ("\"%s", percent_escape (value));
1309               else
1310                 {
1311                   /* FIXME: Verify that the number is sane.  */
1312                   opt_value = xstrdup (value);
1313                 }
1314
1315               /* Now enter the option into the table.  */
1316               if (!(option->flags & GC_OPT_FLAG_LIST))
1317                 {
1318                   if (option->value)
1319                     free (option->value);
1320                   option->value = opt_value;
1321                 }
1322               else
1323                 {
1324                   if (!option->value)
1325                     option->value = opt_value;
1326                   else
1327                     {
1328                       char *opt_val = opt_value;
1329
1330                       option->value = xasprintf ("%s,%s", option->value,
1331                                                  opt_val);
1332                       xfree (opt_value);
1333                     }
1334                 }
1335             }
1336         }
1337
1338       if (ferror (config))
1339         gc_error (1, errno, "error reading from %s", config_pathname);
1340       if (fclose (config) && ferror (config))
1341         gc_error (1, errno, "error closing %s", config_pathname);
1342     }
1343
1344   if (line)
1345     free (line);
1346 }
1347
1348
1349 /* Retrieve the options for the component COMPONENT from backend
1350    BACKEND, which we already know is of type file list.  */ 
1351 static void
1352 retrieve_options_from_file (gc_component_t component, gc_backend_t backend)
1353 {
1354   gc_option_t *list_option;
1355   char *list_pathname;
1356   FILE *list_file;
1357   char *line = NULL;
1358   size_t line_len = 0;
1359   ssize_t length;
1360   char *list = NULL;
1361
1362   list_option = find_option (component,
1363                              gc_backend[backend].option_name, GC_BACKEND_ANY);
1364   assert (list_option);
1365   assert (!list_option->active);
1366
1367   list_pathname = get_config_pathname (component, backend);
1368   list_file = fopen (list_pathname, "r");
1369   if (!list_file)
1370     gc_error (0, errno, "warning: can not open list file %s", list_pathname);
1371   else
1372     {
1373
1374       while ((length = getline (&line, &line_len, list_file)) > 0)
1375         {
1376           char *start;
1377           char *end;
1378           char *new_list;
1379
1380           start = line;
1381           while (*start == ' ' || *start == '\t')
1382             start++;
1383           if (!*start || *start == '#' || *start == '\r' || *start == '\n')
1384             continue;
1385
1386           end = start;
1387           while (*end && *end != '#' && *end != '\r' && *end != '\n')
1388             end++;
1389           /* Walk back to skip trailing white spaces.  Looks evil, but
1390              works because of the conditions on START and END imposed
1391              at this point (END is at least START + 1, and START is
1392              not a whitespace character).  */
1393           while (*(end - 1) == ' ' || *(end - 1) == '\t')
1394             end--;
1395           *end = '\0';
1396           /* FIXME: Oh, no!  This is so lame!  Should use realloc and
1397              really append.  */
1398           if (list)
1399             {
1400               new_list = xasprintf ("%s,\"%s", list, percent_escape (start));
1401               xfree (list);
1402               list = new_list;
1403             }
1404           else
1405             list = xasprintf ("\"%s", percent_escape (start));
1406         }
1407       if (ferror (list_file))
1408         gc_error (1, errno, "can not read list file %s", list_pathname);
1409     }
1410
1411   list_option->active = 1;
1412   list_option->value = list;
1413
1414   if (line)
1415     free (line);
1416 }
1417
1418
1419 /* Retrieve the currently active options and their defaults from all
1420    involved backends for this component.  */
1421 void
1422 gc_component_retrieve_options (int component)
1423 {
1424   int backend_seen[GC_BACKEND_NR];
1425   gc_backend_t backend;
1426   gc_option_t *option = gc_component[component].options;
1427
1428   for (backend = 0; backend < GC_BACKEND_NR; backend++)
1429     backend_seen[backend] = 0;
1430
1431   while (option->name)
1432     {
1433       if (!(option->flags & GC_OPT_FLAG_GROUP))
1434         {
1435           backend = option->backend;
1436
1437           if (backend_seen[backend])
1438             {
1439               option++;
1440               continue;
1441             }
1442           backend_seen[backend] = 1;
1443
1444           assert (backend != GC_BACKEND_ANY);
1445
1446           if (gc_backend[backend].program)
1447             retrieve_options_from_program (component, backend);
1448           else
1449             retrieve_options_from_file (component, backend);
1450         }
1451       option++;
1452     }
1453 }
1454
1455 \f
1456 /* Perform a simple validity check based on the type.  Return in
1457    NEW_VALUE_NR the value of the number in NEW_VALUE if OPTION is of
1458    type GC_ARG_TYPE_NONE.  */
1459 static void
1460 option_check_validity (gc_option_t *option, unsigned long flags,
1461                        char *new_value, unsigned long *new_value_nr)
1462 {
1463   char *arg;
1464
1465   if (!option->active)
1466     gc_error (1, 0, "option %s not supported by backend", option->name);
1467       
1468   if (option->new_flags || option->new_value)
1469     gc_error (1, 0, "option %s already changed", option->name);
1470
1471   if (flags & GC_OPT_FLAG_DEFAULT)
1472     {
1473       if (*new_value)
1474         gc_error (1, 0, "argument %s provided for deleted option %s",
1475                   new_value, option->name);
1476
1477       return;
1478     }
1479
1480   /* GC_ARG_TYPE_NONE options have special list treatment.  */
1481   if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
1482     {
1483       char *tail;
1484
1485       errno = 0;
1486       *new_value_nr = strtoul (new_value, &tail, 0);
1487
1488       if (errno)
1489         gc_error (1, errno, "invalid argument for option %s",
1490                   option->name);
1491       if (*tail)
1492         gc_error (1, 0, "garbage after argument for option %s",
1493                       option->name);
1494
1495       if (!(option->flags & GC_OPT_FLAG_LIST))
1496         {
1497           if (*new_value_nr != 1)
1498             gc_error (1, 0, "argument for non-list option %s of type 0 "
1499                       "(none) must be 1", option->name);
1500         }
1501       else
1502         {
1503           if (*new_value_nr == 0)
1504             gc_error (1, 0, "argument for option %s of type 0 (none) "
1505                       "must be positive", option->name);
1506         }
1507
1508       return;
1509     }
1510
1511   arg = new_value;
1512   do
1513     {
1514       if (*arg == '\0' || *arg == ',')
1515         {
1516           if (!(option->flags & GC_OPT_FLAG_ARG_OPT))
1517             gc_error (1, 0, "argument required for option %s", option->name);
1518
1519           if (*arg == ',' && !(option->flags & GC_OPT_FLAG_LIST))
1520             gc_error (1, 0, "list found for non-list option %s", option->name);
1521         }
1522       else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING)
1523         {
1524           if (*arg != '"')
1525             gc_error (1, 0, "string argument for option %s must begin "
1526                       "with a quote (\") character", option->name);
1527         }
1528       else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
1529         {
1530           errno = 0;
1531           (void) strtol (arg, &arg, 0);
1532
1533           if (errno)
1534             gc_error (1, errno, "invalid argument for option %s",
1535                       option->name);
1536
1537           if (*arg != '\0' && *arg != ',')
1538             gc_error (1, 0, "garbage after argument for option %s",
1539                       option->name);
1540         }
1541       else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
1542         {
1543           errno = 0;
1544           (void) strtoul (arg, &arg, 0);
1545
1546           if (errno)
1547             gc_error (1, errno, "invalid argument for option %s",
1548                       option->name);
1549
1550           if (*arg != '\0' && *arg != ',')
1551             gc_error (1, 0, "garbage after argument for option %s",
1552                       option->name);
1553         }
1554       arg = strchr (arg, ',');
1555       if (arg)
1556         arg++;
1557     }
1558   while (arg && *arg);
1559 }
1560
1561
1562 /* Create and verify the new configuration file for the specified
1563    backend and component.  Returns 0 on success and -1 on error.  */
1564 static int
1565 change_options_file (gc_component_t component, gc_backend_t backend,
1566                      char **src_filenamep, char **dest_filenamep,
1567                      char **orig_filenamep)
1568 {
1569   static const char marker[] = "###+++--- GPGConf ---+++###";
1570   /* True if we are within the marker in the config file.  */
1571   int in_marker = 0;
1572   gc_option_t *option;
1573   char *line = NULL;
1574   size_t line_len;
1575   ssize_t length;
1576   int res;
1577   int fd;
1578   FILE *src_file = NULL;
1579   FILE *dest_file = NULL;
1580   char *src_filename;
1581   char *dest_filename;
1582   char *orig_filename;
1583   char *arg;
1584   char *cur_arg = NULL;
1585
1586   option = find_option (component,
1587                         gc_backend[backend].option_name, GC_BACKEND_ANY);
1588   assert (option);
1589   assert (option->active);
1590   assert (gc_arg_type[option->arg_type].fallback != GC_ARG_TYPE_NONE);
1591   assert (!(option->flags & GC_OPT_FLAG_ARG_OPT));
1592
1593   /* FIXME.  Throughout the function, do better error reporting.  */
1594   /* Note that get_config_pathname() calls percent_deescape(), so we
1595      call this before processing the arguments.  */
1596   dest_filename = xstrdup (get_config_pathname (component, backend));
1597   src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ());
1598   orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ());
1599
1600   arg = option->new_value;
1601   if (arg)
1602     {
1603       char *end;
1604
1605       arg++;
1606       end = strchr (arg, ',');
1607       if (end)
1608         *end = '\0';
1609
1610       cur_arg = percent_deescape (arg);
1611       if (end)
1612         {
1613           *end = ',';
1614           arg = end + 1;
1615         }
1616       else
1617         arg = NULL;
1618     }
1619
1620   res = link (dest_filename, orig_filename);
1621   if (res < 0 && errno != ENOENT)
1622     return -1;
1623   if (res < 0)
1624     {
1625       xfree (orig_filename);
1626       orig_filename = NULL;
1627     }
1628
1629   /* We now initialize the return strings, so the caller can do the
1630      cleanup for us.  */
1631   *src_filenamep = src_filename;
1632   *dest_filenamep = dest_filename;
1633   *orig_filenamep = orig_filename;
1634
1635   /* Use open() so that we can use O_EXCL.  */
1636   fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
1637   if (fd < 0)
1638     return -1;
1639   src_file = fdopen (fd, "w");
1640   res = errno;
1641   if (!src_file)
1642     {
1643       errno = res;
1644       return -1;
1645     }
1646
1647   /* Only if ORIG_FILENAME is not NULL did the configuration file
1648      exist already.  In this case, we will copy its content into the
1649      new configuration file, changing it to our liking in the
1650      process.  */
1651   if (orig_filename)
1652     {
1653       dest_file = fopen (dest_filename, "r");
1654       if (!dest_file)
1655         goto change_file_one_err;
1656
1657       while ((length = getline (&line, &line_len, dest_file)) > 0)
1658         {
1659           int disable = 0;
1660           char *start;
1661
1662           if (!strncmp (marker, line, sizeof (marker) - 1))
1663             {
1664               if (!in_marker)
1665                 in_marker = 1;
1666               else
1667                 break;
1668             }
1669
1670           start = line;
1671           while (*start == ' ' || *start == '\t')
1672             start++;
1673           if (*start && *start != '\r' && *start != '\n' && *start != '#')
1674             {
1675               char *end;
1676               char *endp;
1677               char saved_end;
1678
1679               endp = start;
1680               end = endp;
1681
1682               /* Search for the end of the line.  */
1683               while (*endp && *endp != '#' && *endp != '\r' && *endp != '\n')
1684                 {
1685                   endp++;
1686                   if (*endp && *endp != ' ' && *endp != '\t'
1687                       && *endp != '\r' && *endp != '\n' && *endp != '#')
1688                     end = endp + 1;
1689                 }
1690               saved_end = *end;
1691               *end = '\0';
1692
1693               if ((option->new_flags & GC_OPT_FLAG_DEFAULT)
1694                   || !cur_arg || strcmp (start, cur_arg))
1695                 disable = 1;
1696               else
1697                 {
1698                   /* Find next argument.  */
1699                   if (arg)
1700                     {
1701                       char *arg_end;
1702
1703                       arg++;
1704                       arg_end = strchr (arg, ',');
1705                       if (arg_end)
1706                         *arg_end = '\0';
1707
1708                       cur_arg = percent_deescape (arg);
1709                       if (arg_end)
1710                         {
1711                           *arg_end = ',';
1712                           arg = arg_end + 1;
1713                         }
1714                       else
1715                         arg = NULL;
1716                     }
1717                   else
1718                     cur_arg = NULL;
1719                 }
1720
1721               *end = saved_end;
1722             }
1723
1724           if (disable)
1725             {
1726               if (!in_marker)
1727                 {
1728                   fprintf (src_file,
1729                            "# GPGConf disabled this option here at %s\n",
1730                            asctimestamp (gnupg_get_time ()));
1731                   if (ferror (src_file))
1732                     goto change_file_one_err;
1733                   fprintf (src_file, "# %s", line);
1734                   if (ferror (src_file))
1735                     goto change_file_one_err;
1736                 }
1737             }
1738           else
1739             {
1740               fprintf (src_file, "%s", line);
1741               if (ferror (src_file))
1742                 goto change_file_one_err;
1743             }
1744         }
1745       if (ferror (dest_file))
1746         goto change_file_one_err;
1747     }
1748
1749   if (!in_marker)
1750     {
1751       /* There was no marker.  This is the first time we edit the
1752          file.  We add our own marker at the end of the file and
1753          proceed.  Note that we first write a newline, this guards us
1754          against files which lack the newline at the end of the last
1755          line, while it doesn't hurt us in all other cases.  */
1756       fprintf (src_file, "\n%s\n", marker);
1757       if (ferror (src_file))
1758         goto change_file_one_err;
1759     }
1760
1761   /* At this point, we have copied everything up to the end marker
1762      into the new file, except for the arguments we are going to add.
1763      Now, dump the new arguments and write the end marker, possibly
1764      followed by the rest of the original file.  */
1765   while (cur_arg)
1766     {
1767       fprintf (src_file, "%s\n", cur_arg);
1768
1769       /* Find next argument.  */
1770       if (arg)
1771         {
1772           char *end;
1773
1774           arg++;
1775           end = strchr (arg, ',');
1776           if (end)
1777             *end = '\0';
1778
1779           cur_arg = percent_deescape (arg);
1780           if (end)
1781             {
1782               *end = ',';
1783               arg = end + 1;
1784             }
1785           else
1786             arg = NULL;
1787         }
1788       else
1789         cur_arg = NULL;
1790     }
1791
1792   fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
1793   if (ferror (src_file))
1794     goto change_file_one_err;
1795
1796   if (!in_marker)
1797     {
1798       fprintf (src_file, "# GPGConf edited this configuration file.\n");
1799       if (ferror (src_file))
1800         goto change_file_one_err;
1801       fprintf (src_file, "# It will disable options before this marked "
1802                "block, but it will\n");
1803       if (ferror (src_file))
1804         goto change_file_one_err;
1805       fprintf (src_file, "# never change anything below these lines.\n");
1806       if (ferror (src_file))
1807         goto change_file_one_err;
1808     }
1809   if (dest_file)
1810     {
1811       while ((length = getline (&line, &line_len, dest_file)) > 0)
1812         {
1813           fprintf (src_file, "%s", line);
1814           if (ferror (src_file))
1815             goto change_file_one_err;
1816         }
1817       if (ferror (dest_file))
1818         goto change_file_one_err;
1819     }
1820   if (line)
1821     free (line);
1822   res = fclose (src_file);
1823   if (res)
1824     {
1825       res = errno;
1826       close (fd);
1827       if (dest_file)
1828         fclose (dest_file);
1829       errno = res;
1830       return -1;
1831     }
1832   close (fd);
1833   if (dest_file)
1834     {
1835       res = fclose (dest_file);
1836       if (res)
1837         return -1;
1838     }
1839   return 0;
1840
1841  change_file_one_err:
1842   if (line)
1843     free (line);
1844   res = errno;
1845   if (src_file)
1846     {
1847       fclose (src_file);
1848       close (fd);
1849     }
1850   if (dest_file)
1851     fclose (dest_file);
1852   errno = res;
1853   return -1;
1854 }
1855
1856
1857 /* Create and verify the new configuration file for the specified
1858    backend and component.  Returns 0 on success and -1 on error.  */
1859 static int
1860 change_options_program (gc_component_t component, gc_backend_t backend,
1861                         char **src_filenamep, char **dest_filenamep,
1862                         char **orig_filenamep)
1863 {
1864   static const char marker[] = "###+++--- GPGConf ---+++###";
1865   /* True if we are within the marker in the config file.  */
1866   int in_marker = 0;
1867   gc_option_t *option;
1868   char *line = NULL;
1869   size_t line_len;
1870   ssize_t length;
1871   int res;
1872   int fd;
1873   FILE *src_file = NULL;
1874   FILE *dest_file = NULL;
1875   char *src_filename;
1876   char *dest_filename;
1877   char *orig_filename;
1878
1879   /* FIXME.  Throughout the function, do better error reporting.  */
1880   dest_filename = xstrdup (get_config_pathname (component, backend));
1881   src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ());
1882   orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ());
1883
1884   res = link (dest_filename, orig_filename);
1885   if (res < 0 && errno != ENOENT)
1886     return -1;
1887   if (res < 0)
1888     {
1889       xfree (orig_filename);
1890       orig_filename = NULL;
1891     }
1892
1893   /* We now initialize the return strings, so the caller can do the
1894      cleanup for us.  */
1895   *src_filenamep = src_filename;
1896   *dest_filenamep = dest_filename;
1897   *orig_filenamep = orig_filename;
1898
1899   /* Use open() so that we can use O_EXCL.  */
1900   fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
1901   if (fd < 0)
1902     return -1;
1903   src_file = fdopen (fd, "w");
1904   res = errno;
1905   if (!src_file)
1906     {
1907       errno = res;
1908       return -1;
1909     }
1910
1911   /* Only if ORIG_FILENAME is not NULL did the configuration file
1912      exist already.  In this case, we will copy its content into the
1913      new configuration file, changing it to our liking in the
1914      process.  */
1915   if (orig_filename)
1916     {
1917       dest_file = fopen (dest_filename, "r");
1918       if (!dest_file)
1919         goto change_one_err;
1920
1921       while ((length = getline (&line, &line_len, dest_file)) > 0)
1922         {
1923           int disable = 0;
1924           char *start;
1925
1926           if (!strncmp (marker, line, sizeof (marker) - 1))
1927             {
1928               if (!in_marker)
1929                 in_marker = 1;
1930               else
1931                 break;
1932             }
1933
1934           start = line;
1935           while (*start == ' ' || *start == '\t')
1936             start++;
1937           if (*start && *start != '\r' && *start != '\n' && *start != '#')
1938             {
1939               char *end;
1940               char saved_end;
1941
1942               end = start;
1943               while (*end && *end != ' ' && *end != '\t'
1944                      && *end != '\r' && *end != '\n' && *end != '#')
1945                 end++;
1946               saved_end = *end;
1947               *end = '\0';
1948
1949               option = find_option (component, start, backend);
1950               *end = saved_end;
1951               if (option && ((option->new_flags & GC_OPT_FLAG_DEFAULT)
1952                              || option->new_value))
1953                 disable = 1;
1954             }
1955           if (disable)
1956             {
1957               if (!in_marker)
1958                 {
1959                   fprintf (src_file,
1960                            "# GPGConf disabled this option here at %s\n",
1961                            asctimestamp (gnupg_get_time ()));
1962                   if (ferror (src_file))
1963                     goto change_one_err;
1964                   fprintf (src_file, "# %s", line);
1965                   if (ferror (src_file))
1966                     goto change_one_err;
1967                 }
1968             }
1969           else
1970             {
1971               fprintf (src_file, "%s", line);
1972               if (ferror (src_file))
1973                 goto change_one_err;
1974             }
1975         }
1976       if (ferror (dest_file))
1977         goto change_one_err;
1978     }
1979
1980   if (!in_marker)
1981     {
1982       /* There was no marker.  This is the first time we edit the
1983          file.  We add our own marker at the end of the file and
1984          proceed.  Note that we first write a newline, this guards us
1985          against files which lack the newline at the end of the last
1986          line, while it doesn't hurt us in all other cases.  */
1987       fprintf (src_file, "\n%s\n", marker);
1988       if (ferror (src_file))
1989         goto change_one_err;
1990     }
1991   /* At this point, we have copied everything up to the end marker
1992      into the new file, except for the options we are going to change.
1993      Now, dump the changed options (except for those we are going to
1994      revert to their default), and write the end marker, possibly
1995      followed by the rest of the original file.  */
1996   option = gc_component[component].options;
1997   while (option->name)
1998     {
1999       if (!(option->flags & GC_OPT_FLAG_GROUP)
2000           && option->backend == backend
2001           && option->new_value)
2002         {
2003           char *arg = option->new_value;
2004
2005           do
2006             {
2007               if (*arg == '\0' || *arg == ',')
2008                 {
2009                   fprintf (src_file, "%s\n", option->name);
2010                   if (ferror (src_file))
2011                     goto change_one_err;
2012                 }
2013               else if (gc_arg_type[option->arg_type].fallback
2014                        == GC_ARG_TYPE_NONE)
2015                 {
2016                   assert (*arg == '1');
2017                   fprintf (src_file, "%s\n", option->name);
2018                   if (ferror (src_file))
2019                     goto change_one_err;
2020
2021                   arg++;
2022                 }
2023               else if (gc_arg_type[option->arg_type].fallback
2024                        == GC_ARG_TYPE_STRING)
2025                 {
2026                   char *end;
2027                   
2028                   assert (*arg == '"');
2029                   arg++;
2030                   
2031                   end = strchr (arg, ',');
2032                   if (end)
2033                     *end = '\0';
2034
2035                   fprintf (src_file, "%s %s\n", option->name,
2036                            percent_deescape (arg));
2037                   if (ferror (src_file))
2038                     goto change_one_err;
2039
2040                   if (end)
2041                     *end = ',';
2042                   arg = end;
2043                 }
2044               else
2045                 {
2046                   char *end;
2047
2048                   end = strchr (arg, ',');
2049                   if (end)
2050                     *end = '\0';
2051
2052                   fprintf (src_file, "%s %s\n", option->name, arg);
2053                   if (ferror (src_file))
2054                     goto change_one_err;
2055
2056                   if (end)
2057                     *end = ',';
2058                   arg = end;
2059                 }
2060
2061               assert (arg == NULL || *arg == '\0' || *arg == ',');
2062               if (arg && *arg == ',')
2063                 arg++;
2064             }
2065           while (arg && *arg);
2066         }
2067       option++;
2068     }
2069
2070   fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
2071   if (ferror (src_file))
2072     goto change_one_err;
2073
2074   if (!in_marker)
2075     {
2076       fprintf (src_file, "# GPGConf edited this configuration file.\n");
2077       if (ferror (src_file))
2078         goto change_one_err;
2079       fprintf (src_file, "# It will disable options before this marked "
2080                "block, but it will\n");
2081       if (ferror (src_file))
2082         goto change_one_err;
2083       fprintf (src_file, "# never change anything below these lines.\n");
2084       if (ferror (src_file))
2085         goto change_one_err;
2086     }
2087   if (dest_file)
2088     {
2089       while ((length = getline (&line, &line_len, dest_file)) > 0)
2090         {
2091           fprintf (src_file, "%s", line);
2092           if (ferror (src_file))
2093             goto change_one_err;
2094         }
2095       if (ferror (dest_file))
2096         goto change_one_err;
2097     }
2098   if (line)
2099     free (line);
2100   res = fclose (src_file);
2101   if (res)
2102     {
2103       res = errno;
2104       close (fd);
2105       if (dest_file)
2106         fclose (dest_file);
2107       errno = res;
2108       return -1;
2109     }
2110   close (fd);
2111   if (dest_file)
2112     {
2113       res = fclose (dest_file);
2114       if (res)
2115         return -1;
2116     }
2117   return 0;
2118
2119  change_one_err:
2120   if (line)
2121     free (line);
2122   res = errno;
2123   if (src_file)
2124     {
2125       fclose (src_file);
2126       close (fd);
2127     }
2128   if (dest_file)
2129     fclose (dest_file);
2130   errno = res;
2131   return -1;
2132 }
2133
2134
2135 /* Read the modifications from IN and apply them.  */
2136 void
2137 gc_component_change_options (int component, FILE *in)
2138 {
2139   int err = 0;
2140   int runtime[GC_BACKEND_NR];
2141   char *src_pathname[GC_BACKEND_NR];
2142   char *dest_pathname[GC_BACKEND_NR];
2143   char *orig_pathname[GC_BACKEND_NR];
2144   gc_backend_t backend;
2145   gc_option_t *option;
2146   char *line = NULL;
2147   size_t line_len = 0;
2148   ssize_t length;
2149
2150   for (backend = 0; backend < GC_BACKEND_NR; backend++)
2151     {
2152       runtime[backend] = 0;
2153       src_pathname[backend] = NULL;
2154       dest_pathname[backend] = NULL;
2155       orig_pathname[backend] = NULL;
2156     }
2157
2158   while ((length = getline (&line, &line_len, in)) > 0)
2159     {
2160       char *linep;
2161       unsigned long flags = 0;
2162       char *new_value = "";
2163       unsigned long new_value_nr;
2164
2165       /* Strip newline and carriage return, if present.  */
2166       while (length > 0
2167              && (line[length - 1] == '\n' || line[length - 1] == '\r'))
2168         line[--length] = '\0';
2169
2170       linep = strchr (line, ':');
2171       if (linep)
2172         *(linep++) = '\0';
2173
2174       /* Extract additional flags.  Default to none.  */
2175       if (linep)
2176         {
2177           char *end;
2178           char *tail;
2179
2180           end = strchr (linep, ':');
2181           if (end)
2182             *(end++) = '\0';
2183
2184           errno = 0;
2185           flags = strtoul (linep, &tail, 0);
2186           if (errno)
2187             gc_error (1, errno, "malformed flags in option %s", line);
2188           if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
2189             gc_error (1, 0, "garbage after flags in option %s", line);
2190
2191           linep = end;
2192         }
2193
2194       /* Extract default value, if present.  Default to empty if
2195          not.  */
2196       if (linep)
2197         {
2198           char *end;
2199
2200           end = strchr (linep, ':');
2201           if (end)
2202             *(end++) = '\0';
2203
2204           new_value = linep;
2205
2206           linep = end;
2207         }
2208
2209       option = find_option (component, line, GC_BACKEND_ANY);
2210       if (!option)
2211         gc_error (1, 0, "unknown option %s", line);
2212
2213       option_check_validity (option, flags, new_value, &new_value_nr);
2214
2215       if (option->flags & GC_OPT_FLAG_RUNTIME)
2216         runtime[option->backend] = 1;
2217
2218       option->new_flags = flags;
2219       if (!(flags & GC_OPT_FLAG_DEFAULT))
2220         {
2221           if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
2222               && (option->flags & GC_OPT_FLAG_LIST))
2223             {
2224               char *str;
2225
2226               /* We convert the number to a list of 1's for
2227                  convenient list handling.  */
2228               assert (new_value_nr > 0);
2229               option->new_value = xmalloc ((2 * (new_value_nr - 1) + 1) + 1);
2230               str = option->new_value;
2231               *(str++) = '1';
2232               while (--new_value_nr > 0)
2233                 {
2234                   *(str++) = ',';
2235                   *(str++) = '1';
2236                 }
2237               *(str++) = '\0';
2238             }
2239           else
2240             option->new_value = xstrdup (new_value);
2241         }
2242     }
2243
2244   /* Now that we have collected and locally verified the changes,
2245      write them out to new configuration files, verify them
2246      externally, and then commit them.  */
2247   option = gc_component[component].options;
2248   while (option->name)
2249     {
2250       /* Go on if we have already seen this backend, or if there is
2251          nothing to do.  */
2252       if (src_pathname[option->backend]
2253           || !(option->new_flags || option->new_value))
2254         {
2255           option++;
2256           continue;
2257         }
2258
2259       if (gc_backend[option->backend].program)
2260         err = change_options_program (component, option->backend,
2261                                       &src_pathname[option->backend],
2262                                       &dest_pathname[option->backend],
2263                                       &orig_pathname[option->backend]);
2264       else
2265         err = change_options_file (component, option->backend,
2266                                    &src_pathname[option->backend],
2267                                    &dest_pathname[option->backend],
2268                                    &orig_pathname[option->backend]);
2269         
2270       if (err)
2271         break;
2272           
2273       option++;
2274     }
2275
2276   if (!err)
2277     {
2278       int i;
2279
2280       for (i = 0; i < GC_BACKEND_NR; i++)
2281         {
2282           if (src_pathname[i])
2283             {
2284               /* FIXME: Make a verification here.  */
2285
2286               assert (dest_pathname[i]);
2287
2288               if (orig_pathname[i])
2289                 err = rename (src_pathname[i], dest_pathname[i]);
2290               else
2291                 {
2292                   /* This is a bit safer than rename() because we
2293                      expect DEST_PATHNAME not to be there.  If it
2294                      happens to be there, this will fail.  */
2295                   err = link (src_pathname[i], dest_pathname[i]);
2296                   if (!err)
2297                     unlink (src_pathname[i]);
2298                 }
2299               if (err)
2300                 break;
2301               src_pathname[i] = NULL;
2302             }
2303         }
2304     }
2305
2306   if (err)
2307     {
2308       int i;
2309       int saved_errno = errno;
2310
2311       /* An error occured.  */
2312       for (i = 0; i < GC_BACKEND_NR; i++)
2313         {
2314           if (src_pathname[i])
2315             {
2316               /* The change was not yet committed.  */
2317               unlink (src_pathname[i]);
2318               if (orig_pathname[i])
2319                 unlink (orig_pathname[i]);
2320             }
2321           else
2322             {
2323               /* The changes were already committed.  FIXME: This is a
2324                  tad dangerous, as we don't know if we don't overwrite
2325                  a version of the file that is even newer than the one
2326                  we just installed.  */
2327               if (orig_pathname[i])
2328                 rename (orig_pathname[i], dest_pathname[i]);
2329               else
2330                 unlink (dest_pathname[i]);
2331             }
2332         }
2333       gc_error (1, saved_errno, "could not commit changes");
2334     }
2335
2336   /* If it all worked, notify the daemons of the changes.  */
2337   if (opt.runtime)
2338     for (backend = 0; backend < GC_BACKEND_NR; backend++)  
2339       {
2340         if (runtime[backend] && gc_backend[backend].runtime_change)
2341           (*gc_backend[backend].runtime_change) ();
2342       }
2343
2344   if (line)
2345     free (line);
2346 }