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