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