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