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