2004-01-30 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / tools / gpgconf-comp.c
1 /* gpgconf-comp.c - Configuration utility for GnuPG.
2    Copyright (C) 2003 g10 Code GmbH
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-config-file" },
147     { "GPGSM", "gpgsm", "gpgconf-config-file" },
148     { "GPG Agent", "gpg-agent", "gpgconf-config-file" },
149     { "DirMngr", "dirmngr", "gpgconf-config-file" },
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
180     /* Complex argument types.  */
181
182     /* A complete pathname.  */
183     GC_ARG_TYPE_PATHNAME = 4,
184
185     /* An LDAP server in the format
186        HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN.  */
187     GC_ARG_TYPE_LDAP_SERVER = 5,
188
189     /* A 40 character fingerprint.  */
190     GC_ARG_TYPE_KEY_FPR = 6,
191
192     /* ADD NEW ENTRIES HERE.  */
193
194     /* The number of the above entries.  */
195     GC_ARG_TYPE_NR
196   } gc_arg_type_t;
197
198
199 /* For every argument, we record some information about it in the
200    following struct.  */
201 static struct
202 {
203   /* For every argument type exists a basic argument type that can be
204      used as a fallback for input and validation purposes.  */
205   gc_arg_type_t fallback;
206
207   /* Human-readable name of the type.  */
208   const char *name;
209 } gc_arg_type[GC_ARG_TYPE_NR] =
210   {
211     /* The basic argument types have their own types as fallback.  */
212     { GC_ARG_TYPE_NONE, "none" },
213     { GC_ARG_TYPE_STRING, "string" },
214     { GC_ARG_TYPE_INT32, "int32" },
215     { GC_ARG_TYPE_UINT32, "uint32" },
216
217     /* The complex argument types have a basic type as fallback.  */
218     { GC_ARG_TYPE_STRING, "pathname" },
219     { GC_ARG_TYPE_STRING, "ldap server" },
220     { GC_ARG_TYPE_STRING, "key fpr" },
221   };
222
223
224 /* Every option has an associated expert level, than can be used to
225    hide advanced and expert options from beginners.  If you add to
226    this list, don't forget to update GC_LEVEL below.  YOU MUST NOT
227    CHANGE THE NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE
228    EXTERNAL INTERFACE.  */
229 typedef enum
230   {
231     /* The basic options should always be displayed.  */
232     GC_LEVEL_BASIC,
233
234     /* The advanced options may be hidden from beginners.  */
235     GC_LEVEL_ADVANCED,
236
237     /* The expert options should only be displayed to experts.  */
238     GC_LEVEL_EXPERT,
239
240     /* The invisible options should normally never be displayed.  */
241     GC_LEVEL_INVISIBLE,
242
243     /* The internal options are never exported, they mark options that
244        are recorded for internal use only.  */
245     GC_LEVEL_INTERNAL,
246
247     /* ADD NEW ENTRIES HERE.  */
248
249     /* The number of the above entries.  */
250     GC_LEVEL_NR
251   } gc_expert_level_t;
252
253 /* A description for each expert level.  */
254 static struct
255 {
256   const char *name;
257 } gc_level[] =
258   {
259     { "basic" },
260     { "advanced" },
261     { "expert" },
262     { "invisible" },
263     { "internal" }
264   };
265
266
267 /* Option flags.  YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING
268    FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE.  */
269 #define GC_OPT_FLAG_NONE        0
270 /* Some entries in the option list are not options, but mark the
271    beginning of a new group of options.  These entries have the GROUP
272    flag set.  */
273 #define GC_OPT_FLAG_GROUP       (1 << 0)
274 /* The ARG_OPT flag for an option indicates that the argument is
275    optional.  */
276 #define GC_OPT_FLAG_ARG_OPT     (1 << 1)
277 /* The LIST flag for an option indicates that the option can occur
278    several times.  A comma separated list of arguments is used as the
279    argument value.  */
280 #define GC_OPT_FLAG_LIST        (1 << 2)
281 /* The RUNTIME flag for an option indicates that the option can be
282    changed at runtime.  */
283 #define GC_OPT_FLAG_RUNTIME     (1 << 3)
284
285 /* A human-readable description for each flag.  */
286 static struct
287 {
288   const char *name;
289 } gc_flag[] =
290   {
291     { "group" },
292     { "optional arg" },
293     { "list" },
294     { "runtime" }
295   };
296
297
298 /* To each option, or group marker, the information in the GC_OPTION
299    struct is provided.  If you change this, don't forget to update the
300    option list of each component.  */
301 struct gc_option
302 {
303   /* If this is NULL, then this is a terminator in an array of unknown
304      length.  Otherwise, if this entry is a group marker (see FLAGS),
305      then this is the name of the group described by this entry.
306      Otherwise it is the name of the option described by this
307      entry.  The name must not contain a colon.  */
308   const char *name;
309
310   /* The option flags.  If the GROUP flag is set, then this entry is a
311      group marker, not an option, and only the fields LEVEL,
312      DESC_DOMAIN and DESC are valid.  In all other cases, this entry
313      describes a new option and all fields are valid.  */
314   unsigned int flags;
315
316   /* The expert level.  This field is valid for options and groups.  A
317      group has the expert level of the lowest-level option in the
318      group.  */
319   gc_expert_level_t level;
320
321   /* A gettext domain in which the following description can be found.
322      If this is NULL, then DESC is not translated.  Valid for groups
323      and options.  */
324   const char *desc_domain;
325
326   /* A gettext description for this group or option.  If it starts
327      with a '|', then the string up to the next '|' describes the
328      argument, and the description follows the second '|'.  */
329   const char *desc;
330
331   /* The following fields are only valid for options.  */
332
333   /* The type of the option argument.  */
334   gc_arg_type_t arg_type;
335
336   /* The backend that implements this option.  */
337   gc_backend_t backend;
338
339   /* The following fields are set to NULL at startup (because all
340      option's are declared as static variables).  They are at the end
341      of the list so that they can be omitted from the option
342      declarations.  */
343
344   /* The default value for this option.  This is NULL if the option is
345      not present in the backend, the empty string if no default is
346      available, and otherwise a quoted string.  */
347   char *default_value;
348
349   /* The current value of this option.  */
350   char *value;
351
352   /* The new value of this option.  */
353   char *new_value;
354 };
355 typedef struct gc_option gc_option_t;
356
357 /* Use this macro to terminate an option list.  */
358 #define GC_OPTION_NULL { NULL }
359
360 \f
361 /* The options of the GC_COMPONENT_GPG_AGENT component.  */
362 static gc_option_t gc_options_gpg_agent[] =
363  {
364    GC_OPTION_NULL
365  };
366
367
368 /* The options of the GC_COMPONENT_DIRMNGR component.  */
369 static gc_option_t gc_options_dirmngr[] =
370  {
371    /* The configuration file to which we write the changes.  */
372    { "gpgconf-config-file", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
373      NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
374
375    { "Monitor",
376      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
377      NULL, "Options controlling the diagnostic output" },
378    { "verbose", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
379      "dirmngr", "verbose",
380      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
381    { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
382      "dirmngr", "be somewhat more quiet",
383      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
384    { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
385      NULL, NULL,
386      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
387
388    { "Format",
389      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
390      NULL, "Options controlling the format of the output" },
391    { "sh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
392      "dirmngr", "sh-style command output",
393      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
394    { "csh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
395      "dirmngr", "csh-style command output",
396      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
397    
398    { "Configuration",
399      GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
400      NULL, "Options controlling the configuration" },
401    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
402      "dirmngr", "|FILE|read options from FILE",
403      GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
404
405    { "Debug",
406      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
407      "dirmngr", "Options useful for debugging" },
408    { "debug", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
409      "dirmngr", "|FLAGS|set the debugging FLAGS",
410      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
411    { "debug-all", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
412      "dirmngr", "set all debugging flags",
413      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
414    { "no-detach", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
415      "dirmngr", "do not detach from the console",
416      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
417    { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
418      "dirmngr", "|FILE|write logs to FILE",
419      GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
420    { "debug-wait", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
421      NULL, NULL,
422      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
423    { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
424      NULL, NULL,
425      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
426
427    { "Enforcement",
428      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
429      NULL, "Options controlling the interactivity and enforcement" },
430    { "batch", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
431      "dirmngr", "run without asking a user",
432      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
433    { "force", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
434      "dirmngr", "force loading of outdated CRLs",
435      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
436
437    { "LDAP",
438      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
439      NULL, "Configuration of LDAP servers to use" },
440    { "add-servers", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
441      "dirmngr", "add new servers discovered in CRL distribution points"
442      " to serverlist", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
443    { "ldaptimeout", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
444      "dirmngr", "|N|set LDAP timeout to N seconds",
445      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
446    /* The following entry must not be removed, as it is required for
447       the GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST.  */
448    { "ldapserverlist-file",
449      GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
450      "dirmngr", "|FILE|read LDAP server list from FILE",
451      GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
452    /* This entry must come after at least one entry for
453       GC_BACKEND_DIRMNGR in this component, so that the entry for
454       "ldapserverlist-file will be initialized before this one.  */
455    { "LDAP Server", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
456      NULL, "LDAP server list",
457      GC_ARG_TYPE_LDAP_SERVER, GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST },
458
459    { "CRL",
460      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
461      NULL, "Configuration of the CRL" },
462    { "max-replies", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
463      "dirmngr", "|N|do not return more than N items in one query",
464      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
465
466    GC_OPTION_NULL
467  };
468
469 \f
470 /* Component system.  Each component is a set of options that can be
471    configured at the same time.  If you change this, don't forget to
472    update GC_COMPONENT below.  */
473 typedef enum
474   {
475     /* The GPG Agent.  */
476     GC_COMPONENT_GPG_AGENT,
477
478     /* The LDAP Directory Manager for CRLs.  */
479     GC_COMPONENT_DIRMNGR,
480
481     /* The number of components.  */
482     GC_COMPONENT_NR
483   } gc_component_t;
484
485
486 /* The information associated with each component.  */
487 static struct
488 {
489   /* The name of this component.  Must not contain a colon (':')
490      character.  */
491   const char *name;
492
493   /* The gettext domain for the description DESC.  If this is NULL,
494      then the description is not translated.  */
495   const char *desc_domain;
496
497   /* The description for this domain.  */
498   const char *desc;
499
500   /* The list of options for this component, terminated by
501      GC_OPTION_NULL.  */
502   gc_option_t *options;
503 } gc_component[] =
504   {
505     { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent },
506     { "dirmngr", NULL, "CRL Manager", gc_options_dirmngr }
507   };
508
509 \f
510 /* Robust version of dgettext.  */
511 static const char *
512 my_dgettext (const char *domain, const char *msgid)
513 {
514   if (domain)
515     {
516       char *text = dgettext (domain, msgid);
517       return text ? text : msgid;
518     }
519   else
520     return msgid;
521 }
522
523
524 /* Percent-Escape special characters.  The string is valid until the
525    next invocation of the function.  */
526 static char *
527 percent_escape (const char *src)
528 {
529   static char *esc_str;
530   static int esc_str_len;
531   int new_len = 3 * strlen (src) + 1;
532   char *dst;
533
534   if (esc_str_len < new_len)
535     {
536       char *new_esc_str = realloc (esc_str, new_len);
537       if (!new_esc_str)
538         gc_error (1, errno, "can not escape string");
539       esc_str = new_esc_str;
540       esc_str_len = new_len;
541     }
542
543   dst = esc_str;
544   while (*src)
545     {
546       if (*src == '%')
547         {
548           *(dst++) = '%';
549           *(dst++) = '2';
550           *(dst++) = '5';
551         }         
552       else if (*src == ':')
553         {
554           /* The colon is used as field separator.  */
555           *(dst++) = '%';
556           *(dst++) = '3';
557           *(dst++) = 'a';
558         }
559       else if (*src == ',')
560         {
561           /* The comma is used as list separator.  */
562           *(dst++) = '%';
563           *(dst++) = '2';
564           *(dst++) = 'c';
565         }
566       else
567         *(dst++) = *(src);
568       src++;
569     }
570   *dst = '\0';
571   return esc_str;
572 }
573
574
575 \f
576 /* List all components that are available.  */
577 void
578 gc_component_list_components (FILE *out)
579 {
580   gc_component_t idx;
581
582   for (idx = 0; idx < GC_COMPONENT_NR; idx++)
583     {
584       const char *desc = gc_component[idx].desc;
585       desc = my_dgettext (gc_component[idx].desc_domain, desc);
586       fprintf (out, "%s:%s\n", gc_component[idx].name, percent_escape (desc));
587     }
588 }
589
590 \f
591 /* Find the component with the name NAME.  Returns -1 if not
592    found.  */
593 int
594 gc_component_find (const char *name)
595 {
596   gc_component_t idx;
597
598   for (idx = 0; idx < GC_COMPONENT_NR; idx++)
599     {
600       if (!strcmp (name, gc_component[idx].name))
601         return idx;
602     }
603   return -1;
604 }
605
606 \f
607 /* List all options of the component COMPONENT.  */
608 void
609 gc_component_list_options (int component, FILE *out)
610 {  
611   const gc_option_t *option = gc_component[component].options;
612
613   while (option->name)
614     {
615       const char *desc = NULL;
616       char *arg_name = NULL;
617
618       /* Do not output unknown or internal options.  */
619       if (!option->default_value || option->level == GC_LEVEL_INTERNAL)
620         {
621           option++;
622           continue;
623         }
624
625       if (option->desc)
626         {
627           desc = my_dgettext (option->desc_domain, option->desc);
628
629           if (*desc == '|')
630             {
631               const char *arg_tail = strchr (&desc[1], '|');
632
633               if (arg_tail)
634                 {
635                   int arg_len = arg_tail - &desc[1];
636                   arg_name = xmalloc (arg_len + 1);
637                   memcpy (arg_name, &desc[1], arg_len);
638                   arg_name[arg_len] = '\0';
639                   desc = arg_tail + 1;
640                 }
641             }
642         }
643
644       /* YOU MUST NOT REORDER THE FIELDS IN THIS OUTPUT, AS THEIR
645          ORDER IS PART OF THE EXTERNAL INTERFACE.  YOU MUST NOT REMOVE
646          ANY FIELDS.  */
647
648       /* The name field.  */
649       fprintf (out, "%s", option->name);
650
651       /* The flags field.  */
652       fprintf (out, ":%u", option->flags);
653       if (opt.verbose)
654         {
655           putc (' ', out);
656           
657           if (!option->flags)
658             fprintf (out, "none");
659           else
660             {
661               unsigned int flags = option->flags;
662               unsigned int flag = 0;
663               unsigned int first = 1;
664
665               while (flags)
666                 {
667                   if (flags & 1)
668                     {
669                       if (first)
670                         first = 0;
671                       else
672                         putc (',', out);
673                       fprintf (out, "%s", gc_flag[flag].name);
674                     }
675                   flags >>= 1;
676                   flag++;
677                 }
678             }
679         }
680
681       /* The level field.  */
682       fprintf (out, ":%u", option->level);
683       if (opt.verbose)
684         fprintf (out, " %s", gc_level[option->level].name);
685
686       /* The description field.  */
687       fprintf (out, ":%s", desc ? percent_escape (desc) : "");
688
689       /* The type field.  */
690       fprintf (out, ":%u", option->arg_type);
691       if (opt.verbose)
692         fprintf (out, " %s", gc_arg_type[option->arg_type].name);
693
694       /* The alternate type field.  */
695       fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback);
696       if (opt.verbose)
697         fprintf (out, " %s",
698                  gc_arg_type[gc_arg_type[option->arg_type].fallback].name);
699
700       /* The argument name field.  */
701       fprintf (out, ":%s", arg_name ? percent_escape (arg_name) : "");
702       if (arg_name)
703         xfree (arg_name);
704
705       /* The default value field.  */
706       fprintf (out, ":%s", option->default_value ? option->default_value : "");
707
708       /* The value field.  */
709       fprintf (out, ":%s", option->value ? option->value : "");
710
711       /* ADD NEW FIELDS HERE.  */
712
713       putc ('\n', out);
714       option++;
715     }
716 }
717
718
719 /* Find the option NAME in component COMPONENT, for the backend
720    BACKEND.  If BACKEND is GC_BACKEND_ANY, any backend will match.  */
721 static gc_option_t *
722 find_option (gc_component_t component, const char *name,
723              gc_backend_t backend)
724 {
725   gc_option_t *option = gc_component[component].options;
726   while (option->name)
727     {
728       if (!(option->flags & GC_OPT_FLAG_GROUP)
729           && !strcmp (option->name, name)
730           && (backend == GC_BACKEND_ANY || option->backend == backend))
731         break;
732       option++;
733     }
734   return option->name ? option : NULL;
735 }
736
737 \f
738 /* Determine the configuration pathname for the component COMPONENT
739    and backend BACKEND.  */
740 static char *
741 get_config_pathname (gc_component_t component, gc_backend_t backend)
742 {
743   char *pathname;
744   gc_option_t *option = find_option
745     (component, gc_backend[backend].option_config_filename, GC_BACKEND_ANY);
746   assert (option);
747
748   if (!option->default_value)
749     gc_error (1, 0, "option %s, needed by backend %s, was not initialized",
750               gc_backend[backend].option_config_filename,
751               gc_backend[backend].name);
752   if (*option->value)
753     pathname = option->value;
754   else
755     pathname = option->default_value;
756
757   if (*pathname != '/')
758     gc_error (1, 0, "option %s, needed by backend %s, is not absolute",
759               gc_backend[backend].option_config_filename,
760               gc_backend[backend].name);
761
762   return pathname;
763 }
764
765 \f
766 /* Retrieve the options for the component COMPONENT from backend
767    BACKEND, which we already know is a program-type backend.  */
768 static void
769 retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
770 {
771   char *cmd_line;
772   char *line = NULL;
773   size_t line_len = 0;
774   ssize_t length;
775   FILE *output;
776
777   asprintf (&cmd_line, "%s --gpgconf-list", gc_backend[backend].program);
778   if (!cmd_line)
779     gc_error (1, errno, "can not construct command line");
780
781   output = popen (cmd_line, "r");
782   if (!output)
783     gc_error (1, errno, "could not gather active options from %s", cmd_line);
784
785   while ((length = getline (&line, &line_len, output)) > 0)
786     {
787       gc_option_t *option;
788       char *default_value;
789       char *value;
790
791       /* Strip newline and carriage return, if present.  */
792       while (length > 0
793              && (line[length - 1] == '\n' || line[length - 1] == '\r'))
794         line[--length] = '\0';
795
796       /* Extract default value and value, if present.  Default to
797          empty if not.  */
798       default_value = strchr (line, ':');
799       if (!default_value)
800         {
801           default_value = "";
802           value = "";
803         }
804       else
805         {
806           *(default_value++) = '\0';
807           value = strchr (default_value, ':');
808           if (!value)
809             value = "";
810           else
811             {
812               char *end;
813
814               *(value++) = '\0';
815               end = strchr (value, ':');
816               if (end)
817                 *end = '\0';
818             }
819         }
820
821       /* Look up the option in the component and install the
822          configuration data.  */
823       option = find_option (component, line, backend);
824       if (option)
825         {
826           if (option->default_value)
827             gc_error (1, errno, "option %s returned twice from %s",
828                       line, cmd_line);
829           option->default_value = strdup (default_value);
830           option->value = strdup (value);
831           if (!option->default_value || !option->value)
832             gc_error (1, errno, "could not store options");
833         }
834     }
835   if (ferror (output))
836     gc_error (1, errno, "error reading from %s", cmd_line);
837   if (fclose (output) && ferror (output))
838     gc_error (1, errno, "error closing %s", cmd_line);
839   free (cmd_line);
840 }
841
842
843 /* Retrieve the options for the component COMPONENT from backend
844    BACKEND, which we already know is of type file list.  */ 
845 static void
846 retrieve_options_from_file (gc_component_t component, gc_backend_t backend)
847 {
848   gc_option_t *list_option;
849   char *list_pathname;
850   FILE *list_file;
851   char *line = NULL;
852   size_t line_len = 0;
853   ssize_t length;
854   char *list;
855
856   list_option = find_option (component,
857                              gc_backend[backend].option_name, GC_BACKEND_ANY);
858   assert (list_option);
859
860   list_pathname = get_config_pathname (component, backend);
861
862   list_file = fopen (list_pathname, "r");
863   if (ferror (list_file))
864     gc_error (1, errno, "can not open list file %s", list_pathname);
865
866   list = strdup ("\"");
867   if (!list)
868     gc_error (1, errno, "can not allocate initial list string");
869
870   while ((length = getline (&line, &line_len, list_file)) > 0)
871     {
872       char *start;
873       char *end;
874       char *new_list;
875
876       start = line;
877       while (*start == ' ' || *start == '\t')
878         start++;
879       if (!*start || *start == '#' || *start == '\r' || *start == '\n')
880         continue;
881
882       end = start;
883       while (*end && *end != '#' && *end != '\r' && *end != '\n')
884         end++;
885       /* Walk back to skip trailing white spaces.  Looks evil, but
886          works because of the conditions on START and END imposed
887          at this point (END is at least START + 1, and START is
888          not a whitespace character).  */
889       while (*(end - 1) == ' ' || *(end - 1) == '\t')
890         end--;
891       *end = '\0';
892       /* FIXME: Oh, no!  This is so lame!  Use realloc and really
893          append.  */
894       if (list)
895         {
896           asprintf (&new_list, "%s,%s", list, percent_escape (start));
897           free (list);
898           list = new_list;
899         }
900       if (!list)
901         gc_error (1, errno, "can not construct list");
902     }
903   if (ferror (list_file))
904     gc_error (1, errno, "can not read list file %s", list_pathname);
905   list_option->default_value = "";
906   list_option->value = list;
907 }
908
909
910 /* Retrieve the currently active options and their defaults from all
911    involved backends for this component.  */
912 void
913 gc_component_retrieve_options (int component)
914 {
915   int backend_seen[GC_BACKEND_NR];
916   gc_backend_t backend;
917   gc_option_t *option = gc_component[component].options;
918
919   for (backend = 0; backend < GC_BACKEND_NR; backend++)
920     backend_seen[backend] = 0;
921
922   while (option->name)
923     {
924       if (!(option->flags & GC_OPT_FLAG_GROUP))
925         {
926           backend = option->backend;
927
928           if (backend_seen[backend])
929             {
930               option++;
931               continue;
932             }
933           backend_seen[backend] = 1;
934
935           assert (backend != GC_BACKEND_ANY);
936
937           if (gc_backend[backend].program)
938             retrieve_options_from_program (component, backend);
939           else
940             retrieve_options_from_file (component, backend);
941         }
942       option++;
943     }
944 }
945
946 \f
947 /* Perform a simple validity check based on the type.  */
948 static void
949 option_check_validity (gc_option_t *option, const char *new_value)
950 {
951   if (option->new_value)
952     gc_error (1, 0, "option %s already changed", option->name);
953
954   if (!*new_value)
955     return;
956
957   /* FIXME.  Verify that lists are lists, numbers are numbers, strings
958      are strings, etc.  */
959 }
960
961
962 /* Create and verify the new configuration file for the specified
963    backend and component.  Returns 0 on success and -1 on error.  */
964 static int
965 change_options_file (gc_component_t component, gc_backend_t backend,
966                      char **src_filenamep, char **dest_filenamep,
967                      char **orig_filenamep)
968 {
969   /* FIXME.  */
970   assert (!"Not implemented.");
971   return -1;
972 }
973
974
975 /* Create and verify the new configuration file for the specified
976    backend and component.  Returns 0 on success and -1 on error.  */
977 static int
978 change_options_program (gc_component_t component, gc_backend_t backend,
979                         char **src_filenamep, char **dest_filenamep,
980                         char **orig_filenamep)
981 {
982   static const char marker[] = "###+++--- GPGConf ---+++###";
983   /* True if we are within the marker in the config file.  */
984   int in_marker = 0;
985   gc_option_t *option;
986   char *line;
987   size_t line_len;
988   ssize_t length;
989   int res;
990   int fd;
991   FILE *src_file = NULL;
992   FILE *dest_file = NULL;
993   char *src_filename;
994   char *dest_filename;
995   char *orig_filename;
996
997   /* FIXME.  Throughout the function, do better error reporting.  */
998   dest_filename = strdup (get_config_pathname (component, backend));
999   if (!dest_filename)
1000     return -1;
1001   asprintf (&src_filename, "%s.gpgconf.%i.new", dest_filename, getpid ());
1002   if (!src_filename)
1003     return -1;
1004   asprintf (&orig_filename, "%s.gpgconf.%i.bak", dest_filename, getpid ());
1005   if (!orig_filename)
1006     return -1;
1007
1008   res = link (dest_filename, orig_filename);
1009   if (res < 0 && errno != ENOENT)
1010     return -1;
1011   if (res < 0)
1012     {
1013       free (orig_filename);
1014       orig_filename = NULL;
1015     }
1016   /* We now initialize the return strings, so the caller can do the
1017      cleanup for us.  */
1018   *src_filenamep = src_filename;
1019   *dest_filenamep = dest_filename;
1020   *orig_filenamep = orig_filename;
1021
1022   /* Use open() so that we can use O_EXCL.  */
1023   fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
1024   if (fd < 0)
1025     return -1;
1026   src_file = fdopen (fd, "w");
1027   res = errno;
1028   if (!src_file)
1029     {
1030       errno = res;
1031       return -1;
1032     }
1033
1034   /* Only if ORIG_FILENAME is not NULL did the configuration file
1035      exist already.  In this case, we will copy its content into the
1036      new configuration file, changing it to our liking in the
1037      process.  */
1038   if (orig_filename)
1039     {
1040       dest_file = fopen (dest_filename, "r");
1041       if (!dest_file)
1042         goto change_one_err;
1043
1044       while ((length = getline (&line, &line_len, dest_file)) > 0)
1045         {
1046           int disable = 0;
1047           char *start;
1048           char *end;
1049
1050           if (!strncmp (marker, line, sizeof (marker) - 1))
1051             {
1052               if (!in_marker)
1053                 in_marker = 1;
1054               else
1055                 break;
1056             }
1057
1058           start = line;
1059           while (*start == ' ' || *start == '\t')
1060             start++;
1061           if (*start && *start != '\r' && *start != '\n' && *start != '#')
1062             {
1063               char saved_end;
1064
1065               end = start;
1066               while (*end && *end != ' ' && *end != '\t'
1067                      && *end != '\r' && *end != '\n' && *end != '#')
1068                 end++;
1069               saved_end = *end;
1070               *end = '\0';
1071
1072               option = find_option (component, start, backend);
1073               *end = saved_end;
1074               if (option && option->new_value)
1075                 disable = 1;
1076             }
1077           if (disable)
1078             {
1079               if (!in_marker)
1080                 {
1081                   fprintf (src_file,
1082                            "# GPGConf disabled this option here at %s\n",
1083                            asctimestamp (gnupg_get_time ()));
1084                   if (ferror (src_file))
1085                     goto change_one_err;
1086                   fprintf (src_file, "# %s", line);
1087                   if (ferror (src_file))
1088                     goto change_one_err;
1089                 }
1090             }
1091           else
1092             {
1093               fprintf (src_file, "%s", line);
1094               if (ferror (src_file))
1095                 goto change_one_err;
1096             }
1097         }
1098       if (ferror (dest_file))
1099         goto change_one_err;
1100     }
1101
1102   if (!in_marker)
1103     {
1104       /* There was no marker.  This is the first time we edit the
1105          file.  We add our own marker at the end of the file and
1106          proceed.  Note that we first write a newline, this guards us
1107          against files which lack the newline at the end of the last
1108          line, while it doesn't hurt us in all other cases.  */
1109       fprintf (src_file, "\n%s\n", marker);
1110       if (ferror (src_file))
1111         goto change_one_err;
1112     }
1113   /* At this point, we have copied everything up to the end marker
1114      into the new file, except for the options we are going to change.
1115      Now, dump the changed options (except for those we are going to
1116      revert to their default), and write the end marker, possibly
1117      followed by the rest of the original file.  */
1118   option = gc_component[component].options;
1119   while (option->name)
1120     {
1121       if (!(option->flags & GC_OPT_FLAG_GROUP)
1122           && option->backend == backend
1123           && option->new_value
1124           && *option->new_value)
1125         {
1126           if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING)
1127             fprintf (src_file, "%s %s\n", option->name, &option->new_value[1]);
1128           else if (option->arg_type == GC_ARG_TYPE_NONE)
1129             fprintf (src_file, "%s\n", option->name);
1130           else
1131             fprintf (src_file, "%s %s\n", option->name, option->new_value);
1132           if (ferror (src_file))
1133             goto change_one_err;
1134         }
1135       option++;
1136     }
1137   {
1138     fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
1139     if (ferror (src_file))
1140       goto change_one_err;
1141   }
1142   if (!in_marker)
1143     {
1144       fprintf (src_file, "# GPGConf edited this configuration file.\n");
1145       if (ferror (src_file))
1146         goto change_one_err;
1147       fprintf (src_file, "# It will disable options before this marked "
1148                "block, but it will\n");
1149       if (ferror (src_file))
1150         goto change_one_err;
1151       fprintf (src_file, "# never change anything below these lines.\n");
1152       if (ferror (src_file))
1153         goto change_one_err;
1154     }
1155   if (dest_file)
1156     {
1157       while ((length = getline (&line, &line_len, dest_file)) > 0)
1158         {
1159           fprintf (src_file, "%s", line);
1160           if (ferror (src_file))
1161             goto change_one_err;
1162         }
1163       if (ferror (dest_file))
1164         goto change_one_err;
1165     }
1166   res = fclose (src_file);
1167   if (res)
1168     {
1169       res = errno;
1170       close (fd);
1171       if (dest_file)
1172         fclose (dest_file);
1173       errno = res;
1174       return -1;
1175     }
1176   close (fd);
1177   if (dest_file)
1178     {
1179       res = fclose (dest_file);
1180       if (res)
1181         return -1;
1182     }
1183   return 0;
1184
1185  change_one_err:
1186   res = errno;
1187   if (src_file)
1188     {
1189       fclose (src_file);
1190       close (fd);
1191     }
1192   if (dest_file)
1193     fclose (dest_file);
1194   errno = res;
1195   return -1;
1196 }
1197
1198 /* Read the modifications from IN and apply them.  */
1199 void
1200 gc_component_change_options (int component, FILE *in)
1201 {
1202   int err = 0;
1203   char *src_pathname[GC_BACKEND_NR];
1204   char *dest_pathname[GC_BACKEND_NR];
1205   char *orig_pathname[GC_BACKEND_NR];
1206   gc_backend_t backend;
1207   gc_option_t *option;
1208   char *line = NULL;
1209   size_t line_len = 0;
1210   ssize_t length;
1211
1212   for (backend = 0; backend < GC_BACKEND_NR; backend++)
1213     {
1214       src_pathname[backend] = NULL;
1215       dest_pathname[backend] = NULL;
1216       orig_pathname[backend] = NULL;
1217     }
1218
1219   while ((length = getline (&line, &line_len, in)) > 0)
1220     {
1221       char *value;
1222
1223       /* Strip newline and carriage return, if present.  */
1224       while (length > 0
1225              && (line[length - 1] == '\n' || line[length - 1] == '\r'))
1226         line[--length] = '\0';
1227
1228       value = strchr (line, ':');
1229       if (!value)
1230         value = "";
1231       else
1232         {
1233           char *end;
1234
1235           *(value++) = '\0';
1236           end = strchr (value, ':');
1237           if (end)
1238             *end = '\0';
1239         }
1240
1241       option = find_option (component, line, GC_BACKEND_ANY);
1242       if (!option)
1243         gc_error (1, 0, "unknown option %s", line);
1244
1245       option_check_validity (option, value);
1246       option->new_value = strdup (value);
1247     }
1248
1249   /* Now that we have collected and locally verified the changes,
1250      write them out to new configuration files, verify them
1251      externally, and then commit them.  */
1252   option = gc_component[component].options;
1253   while (option->name)
1254     {
1255       /* Go on if we have already seen this backend, or if there is
1256          nothing to do.  */
1257       if (src_pathname[option->backend] || !option->new_value)
1258         {
1259           option++;
1260           continue;
1261         }
1262
1263       if (gc_backend[option->backend].program)
1264         err = change_options_program (component, option->backend,
1265                                       &src_pathname[component],
1266                                       &dest_pathname[component],
1267                                       &orig_pathname[component]);
1268       else
1269         err = change_options_file (component, option->backend,
1270                                    &src_pathname[component],
1271                                    &dest_pathname[component],
1272                                    &orig_pathname[component]);
1273         
1274       if (err)
1275         break;
1276           
1277       option++;
1278     }
1279   if (!err)
1280     {
1281       int i;
1282
1283       for (i = 0; i < GC_COMPONENT_NR; i++)
1284         {
1285           if (src_pathname[i])
1286             {
1287               /* FIXME: Make a verification here.  */
1288
1289               assert (dest_pathname[i]);
1290
1291               if (orig_pathname[i])
1292                 err = rename (src_pathname[i], dest_pathname[i]);
1293               else
1294                 {
1295                   /* This is a bit safer than rename() because we
1296                      expect DEST_PATHNAME not to be there.  If it
1297                      happens to be there, this will fail.  */
1298                   err = link (src_pathname[i], dest_pathname[i]);
1299                   if (!err)
1300                     unlink (src_pathname[i]);
1301                 }
1302               if (err)
1303                 break;
1304               src_pathname[i] = NULL;
1305             }
1306         }
1307     }
1308
1309   if (err)
1310     {
1311       int i;
1312       int saved_errno = errno;
1313
1314       /* An error occured.  */
1315       for (i = 0; i < GC_COMPONENT_NR; i++)
1316         {
1317           if (src_pathname[i])
1318             {
1319               /* The change was not yet committed.  */
1320               unlink (src_pathname[i]);
1321               if (orig_pathname[i])
1322                 unlink (orig_pathname[i]);
1323             }
1324           else
1325             {
1326               /* The changes were already committed.  FIXME: This is a
1327                  tad dangerous, as we don't know if we don't overwrite
1328                  a version of the file that is even newer than the one
1329                  we just installed.  */
1330               if (orig_pathname[i])
1331                 rename (orig_pathname[i], dest_pathname[i]);
1332               else
1333                 unlink (dest_pathname[i]);
1334             }
1335         }
1336       gc_error (1, saved_errno, "could not commit changes");
1337     }
1338 }