2004-02-25 Marcus Brinkmann <marcus@g10code.de>
[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
36 /* For log_logv(), asctimestamp(), gnupg_get_time ().  */
37 #define JNLIB_NEED_LOG_LOGV
38 #include "util.h"
39
40 #include "gpgconf.h"
41
42 \f
43 /* TODO:
44    Portability - Add gnulib replacements for getline, etc.
45    Backend: File backend must be able to write out changes !!!
46    Components: Add more components and their options.
47    Robustness: Do more validation.  Call programs to do validation for us.
48    Don't use popen, as this will not tell us if the program had a
49    non-zero exit code.
50    Add options to change backend binary path.
51    Extract binary path for some backends from gpgsm/gpg config.
52 */
53
54 \f
55 #if defined (__riscos__) \
56     || (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ))
57 void gc_error (int status, int errnum, const char *fmt, ...) \
58   __attribute__ ((format (printf, 3, 4)));
59 #endif
60
61 /* Output a diagnostic message.  If ERRNUM is not 0, then the output
62    is followed by a colon, a white space, and the error string for the
63    error number ERRNUM.  In any case the output is finished by a
64    newline.  The message is prepended by the program name, a colon,
65    and a whitespace.  The output may be further formatted or
66    redirected by the jnlib logging facility.  */
67 void
68 gc_error (int status, int errnum, const char *fmt, ...)
69 {
70   va_list arg_ptr;
71
72   va_start (arg_ptr, fmt);
73   log_logv (JNLIB_LOG_ERROR, fmt, arg_ptr);
74   va_end (arg_ptr);
75
76   if (errnum)
77     log_printf (": %s\n", strerror (errnum));
78   else
79     log_printf ("\n");
80
81   if (status)
82     {
83       log_printf (NULL);
84       log_printf ("fatal error (exit status %i)\n", status);
85       exit (status);
86     }
87 }
88
89 \f
90 /* Backend configuration.  Backends are used to decide how the default
91    and current value of an option can be determined, and how the
92    option can be changed.  To every option in every component belongs
93    exactly one backend that controls and determines the option.  Some
94    backends are programs from the GPG system.  Others might be
95    implemented by GPGConf itself.  If you change this enum, don't
96    forget to update GC_BACKEND below.  */
97 typedef enum
98   {
99     /* Any backend, used for find_option ().  */
100     GC_BACKEND_ANY,
101
102     /* The Gnu Privacy Guard.  */
103     GC_BACKEND_GPG,
104
105     /* The Gnu Privacy Guard for S/MIME.  */
106     GC_BACKEND_GPGSM,
107
108     /* The GPG Agent.  */
109     GC_BACKEND_GPG_AGENT,
110
111     /* The Aegypten directory manager.  */
112     GC_BACKEND_DIRMNGR,
113
114     /* The LDAP server list file for the Aegypten director manager.  */
115     GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST,
116
117     /* The number of the above entries.  */
118     GC_BACKEND_NR
119   } gc_backend_t;
120
121
122 /* To be able to implement generic algorithms for the various
123    backends, we collect all information about them in this struct.  */
124 static struct
125 {
126   /* The name of the backend.  */
127   const char *name;
128
129   /* The name of the program that acts as the backend.  Some backends
130      don't have an associated program, but are implemented directly by
131      GPGConf.  In this case, PROGRAM is NULL.  */
132   char *program;
133
134   /* The option name for the configuration filename of this backend.
135      This must be an absolute pathname.  It can be an option from a
136      different backend (but then ordering of the options might
137      matter).  */
138   const char *option_config_filename;
139
140   /* If this is a file backend rather than a program backend, then
141      this is the name of the option associated with the file.  */
142   const char *option_name;
143 } gc_backend[GC_BACKEND_NR] =
144   {
145     { NULL, NULL, NULL },               /* GC_BACKEND_ANY dummy entry.  */
146     { "GnuPG", "gpg", "gpgconf-gpg.conf" },
147     { "GPGSM", "gpgsm", "gpgconf-gpgsm.conf" },
148     { "GPG Agent", "gpg-agent", "gpgconf-gpg-agent.conf" },
149     { "DirMngr", "dirmngr", "gpgconf-dirmngr.conf" },
150     { "DirMngr LDAP Server List", NULL, "ldapserverlist-file", "LDAP Server" },
151   };
152
153 \f
154 /* Option configuration.  */
155
156 /* An option might take an argument, or not.  Argument types can be
157    basic or complex.  Basic types are generic and easy to validate.
158    Complex types provide more specific information about the intended
159    use, but can be difficult to validate.  If you add to this enum,
160    don't forget to update GC_ARG_TYPE below.  YOU MUST NOT CHANGE THE
161    NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE EXTERNAL
162    INTERFACE.  */
163 typedef enum
164   {
165     /* Basic argument types.  */
166
167     /* No argument.  */
168     GC_ARG_TYPE_NONE = 0,
169
170     /* A String argument.  */
171     GC_ARG_TYPE_STRING = 1,
172
173     /* A signed integer argument.  */
174     GC_ARG_TYPE_INT32 = 2,
175
176     /* An unsigned integer argument.  */
177     GC_ARG_TYPE_UINT32 = 3,
178
179     /* ADD NEW BASIC TYPE ENTRIES HERE.  */
180
181     /* Complex argument types.  */
182
183     /* A complete pathname.  */
184     GC_ARG_TYPE_PATHNAME = 32,
185
186     /* An LDAP server in the format
187        HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN.  */
188     GC_ARG_TYPE_LDAP_SERVER = 33,
189
190     /* A 40 character fingerprint.  */
191     GC_ARG_TYPE_KEY_FPR = 34,
192
193     /* ADD NEW COMPLEX TYPE ENTRIES HERE.  */
194
195     /* The number of the above entries.  */
196     GC_ARG_TYPE_NR
197   } gc_arg_type_t;
198
199
200 /* For every argument, we record some information about it in the
201    following struct.  */
202 static struct
203 {
204   /* For every argument type exists a basic argument type that can be
205      used as a fallback for input and validation purposes.  */
206   gc_arg_type_t fallback;
207
208   /* Human-readable name of the type.  */
209   const char *name;
210 } gc_arg_type[GC_ARG_TYPE_NR] =
211   {
212     /* The basic argument types have their own types as fallback.  */
213     { GC_ARG_TYPE_NONE, "none" },
214     { GC_ARG_TYPE_STRING, "string" },
215     { GC_ARG_TYPE_INT32, "int32" },
216     { GC_ARG_TYPE_UINT32, "uint32" },
217
218     /* Reserved basic type entries for future extension.  */
219     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
220     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
221     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
222     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
223     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
224     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
225     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
226     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
227     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
228     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
229     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
230     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
231     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
232     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
233
234     /* The complex argument types have a basic type as fallback.  */
235     { GC_ARG_TYPE_STRING, "pathname" },
236     { GC_ARG_TYPE_STRING, "ldap server" },
237     { GC_ARG_TYPE_STRING, "key fpr" },
238   };
239
240
241 /* Every option has an associated expert level, than can be used to
242    hide advanced and expert options from beginners.  If you add to
243    this list, don't forget to update GC_LEVEL below.  YOU MUST NOT
244    CHANGE THE NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE
245    EXTERNAL INTERFACE.  */
246 typedef enum
247   {
248     /* The basic options should always be displayed.  */
249     GC_LEVEL_BASIC,
250
251     /* The advanced options may be hidden from beginners.  */
252     GC_LEVEL_ADVANCED,
253
254     /* The expert options should only be displayed to experts.  */
255     GC_LEVEL_EXPERT,
256
257     /* The invisible options should normally never be displayed.  */
258     GC_LEVEL_INVISIBLE,
259
260     /* The internal options are never exported, they mark options that
261        are recorded for internal use only.  */
262     GC_LEVEL_INTERNAL,
263
264     /* ADD NEW ENTRIES HERE.  */
265
266     /* The number of the above entries.  */
267     GC_LEVEL_NR
268   } gc_expert_level_t;
269
270 /* A description for each expert level.  */
271 static struct
272 {
273   const char *name;
274 } gc_level[] =
275   {
276     { "basic" },
277     { "advanced" },
278     { "expert" },
279     { "invisible" },
280     { "internal" }
281   };
282
283
284 /* Option flags.  YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING
285    FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE.  */
286 #define GC_OPT_FLAG_NONE        0UL
287 /* Some entries in the option list are not options, but mark the
288    beginning of a new group of options.  These entries have the GROUP
289    flag set.  */
290 #define GC_OPT_FLAG_GROUP       (1UL << 0)
291 /* The ARG_OPT flag for an option indicates that the argument is
292    optional.  */
293 #define GC_OPT_FLAG_ARG_OPT     (1UL << 1)
294 /* The LIST flag for an option indicates that the option can occur
295    several times.  A comma separated list of arguments is used as the
296    argument value.  */
297 #define GC_OPT_FLAG_LIST        (1UL << 2)
298 /* The RUNTIME flag for an option indicates that the option can be
299    changed at runtime.  */
300 #define GC_OPT_FLAG_RUNTIME     (1UL << 3)
301
302 /* The following flags are incorporated from the backend.  */
303 /* The DEFAULT flag for an option indicates that the option has a
304    default value.  */
305 #define GC_OPT_FLAG_DEFAULT     (1UL << 4)
306 /* The DEF_DESC flag for an option indicates that the option has a
307    default, which is described by the value of the default field.  */
308 #define GC_OPT_FLAG_DEF_DESC    (1UL << 5)
309 /* The NO_ARG_DESC flag for an option indicates that the argument has
310    a default, which is described by the value of the ARGDEF field.  */
311 #define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6)
312
313 /* A human-readable description for each flag.  */
314 static struct
315 {
316   const char *name;
317 } gc_flag[] =
318   {
319     { "group" },
320     { "optional arg" },
321     { "list" },
322     { "runtime" }
323   };
324
325
326 /* To each option, or group marker, the information in the GC_OPTION
327    struct is provided.  If you change this, don't forget to update the
328    option list of each component.  */
329 struct gc_option
330 {
331   /* If this is NULL, then this is a terminator in an array of unknown
332      length.  Otherwise, if this entry is a group marker (see FLAGS),
333      then this is the name of the group described by this entry.
334      Otherwise it is the name of the option described by this
335      entry.  The name must not contain a colon.  */
336   const char *name;
337
338   /* The option flags.  If the GROUP flag is set, then this entry is a
339      group marker, not an option, and only the fields LEVEL,
340      DESC_DOMAIN and DESC are valid.  In all other cases, this entry
341      describes a new option and all fields are valid.  */
342   unsigned long flags;
343
344   /* The expert level.  This field is valid for options and groups.  A
345      group has the expert level of the lowest-level option in the
346      group.  */
347   gc_expert_level_t level;
348
349   /* A gettext domain in which the following description can be found.
350      If this is NULL, then DESC is not translated.  Valid for groups
351      and options.  */
352   const char *desc_domain;
353
354   /* A gettext description for this group or option.  If it starts
355      with a '|', then the string up to the next '|' describes the
356      argument, and the description follows the second '|'.  */
357   const char *desc;
358
359   /* The following fields are only valid for options.  */
360
361   /* The type of the option argument.  */
362   gc_arg_type_t arg_type;
363
364   /* The backend that implements this option.  */
365   gc_backend_t backend;
366
367   /* The following fields are set to NULL at startup (because all
368      option's are declared as static variables).  They are at the end
369      of the list so that they can be omitted from the option
370      declarations.  */
371
372   /* This is true if the option is supported by this version of the
373      backend.  */
374   int active;
375
376   /* The default value for this option.  This is NULL if the option is
377      not present in the backend, the empty string if no default is
378      available, and otherwise a quoted string.  */
379   char *default_value;
380
381   /* The default argument is only valid if the "optional arg" flag is
382      set, and specifies the default argument (value) that is used if
383      the argument is omitted.  */
384   char *default_arg;
385
386   /* The current value of this option.  */
387   char *value;
388
389   /* The new flags for this option.  The only defined flag is actually
390      GC_OPT_FLAG_DEFAULT, and it means that the option should be
391      deleted.  In this case, NEW_VALUE is NULL.  */
392   unsigned long new_flags;
393
394   /* The new value of this option.  */
395   char *new_value;
396 };
397 typedef struct gc_option gc_option_t;
398
399 /* Use this macro to terminate an option list.  */
400 #define GC_OPTION_NULL { NULL }
401
402 \f
403 /* The options of the GC_COMPONENT_GPG_AGENT component.  */
404 static gc_option_t gc_options_gpg_agent[] =
405  {
406    GC_OPTION_NULL
407  };
408
409
410 /* The options of the GC_COMPONENT_SCDAEMON component.  */
411 static gc_option_t gc_options_scdaemon[] =
412  {
413    GC_OPTION_NULL
414  };
415
416
417 /* The options of the GC_COMPONENT_GPGSM component.  */
418 static gc_option_t gc_options_gpgsm[] =
419  {
420    GC_OPTION_NULL
421  };
422
423
424 /* The options of the GC_COMPONENT_DIRMNGR component.  */
425 static gc_option_t gc_options_dirmngr[] =
426  {
427    /* The configuration file to which we write the changes.  */
428    { "gpgconf-dirmngr.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
429      NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
430
431    { "Monitor",
432      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
433      NULL, "Options controlling the diagnostic output" },
434    { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
435      "dirmngr", "verbose",
436      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
437    { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
438      "dirmngr", "be somewhat more quiet",
439      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
440    { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
441      NULL, NULL,
442      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
443
444    { "Format",
445      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
446      NULL, "Options controlling the format of the output" },
447    { "sh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
448      "dirmngr", "sh-style command output",
449      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
450    { "csh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
451      "dirmngr", "csh-style command output",
452      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
453    
454    { "Configuration",
455      GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
456      NULL, "Options controlling the configuration" },
457    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
458      "dirmngr", "|FILE|read options from FILE",
459      GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
460
461    { "Debug",
462      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
463      "dirmngr", "Options useful for debugging" },
464    { "debug", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
465      "dirmngr", "|FLAGS|set the debugging FLAGS",
466      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
467    { "debug-all", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
468      "dirmngr", "set all debugging flags",
469      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
470    { "no-detach", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
471      "dirmngr", "do not detach from the console",
472      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
473    { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
474      "dirmngr", "|FILE|write logs to FILE",
475      GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
476    { "debug-wait", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
477      NULL, NULL,
478      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
479    { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
480      NULL, NULL,
481      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
482
483    { "Enforcement",
484      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
485      NULL, "Options controlling the interactivity and enforcement" },
486    { "batch", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
487      "dirmngr", "run without asking a user",
488      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
489    { "force", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
490      "dirmngr", "force loading of outdated CRLs",
491      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
492
493    { "LDAP",
494      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
495      NULL, "Configuration of LDAP servers to use" },
496    { "add-servers", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
497      "dirmngr", "add new servers discovered in CRL distribution points"
498      " to serverlist", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
499    { "ldaptimeout", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
500      "dirmngr", "|N|set LDAP timeout to N seconds",
501      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
502    /* The following entry must not be removed, as it is required for
503       the GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST.  */
504    { "ldapserverlist-file",
505      GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
506      "dirmngr", "|FILE|read LDAP server list from FILE",
507      GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
508    /* This entry must come after at least one entry for
509       GC_BACKEND_DIRMNGR in this component, so that the entry for
510       "ldapserverlist-file will be initialized before this one.  */
511    { "LDAP Server", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
512      NULL, "LDAP server list",
513      GC_ARG_TYPE_LDAP_SERVER, GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST },
514
515    { "CRL",
516      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
517      NULL, "Configuration of the CRL" },
518    { "max-replies", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
519      "dirmngr", "|N|do not return more than N items in one query",
520      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
521
522    GC_OPTION_NULL
523  };
524
525 \f
526 /* Component system.  Each component is a set of options that can be
527    configured at the same time.  If you change this, don't forget to
528    update GC_COMPONENT below.  */
529 typedef enum
530   {
531     /* The GPG Agent.  */
532     GC_COMPONENT_GPG_AGENT,
533
534     /* The Smardcard Daemon.  */
535     GC_COMPONENT_SCDAEMON,
536
537     /* GPG for S/MIME.  */
538     GC_COMPONENT_GPGSM,
539
540     /* The LDAP Directory Manager for CRLs.  */
541     GC_COMPONENT_DIRMNGR,
542
543     /* The number of components.  */
544     GC_COMPONENT_NR
545   } gc_component_t;
546
547
548 /* The information associated with each component.  */
549 static struct
550 {
551   /* The name of this component.  Must not contain a colon (':')
552      character.  */
553   const char *name;
554
555   /* The gettext domain for the description DESC.  If this is NULL,
556      then the description is not translated.  */
557   const char *desc_domain;
558
559   /* The description for this domain.  */
560   const char *desc;
561
562   /* The list of options for this component, terminated by
563      GC_OPTION_NULL.  */
564   gc_option_t *options;
565 } gc_component[] =
566   {
567     { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent },
568     { "scdaemon", NULL, "Smartcard Daemon", gc_options_scdaemon },
569     { "gpgsm", NULL, "GPG for S/MIME", gc_options_gpgsm },
570     { "dirmngr", NULL, "CRL Manager", gc_options_dirmngr }
571   };
572
573 \f
574 /* Robust version of dgettext.  */
575 static const char *
576 my_dgettext (const char *domain, const char *msgid)
577 {
578   if (domain)
579     {
580       char *text = dgettext (domain, msgid);
581       return text ? text : msgid;
582     }
583   else
584     return msgid;
585 }
586
587
588 /* Percent-Escape special characters.  The string is valid until the
589    next invocation of the function.  */
590 static char *
591 percent_escape (const char *src)
592 {
593   static char *esc_str;
594   static int esc_str_len;
595   int new_len = 3 * strlen (src) + 1;
596   char *dst;
597
598   if (esc_str_len < new_len)
599     {
600       char *new_esc_str = realloc (esc_str, new_len);
601       if (!new_esc_str)
602         gc_error (1, errno, "can not escape string");
603       esc_str = new_esc_str;
604       esc_str_len = new_len;
605     }
606
607   dst = esc_str;
608   while (*src)
609     {
610       if (*src == '%')
611         {
612           *(dst++) = '%';
613           *(dst++) = '2';
614           *(dst++) = '5';
615         }         
616       else if (*src == ':')
617         {
618           /* The colon is used as field separator.  */
619           *(dst++) = '%';
620           *(dst++) = '3';
621           *(dst++) = 'a';
622         }
623       else if (*src == ',')
624         {
625           /* The comma is used as list separator.  */
626           *(dst++) = '%';
627           *(dst++) = '2';
628           *(dst++) = 'c';
629         }
630       else
631         *(dst++) = *(src);
632       src++;
633     }
634   *dst = '\0';
635   return esc_str;
636 }
637
638
639 /* Convert two hexadecimal digits from STR to the value they
640    represent.  Returns -1 if one of the characters is not a
641    hexadecimal digit.  */
642 static int
643 hextobyte (const char *str)
644 {
645   int val = 0;
646   int i;
647
648 #define NROFHEXDIGITS 2
649   for (i = 0; i < NROFHEXDIGITS; i++)
650     {
651       if (*str >= '0' && *str <= '9')
652         val += *str - '0';
653       else if (*str >= 'A' && *str <= 'F')
654         val += 10 + *str - 'A';
655       else if (*str >= 'a' && *str <= 'f')
656         val += 10 + *str - 'a';
657       else
658         return -1;
659       if (i < NROFHEXDIGITS - 1)
660         val *= 16;
661       str++;
662     }
663   return val;
664 }
665
666
667
668 /* Percent-Deescape special characters.  The string is valid until the
669    next invocation of the function.  */
670 static char *
671 percent_deescape (const char *src)
672 {
673   static char *str;
674   static int str_len;
675   int new_len = 3 * strlen (src) + 1;
676   char *dst;
677
678   if (str_len < new_len)
679     {
680       char *new_str = realloc (str, new_len);
681       if (!new_str)
682         gc_error (1, errno, "can not deescape string");
683       str = new_str;
684       str_len = new_len;
685     }
686
687   dst = str;
688   while (*src)
689     {
690       if (*src == '%')
691         {
692           int val = hextobyte (src + 1);
693
694           if (val < 0)
695             gc_error (1, 0, "malformed end of string %s", src);
696
697           *(dst++) = (char) val;
698           src += 3;
699         }         
700       else
701         *(dst++) = *(src++);
702     }
703   *dst = '\0';
704   return str;
705 }
706
707 \f
708 /* List all components that are available.  */
709 void
710 gc_component_list_components (FILE *out)
711 {
712   gc_component_t idx;
713
714   for (idx = 0; idx < GC_COMPONENT_NR; idx++)
715     {
716       const char *desc = gc_component[idx].desc;
717       desc = my_dgettext (gc_component[idx].desc_domain, desc);
718       fprintf (out, "%s:%s\n", gc_component[idx].name, percent_escape (desc));
719     }
720 }
721
722 \f
723 /* Find the component with the name NAME.  Returns -1 if not
724    found.  */
725 int
726 gc_component_find (const char *name)
727 {
728   gc_component_t idx;
729
730   for (idx = 0; idx < GC_COMPONENT_NR; idx++)
731     {
732       if (!strcmp (name, gc_component[idx].name))
733         return idx;
734     }
735   return -1;
736 }
737
738 \f
739 /* List all options of the component COMPONENT.  */
740 void
741 gc_component_list_options (int component, FILE *out)
742 {  
743   const gc_option_t *option = gc_component[component].options;
744
745   while (option->name)
746     {
747       const char *desc = NULL;
748       char *arg_name = NULL;
749
750       /* Do not output unknown or internal options.  */
751       if (!(option->flags & GC_OPT_FLAG_GROUP)
752           && (!option->active || option->level == GC_LEVEL_INTERNAL))
753         {
754           option++;
755           continue;
756         }
757
758       if (option->desc)
759         {
760           desc = my_dgettext (option->desc_domain, option->desc);
761
762           if (*desc == '|')
763             {
764               const char *arg_tail = strchr (&desc[1], '|');
765
766               if (arg_tail)
767                 {
768                   int arg_len = arg_tail - &desc[1];
769                   arg_name = xmalloc (arg_len + 1);
770                   memcpy (arg_name, &desc[1], arg_len);
771                   arg_name[arg_len] = '\0';
772                   desc = arg_tail + 1;
773                 }
774             }
775         }
776
777       /* YOU MUST NOT REORDER THE FIELDS IN THIS OUTPUT, AS THEIR
778          ORDER IS PART OF THE EXTERNAL INTERFACE.  YOU MUST NOT REMOVE
779          ANY FIELDS.  */
780
781       /* The name field.  */
782       fprintf (out, "%s", option->name);
783
784       /* The flags field.  */
785       fprintf (out, ":%lu", option->flags);
786       if (opt.verbose)
787         {
788           putc (' ', out);
789           
790           if (!option->flags)
791             fprintf (out, "none");
792           else
793             {
794               unsigned long flags = option->flags;
795               unsigned long flag = 0;
796               unsigned long first = 1;
797
798               while (flags)
799                 {
800                   if (flags & 1)
801                     {
802                       if (first)
803                         first = 0;
804                       else
805                         putc (',', out);
806                       fprintf (out, "%s", gc_flag[flag].name);
807                     }
808                   flags >>= 1;
809                   flag++;
810                 }
811             }
812         }
813
814       /* The level field.  */
815       fprintf (out, ":%u", option->level);
816       if (opt.verbose)
817         fprintf (out, " %s", gc_level[option->level].name);
818
819       /* The description field.  */
820       fprintf (out, ":%s", desc ? percent_escape (desc) : "");
821
822       /* The type field.  */
823       fprintf (out, ":%u", option->arg_type);
824       if (opt.verbose)
825         fprintf (out, " %s", gc_arg_type[option->arg_type].name);
826
827       /* The alternate type field.  */
828       fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback);
829       if (opt.verbose)
830         fprintf (out, " %s",
831                  gc_arg_type[gc_arg_type[option->arg_type].fallback].name);
832
833       /* The argument name field.  */
834       fprintf (out, ":%s", arg_name ? percent_escape (arg_name) : "");
835       if (arg_name)
836         xfree (arg_name);
837
838       /* The default value field.  */
839       fprintf (out, ":%s", option->default_value ? option->default_value : "");
840
841       /* The default argument field.  */
842       fprintf (out, ":%s", option->default_arg ? option->default_arg : "");
843
844       /* The value field.  */
845       if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
846           && (option->flags & GC_OPT_FLAG_LIST)
847           && option->value)
848         /* The special format "1,1,1,1,...,1" is converted to a number
849            here.  */
850         fprintf (out, ":%u", (strlen (option->value) + 1) / 2);
851       else
852         fprintf (out, ":%s", option->value ? option->value : "");
853
854       /* ADD NEW FIELDS HERE.  */
855
856       putc ('\n', out);
857       option++;
858     }
859 }
860
861
862 /* Find the option NAME in component COMPONENT, for the backend
863    BACKEND.  If BACKEND is GC_BACKEND_ANY, any backend will match.  */
864 static gc_option_t *
865 find_option (gc_component_t component, const char *name,
866              gc_backend_t backend)
867 {
868   gc_option_t *option = gc_component[component].options;
869   while (option->name)
870     {
871       if (!(option->flags & GC_OPT_FLAG_GROUP)
872           && !strcmp (option->name, name)
873           && (backend == GC_BACKEND_ANY || option->backend == backend))
874         break;
875       option++;
876     }
877   return option->name ? option : NULL;
878 }
879
880 \f
881 /* Determine the configuration pathname for the component COMPONENT
882    and backend BACKEND.  */
883 static char *
884 get_config_pathname (gc_component_t component, gc_backend_t backend)
885 {
886   char *pathname = NULL;
887   gc_option_t *option = find_option
888     (component, gc_backend[backend].option_config_filename, GC_BACKEND_ANY);
889   assert (option);
890   assert (option->arg_type == GC_ARG_TYPE_PATHNAME);
891   assert (!(option->flags & GC_OPT_FLAG_LIST));
892
893   if (!option->active || !option->default_value)
894     gc_error (1, 0, "Option %s, needed by backend %s, was not initialized",
895               gc_backend[backend].option_config_filename,
896               gc_backend[backend].name);
897
898   if (option->value && *option->value)
899     pathname = percent_deescape (&option->value[1]);
900   else if (option->default_value && *option->default_value)
901     pathname = percent_deescape (&option->default_value[1]);
902   else
903     pathname = "";
904
905   if (pathname[0] != '/')
906     gc_error (1, 0, "Option %s, needed by backend %s, is not absolute",
907               gc_backend[backend].option_config_filename,
908               gc_backend[backend].name);
909
910   return pathname;
911 }
912
913 \f
914 /* Retrieve the options for the component COMPONENT from backend
915    BACKEND, which we already know is a program-type backend.  */
916 static void
917 retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
918 {
919   char *cmd_line;
920   char *line = NULL;
921   size_t line_len = 0;
922   ssize_t length;
923   FILE *config;
924   char *config_pathname;
925
926   cmd_line = xasprintf ("%s --gpgconf-list", gc_backend[backend].program);
927
928   config = popen (cmd_line, "r");
929   if (!config)
930     gc_error (1, errno, "could not gather active options from %s", cmd_line);
931
932   while ((length = getline (&line, &line_len, config)) > 0)
933     {
934       gc_option_t *option;
935       char *linep;
936       unsigned long flags = 0;
937       char *default_value = NULL;
938       
939       /* Strip newline and carriage return, if present.  */
940       while (length > 0
941              && (line[length - 1] == '\n' || line[length - 1] == '\r'))
942         line[--length] = '\0';
943
944       linep = strchr (line, ':');
945       if (linep)
946         *(linep++) = '\0';
947       
948       /* Extract additional flags.  Default to none.  */
949       if (linep)
950         {
951           char *end;
952           char *tail;
953
954           end = strchr (linep, ':');
955           if (end)
956             *(end++) = '\0';
957
958           errno = 0;
959           flags = strtoul (linep, &tail, 0);
960           if (errno)
961             gc_error (1, errno, "malformed flags in option %s from %s", line, cmd_line);
962           if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
963             gc_error (1, 0, "garbage after flags in option %s from %s", line, cmd_line);
964
965           linep = end;
966         }
967
968       /* Extract default value, if present.  Default to empty if
969          not.  */
970       if (linep)
971         {
972           char *end;
973
974           end = strchr (linep, ':');
975           if (end)
976             *(end++) = '\0';
977
978           if (flags & GC_OPT_FLAG_DEFAULT)
979             default_value = linep;
980
981           linep = end;
982         }
983
984       /* Look up the option in the component and install the
985          configuration data.  */
986       option = find_option (component, line, backend);
987       if (option)
988         {
989           if (option->active)
990             gc_error (1, errno, "option %s returned twice from %s",
991                       line, cmd_line);
992           option->active = 1;
993
994           option->flags |= flags;
995           if (default_value && *default_value)
996             option->default_value = xstrdup (default_value);
997         }
998     }
999   if (ferror (config))
1000     gc_error (1, errno, "error reading from %s", cmd_line);
1001   if (fclose (config) && ferror (config))
1002     gc_error (1, errno, "error closing %s", cmd_line);
1003   xfree (cmd_line);
1004
1005   /* At this point, we can parse the configuration file.  */
1006   config_pathname = get_config_pathname (component, backend);
1007
1008   config = fopen (config_pathname, "r");
1009   if (!config)
1010     gc_error (0, errno, "warning: can not open config file %s",
1011               config_pathname);
1012   else
1013     {
1014       while ((length = getline (&line, &line_len, config)) > 0)
1015         {
1016           char *name;
1017           char *value;
1018           gc_option_t *option;
1019           
1020           name = line;
1021           while (*name == ' ' || *name == '\t')
1022             name++;
1023           if (!*name || *name == '#' || *name == '\r' || *name == '\n')
1024             continue;
1025
1026           value = name;
1027           while (*value && *value != ' ' && *value != '\t'
1028                  && *value != '#' && *value != '\r' && *value != '\n')
1029             value++;
1030           if (*value == ' ' || *value == '\t')
1031             {
1032               char *end;
1033
1034               *(value++) = '\0';
1035               while (*value == ' ' || *value == '\t')
1036                 value++;
1037
1038               end = value;
1039               while (*end && *end != '#' && *end != '\r' && *end != '\n')
1040                 end++;
1041               while (end > value && (end[-1] == ' ' || end[-1] == '\t'))
1042                 end--;
1043               *end = '\0';
1044             }
1045           else
1046             *value = '\0';
1047
1048           /* Look up the option in the component and install the
1049              configuration data.  */
1050           option = find_option (component, line, backend);
1051           if (option)
1052             {
1053               char *opt_value;
1054
1055               if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
1056                 {
1057                   if (*value)
1058                     gc_error (0, 0,
1059                               "warning: ignoring argument %s for option %s",
1060                               value, name);
1061                   opt_value = xstrdup ("1");
1062                 }
1063               else if (gc_arg_type[option->arg_type].fallback
1064                        == GC_ARG_TYPE_STRING)
1065                 opt_value = xasprintf ("\"%s", percent_escape (value));
1066               else
1067                 {
1068                   /* FIXME: Verify that the number is sane.  */
1069                   opt_value = xstrdup (value);
1070                 }
1071
1072               /* Now enter the option into the table.  */
1073               if (!(option->flags & GC_OPT_FLAG_LIST))
1074                 {
1075                   if (option->value)
1076                     free (option->value);
1077                   option->value = opt_value;
1078                 }
1079               else
1080                 {
1081                   if (!option->value)
1082                     option->value = opt_value;
1083                   else
1084                     {
1085                       char *opt_val = opt_value;
1086
1087                       if (gc_arg_type[option->arg_type].fallback
1088                           == GC_ARG_TYPE_STRING)
1089                         opt_val++;
1090
1091                       /* FIXME.  For type none arguments, this is
1092                          wrong.  */
1093                       option->value = xasprintf ("%s,%s", option->value,
1094                                                  opt_val);
1095                       xfree (opt_value);
1096                     }
1097                 }
1098             }
1099         }
1100
1101       if (ferror (config))
1102         gc_error (1, errno, "error reading from %s", config_pathname);
1103       if (fclose (config) && ferror (config))
1104         gc_error (1, errno, "error closing %s", config_pathname);
1105     }
1106
1107   if (line)
1108     free (line);
1109 }
1110
1111
1112 /* Retrieve the options for the component COMPONENT from backend
1113    BACKEND, which we already know is of type file list.  */ 
1114 static void
1115 retrieve_options_from_file (gc_component_t component, gc_backend_t backend)
1116 {
1117   gc_option_t *list_option;
1118   char *list_pathname;
1119   FILE *list_file;
1120   char *line = NULL;
1121   size_t line_len = 0;
1122   ssize_t length;
1123   char *list = NULL;
1124
1125   list_option = find_option (component,
1126                              gc_backend[backend].option_name, GC_BACKEND_ANY);
1127   assert (list_option);
1128   assert (!list_option->active);
1129
1130   list_pathname = get_config_pathname (component, backend);
1131   list_file = fopen (list_pathname, "r");
1132   if (!list_file)
1133     gc_error (0, errno, "warning: can not open list file %s", list_pathname);
1134   else
1135     {
1136
1137       while ((length = getline (&line, &line_len, list_file)) > 0)
1138         {
1139           char *start;
1140           char *end;
1141           char *new_list;
1142
1143           start = line;
1144           while (*start == ' ' || *start == '\t')
1145             start++;
1146           if (!*start || *start == '#' || *start == '\r' || *start == '\n')
1147             continue;
1148
1149           end = start;
1150           while (*end && *end != '#' && *end != '\r' && *end != '\n')
1151             end++;
1152           /* Walk back to skip trailing white spaces.  Looks evil, but
1153              works because of the conditions on START and END imposed
1154              at this point (END is at least START + 1, and START is
1155              not a whitespace character).  */
1156           while (*(end - 1) == ' ' || *(end - 1) == '\t')
1157             end--;
1158           *end = '\0';
1159           /* FIXME: Oh, no!  This is so lame!  Use realloc and really
1160              append.  */
1161           if (list)
1162             {
1163               new_list = xasprintf ("%s,%s", list, percent_escape (start));
1164               xfree (list);
1165               list = new_list;
1166             }
1167           else
1168             list = xasprintf ("\"%s", percent_escape (start));
1169         }
1170       if (ferror (list_file))
1171         gc_error (1, errno, "can not read list file %s", list_pathname);
1172     }
1173
1174   list_option->active = 1;
1175   list_option->value = list;
1176
1177   if (line)
1178     free (line);
1179 }
1180
1181
1182 /* Retrieve the currently active options and their defaults from all
1183    involved backends for this component.  */
1184 void
1185 gc_component_retrieve_options (int component)
1186 {
1187   int backend_seen[GC_BACKEND_NR];
1188   gc_backend_t backend;
1189   gc_option_t *option = gc_component[component].options;
1190
1191   for (backend = 0; backend < GC_BACKEND_NR; backend++)
1192     backend_seen[backend] = 0;
1193
1194   while (option->name)
1195     {
1196       if (!(option->flags & GC_OPT_FLAG_GROUP))
1197         {
1198           backend = option->backend;
1199
1200           if (backend_seen[backend])
1201             {
1202               option++;
1203               continue;
1204             }
1205           backend_seen[backend] = 1;
1206
1207           assert (backend != GC_BACKEND_ANY);
1208
1209           if (gc_backend[backend].program)
1210             retrieve_options_from_program (component, backend);
1211           else
1212             retrieve_options_from_file (component, backend);
1213         }
1214       option++;
1215     }
1216 }
1217
1218 \f
1219 /* Perform a simple validity check based on the type.  */
1220 static void
1221 option_check_validity (gc_option_t *option, unsigned long flags,
1222                        const char *new_value)
1223 {
1224   if (option->new_flags || option->new_value)
1225     gc_error (1, 0, "option %s already changed", option->name);
1226
1227   if ((flags & GC_OPT_FLAG_DEFAULT) && *new_value)
1228     gc_error (1, 0, "value %s provided for deleted option %s",
1229               new_value, option->name);
1230
1231   if (!*new_value)
1232     return;
1233
1234   /* FIXME.  Verify that lists are lists, numbers are numbers, strings
1235      are strings, etc.  */
1236 }
1237
1238
1239 /* Create and verify the new configuration file for the specified
1240    backend and component.  Returns 0 on success and -1 on error.  */
1241 static int
1242 change_options_file (gc_component_t component, gc_backend_t backend,
1243                      char **src_filenamep, char **dest_filenamep,
1244                      char **orig_filenamep)
1245 {
1246   /* FIXME.  */
1247   assert (!"Not implemented.");
1248   return -1;
1249 }
1250
1251
1252 /* Create and verify the new configuration file for the specified
1253    backend and component.  Returns 0 on success and -1 on error.  */
1254 static int
1255 change_options_program (gc_component_t component, gc_backend_t backend,
1256                         char **src_filenamep, char **dest_filenamep,
1257                         char **orig_filenamep)
1258 {
1259   static const char marker[] = "###+++--- GPGConf ---+++###";
1260   /* True if we are within the marker in the config file.  */
1261   int in_marker = 0;
1262   gc_option_t *option;
1263   char *line = NULL;
1264   size_t line_len;
1265   ssize_t length;
1266   int res;
1267   int fd;
1268   FILE *src_file = NULL;
1269   FILE *dest_file = NULL;
1270   char *src_filename;
1271   char *dest_filename;
1272   char *orig_filename;
1273
1274   /* FIXME.  Throughout the function, do better error reporting.  */
1275   dest_filename = xstrdup (get_config_pathname (component, backend));
1276   src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ());
1277   orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ());
1278
1279   res = link (dest_filename, orig_filename);
1280   if (res < 0 && errno != ENOENT)
1281     return -1;
1282   if (res < 0)
1283     {
1284       xfree (orig_filename);
1285       orig_filename = NULL;
1286     }
1287   /* We now initialize the return strings, so the caller can do the
1288      cleanup for us.  */
1289   *src_filenamep = src_filename;
1290   *dest_filenamep = dest_filename;
1291   *orig_filenamep = orig_filename;
1292
1293   /* Use open() so that we can use O_EXCL.  */
1294   fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
1295   if (fd < 0)
1296     return -1;
1297   src_file = fdopen (fd, "w");
1298   res = errno;
1299   if (!src_file)
1300     {
1301       errno = res;
1302       return -1;
1303     }
1304
1305   /* Only if ORIG_FILENAME is not NULL did the configuration file
1306      exist already.  In this case, we will copy its content into the
1307      new configuration file, changing it to our liking in the
1308      process.  */
1309   if (orig_filename)
1310     {
1311       dest_file = fopen (dest_filename, "r");
1312       if (!dest_file)
1313         goto change_one_err;
1314
1315       while ((length = getline (&line, &line_len, dest_file)) > 0)
1316         {
1317           int disable = 0;
1318           char *start;
1319           char *end;
1320
1321           if (!strncmp (marker, line, sizeof (marker) - 1))
1322             {
1323               if (!in_marker)
1324                 in_marker = 1;
1325               else
1326                 break;
1327             }
1328
1329           start = line;
1330           while (*start == ' ' || *start == '\t')
1331             start++;
1332           if (*start && *start != '\r' && *start != '\n' && *start != '#')
1333             {
1334               char saved_end;
1335
1336               end = start;
1337               while (*end && *end != ' ' && *end != '\t'
1338                      && *end != '\r' && *end != '\n' && *end != '#')
1339                 end++;
1340               saved_end = *end;
1341               *end = '\0';
1342
1343               option = find_option (component, start, backend);
1344               *end = saved_end;
1345               if (option && (option->new_flags & GC_OPT_FLAG_DEFAULT))
1346                 disable = 1;
1347             }
1348           if (disable)
1349             {
1350               if (!in_marker)
1351                 {
1352                   fprintf (src_file,
1353                            "# GPGConf disabled this option here at %s\n",
1354                            asctimestamp (gnupg_get_time ()));
1355                   if (ferror (src_file))
1356                     goto change_one_err;
1357                   fprintf (src_file, "# %s", line);
1358                   if (ferror (src_file))
1359                     goto change_one_err;
1360                 }
1361             }
1362           else
1363             {
1364               fprintf (src_file, "%s", line);
1365               if (ferror (src_file))
1366                 goto change_one_err;
1367             }
1368         }
1369       if (ferror (dest_file))
1370         goto change_one_err;
1371     }
1372
1373   if (!in_marker)
1374     {
1375       /* There was no marker.  This is the first time we edit the
1376          file.  We add our own marker at the end of the file and
1377          proceed.  Note that we first write a newline, this guards us
1378          against files which lack the newline at the end of the last
1379          line, while it doesn't hurt us in all other cases.  */
1380       fprintf (src_file, "\n%s\n", marker);
1381       if (ferror (src_file))
1382         goto change_one_err;
1383     }
1384   /* At this point, we have copied everything up to the end marker
1385      into the new file, except for the options we are going to change.
1386      Now, dump the changed options (except for those we are going to
1387      revert to their default), and write the end marker, possibly
1388      followed by the rest of the original file.  */
1389   option = gc_component[component].options;
1390   while (option->name)
1391     {
1392       /* FIXME: Add support for lists and default arg (new_value eq "").  */
1393       if (!(option->flags & GC_OPT_FLAG_GROUP)
1394           && option->backend == backend
1395           && option->new_value
1396           && *option->new_value)
1397         {
1398           if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING)
1399             fprintf (src_file, "%s %s\n", option->name,
1400                      percent_deescape (&option->new_value[1]));
1401           else if (option->arg_type == GC_ARG_TYPE_NONE)
1402             fprintf (src_file, "%s\n", option->name);
1403           else
1404             fprintf (src_file, "%s %s\n", option->name, option->new_value);
1405           if (ferror (src_file))
1406             goto change_one_err;
1407         }
1408       option++;
1409     }
1410
1411   fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
1412   if (ferror (src_file))
1413     goto change_one_err;
1414
1415   if (!in_marker)
1416     {
1417       fprintf (src_file, "# GPGConf edited this configuration file.\n");
1418       if (ferror (src_file))
1419         goto change_one_err;
1420       fprintf (src_file, "# It will disable options before this marked "
1421                "block, but it will\n");
1422       if (ferror (src_file))
1423         goto change_one_err;
1424       fprintf (src_file, "# never change anything below these lines.\n");
1425       if (ferror (src_file))
1426         goto change_one_err;
1427     }
1428   if (dest_file)
1429     {
1430       while ((length = getline (&line, &line_len, dest_file)) > 0)
1431         {
1432           fprintf (src_file, "%s", line);
1433           if (ferror (src_file))
1434             goto change_one_err;
1435         }
1436       if (ferror (dest_file))
1437         goto change_one_err;
1438     }
1439   if (line)
1440     free (line);
1441   res = fclose (src_file);
1442   if (res)
1443     {
1444       res = errno;
1445       close (fd);
1446       if (dest_file)
1447         fclose (dest_file);
1448       errno = res;
1449       return -1;
1450     }
1451   close (fd);
1452   if (dest_file)
1453     {
1454       res = fclose (dest_file);
1455       if (res)
1456         return -1;
1457     }
1458   return 0;
1459
1460  change_one_err:
1461   if (line)
1462     free (line);
1463   res = errno;
1464   if (src_file)
1465     {
1466       fclose (src_file);
1467       close (fd);
1468     }
1469   if (dest_file)
1470     fclose (dest_file);
1471   errno = res;
1472   return -1;
1473 }
1474
1475 /* Read the modifications from IN and apply them.  */
1476 void
1477 gc_component_change_options (int component, FILE *in)
1478 {
1479   int err = 0;
1480   char *src_pathname[GC_BACKEND_NR];
1481   char *dest_pathname[GC_BACKEND_NR];
1482   char *orig_pathname[GC_BACKEND_NR];
1483   gc_backend_t backend;
1484   gc_option_t *option;
1485   char *line = NULL;
1486   size_t line_len = 0;
1487   ssize_t length;
1488
1489   for (backend = 0; backend < GC_BACKEND_NR; backend++)
1490     {
1491       src_pathname[backend] = NULL;
1492       dest_pathname[backend] = NULL;
1493       orig_pathname[backend] = NULL;
1494     }
1495
1496   while ((length = getline (&line, &line_len, in)) > 0)
1497     {
1498       char *linep;
1499       unsigned long flags = 0;
1500       char *new_value = "";
1501
1502       /* Strip newline and carriage return, if present.  */
1503       while (length > 0
1504              && (line[length - 1] == '\n' || line[length - 1] == '\r'))
1505         line[--length] = '\0';
1506
1507       linep = strchr (line, ':');
1508       if (linep)
1509         *(linep++) = '\0';
1510
1511       /* Extract additional flags.  Default to none.  */
1512       if (linep)
1513         {
1514           char *end;
1515           char *tail;
1516
1517           end = strchr (linep, ':');
1518           if (end)
1519             *(end++) = '\0';
1520
1521           errno = 0;
1522           flags = strtoul (linep, &tail, 0);
1523           if (errno)
1524             gc_error (1, errno, "malformed flags in option %s", line);
1525           if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
1526             gc_error (1, 0, "garbage after flags in option %s", line);
1527
1528           linep = end;
1529         }
1530
1531       /* Extract default value, if present.  Default to empty if
1532          not.  */
1533       if (linep)
1534         {
1535           char *end;
1536
1537           end = strchr (linep, ':');
1538           if (end)
1539             *(end++) = '\0';
1540
1541           new_value = linep;
1542
1543           linep = end;
1544         }
1545
1546       option = find_option (component, line, GC_BACKEND_ANY);
1547       if (!option)
1548         gc_error (1, 0, "unknown option %s", line);
1549
1550       option_check_validity (option, flags, new_value);
1551
1552       option->new_flags = flags;
1553       if (!(flags & GC_OPT_FLAG_DEFAULT))
1554         option->new_value = xstrdup (new_value);
1555     }
1556
1557   /* Now that we have collected and locally verified the changes,
1558      write them out to new configuration files, verify them
1559      externally, and then commit them.  */
1560   option = gc_component[component].options;
1561   while (option->name)
1562     {
1563       /* Go on if we have already seen this backend, or if there is
1564          nothing to do.  */
1565       if (src_pathname[option->backend] || !(option->new_flags || option->new_value))
1566         {
1567           option++;
1568           continue;
1569         }
1570
1571       if (gc_backend[option->backend].program)
1572         err = change_options_program (component, option->backend,
1573                                       &src_pathname[component],
1574                                       &dest_pathname[component],
1575                                       &orig_pathname[component]);
1576       else
1577         err = change_options_file (component, option->backend,
1578                                    &src_pathname[component],
1579                                    &dest_pathname[component],
1580                                    &orig_pathname[component]);
1581         
1582       if (err)
1583         break;
1584           
1585       option++;
1586     }
1587   if (!err)
1588     {
1589       int i;
1590
1591       for (i = 0; i < GC_COMPONENT_NR; i++)
1592         {
1593           if (src_pathname[i])
1594             {
1595               /* FIXME: Make a verification here.  */
1596
1597               assert (dest_pathname[i]);
1598
1599               if (orig_pathname[i])
1600                 err = rename (src_pathname[i], dest_pathname[i]);
1601               else
1602                 {
1603                   /* This is a bit safer than rename() because we
1604                      expect DEST_PATHNAME not to be there.  If it
1605                      happens to be there, this will fail.  */
1606                   err = link (src_pathname[i], dest_pathname[i]);
1607                   if (!err)
1608                     unlink (src_pathname[i]);
1609                 }
1610               if (err)
1611                 break;
1612               src_pathname[i] = NULL;
1613             }
1614         }
1615     }
1616
1617   if (err)
1618     {
1619       int i;
1620       int saved_errno = errno;
1621
1622       /* An error occured.  */
1623       for (i = 0; i < GC_COMPONENT_NR; i++)
1624         {
1625           if (src_pathname[i])
1626             {
1627               /* The change was not yet committed.  */
1628               unlink (src_pathname[i]);
1629               if (orig_pathname[i])
1630                 unlink (orig_pathname[i]);
1631             }
1632           else
1633             {
1634               /* The changes were already committed.  FIXME: This is a
1635                  tad dangerous, as we don't know if we don't overwrite
1636                  a version of the file that is even newer than the one
1637                  we just installed.  */
1638               if (orig_pathname[i])
1639                 rename (orig_pathname[i], dest_pathname[i]);
1640               else
1641                 unlink (dest_pathname[i]);
1642             }
1643         }
1644       gc_error (1, saved_errno, "could not commit changes");
1645     }
1646   if (line)
1647     free (line);
1648 }