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