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