Fix buglet.
[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.  This is never set for GC_ARG_TYPE_NONE options.  */
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 the option OPTION.  */
740 static void
741 list_one_option (const gc_option_t *option, FILE *out)
742 {
743   const char *desc = NULL;
744   char *arg_name = NULL;
745
746   if (option->desc)
747     {
748       desc = my_dgettext (option->desc_domain, option->desc);
749
750       if (*desc == '|')
751         {
752           const char *arg_tail = strchr (&desc[1], '|');
753
754           if (arg_tail)
755             {
756               int arg_len = arg_tail - &desc[1];
757               arg_name = xmalloc (arg_len + 1);
758               memcpy (arg_name, &desc[1], arg_len);
759               arg_name[arg_len] = '\0';
760               desc = arg_tail + 1;
761             }
762         }
763     }
764
765
766   /* YOU MUST NOT REORDER THE FIELDS IN THIS OUTPUT, AS THEIR ORDER IS
767      PART OF THE EXTERNAL INTERFACE.  YOU MUST NOT REMOVE ANY
768      FIELDS.  */
769
770   /* The name field.  */
771   fprintf (out, "%s", option->name);
772
773   /* The flags field.  */
774   fprintf (out, ":%lu", option->flags);
775   if (opt.verbose)
776     {
777       putc (' ', out);
778           
779       if (!option->flags)
780         fprintf (out, "none");
781       else
782         {
783           unsigned long flags = option->flags;
784           unsigned long flag = 0;
785           unsigned long first = 1;
786
787           while (flags)
788             {
789               if (flags & 1)
790                 {
791                   if (first)
792                     first = 0;
793                   else
794                     putc (',', out);
795                   fprintf (out, "%s", gc_flag[flag].name);
796                 }
797               flags >>= 1;
798               flag++;
799             }
800         }
801     }
802
803   /* The level field.  */
804   fprintf (out, ":%u", option->level);
805   if (opt.verbose)
806     fprintf (out, " %s", gc_level[option->level].name);
807
808   /* The description field.  */
809   fprintf (out, ":%s", desc ? percent_escape (desc) : "");
810   
811   /* The type field.  */
812   fprintf (out, ":%u", option->arg_type);
813   if (opt.verbose)
814     fprintf (out, " %s", gc_arg_type[option->arg_type].name);
815
816   /* The alternate type field.  */
817   fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback);
818   if (opt.verbose)
819     fprintf (out, " %s",
820              gc_arg_type[gc_arg_type[option->arg_type].fallback].name);
821
822   /* The argument name field.  */
823   fprintf (out, ":%s", arg_name ? percent_escape (arg_name) : "");
824   if (arg_name)
825     xfree (arg_name);
826
827   /* The default value field.  */
828   fprintf (out, ":%s", option->default_value ? option->default_value : "");
829
830   /* The default argument field.  */
831   fprintf (out, ":%s", option->default_arg ? option->default_arg : "");
832
833   /* The value field.  */
834   if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
835       && (option->flags & GC_OPT_FLAG_LIST)
836       && option->value)
837     /* The special format "1,1,1,1,...,1" is converted to a number
838        here.  */
839     fprintf (out, ":%u", (strlen (option->value) + 1) / 2);
840   else
841     fprintf (out, ":%s", option->value ? option->value : "");
842
843   /* ADD NEW FIELDS HERE.  */
844
845   putc ('\n', out);
846 }
847
848
849 /* List all options of the component COMPONENT.  */
850 void
851 gc_component_list_options (int component, FILE *out)
852 {  
853   const gc_option_t *option = gc_component[component].options;
854   const gc_option_t *group_option = NULL;
855
856   while (option->name)
857     {
858       /* Do not output unknown or internal options.  */
859       if (!(option->flags & GC_OPT_FLAG_GROUP)
860           && (!option->active || option->level == GC_LEVEL_INTERNAL))
861         {
862           option++;
863           continue;
864         }
865
866       if (option->flags & GC_OPT_FLAG_GROUP)
867         group_option = option;
868       else
869         {
870           if (group_option)
871             {
872               list_one_option (group_option, out);
873               group_option = NULL;
874             }
875
876           list_one_option (option, out);
877         }
878
879       option++;
880     }
881 }
882
883
884 /* Find the option NAME in component COMPONENT, for the backend
885    BACKEND.  If BACKEND is GC_BACKEND_ANY, any backend will match.  */
886 static gc_option_t *
887 find_option (gc_component_t component, const char *name,
888              gc_backend_t backend)
889 {
890   gc_option_t *option = gc_component[component].options;
891   while (option->name)
892     {
893       if (!(option->flags & GC_OPT_FLAG_GROUP)
894           && !strcmp (option->name, name)
895           && (backend == GC_BACKEND_ANY || option->backend == backend))
896         break;
897       option++;
898     }
899   return option->name ? option : NULL;
900 }
901
902 \f
903 /* Determine the configuration pathname for the component COMPONENT
904    and backend BACKEND.  */
905 static char *
906 get_config_pathname (gc_component_t component, gc_backend_t backend)
907 {
908   char *pathname = NULL;
909   gc_option_t *option = find_option
910     (component, gc_backend[backend].option_config_filename, GC_BACKEND_ANY);
911   assert (option);
912   assert (option->arg_type == GC_ARG_TYPE_PATHNAME);
913   assert (!(option->flags & GC_OPT_FLAG_LIST));
914
915   if (!option->active || !option->default_value)
916     gc_error (1, 0, "Option %s, needed by backend %s, was not initialized",
917               gc_backend[backend].option_config_filename,
918               gc_backend[backend].name);
919
920   if (option->value && *option->value)
921     pathname = percent_deescape (&option->value[1]);
922   else if (option->default_value && *option->default_value)
923     pathname = percent_deescape (&option->default_value[1]);
924   else
925     pathname = "";
926
927   if (pathname[0] != '/')
928     gc_error (1, 0, "Option %s, needed by backend %s, is not absolute",
929               gc_backend[backend].option_config_filename,
930               gc_backend[backend].name);
931
932   return pathname;
933 }
934
935 \f
936 /* Retrieve the options for the component COMPONENT from backend
937    BACKEND, which we already know is a program-type backend.  */
938 static void
939 retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
940 {
941   char *cmd_line;
942   char *line = NULL;
943   size_t line_len = 0;
944   ssize_t length;
945   FILE *config;
946   char *config_pathname;
947
948   cmd_line = xasprintf ("%s --gpgconf-list", gc_backend[backend].program);
949
950   config = popen (cmd_line, "r");
951   if (!config)
952     gc_error (1, errno, "could not gather active options from %s", cmd_line);
953
954   while ((length = getline (&line, &line_len, config)) > 0)
955     {
956       gc_option_t *option;
957       char *linep;
958       unsigned long flags = 0;
959       char *default_value = NULL;
960       
961       /* Strip newline and carriage return, if present.  */
962       while (length > 0
963              && (line[length - 1] == '\n' || line[length - 1] == '\r'))
964         line[--length] = '\0';
965
966       linep = strchr (line, ':');
967       if (linep)
968         *(linep++) = '\0';
969       
970       /* Extract additional flags.  Default to none.  */
971       if (linep)
972         {
973           char *end;
974           char *tail;
975
976           end = strchr (linep, ':');
977           if (end)
978             *(end++) = '\0';
979
980           errno = 0;
981           flags = strtoul (linep, &tail, 0);
982           if (errno)
983             gc_error (1, errno, "malformed flags in option %s from %s", line, cmd_line);
984           if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
985             gc_error (1, 0, "garbage after flags in option %s from %s", line, cmd_line);
986
987           linep = end;
988         }
989
990       /* Extract default value, if present.  Default to empty if
991          not.  */
992       if (linep)
993         {
994           char *end;
995
996           end = strchr (linep, ':');
997           if (end)
998             *(end++) = '\0';
999
1000           if (flags & GC_OPT_FLAG_DEFAULT)
1001             default_value = linep;
1002
1003           linep = end;
1004         }
1005
1006       /* Look up the option in the component and install the
1007          configuration data.  */
1008       option = find_option (component, line, backend);
1009       if (option)
1010         {
1011           if (option->active)
1012             gc_error (1, errno, "option %s returned twice from %s",
1013                       line, cmd_line);
1014           option->active = 1;
1015
1016           option->flags |= flags;
1017           if (default_value && *default_value)
1018             option->default_value = xstrdup (default_value);
1019         }
1020     }
1021   if (ferror (config))
1022     gc_error (1, errno, "error reading from %s", cmd_line);
1023   if (fclose (config) && ferror (config))
1024     gc_error (1, errno, "error closing %s", cmd_line);
1025   xfree (cmd_line);
1026
1027   /* At this point, we can parse the configuration file.  */
1028   config_pathname = get_config_pathname (component, backend);
1029
1030   config = fopen (config_pathname, "r");
1031   if (!config)
1032     gc_error (0, errno, "warning: can not open config file %s",
1033               config_pathname);
1034   else
1035     {
1036       while ((length = getline (&line, &line_len, config)) > 0)
1037         {
1038           char *name;
1039           char *value;
1040           gc_option_t *option;
1041           
1042           name = line;
1043           while (*name == ' ' || *name == '\t')
1044             name++;
1045           if (!*name || *name == '#' || *name == '\r' || *name == '\n')
1046             continue;
1047
1048           value = name;
1049           while (*value && *value != ' ' && *value != '\t'
1050                  && *value != '#' && *value != '\r' && *value != '\n')
1051             value++;
1052           if (*value == ' ' || *value == '\t')
1053             {
1054               char *end;
1055
1056               *(value++) = '\0';
1057               while (*value == ' ' || *value == '\t')
1058                 value++;
1059
1060               end = value;
1061               while (*end && *end != '#' && *end != '\r' && *end != '\n')
1062                 end++;
1063               while (end > value && (end[-1] == ' ' || end[-1] == '\t'))
1064                 end--;
1065               *end = '\0';
1066             }
1067           else
1068             *value = '\0';
1069
1070           /* Look up the option in the component and install the
1071              configuration data.  */
1072           option = find_option (component, line, backend);
1073           if (option)
1074             {
1075               char *opt_value;
1076
1077               if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
1078                 {
1079                   if (*value)
1080                     gc_error (0, 0,
1081                               "warning: ignoring argument %s for option %s",
1082                               value, name);
1083                   opt_value = xstrdup ("1");
1084                 }
1085               else if (gc_arg_type[option->arg_type].fallback
1086                        == GC_ARG_TYPE_STRING)
1087                 opt_value = xasprintf ("\"%s", percent_escape (value));
1088               else
1089                 {
1090                   /* FIXME: Verify that the number is sane.  */
1091                   opt_value = xstrdup (value);
1092                 }
1093
1094               /* Now enter the option into the table.  */
1095               if (!(option->flags & GC_OPT_FLAG_LIST))
1096                 {
1097                   if (option->value)
1098                     free (option->value);
1099                   option->value = opt_value;
1100                 }
1101               else
1102                 {
1103                   if (!option->value)
1104                     option->value = opt_value;
1105                   else
1106                     {
1107                       char *opt_val = opt_value;
1108
1109                       option->value = xasprintf ("%s,%s", option->value,
1110                                                  opt_val);
1111                       xfree (opt_value);
1112                     }
1113                 }
1114             }
1115         }
1116
1117       if (ferror (config))
1118         gc_error (1, errno, "error reading from %s", config_pathname);
1119       if (fclose (config) && ferror (config))
1120         gc_error (1, errno, "error closing %s", config_pathname);
1121     }
1122
1123   if (line)
1124     free (line);
1125 }
1126
1127
1128 /* Retrieve the options for the component COMPONENT from backend
1129    BACKEND, which we already know is of type file list.  */ 
1130 static void
1131 retrieve_options_from_file (gc_component_t component, gc_backend_t backend)
1132 {
1133   gc_option_t *list_option;
1134   char *list_pathname;
1135   FILE *list_file;
1136   char *line = NULL;
1137   size_t line_len = 0;
1138   ssize_t length;
1139   char *list = NULL;
1140
1141   list_option = find_option (component,
1142                              gc_backend[backend].option_name, GC_BACKEND_ANY);
1143   assert (list_option);
1144   assert (!list_option->active);
1145
1146   list_pathname = get_config_pathname (component, backend);
1147   list_file = fopen (list_pathname, "r");
1148   if (!list_file)
1149     gc_error (0, errno, "warning: can not open list file %s", list_pathname);
1150   else
1151     {
1152
1153       while ((length = getline (&line, &line_len, list_file)) > 0)
1154         {
1155           char *start;
1156           char *end;
1157           char *new_list;
1158
1159           start = line;
1160           while (*start == ' ' || *start == '\t')
1161             start++;
1162           if (!*start || *start == '#' || *start == '\r' || *start == '\n')
1163             continue;
1164
1165           end = start;
1166           while (*end && *end != '#' && *end != '\r' && *end != '\n')
1167             end++;
1168           /* Walk back to skip trailing white spaces.  Looks evil, but
1169              works because of the conditions on START and END imposed
1170              at this point (END is at least START + 1, and START is
1171              not a whitespace character).  */
1172           while (*(end - 1) == ' ' || *(end - 1) == '\t')
1173             end--;
1174           *end = '\0';
1175           /* FIXME: Oh, no!  This is so lame!  Use realloc and really
1176              append.  */
1177           if (list)
1178             {
1179               new_list = xasprintf ("%s,%s", list, percent_escape (start));
1180               xfree (list);
1181               list = new_list;
1182             }
1183           else
1184             list = xasprintf ("\"%s", percent_escape (start));
1185         }
1186       if (ferror (list_file))
1187         gc_error (1, errno, "can not read list file %s", list_pathname);
1188     }
1189
1190   list_option->active = 1;
1191   list_option->value = list;
1192
1193   if (line)
1194     free (line);
1195 }
1196
1197
1198 /* Retrieve the currently active options and their defaults from all
1199    involved backends for this component.  */
1200 void
1201 gc_component_retrieve_options (int component)
1202 {
1203   int backend_seen[GC_BACKEND_NR];
1204   gc_backend_t backend;
1205   gc_option_t *option = gc_component[component].options;
1206
1207   for (backend = 0; backend < GC_BACKEND_NR; backend++)
1208     backend_seen[backend] = 0;
1209
1210   while (option->name)
1211     {
1212       if (!(option->flags & GC_OPT_FLAG_GROUP))
1213         {
1214           backend = option->backend;
1215
1216           if (backend_seen[backend])
1217             {
1218               option++;
1219               continue;
1220             }
1221           backend_seen[backend] = 1;
1222
1223           assert (backend != GC_BACKEND_ANY);
1224
1225           if (gc_backend[backend].program)
1226             retrieve_options_from_program (component, backend);
1227           else
1228             retrieve_options_from_file (component, backend);
1229         }
1230       option++;
1231     }
1232 }
1233
1234 \f
1235 /* Perform a simple validity check based on the type.  Return in
1236    NEW_VALUE_NR the value of the number in NEW_VALUE if OPTION is of
1237    type GC_ARG_TYPE_NONE.  */
1238 static void
1239 option_check_validity (gc_option_t *option, unsigned long flags,
1240                        char *new_value, unsigned long *new_value_nr)
1241 {
1242   char *arg;
1243
1244   if (!option->active)
1245     gc_error (1, 0, "option %s not supported by backend", option->name);
1246       
1247   if (option->new_flags || option->new_value)
1248     gc_error (1, 0, "option %s already changed", option->name);
1249
1250   if (flags & GC_OPT_FLAG_DEFAULT)
1251     {
1252       if (*new_value)
1253         gc_error (1, 0, "argument %s provided for deleted option %s",
1254                   new_value, option->name);
1255
1256       return;
1257     }
1258
1259   /* GC_ARG_TYPE_NONE options have special list treatment.  */
1260   if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
1261     {
1262       char *tail;
1263
1264       errno = 0;
1265       *new_value_nr = strtoul (new_value, &tail, 0);
1266
1267       if (errno)
1268         gc_error (1, errno, "invalid argument for option %s",
1269                   option->name);
1270       if (*tail)
1271         gc_error (1, 0, "garbage after argument for option %s",
1272                       option->name);
1273
1274       if (!(option->flags & GC_OPT_FLAG_LIST))
1275         {
1276           if (*new_value_nr != 1)
1277             gc_error (1, 0, "argument for non-list option %s of type 0 "
1278                       "(none) must be 1", option->name);
1279         }
1280       else
1281         {
1282           if (*new_value_nr == 0)
1283             gc_error (1, 0, "argument for option %s of type 0 (none) "
1284                       "must be positive", option->name);
1285         }
1286
1287       return;
1288     }
1289
1290   arg = new_value;
1291   do
1292     {
1293       if (*arg == '\0' || *arg == ',')
1294         {
1295           if (!(option->flags & GC_OPT_FLAG_ARG_OPT))
1296             gc_error (1, 0, "argument required for option %s", option->name);
1297
1298           if (*arg == ',' && !(option->flags & GC_OPT_FLAG_LIST))
1299             gc_error (1, 0, "list found for non-list option %s", option->name);
1300         }
1301       else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING)
1302         {
1303           if (*arg != '"')
1304             gc_error (1, 0, "string argument for option %s must begin "
1305                       "with a quote (\") character", option->name);
1306         }
1307       else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
1308         {
1309           errno = 0;
1310           (void) strtol (arg, &arg, 0);
1311
1312           if (errno)
1313             gc_error (1, errno, "invalid argument for option %s",
1314                       option->name);
1315
1316           if (*arg != '\0' && *arg != ',')
1317             gc_error (1, 0, "garbage after argument for option %s",
1318                       option->name);
1319         }
1320       else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
1321         {
1322           errno = 0;
1323           (void) strtoul (arg, &arg, 0);
1324
1325           if (errno)
1326             gc_error (1, errno, "invalid argument for option %s",
1327                       option->name);
1328
1329           if (*arg != '\0' && *arg != ',')
1330             gc_error (1, 0, "garbage after argument for option %s",
1331                       option->name);
1332         }
1333       arg = strchr (arg, ',');
1334       if (arg)
1335         arg++;
1336     }
1337   while (arg && *arg);
1338 }
1339
1340
1341 /* Create and verify the new configuration file for the specified
1342    backend and component.  Returns 0 on success and -1 on error.  */
1343 static int
1344 change_options_file (gc_component_t component, gc_backend_t backend,
1345                      char **src_filenamep, char **dest_filenamep,
1346                      char **orig_filenamep)
1347 {
1348   static const char marker[] = "###+++--- GPGConf ---+++###";
1349   /* True if we are within the marker in the config file.  */
1350   int in_marker = 0;
1351   gc_option_t *option;
1352   char *line = NULL;
1353   size_t line_len;
1354   ssize_t length;
1355   int res;
1356   int fd;
1357   FILE *src_file = NULL;
1358   FILE *dest_file = NULL;
1359   char *src_filename;
1360   char *dest_filename;
1361   char *orig_filename;
1362   char *arg;
1363   char *cur_arg = NULL;
1364
1365   option = find_option (component,
1366                         gc_backend[backend].option_name, GC_BACKEND_ANY);
1367   assert (option);
1368   assert (option->active);
1369   assert (gc_arg_type[option->arg_type].fallback != GC_ARG_TYPE_NONE);
1370   assert (!(option->flags & GC_OPT_FLAG_ARG_OPT));
1371
1372   /* FIXME.  Throughout the function, do better error reporting.  */
1373   /* Note that get_config_pathname() calls percent_deescape(), so we
1374      call this before processing the arguments.  */
1375   dest_filename = xstrdup (get_config_pathname (component, backend));
1376   src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ());
1377   orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ());
1378
1379   arg = option->new_value;
1380   if (arg)
1381     {
1382       char *end;
1383
1384       arg++;
1385       end = strchr (arg, ',');
1386       if (end)
1387         *end = '\0';
1388
1389       cur_arg = percent_deescape (arg);
1390       if (end)
1391         {
1392           *end = ',';
1393           arg = end + 1;
1394         }
1395       else
1396         arg = NULL;
1397     }
1398
1399   res = link (dest_filename, orig_filename);
1400   if (res < 0 && errno != ENOENT)
1401     return -1;
1402   if (res < 0)
1403     {
1404       xfree (orig_filename);
1405       orig_filename = NULL;
1406     }
1407
1408   /* We now initialize the return strings, so the caller can do the
1409      cleanup for us.  */
1410   *src_filenamep = src_filename;
1411   *dest_filenamep = dest_filename;
1412   *orig_filenamep = orig_filename;
1413
1414   /* Use open() so that we can use O_EXCL.  */
1415   fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
1416   if (fd < 0)
1417     return -1;
1418   src_file = fdopen (fd, "w");
1419   res = errno;
1420   if (!src_file)
1421     {
1422       errno = res;
1423       return -1;
1424     }
1425
1426   /* Only if ORIG_FILENAME is not NULL did the configuration file
1427      exist already.  In this case, we will copy its content into the
1428      new configuration file, changing it to our liking in the
1429      process.  */
1430   if (orig_filename)
1431     {
1432       dest_file = fopen (dest_filename, "r");
1433       if (!dest_file)
1434         goto change_file_one_err;
1435
1436       while ((length = getline (&line, &line_len, dest_file)) > 0)
1437         {
1438           int disable = 0;
1439           char *start;
1440
1441           if (!strncmp (marker, line, sizeof (marker) - 1))
1442             {
1443               if (!in_marker)
1444                 in_marker = 1;
1445               else
1446                 break;
1447             }
1448
1449           start = line;
1450           while (*start == ' ' || *start == '\t')
1451             start++;
1452           if (*start && *start != '\r' && *start != '\n' && *start != '#')
1453             {
1454               char *end;
1455               char *endp;
1456               char saved_end;
1457
1458               endp = start;
1459               end = endp;
1460
1461               /* Search for the end of the line.  */
1462               while (*endp && *endp != '#' && *endp != '\r' && *endp != '\n')
1463                 {
1464                   endp++;
1465                   if (*endp && *endp != ' ' && *endp != '\t'
1466                       && *endp != '\r' && *endp != '\n' && *endp != '#')
1467                     end = endp + 1;
1468                 }
1469               saved_end = *end;
1470               *end = '\0';
1471
1472               if ((option->new_flags & GC_OPT_FLAG_DEFAULT)
1473                   || !cur_arg || strcmp (start, cur_arg))
1474                 disable = 1;
1475               else
1476                 {
1477                   /* Find next argument.  */
1478                   if (arg)
1479                     {
1480                       char *arg_end;
1481
1482                       arg++;
1483                       arg_end = strchr (arg, ',');
1484                       if (arg_end)
1485                         *arg_end = '\0';
1486
1487                       cur_arg = percent_deescape (arg);
1488                       if (arg_end)
1489                         {
1490                           *arg_end = ',';
1491                           arg = arg_end + 1;
1492                         }
1493                       else
1494                         arg = NULL;
1495                     }
1496                   else
1497                     cur_arg = NULL;
1498                 }
1499
1500               *end = saved_end;
1501             }
1502
1503           if (disable)
1504             {
1505               if (!in_marker)
1506                 {
1507                   fprintf (src_file,
1508                            "# GPGConf disabled this option here at %s\n",
1509                            asctimestamp (gnupg_get_time ()));
1510                   if (ferror (src_file))
1511                     goto change_file_one_err;
1512                   fprintf (src_file, "# %s", line);
1513                   if (ferror (src_file))
1514                     goto change_file_one_err;
1515                 }
1516             }
1517           else
1518             {
1519               fprintf (src_file, "%s", line);
1520               if (ferror (src_file))
1521                 goto change_file_one_err;
1522             }
1523         }
1524       if (ferror (dest_file))
1525         goto change_file_one_err;
1526     }
1527
1528   if (!in_marker)
1529     {
1530       /* There was no marker.  This is the first time we edit the
1531          file.  We add our own marker at the end of the file and
1532          proceed.  Note that we first write a newline, this guards us
1533          against files which lack the newline at the end of the last
1534          line, while it doesn't hurt us in all other cases.  */
1535       fprintf (src_file, "\n%s\n", marker);
1536       if (ferror (src_file))
1537         goto change_file_one_err;
1538     }
1539
1540   /* At this point, we have copied everything up to the end marker
1541      into the new file, except for the arguments we are going to add.
1542      Now, dump the new arguments and write the end marker, possibly
1543      followed by the rest of the original file.  */
1544   while (cur_arg)
1545     {
1546       fprintf (src_file, "%s\n", cur_arg);
1547
1548       /* Find next argument.  */
1549       if (arg)
1550         {
1551           char *end;
1552
1553           arg++;
1554           end = strchr (arg, ',');
1555           if (end)
1556             *end = '\0';
1557
1558           cur_arg = percent_deescape (arg);
1559           if (end)
1560             {
1561               *end = ',';
1562               arg = end + 1;
1563             }
1564           else
1565             arg = NULL;
1566         }
1567       else
1568         cur_arg = NULL;
1569     }
1570
1571   fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
1572   if (ferror (src_file))
1573     goto change_file_one_err;
1574
1575   if (!in_marker)
1576     {
1577       fprintf (src_file, "# GPGConf edited this configuration file.\n");
1578       if (ferror (src_file))
1579         goto change_file_one_err;
1580       fprintf (src_file, "# It will disable options before this marked "
1581                "block, but it will\n");
1582       if (ferror (src_file))
1583         goto change_file_one_err;
1584       fprintf (src_file, "# never change anything below these lines.\n");
1585       if (ferror (src_file))
1586         goto change_file_one_err;
1587     }
1588   if (dest_file)
1589     {
1590       while ((length = getline (&line, &line_len, dest_file)) > 0)
1591         {
1592           fprintf (src_file, "%s", line);
1593           if (ferror (src_file))
1594             goto change_file_one_err;
1595         }
1596       if (ferror (dest_file))
1597         goto change_file_one_err;
1598     }
1599   if (line)
1600     free (line);
1601   res = fclose (src_file);
1602   if (res)
1603     {
1604       res = errno;
1605       close (fd);
1606       if (dest_file)
1607         fclose (dest_file);
1608       errno = res;
1609       return -1;
1610     }
1611   close (fd);
1612   if (dest_file)
1613     {
1614       res = fclose (dest_file);
1615       if (res)
1616         return -1;
1617     }
1618   return 0;
1619
1620  change_file_one_err:
1621   if (line)
1622     free (line);
1623   res = errno;
1624   if (src_file)
1625     {
1626       fclose (src_file);
1627       close (fd);
1628     }
1629   if (dest_file)
1630     fclose (dest_file);
1631   errno = res;
1632   return -1;
1633 }
1634
1635
1636 /* Create and verify the new configuration file for the specified
1637    backend and component.  Returns 0 on success and -1 on error.  */
1638 static int
1639 change_options_program (gc_component_t component, gc_backend_t backend,
1640                         char **src_filenamep, char **dest_filenamep,
1641                         char **orig_filenamep)
1642 {
1643   static const char marker[] = "###+++--- GPGConf ---+++###";
1644   /* True if we are within the marker in the config file.  */
1645   int in_marker = 0;
1646   gc_option_t *option;
1647   char *line = NULL;
1648   size_t line_len;
1649   ssize_t length;
1650   int res;
1651   int fd;
1652   FILE *src_file = NULL;
1653   FILE *dest_file = NULL;
1654   char *src_filename;
1655   char *dest_filename;
1656   char *orig_filename;
1657
1658   /* FIXME.  Throughout the function, do better error reporting.  */
1659   dest_filename = xstrdup (get_config_pathname (component, backend));
1660   src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ());
1661   orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ());
1662
1663   res = link (dest_filename, orig_filename);
1664   if (res < 0 && errno != ENOENT)
1665     return -1;
1666   if (res < 0)
1667     {
1668       xfree (orig_filename);
1669       orig_filename = NULL;
1670     }
1671
1672   /* We now initialize the return strings, so the caller can do the
1673      cleanup for us.  */
1674   *src_filenamep = src_filename;
1675   *dest_filenamep = dest_filename;
1676   *orig_filenamep = orig_filename;
1677
1678   /* Use open() so that we can use O_EXCL.  */
1679   fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
1680   if (fd < 0)
1681     return -1;
1682   src_file = fdopen (fd, "w");
1683   res = errno;
1684   if (!src_file)
1685     {
1686       errno = res;
1687       return -1;
1688     }
1689
1690   /* Only if ORIG_FILENAME is not NULL did the configuration file
1691      exist already.  In this case, we will copy its content into the
1692      new configuration file, changing it to our liking in the
1693      process.  */
1694   if (orig_filename)
1695     {
1696       dest_file = fopen (dest_filename, "r");
1697       if (!dest_file)
1698         goto change_one_err;
1699
1700       while ((length = getline (&line, &line_len, dest_file)) > 0)
1701         {
1702           int disable = 0;
1703           char *start;
1704
1705           if (!strncmp (marker, line, sizeof (marker) - 1))
1706             {
1707               if (!in_marker)
1708                 in_marker = 1;
1709               else
1710                 break;
1711             }
1712
1713           start = line;
1714           while (*start == ' ' || *start == '\t')
1715             start++;
1716           if (*start && *start != '\r' && *start != '\n' && *start != '#')
1717             {
1718               char *end;
1719               char saved_end;
1720
1721               end = start;
1722               while (*end && *end != ' ' && *end != '\t'
1723                      && *end != '\r' && *end != '\n' && *end != '#')
1724                 end++;
1725               saved_end = *end;
1726               *end = '\0';
1727
1728               option = find_option (component, start, backend);
1729               *end = saved_end;
1730               if (option && ((option->new_flags & GC_OPT_FLAG_DEFAULT)
1731                              || option->new_value))
1732                 disable = 1;
1733             }
1734           if (disable)
1735             {
1736               if (!in_marker)
1737                 {
1738                   fprintf (src_file,
1739                            "# GPGConf disabled this option here at %s\n",
1740                            asctimestamp (gnupg_get_time ()));
1741                   if (ferror (src_file))
1742                     goto change_one_err;
1743                   fprintf (src_file, "# %s", line);
1744                   if (ferror (src_file))
1745                     goto change_one_err;
1746                 }
1747             }
1748           else
1749             {
1750               fprintf (src_file, "%s", line);
1751               if (ferror (src_file))
1752                 goto change_one_err;
1753             }
1754         }
1755       if (ferror (dest_file))
1756         goto change_one_err;
1757     }
1758
1759   if (!in_marker)
1760     {
1761       /* There was no marker.  This is the first time we edit the
1762          file.  We add our own marker at the end of the file and
1763          proceed.  Note that we first write a newline, this guards us
1764          against files which lack the newline at the end of the last
1765          line, while it doesn't hurt us in all other cases.  */
1766       fprintf (src_file, "\n%s\n", marker);
1767       if (ferror (src_file))
1768         goto change_one_err;
1769     }
1770   /* At this point, we have copied everything up to the end marker
1771      into the new file, except for the options we are going to change.
1772      Now, dump the changed options (except for those we are going to
1773      revert to their default), and write the end marker, possibly
1774      followed by the rest of the original file.  */
1775   option = gc_component[component].options;
1776   while (option->name)
1777     {
1778       if (!(option->flags & GC_OPT_FLAG_GROUP)
1779           && option->backend == backend
1780           && option->new_value)
1781         {
1782           char *arg = option->new_value;
1783
1784           do
1785             {
1786               if (*arg == '\0' || *arg == ',')
1787                 {
1788                   fprintf (src_file, "%s\n", option->name);
1789                   if (ferror (src_file))
1790                     goto change_one_err;
1791                 }
1792               else if (gc_arg_type[option->arg_type].fallback
1793                        == GC_ARG_TYPE_NONE)
1794                 {
1795                   assert (*arg == '1');
1796                   fprintf (src_file, "%s\n", option->name);
1797                   if (ferror (src_file))
1798                     goto change_one_err;
1799
1800                   arg++;
1801                 }
1802               else if (gc_arg_type[option->arg_type].fallback
1803                        == GC_ARG_TYPE_STRING)
1804                 {
1805                   char *end;
1806                   
1807                   assert (*arg == '"');
1808                   arg++;
1809                   
1810                   end = strchr (arg, ',');
1811                   if (end)
1812                     *end = '\0';
1813
1814                   fprintf (src_file, "%s %s\n", option->name,
1815                            percent_deescape (arg));
1816                   if (ferror (src_file))
1817                     goto change_one_err;
1818
1819                   if (end)
1820                     *end = ',';
1821                   arg = end;
1822                 }
1823               else
1824                 {
1825                   char *end;
1826
1827                   end = strchr (arg, ',');
1828                   if (end)
1829                     *end = '\0';
1830
1831                   fprintf (src_file, "%s %s\n", option->name, arg);
1832                   if (ferror (src_file))
1833                     goto change_one_err;
1834
1835                   if (end)
1836                     *end = ',';
1837                   arg = end;
1838                 }
1839
1840               assert (arg == NULL || *arg == '\0' || *arg == ',');
1841               if (arg && *arg == ',')
1842                 arg++;
1843             }
1844           while (arg && *arg);
1845         }
1846       option++;
1847     }
1848
1849   fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
1850   if (ferror (src_file))
1851     goto change_one_err;
1852
1853   if (!in_marker)
1854     {
1855       fprintf (src_file, "# GPGConf edited this configuration file.\n");
1856       if (ferror (src_file))
1857         goto change_one_err;
1858       fprintf (src_file, "# It will disable options before this marked "
1859                "block, but it will\n");
1860       if (ferror (src_file))
1861         goto change_one_err;
1862       fprintf (src_file, "# never change anything below these lines.\n");
1863       if (ferror (src_file))
1864         goto change_one_err;
1865     }
1866   if (dest_file)
1867     {
1868       while ((length = getline (&line, &line_len, dest_file)) > 0)
1869         {
1870           fprintf (src_file, "%s", line);
1871           if (ferror (src_file))
1872             goto change_one_err;
1873         }
1874       if (ferror (dest_file))
1875         goto change_one_err;
1876     }
1877   if (line)
1878     free (line);
1879   res = fclose (src_file);
1880   if (res)
1881     {
1882       res = errno;
1883       close (fd);
1884       if (dest_file)
1885         fclose (dest_file);
1886       errno = res;
1887       return -1;
1888     }
1889   close (fd);
1890   if (dest_file)
1891     {
1892       res = fclose (dest_file);
1893       if (res)
1894         return -1;
1895     }
1896   return 0;
1897
1898  change_one_err:
1899   if (line)
1900     free (line);
1901   res = errno;
1902   if (src_file)
1903     {
1904       fclose (src_file);
1905       close (fd);
1906     }
1907   if (dest_file)
1908     fclose (dest_file);
1909   errno = res;
1910   return -1;
1911 }
1912
1913
1914 /* Read the modifications from IN and apply them.  */
1915 void
1916 gc_component_change_options (int component, FILE *in)
1917 {
1918   int err = 0;
1919   char *src_pathname[GC_BACKEND_NR];
1920   char *dest_pathname[GC_BACKEND_NR];
1921   char *orig_pathname[GC_BACKEND_NR];
1922   gc_backend_t backend;
1923   gc_option_t *option;
1924   char *line = NULL;
1925   size_t line_len = 0;
1926   ssize_t length;
1927
1928   for (backend = 0; backend < GC_BACKEND_NR; backend++)
1929     {
1930       src_pathname[backend] = NULL;
1931       dest_pathname[backend] = NULL;
1932       orig_pathname[backend] = NULL;
1933     }
1934
1935   while ((length = getline (&line, &line_len, in)) > 0)
1936     {
1937       char *linep;
1938       unsigned long flags = 0;
1939       char *new_value = "";
1940       unsigned long new_value_nr;
1941
1942       /* Strip newline and carriage return, if present.  */
1943       while (length > 0
1944              && (line[length - 1] == '\n' || line[length - 1] == '\r'))
1945         line[--length] = '\0';
1946
1947       linep = strchr (line, ':');
1948       if (linep)
1949         *(linep++) = '\0';
1950
1951       /* Extract additional flags.  Default to none.  */
1952       if (linep)
1953         {
1954           char *end;
1955           char *tail;
1956
1957           end = strchr (linep, ':');
1958           if (end)
1959             *(end++) = '\0';
1960
1961           errno = 0;
1962           flags = strtoul (linep, &tail, 0);
1963           if (errno)
1964             gc_error (1, errno, "malformed flags in option %s", line);
1965           if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
1966             gc_error (1, 0, "garbage after flags in option %s", line);
1967
1968           linep = end;
1969         }
1970
1971       /* Extract default value, if present.  Default to empty if
1972          not.  */
1973       if (linep)
1974         {
1975           char *end;
1976
1977           end = strchr (linep, ':');
1978           if (end)
1979             *(end++) = '\0';
1980
1981           new_value = linep;
1982
1983           linep = end;
1984         }
1985
1986       option = find_option (component, line, GC_BACKEND_ANY);
1987       if (!option)
1988         gc_error (1, 0, "unknown option %s", line);
1989
1990       option_check_validity (option, flags, new_value, &new_value_nr);
1991
1992       option->new_flags = flags;
1993       if (!(flags & GC_OPT_FLAG_DEFAULT))
1994         {
1995           if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
1996               && (option->flags & GC_OPT_FLAG_LIST))
1997             {
1998               char *str;
1999
2000               /* We convert the number to a list of 1's for
2001                  convenient list handling.  */
2002               assert (new_value_nr > 0);
2003               option->new_value = xmalloc ((2 * (new_value_nr - 1) + 1) + 1);
2004               str = option->new_value;
2005               *(str++) = '1';
2006               while (--new_value_nr > 0)
2007                 {
2008                   *(str++) = ',';
2009                   *(str++) = '1';
2010                 }
2011               *(str++) = '\0';
2012             }
2013           else
2014             option->new_value = xstrdup (new_value);
2015         }
2016     }
2017
2018   /* Now that we have collected and locally verified the changes,
2019      write them out to new configuration files, verify them
2020      externally, and then commit them.  */
2021   option = gc_component[component].options;
2022   while (option->name)
2023     {
2024       /* Go on if we have already seen this backend, or if there is
2025          nothing to do.  */
2026       if (src_pathname[option->backend] || !(option->new_flags || option->new_value))
2027         {
2028           option++;
2029           continue;
2030         }
2031
2032       if (gc_backend[option->backend].program)
2033         err = change_options_program (component, option->backend,
2034                                       &src_pathname[component],
2035                                       &dest_pathname[component],
2036                                       &orig_pathname[component]);
2037       else
2038         err = change_options_file (component, option->backend,
2039                                    &src_pathname[component],
2040                                    &dest_pathname[component],
2041                                    &orig_pathname[component]);
2042         
2043       if (err)
2044         break;
2045           
2046       option++;
2047     }
2048
2049   if (!err)
2050     {
2051       int i;
2052
2053       for (i = 0; i < GC_COMPONENT_NR; i++)
2054         {
2055           if (src_pathname[i])
2056             {
2057               /* FIXME: Make a verification here.  */
2058
2059               assert (dest_pathname[i]);
2060
2061               if (orig_pathname[i])
2062                 err = rename (src_pathname[i], dest_pathname[i]);
2063               else
2064                 {
2065                   /* This is a bit safer than rename() because we
2066                      expect DEST_PATHNAME not to be there.  If it
2067                      happens to be there, this will fail.  */
2068                   err = link (src_pathname[i], dest_pathname[i]);
2069                   if (!err)
2070                     unlink (src_pathname[i]);
2071                 }
2072               if (err)
2073                 break;
2074               src_pathname[i] = NULL;
2075             }
2076         }
2077     }
2078
2079   if (err)
2080     {
2081       int i;
2082       int saved_errno = errno;
2083
2084       /* An error occured.  */
2085       for (i = 0; i < GC_COMPONENT_NR; i++)
2086         {
2087           if (src_pathname[i])
2088             {
2089               /* The change was not yet committed.  */
2090               unlink (src_pathname[i]);
2091               if (orig_pathname[i])
2092                 unlink (orig_pathname[i]);
2093             }
2094           else
2095             {
2096               /* The changes were already committed.  FIXME: This is a
2097                  tad dangerous, as we don't know if we don't overwrite
2098                  a version of the file that is even newer than the one
2099                  we just installed.  */
2100               if (orig_pathname[i])
2101                 rename (orig_pathname[i], dest_pathname[i]);
2102               else
2103                 unlink (dest_pathname[i]);
2104             }
2105         }
2106       gc_error (1, saved_errno, "could not commit changes");
2107     }
2108   if (line)
2109     free (line);
2110 }